Time.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "Time.H"
30 #include "PstreamReduceOps.H"
31 #include "argList.H"
32 #include "HashSet.H"
33 #include "profiling.H"
34 #include "demandDrivenData.H"
35 #include "IOdictionary.H"
36 #include "registerSwitch.H"
37 
38 #include <sstream>
39 
40 // * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44  defineTypeNameAndDebug(Time, 0);
45 }
46 
47 const Foam::Enum
48 <
50 >
52 ({
53  { stopAtControls::saEndTime, "endTime" },
54  { stopAtControls::saNoWriteNow, "noWriteNow" },
55  { stopAtControls::saWriteNow, "writeNow" },
56  { stopAtControls::saNextWrite, "nextWrite" },
57  // Leave saUnknown untabulated - fallback to flag unknown settings
58 });
59 
60 
61 const Foam::Enum
62 <
64 >
66 ({
67  { writeControls::wcNone, "none" },
68  { writeControls::wcTimeStep, "timeStep" },
69  { writeControls::wcRunTime, "runTime" },
70  { writeControls::wcAdjustableRunTime, "adjustable" },
71  { writeControls::wcAdjustableRunTime, "adjustableRunTime" },
72  { writeControls::wcClockTime, "clockTime" },
73  { writeControls::wcCpuTime, "cpuTime" },
74  // Leave wcUnknown untabulated - fallback to flag unknown settings
75 });
76 
77 
79 
81 
82 const int Foam::Time::maxPrecision_(3 - log10(SMALL));
83 
85 
87 (
88  Foam::debug::infoSwitch("printExecutionFormat", 0)
89 );
90 
92 (
93  "printExecutionFormat",
94  int,
96 );
97 
98 
99 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
100 
102 {
103  bool adjustTime = false;
104  scalar timeToNextWrite = VGREAT;
105 
107  {
108  adjustTime = true;
109  timeToNextWrite = max
110  (
111  0.0,
113  );
114  }
115 
116  if (adjustTime)
117  {
118  scalar nSteps = timeToNextWrite/deltaT_;
119 
120  // For tiny deltaT the label can overflow!
121  if (nSteps < labelMax)
122  {
123  // nSteps can be < 1 so make sure at least 1
124  label nStepsToNextWrite = max(1, round(nSteps));
125 
126  scalar newDeltaT = timeToNextWrite/nStepsToNextWrite;
127 
128  // Control the increase of the time step to within a factor of 2
129  // and the decrease within a factor of 5.
130  if (newDeltaT >= deltaT_)
131  {
132  deltaT_ = min(newDeltaT, 2.0*deltaT_);
133  }
134  else
135  {
136  deltaT_ = max(newDeltaT, 0.2*deltaT_);
137  }
138  }
139  }
140 
141  functionObjects_.adjustTimeStep();
142 }
143 
144 
146 {
147  // default is to resume calculation from "latestTime"
148  const word startFrom = controlDict_.lookupOrDefault<word>
149  (
150  "startFrom",
151  "latestTime"
152  );
153 
154  if (startFrom == "startTime")
155  {
156  controlDict_.readEntry("startTime", startTime_);
157  }
158  else
159  {
160  // Search directory for valid time directories
161  instantList timeDirs = findTimes(path(), constant());
162 
163  const label nTimes = timeDirs.size();
164 
165  if (startFrom == "firstTime")
166  {
167  if (nTimes > 1 && timeDirs.first().name() == constant())
168  {
169  startTime_ = timeDirs[1].value();
170  }
171  else if (nTimes)
172  {
173  startTime_ = timeDirs.first().value();
174  }
175  }
176  else if (startFrom == "latestTime")
177  {
178  if (nTimes)
179  {
180  startTime_ = timeDirs.last().value();
181  }
182  }
183  else
184  {
185  FatalIOErrorInFunction(controlDict_)
186  << "expected startTime, firstTime or latestTime"
187  << " found '" << startFrom << "'"
188  << exit(FatalIOError);
189  }
190  }
191 
192  setTime(startTime_, 0);
193 
194  readDict();
195  deltaTSave_ = deltaT_;
196  deltaT0_ = deltaT_;
197 
198  // Check if time directory exists
199  // If not increase time precision to see if it is formatted differently.
200  if (!fileHandler().exists(timePath(), false))
201  {
202  int oldPrecision = precision_;
203  int requiredPrecision = -1;
204  bool found = false;
205  word oldTime(timeName());
206  for
207  (
208  precision_ = maxPrecision_;
209  precision_ > oldPrecision;
210  --precision_
211  )
212  {
213  // Update the time formatting
214  setTime(startTime_, 0);
215 
216  word newTime(timeName());
217  if (newTime == oldTime)
218  {
219  break;
220  }
221  oldTime = newTime;
222 
223  // Check the existence of the time directory with the new format
224  found = fileHandler().exists(timePath(), false);
225 
226  if (found)
227  {
228  requiredPrecision = precision_;
229  }
230  }
231 
232  if (requiredPrecision > 0)
233  {
234  // Update the time precision
235  precision_ = requiredPrecision;
236 
237  // Update the time formatting
238  setTime(startTime_, 0);
239 
241  << "Increasing the timePrecision from " << oldPrecision
242  << " to " << precision_
243  << " to support the formatting of the current time directory "
244  << timeName() << nl << endl;
245  }
246  else
247  {
248  // Could not find time directory so assume it is not present
249  precision_ = oldPrecision;
250 
251  // Revert the time formatting
252  setTime(startTime_, 0);
253  }
254  }
255 
256  if (Pstream::parRun())
257  {
258  scalar sumStartTime = startTime_;
259  reduce(sumStartTime, sumOp<scalar>());
260  if
261  (
262  mag(Pstream::nProcs()*startTime_ - sumStartTime)
263  > Pstream::nProcs()*deltaT_/10.0
264  )
265  {
266  FatalIOErrorInFunction(controlDict_)
267  << "Start time is not the same for all processors" << nl
268  << "processor " << Pstream::myProcNo() << " has startTime "
269  << startTime_ << exit(FatalIOError);
270  }
271  }
272 
273  IOdictionary timeDict
274  (
275  IOobject
276  (
277  "time",
278  timeName(),
279  "uniform",
280  *this,
283  false
284  )
285  );
286 
287  // Read and set the deltaT only if time-step adjustment is active
288  // otherwise use the deltaT from the controlDict
289  if (controlDict_.lookupOrDefault("adjustTimeStep", false))
290  {
291  if (timeDict.readIfPresent("deltaT", deltaT_))
292  {
293  deltaTSave_ = deltaT_;
294  deltaT0_ = deltaT_;
295  }
296  }
297 
298  timeDict.readIfPresent("deltaT0", deltaT0_);
299 
300  if (timeDict.readIfPresent("index", startTimeIndex_))
301  {
302  timeIndex_ = startTimeIndex_;
303  }
304 
305 
306  // Check if values stored in time dictionary are consistent
307 
308  // 1. Based on time name
309  bool checkValue = true;
310 
311  string storedTimeName;
312  if (timeDict.readIfPresent("name", storedTimeName))
313  {
314  if (storedTimeName == timeName())
315  {
316  // Same time. No need to check stored value
317  checkValue = false;
318  }
319  }
320 
321  // 2. Based on time value
322  // (consistent up to the current time writing precision so it won't
323  // trigger if we just change the write precision)
324  if (checkValue)
325  {
326  scalar storedTimeValue;
327  if (timeDict.readIfPresent("value", storedTimeValue))
328  {
329  word storedTimeName(timeName(storedTimeValue));
330 
331  if (storedTimeName != timeName())
332  {
333  IOWarningInFunction(timeDict)
334  << "Time read from time dictionary " << storedTimeName
335  << " differs from actual time " << timeName() << '.' << nl
336  << " This may cause unexpected database behaviour."
337  << " If you are not interested" << nl
338  << " in preserving time state delete"
339  << " the time dictionary."
340  << endl;
341  }
342  }
343  }
344 }
345 
346 
347 void Foam::Time::setMonitoring(const bool forceProfiling)
348 {
349  const dictionary* profilingDict = controlDict_.findDict("profiling");
350  if (!profilingDict)
351  {
352  // ... or from etc/controlDict
353  profilingDict = debug::controlDict().findDict("profiling");
354  }
355 
356  // initialize profiling on request
357  // otherwise rely on profiling entry within controlDict
358  // and skip if 'active' keyword is explicitly set to false
359  if (forceProfiling)
360  {
362  (
363  IOobject
364  (
365  "profiling",
366  timeName(),
367  "uniform",
368  *this,
371  ),
372  *this
373  );
374  }
375  else if
376  (
377  profilingDict
378  && profilingDict->lookupOrDefault("active", true)
379  )
380  {
382  (
383  *profilingDict,
384  IOobject
385  (
386  "profiling",
387  timeName(),
388  "uniform",
389  *this,
392  ),
393  *this
394  );
395  }
396 
397  // Time objects not registered so do like objectRegistry::checkIn ourselves.
398  if (runTimeModifiable_)
399  {
400  // Monitor all files that controlDict depends on
401  fileHandler().addWatches(controlDict_, controlDict_.files());
402  }
403 
404  // Clear dependent files - not needed now
405  controlDict_.files().clear();
406 }
407 
408 
409 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
410 
412 (
413  const word& ctrlDictName,
414  const fileName& rootPath,
415  const fileName& caseName,
416  const word& systemName,
417  const word& constantName,
418  const bool enableFunctionObjects,
419  const bool enableLibs
420 )
421 :
422  TimePaths
423  (
424  rootPath,
425  caseName,
426  systemName,
427  constantName
428  ),
429 
430  objectRegistry(*this),
431 
432  loopProfiling_(nullptr),
433  libs_(),
434 
435  controlDict_
436  (
437  IOobject
438  (
439  ctrlDictName,
440  system(),
441  *this,
444  false
445  )
446  ),
447 
448  startTimeIndex_(0),
449  startTime_(0),
450  endTime_(0),
451 
452  stopAt_(saEndTime),
453  writeControl_(wcTimeStep),
454  writeInterval_(GREAT),
455  purgeWrite_(0),
456  subCycling_(0),
457  writeOnce_(false),
458  sigWriteNow_(*this, true),
459  sigStopAtWriteNow_(*this, true),
460  writeStreamOption_(IOstream::ASCII),
461  graphFormat_("raw"),
462  runTimeModifiable_(false),
463  functionObjects_(*this, false)
464 {
465  if (enableFunctionObjects)
466  {
467  functionObjects_.on();
468  }
469 
470  if (enableLibs)
471  {
472  libs_.open(controlDict_, "libs");
473  }
474 
475  // Explicitly set read flags on objectRegistry so anything constructed
476  // from it reads as well (e.g. fvSolution).
478 
479  setControls();
480  setMonitoring();
481 }
482 
483 
485 (
486  const word& ctrlDictName,
487  const argList& args,
488  const word& systemName,
489  const word& constantName
490 )
491 :
492  TimePaths(args, systemName, constantName),
493 
494  objectRegistry(*this),
495 
496  loopProfiling_(nullptr),
497  libs_(),
498 
499  controlDict_
500  (
501  IOobject
502  (
503  ctrlDictName,
504  system(),
505  *this,
508  false
509  )
510  ),
511 
512  startTimeIndex_(0),
513  startTime_(0),
514  endTime_(0),
515 
516  stopAt_(saEndTime),
517  writeControl_(wcTimeStep),
518  writeInterval_(GREAT),
519  purgeWrite_(0),
520  subCycling_(0),
521  writeOnce_(false),
522  sigWriteNow_(*this, true),
523  sigStopAtWriteNow_(*this, true),
524  writeStreamOption_(IOstream::ASCII),
525  graphFormat_("raw"),
526  runTimeModifiable_(false),
527  functionObjects_(*this, false)
528 {
529  // Functions
530  //
531  // * '-withFunctionObjects' exists and used = enable
532  // * '-noFunctionObjects' exists and used = disable
533  // * default: no functions if there is no way to enable/disable them
534  if
535  (
536  argList::validOptions.found("withFunctionObjects")
537  ? args.found("withFunctionObjects")
538  : argList::validOptions.found("noFunctionObjects")
539  ? !args.found("noFunctionObjects")
540  : false
541  )
542  {
543  functionObjects_.on();
544  }
545 
546  // Libraries
547  //
548  // * enabled unless '-no-libs' option was used
549  if (!args.found("no-libs"))
550  {
551  libs_.open(controlDict_, "libs");
552  }
553 
554  // Explicitly set read flags on objectRegistry so anything constructed
555  // from it reads as well (e.g. fvSolution).
557 
558  setControls();
559 
560  // '-profiling' = force profiling, ignore controlDict entry
561  setMonitoring(args.found("profiling"));
562 }
563 
564 
566 (
567  const dictionary& dict,
568  const fileName& rootPath,
569  const fileName& caseName,
570  const word& systemName,
571  const word& constantName,
572  const bool enableFunctionObjects,
573  const bool enableLibs
574 )
575 :
576  TimePaths
577  (
578  rootPath,
579  caseName,
580  systemName,
581  constantName
582  ),
583 
584  objectRegistry(*this),
585 
586  loopProfiling_(nullptr),
587  libs_(),
588 
589  controlDict_
590  (
591  IOobject
592  (
593  controlDictName,
594  system(),
595  *this,
598  false
599  ),
600  dict
601  ),
602 
603  startTimeIndex_(0),
604  startTime_(0),
605  endTime_(0),
606 
607  stopAt_(saEndTime),
608  writeControl_(wcTimeStep),
609  writeInterval_(GREAT),
610  purgeWrite_(0),
611  subCycling_(0),
612  writeOnce_(false),
613  sigWriteNow_(*this, true),
614  sigStopAtWriteNow_(*this, true),
615  writeStreamOption_(IOstream::ASCII),
616  graphFormat_("raw"),
617  runTimeModifiable_(false),
618  functionObjects_(*this, false)
619 {
620  if (enableFunctionObjects)
621  {
622  functionObjects_.on();
623  }
624 
625  if (enableLibs)
626  {
627  libs_.open(controlDict_, "libs");
628  }
629 
630 
631  // Explicitly set read flags on objectRegistry so anything constructed
632  // from it reads as well (e.g. fvSolution).
634 
635  // Since could not construct regIOobject with setting:
636  controlDict_.readOpt() = IOobject::MUST_READ_IF_MODIFIED;
637 
638  setControls();
639  setMonitoring();
640 }
641 
642 
644 (
645  const fileName& rootPath,
646  const fileName& caseName,
647  const word& systemName,
648  const word& constantName,
649  const bool enableFunctionObjects,
650  const bool enableLibs
651 )
652 :
653  TimePaths
654  (
655  rootPath,
656  caseName,
657  systemName,
658  constantName
659  ),
660 
661  objectRegistry(*this),
662 
663  loopProfiling_(nullptr),
664  libs_(),
665 
666  controlDict_
667  (
668  IOobject
669  (
670  controlDictName,
671  system(),
672  *this,
675  false
676  )
677  ),
678 
679  startTimeIndex_(0),
680  startTime_(0),
681  endTime_(0),
682 
683  stopAt_(saEndTime),
684  writeControl_(wcTimeStep),
685  writeInterval_(GREAT),
686  purgeWrite_(0),
687  subCycling_(0),
688  writeOnce_(false),
689  writeStreamOption_(IOstream::ASCII),
690  graphFormat_("raw"),
691  runTimeModifiable_(false),
692  functionObjects_(*this, false)
693 {
694  if (enableFunctionObjects)
695  {
696  functionObjects_.on();
697  }
698 
699  if (enableLibs)
700  {
701  libs_.open(controlDict_, "libs");
702  }
703 
704  setMonitoring(); // for profiling etc
705 }
706 
707 
708 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
709 
711 {
712  return
714  (
715  ".", // root-path
716  ".", // case-name
717  "system",
718  "constant",
719  false, // No enableFunctionObjects
720  false // No enableLibs
721  );
722 }
723 
724 
726 {
727  return
729  (
730  caseDir.path(), // root-path
731  caseDir.name(), // case-name
732  "system",
733  "constant",
734  false, // No enableFunctionObjects
735  false // No enableLibs
736  );
737 }
738 
739 
740 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
741 
743 {
744  deleteDemandDrivenData(loopProfiling_);
745 
746  forAllReverse(controlDict_.watchIndices(), i)
747  {
748  fileHandler().removeWatch(controlDict_.watchIndices()[i]);
749  }
750 
751  // Destroy function objects first
752  functionObjects_.clear();
753 
754  // Clean up profiling
755  profiling::stop(*this);
756 
757  // Ensure all owned objects are also cleaned up now
759 }
760 
761 
762 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
763 
764 Foam::word Foam::Time::timeName(const scalar t, const int precision)
765 {
766  std::ostringstream buf;
767  buf.setf(ios_base::fmtflags(format_), ios_base::floatfield);
768  buf.precision(precision);
769  buf << t;
770  return buf.str();
771 }
772 
773 
775 {
776  return dimensionedScalar::name();
777 }
778 
779 
781 (
782  const fileName& dir,
783  const word& name,
784  const IOobject::readOption rOpt,
785  const word& stopInstance
786 ) const
787 {
788  IOobject startIO
789  (
790  name, // name might be empty!
791  timeName(),
792  dir,
793  *this,
794  rOpt
795  );
796 
797  IOobject io
798  (
799  fileHandler().findInstance
800  (
801  startIO,
802  timeOutputValue(),
803  stopInstance
804  )
805  );
806  return io.instance();
807 }
808 
809 
811 (
812  const fileName& directory,
813  const instant& t
814 ) const
815 {
816  // Simplified version: use findTimes (readDir + sort). The expensive
817  // bit is the readDir, not the sorting. Tbd: avoid calling findInstancePath
818  // from filePath.
819 
820  instantList timeDirs = findTimes(path(), constant());
821  // Note:
822  // - times will include constant (with value 0) as first element.
823  // For backwards compatibility make sure to find 0 in preference
824  // to constant.
825  // - list is sorted so could use binary search
826 
827  forAllReverse(timeDirs, i)
828  {
829  if (t.equal(timeDirs[i].value()))
830  {
831  return timeDirs[i].name();
832  }
833  }
834 
835  return word::null;
836 }
837 
838 
840 {
841  return findInstancePath(path(), t);
842 }
843 
844 
846 {
847  return startTimeIndex_;
848 }
849 
850 
852 {
853  return dimensionedScalar("startTime", dimTime, startTime_);
854 }
855 
856 
858 {
859  return dimensionedScalar("endTime", dimTime, endTime_);
860 }
861 
862 
864 {
865  return stopAt_;
866 }
867 
868 
869 bool Foam::Time::run() const
870 {
871  deleteDemandDrivenData(loopProfiling_);
872 
873  bool isRunning = value() < (endTime_ - 0.5*deltaT_);
874 
875  if (!subCycling_)
876  {
877  // Only execute when the condition is no longer true
878  // ie, when exiting the control loop
879  if (!isRunning && timeIndex_ != startTimeIndex_)
880  {
881  // Ensure functionObjects execute on last time step
882  // (and hence write uptodate functionObjectProperties)
883  {
884  addProfiling(fo, "functionObjects.execute()");
885  functionObjects_.execute();
886  }
887  {
888  addProfiling(fo, "functionObjects.end()");
889  functionObjects_.end();
890  }
891  }
892  }
893 
894  if (isRunning)
895  {
896  if (!subCycling_)
897  {
898  const_cast<Time&>(*this).readModifiedObjects();
899 
900  if (timeIndex_ == startTimeIndex_)
901  {
902  addProfiling(functionObjects, "functionObjects.start()");
903  functionObjects_.start();
904  }
905  else
906  {
907  addProfiling(functionObjects, "functionObjects.execute()");
908  functionObjects_.execute();
909  }
910 
911  // Check if the execution of functionObjects require re-reading
912  // any files. This moves effect of e.g. 'timeActivatedFileUpdate'
913  // one time step forward. Note that we cannot call
914  // readModifiedObjects from within timeActivatedFileUpdate since
915  // it might re-read the functionObjects themselves (and delete
916  // the timeActivatedFileUpdate one)
917  if (functionObjects_.filesModified())
918  {
919  const_cast<Time&>(*this).readModifiedObjects();
920  }
921  }
922 
923  // Update the "is-running" status following the
924  // possible side-effects from functionObjects
925  isRunning = value() < (endTime_ - 0.5*deltaT_);
926 
927  // (re)trigger profiling
928  if (profiling::active())
929  {
930  loopProfiling_ =
931  new profilingTrigger("time.run() " + objectRegistry::name());
932  }
933  }
934 
935  return isRunning;
936 }
937 
938 
940 {
941  const bool isRunning = run();
942 
943  if (isRunning)
944  {
945  operator++();
946  }
947 
948  return isRunning;
949 }
950 
951 
952 bool Foam::Time::end() const
953 {
954  return value() > (endTime_ + 0.5*deltaT_);
955 }
956 
957 
958 bool Foam::Time::stopAt(const stopAtControls stopCtrl) const
959 {
960  if (stopCtrl == stopAtControls::saUnknown)
961  {
962  return false;
963  }
964 
965  const bool changed = (stopAt_ != stopCtrl);
966  stopAt_ = stopCtrl;
967  endTime_ = GREAT;
968 
969  // Adjust endTime
970  if (stopCtrl == stopAtControls::saEndTime)
971  {
972  controlDict_.readEntry("endTime", endTime_);
973  }
974 
975  return changed;
976 }
977 
978 
980 {
981  return controlDict_.lookupOrDefault("adjustTimeStep", false);
982 }
983 
984 
985 void Foam::Time::setTime(const Time& t)
986 {
987  value() = t.value();
988  dimensionedScalar::name() = t.dimensionedScalar::name();
989  timeIndex_ = t.timeIndex_;
990  fileHandler().setTime(*this);
991 }
992 
993 
994 void Foam::Time::setTime(const instant& inst, const label newIndex)
995 {
996  value() = inst.value();
997  dimensionedScalar::name() = inst.name();
998  timeIndex_ = newIndex;
999 
1000  IOdictionary timeDict
1001  (
1002  IOobject
1003  (
1004  "time",
1005  timeName(),
1006  "uniform",
1007  *this,
1010  false
1011  )
1012  );
1013 
1014  timeDict.readIfPresent("deltaT", deltaT_);
1015  timeDict.readIfPresent("deltaT0", deltaT0_);
1016  timeDict.readIfPresent("index", timeIndex_);
1017  fileHandler().setTime(*this);
1018 }
1019 
1020 
1021 void Foam::Time::setTime(const dimensionedScalar& newTime, const label newIndex)
1022 {
1023  setTime(newTime.value(), newIndex);
1024 }
1025 
1026 
1027 void Foam::Time::setTime(const scalar newTime, const label newIndex)
1028 {
1029  value() = newTime;
1030  dimensionedScalar::name() = timeName(timeToUserTime(newTime));
1031  timeIndex_ = newIndex;
1032  fileHandler().setTime(*this);
1033 }
1034 
1035 
1037 {
1038  setEndTime(endTime.value());
1039 }
1040 
1041 
1042 void Foam::Time::setEndTime(const scalar endTime)
1043 {
1044  endTime_ = endTime;
1045 }
1046 
1047 
1050  const dimensionedScalar& deltaT,
1051  const bool adjust
1052 )
1053 {
1054  setDeltaT(deltaT.value(), adjust);
1055 }
1056 
1057 
1058 void Foam::Time::setDeltaT(const scalar deltaT, const bool adjust)
1059 {
1060  deltaT_ = deltaT;
1061  deltaTchanged_ = true;
1062 
1063  if (adjust)
1064  {
1065  adjustDeltaT();
1066  }
1067 }
1068 
1069 
1071 {
1072  prevTimeState_.set(new TimeState(*this)); // Fatal if already set
1073 
1074  setTime(*this - deltaT(), (timeIndex() - 1)*nSubCycles);
1075  deltaT_ /= nSubCycles;
1076  deltaT0_ /= nSubCycles;
1077  deltaTSave_ = deltaT0_;
1078 
1079  subCycling_ = nSubCycles;
1080 
1081  return prevTimeState();
1082 }
1083 
1084 
1086 {
1087  // Only permit adjustment if sub-cycling was already active
1088  // and if the index is valid (positive, non-zero).
1089  // This avoids potential mixups for deleting.
1090 
1091  if (subCycling_ && index > 0)
1092  {
1093  subCycling_ = index;
1094  }
1095 }
1096 
1097 
1099 {
1100  if (subCycling_)
1101  {
1102  TimeState::operator=(prevTimeState());
1103  prevTimeState_.clear();
1104  }
1105 
1106  subCycling_ = 0;
1107 }
1108 
1109 
1110 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1111 
1113 {
1114  return operator+=(deltaT.value());
1115 }
1116 
1117 
1118 Foam::Time& Foam::Time::operator+=(const scalar deltaT)
1119 {
1120  setDeltaT(deltaT);
1121  return operator++();
1122 }
1123 
1124 
1126 {
1127  deltaT0_ = deltaTSave_;
1128  deltaTSave_ = deltaT_;
1129 
1130  // Save old time value and name
1131  const scalar oldTimeValue = timeToUserTime(value());
1132  const word oldTimeName = dimensionedScalar::name();
1133 
1134  // Increment time
1135  setTime(value() + deltaT_, timeIndex_ + 1);
1136 
1137  if (!subCycling_)
1138  {
1139  // If the time is very close to zero reset to zero
1140  if (mag(value()) < 10*SMALL*deltaT_)
1141  {
1142  setTime(0.0, timeIndex_);
1143  }
1144 
1145  if (sigStopAtWriteNow_.active() || sigWriteNow_.active())
1146  {
1147  // A signal might have been sent on one processor only
1148  // Reduce so all decide the same.
1149 
1150  label flag = 0;
1151  if (sigStopAtWriteNow_.active() && stopAt_ == saWriteNow)
1152  {
1153  flag += 1;
1154  }
1155  if (sigWriteNow_.active() && writeOnce_)
1156  {
1157  flag += 2;
1158  }
1159  reduce(flag, maxOp<label>());
1160 
1161  if (flag & 1)
1162  {
1163  stopAt_ = saWriteNow;
1164  }
1165  if (flag & 2)
1166  {
1167  writeOnce_ = true;
1168  }
1169  }
1170 
1171  writeTime_ = false;
1172 
1173  switch (writeControl_)
1174  {
1175  case wcNone:
1176  case wcUnknown:
1177  break;
1178 
1179  case wcTimeStep:
1180  writeTime_ = !(timeIndex_ % label(writeInterval_));
1181  break;
1182 
1183  case wcRunTime:
1184  case wcAdjustableRunTime:
1185  {
1186  const label writeIndex = label
1187  (
1188  ((value() - startTime_) + 0.5*deltaT_)
1189  / writeInterval_
1190  );
1191 
1192  if (writeIndex > writeTimeIndex_)
1193  {
1194  writeTime_ = true;
1195  writeTimeIndex_ = writeIndex;
1196  }
1197  }
1198  break;
1199 
1200  case wcCpuTime:
1201  {
1202  const label writeIndex = label
1203  (
1204  returnReduce(elapsedCpuTime(), maxOp<double>())
1205  / writeInterval_
1206  );
1207  if (writeIndex > writeTimeIndex_)
1208  {
1209  writeTime_ = true;
1210  writeTimeIndex_ = writeIndex;
1211  }
1212  }
1213  break;
1214 
1215  case wcClockTime:
1216  {
1217  const label writeIndex = label
1218  (
1219  returnReduce(elapsedClockTime(), maxOp<double>())
1220  / writeInterval_
1221  );
1222  if (writeIndex > writeTimeIndex_)
1223  {
1224  writeTime_ = true;
1225  writeTimeIndex_ = writeIndex;
1226  }
1227  }
1228  break;
1229  }
1230 
1231 
1232  // Check if endTime needs adjustment to stop at the next run()/end()
1233  if (!end())
1234  {
1235  if (stopAt_ == saNoWriteNow)
1236  {
1237  endTime_ = value();
1238  }
1239  else if (stopAt_ == saWriteNow)
1240  {
1241  endTime_ = value();
1242  writeTime_ = true;
1243  }
1244  else if (stopAt_ == saNextWrite && writeTime_ == true)
1245  {
1246  endTime_ = value();
1247  }
1248  }
1249 
1250  // Override writeTime if one-shot writing
1251  if (writeOnce_)
1252  {
1253  writeTime_ = true;
1254  writeOnce_ = false;
1255  }
1256 
1257  // Adjust the precision of the time directory name if necessary
1258  if (writeTime_)
1259  {
1260  // Tolerance used when testing time equivalence
1261  const scalar timeTol =
1262  max(min(pow(10.0, -precision_), 0.1*deltaT_), SMALL);
1263 
1264  // User-time equivalent of deltaT
1265  const scalar userDeltaT = timeToUserTime(deltaT_);
1266 
1267  // Time value obtained by reading timeName
1268  scalar timeNameValue = -VGREAT;
1269 
1270  // Check that new time representation differs from old one
1271  // reinterpretation of the word
1272  if
1273  (
1274  readScalar(dimensionedScalar::name(), timeNameValue)
1275  && (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
1276  )
1277  {
1278  int oldPrecision = precision_;
1279  while
1280  (
1281  precision_ < maxPrecision_
1282  && readScalar(dimensionedScalar::name(), timeNameValue)
1283  && (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
1284  )
1285  {
1286  precision_++;
1287  setTime(value(), timeIndex());
1288  }
1289 
1290  if (precision_ != oldPrecision)
1291  {
1293  << "Increased the timePrecision from " << oldPrecision
1294  << " to " << precision_
1295  << " to distinguish between timeNames at time "
1297  << endl;
1298 
1299  if (precision_ == maxPrecision_)
1300  {
1301  // Reached maxPrecision limit
1303  << "Current time name " << dimensionedScalar::name()
1304  << nl
1305  << " The maximum time precision has been reached"
1306  " which might result in overwriting previous"
1307  " results."
1308  << endl;
1309  }
1310 
1311  // Check if round-off error caused time-reversal
1312  scalar oldTimeNameValue = -VGREAT;
1313  if
1314  (
1315  readScalar(oldTimeName, oldTimeNameValue)
1316  && (
1317  sign(timeNameValue - oldTimeNameValue)
1318  != sign(deltaT_)
1319  )
1320  )
1321  {
1323  << "Current time name " << dimensionedScalar::name()
1324  << " is set to an instance prior to the "
1325  "previous one "
1326  << oldTimeName << nl
1327  << " This might result in temporal "
1328  "discontinuities."
1329  << endl;
1330  }
1331  }
1332  }
1333  }
1334  }
1335 
1336  return *this;
1337 }
1338 
1339 
1341 {
1342  return operator++();
1343 }
1344 
1345 
1346 // ************************************************************************* //
Foam::dictionary::findDict
dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary pointer if present.
Definition: dictionary.C:503
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::autoPtr::New
static autoPtr< T > New(Args &&... args)
Construct autoPtr of T with forwarding arguments.
Foam::Time::general
default float notation
Definition: Time.H:109
profiling.H
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
Foam::maxOp
Definition: ops.H:223
Foam::Time::writeControls
writeControls
Write control options.
Definition: Time.H:84
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:51
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:129
Foam::exists
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: MSwindows.C:625
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::functionObjectList::adjustTimeStep
bool adjustTimeStep()
Called at the end of Time::adjustDeltaT() if adjustTime is true.
Definition: functionObjectList.C:705
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:46
Foam::Time::end
virtual bool end() const
Return true if end of run,.
Definition: Time.C:952
Foam::labelMax
constexpr label labelMax
Definition: label.H:65
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::fileOperation::addWatches
virtual void addWatches(regIOobject &, const fileNameList &) const
Helper: add watches for list of regIOobjects.
Definition: fileOperation.C:609
Foam::fileName::path
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:186
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::Time::writeControlNames
static const Enum< writeControls > writeControlNames
Names for writeControls.
Definition: Time.H:116
Foam::IOobject::instance
const fileName & instance() const
Definition: IOobjectI.H:167
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:426
Foam::fileName::name
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:209
Foam::system
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
Definition: MSwindows.C:1140
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:414
oldTime
Info<< "Creating field kinetic energy K\n"<< endl;volScalarField K("K", 0.5 *magSqr(U));if(U.nOldTimes()){ volVectorField *Uold=&U.oldTime();volScalarField *Kold=&K.oldTime();*Kold==0.5 *magSqr(*Uold);while(Uold->nOldTimes()) { Uold=&Uold-> oldTime()
Definition: createK.H:12
Foam::dimensioned::name
const word & name() const
Return const reference to name.
Definition: dimensionedType.C:376
Foam::Time::stopAt
virtual stopAtControls stopAt() const
Return the stop control information.
Definition: Time.C:863
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:123
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1181
Foam::FatalIOError
IOerror FatalIOError
Foam::objectRegistry::clear
void clear()
Clear all entries from the registry.
Definition: objectRegistry.C:335
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::dimensioned< scalar >::value
const scalar & value() const
Return const reference to value.
Definition: dimensionedType.C:404
Foam::Instant::equal
bool equal(scalar val) const
True if values are equal (includes SMALL for rounding)
Definition: Instant.C:59
Foam::dictionary::lookupOrDefault
T lookupOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.H:1241
Foam::sign
dimensionedScalar sign(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:166
Foam::Time::controlDictName
static word controlDictName
The default control dictionary name (normally "controlDict")
Definition: Time.H:226
setTime
runTimeSource setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex)
Foam::Time::fmtflags
fmtflags
Supported time directory name formats.
Definition: Time.H:107
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::sumOp
Definition: ops.H:213
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::debug::infoSwitch
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:231
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:42
Foam::Time::stopAtControlNames
static const Enum< stopAtControls > stopAtControlNames
Names for stopAtControls.
Definition: Time.H:119
Foam::dimTime
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:54
Foam::Time::precision_
static int precision_
Time directory name precision.
Definition: Time.H:186
Foam::Time::timeName
virtual word timeName() const
Return current time name.
Definition: Time.C:774
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::Time::adjustDeltaT
void adjustDeltaT()
Adjust the time step so that writing occurs at the specified time.
Definition: Time.C:101
Foam::TimeState
The time value with time-stepping information, user-defined remapping, etc.
Definition: TimeState.H:51
Foam::Time::~Time
virtual ~Time()
Destructor.
Definition: Time.C:742
registerInfoSwitch
registerInfoSwitch("printExecutionFormat", int, Foam::Time::printExecutionFormat_)
Foam::Time::subCycle
virtual TimeState subCycle(const label nSubCycles)
Set time to sub-cycle for the given number of steps.
Definition: Time.C:1070
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::profiling::stop
static void stop(const Time &owner)
Stop profiling, cleanup pool if possible.
Definition: profiling.C:173
Foam::Time::setEndTime
virtual void setEndTime(const dimensionedScalar &endTime)
Reset end time.
Definition: Time.C:1036
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::profiling::active
static bool active()
True if profiling is allowed and is active.
Definition: profiling.C:112
Foam::log10
dimensionedScalar log10(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:263
Foam::fileOperation::setTime
virtual void setTime(const Time &) const
Callback for time change.
Definition: fileOperation.H:515
argList.H
Foam::TimeState::writeTimeIndex_
label writeTimeIndex_
Definition: TimeState.H:58
Foam::IOobject::READ_IF_PRESENT
Definition: IOobject.H:122
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:43
Foam::pow
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Definition: dimensionedScalar.C:75
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::Time::operator+=
virtual Time & operator+=(const dimensionedScalar &deltaT)
Set deltaT to that specified and increment time via operator++()
Definition: Time.C:1112
timeIndex
label timeIndex
Definition: getTimeIndex.H:4
timeName
word timeName
Definition: getTimeIndex.H:3
HashSet.H
dict
dictionary dict
Definition: searchingEngine.H:14
addProfiling
#define addProfiling(name, descr)
Define profiling trigger with specified name and description string.
Definition: profilingTrigger.H:114
Foam::argList::validOptions
static HashTable< string > validOptions
A list of valid options.
Definition: argList.H:207
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::Time::loop
virtual bool loop()
Return true if run should continue and if so increment time.
Definition: Time.C:939
Foam::Time::operator++
virtual Time & operator++()
Prefix increment,.
Definition: Time.C:1125
Foam::dimensioned< scalar >
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:115
Foam::Time::wcAdjustableRunTime
"adjustable" / "adjustableRunTime"
Definition: Time.H:89
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::Time::New
static autoPtr< Time > New()
Construct dummy time, without functionObjects or libraries.
Definition: Time.C:710
PstreamReduceOps.H
Inter-processor communication reduction functions.
Foam::TimePaths
Address the time paths without using the Time class.
Definition: TimePaths.H:56
Foam::Time::findInstance
word findInstance(const fileName &dir, const word &name=word::null, const IOobject::readOption rOpt=IOobject::MUST_READ, const word &stopInstance=word::null) const
Definition: Time.C:781
Foam::Time::Time
Time(const word &ctrlDictName, const argList &args, const word &systemName="system", const word &constantName="constant")
Construct given name of dictionary to read and argument list.
Definition: Time.C:485
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::fileOperation::removeWatch
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
Definition: fileOperation.C:585
Foam::profiling::initialize
static void initialize(const IOobject &ioObj, const Time &owner)
Singleton to initialize profiling pool, everything enabled.
Definition: profiling.C:147
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:444
Foam::Instant::name
const T & name() const
The name/key (const access)
Definition: Instant.H:111
found
bool found
Definition: TABSMDCalcMethod2.H:32
Foam::Time::setDeltaT
virtual void setDeltaT(const dimensionedScalar &deltaT, const bool adjust=true)
Reset time step, normally also calling adjustDeltaT()
Definition: Time.C:1049
IOdictionary.H
Time.H
Foam::autoPtr< Foam::Time >
Foam::Time::findInstancePath
word findInstancePath(const fileName &directory, const instant &t) const
Definition: Time.C:811
Foam::Time::readModifiedObjects
void readModifiedObjects()
Read the objects that have been modified.
Definition: TimeIO.C:459
Foam::IOstreamOption::ASCII
"ascii"
Definition: IOstreamOption.H:66
Foam::profilingTrigger
Triggers for starting/stopping code profiling.
Definition: profilingTrigger.H:54
Foam::Time::printExecutionFormat_
static int printExecutionFormat_
Style for "ExecutionTime = " output.
Definition: Time.H:127
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::fileOperation::exists
bool exists(IOobject &io) const
Does ioobject exist. Is either a directory (empty name()) or.
Definition: fileOperation.C:376
Foam::List< instant >
Foam::Time::maxPrecision_
static const int maxPrecision_
Maximum time directory name precision.
Definition: Time.H:189
Foam::Time::setTime
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:985
Foam::Time::writeInterval_
scalar writeInterval_
Definition: Time.H:159
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::Instant::value
scalar value() const
The value (const access)
Definition: Instant.H:99
Foam::Time::format_
static fmtflags format_
Time directory name format.
Definition: Time.H:183
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
Foam::Time::startTime_
scalar startTime_
Definition: Time.H:151
Foam::IOobject::MUST_READ_IF_MODIFIED
Definition: IOobject.H:121
Foam::TimeState::timeIndex_
label timeIndex_
Definition: TimeState.H:57
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:303
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:375
Foam::Time::isAdjustTimeStep
virtual bool isAdjustTimeStep() const
Return true if adjustTimeStep is true.
Definition: Time.C:979
registerSwitch.H
Foam::Time::stopAtControls
stopAtControls
Definition: Time.H:97
Foam::Time::endTime
virtual dimensionedScalar endTime() const
Return end time.
Definition: Time.C:857
Foam::instant
An instant of time. Contains the time value and name.
Definition: instant.H:52
Foam::Time::setMonitoring
void setMonitoring(const bool forceProfiling=false)
Set file monitoring, profiling, etc.
Definition: Time.C:347
Foam::debug::controlDict
dictionary & controlDict()
Definition: debug.C:143
Foam::IOobject::readOption
readOption
Enumeration defining the read options.
Definition: IOobject.H:118
Foam::Time::endSubCycle
virtual void endSubCycle()
Reset time after sub-cycling back to previous TimeState.
Definition: Time.C:1098
Foam::Time::setControls
void setControls()
Set the controls from the current controlDict.
Definition: Time.C:145
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:306
Foam::IOobject::NO_READ
Definition: IOobject.H:123
args
Foam::argList args(argc, argv)
constant
constant condensation/saturation model.
Foam::Time::writeControl_
writeControls writeControl_
Definition: Time.H:157
Foam::Time::run
virtual bool run() const
Return true if run should continue,.
Definition: Time.C:869
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::TimeState::deltaT_
scalar deltaT_
Definition: TimeState.H:60
Foam::Time::startTime
virtual dimensionedScalar startTime() const
Return start time.
Definition: Time.C:851
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:294
Foam::Time::startTimeIndex
virtual label startTimeIndex() const
Return start time index.
Definition: Time.C:845
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417
Foam::Time::subCycleIndex
virtual void subCycleIndex(const label index)
Adjust the reported sub-cycle index.
Definition: Time.C:1085
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157