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-2020 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 < scalar(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_.getOrDefault<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  // Note: do not use raw fileHandler().exists(...) since does not check
201  // alternative processorsDDD directories naming
202  if (fileHandler().filePath(timePath()).empty())
203  {
204  int oldPrecision = precision_;
205  int requiredPrecision = -1;
206  bool found = false;
207  word oldTime(timeName());
208  for
209  (
210  precision_ = maxPrecision_;
211  precision_ > oldPrecision;
212  --precision_
213  )
214  {
215  // Update the time formatting
216  setTime(startTime_, 0);
217 
218  word newTime(timeName());
219  if (newTime == oldTime)
220  {
221  break;
222  }
223  oldTime = newTime;
224 
225  // Check the existence of the time directory with the new format
226  //found = fileHandler().exists(timePath(), false);
227  const fileName dirName(fileHandler().filePath(timePath()));
228  found = !dirName.empty();
229 
230  if (found)
231  {
232  requiredPrecision = precision_;
233  }
234  }
235 
236  if (requiredPrecision > 0)
237  {
238  // Update the time precision
239  precision_ = requiredPrecision;
240 
241  // Update the time formatting
242  setTime(startTime_, 0);
243 
245  << "Increasing the timePrecision from " << oldPrecision
246  << " to " << precision_
247  << " to support the formatting of the current time directory "
248  << timeName() << nl << endl;
249  }
250  else
251  {
252  // Could not find time directory so assume it is not present
253  precision_ = oldPrecision;
254 
255  // Revert the time formatting
256  setTime(startTime_, 0);
257  }
258  }
259 
260  if (Pstream::parRun())
261  {
262  scalar sumStartTime = startTime_;
263  reduce(sumStartTime, sumOp<scalar>());
264  if
265  (
266  mag(Pstream::nProcs()*startTime_ - sumStartTime)
267  > Pstream::nProcs()*deltaT_/10.0
268  )
269  {
270  FatalIOErrorInFunction(controlDict_)
271  << "Start time is not the same for all processors" << nl
272  << "processor " << Pstream::myProcNo() << " has startTime "
273  << startTime_ << exit(FatalIOError);
274  }
275  }
276 
277  IOdictionary timeDict
278  (
279  IOobject
280  (
281  "time",
282  timeName(),
283  "uniform",
284  *this,
287  false
288  )
289  );
290 
291  // Read and set the deltaT only if time-step adjustment is active
292  // otherwise use the deltaT from the controlDict
293  if (controlDict_.getOrDefault("adjustTimeStep", false))
294  {
295  if (timeDict.readIfPresent("deltaT", deltaT_))
296  {
297  deltaTSave_ = deltaT_;
298  deltaT0_ = deltaT_;
299  }
300  }
301 
302  timeDict.readIfPresent("deltaT0", deltaT0_);
303 
304  if (timeDict.readIfPresent("index", startTimeIndex_))
305  {
306  timeIndex_ = startTimeIndex_;
307  }
308 
309 
310  // Check if values stored in time dictionary are consistent
311 
312  // 1. Based on time name
313  bool checkValue = true;
314 
315  string storedTimeName;
316  if (timeDict.readIfPresent("name", storedTimeName))
317  {
318  if (storedTimeName == timeName())
319  {
320  // Same time. No need to check stored value
321  checkValue = false;
322  }
323  }
324 
325  // 2. Based on time value
326  // (consistent up to the current time writing precision so it won't
327  // trigger if we just change the write precision)
328  if (checkValue)
329  {
330  scalar storedTimeValue;
331  if (timeDict.readIfPresent("value", storedTimeValue))
332  {
333  word storedTimeName(timeName(storedTimeValue));
334 
335  if (storedTimeName != timeName())
336  {
337  IOWarningInFunction(timeDict)
338  << "Time read from time dictionary " << storedTimeName
339  << " differs from actual time " << timeName() << '.' << nl
340  << " This may cause unexpected database behaviour."
341  << " If you are not interested" << nl
342  << " in preserving time state delete"
343  << " the time dictionary."
344  << endl;
345  }
346  }
347  }
348 }
349 
350 
351 void Foam::Time::setMonitoring(const bool forceProfiling)
352 {
353  const dictionary* profilingDict = controlDict_.findDict("profiling");
354  if (!profilingDict)
355  {
356  // ... or from etc/controlDict
357  profilingDict = debug::controlDict().findDict("profiling");
358  }
359 
360  // initialize profiling on request
361  // otherwise rely on profiling entry within controlDict
362  // and skip if 'active' keyword is explicitly set to false
363  if (forceProfiling)
364  {
366  (
367  IOobject
368  (
369  "profiling",
370  timeName(),
371  "uniform",
372  *this,
375  ),
376  *this
377  );
378  }
379  else if
380  (
381  profilingDict
382  && profilingDict->getOrDefault("active", true)
383  )
384  {
386  (
387  *profilingDict,
388  IOobject
389  (
390  "profiling",
391  timeName(),
392  "uniform",
393  *this,
396  ),
397  *this
398  );
399  }
400 
401  // Time objects not registered so do like objectRegistry::checkIn ourselves.
402  if (runTimeModifiable_)
403  {
404  // Monitor all files that controlDict depends on
405  fileHandler().addWatches(controlDict_, controlDict_.files());
406  }
407 
408  // Clear dependent files - not needed now
409  controlDict_.files().clear();
410 }
411 
412 
413 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
414 
416 (
417  const word& ctrlDictName,
418  const fileName& rootPath,
419  const fileName& caseName,
420  const word& systemName,
421  const word& constantName,
422  const bool enableFunctionObjects,
423  const bool enableLibs
424 )
425 :
426  TimePaths
427  (
428  rootPath,
429  caseName,
430  systemName,
431  constantName
432  ),
433 
434  objectRegistry(*this),
435 
436  loopProfiling_(nullptr),
437  libs_(),
438 
439  controlDict_
440  (
441  IOobject
442  (
443  ctrlDictName,
444  system(),
445  *this,
448  false
449  )
450  ),
451 
452  startTimeIndex_(0),
453  startTime_(0),
454  endTime_(0),
455 
456  stopAt_(saEndTime),
457  writeControl_(wcTimeStep),
458  writeInterval_(GREAT),
459  purgeWrite_(0),
460  subCycling_(0),
461  writeOnce_(false),
462  sigWriteNow_(*this, true),
463  sigStopAtWriteNow_(*this, true),
464  writeStreamOption_(IOstream::ASCII),
465  graphFormat_("raw"),
466  runTimeModifiable_(false),
467  functionObjects_(*this, false)
468 {
469  if (enableFunctionObjects)
470  {
471  functionObjects_.on();
472  }
473 
474  if (enableLibs)
475  {
476  libs_.open(controlDict_, "libs");
477  }
478 
479  // Explicitly set read flags on objectRegistry so anything constructed
480  // from it reads as well (e.g. fvSolution).
482 
483  setControls();
484  setMonitoring();
485 }
486 
487 
489 (
490  const word& ctrlDictName,
491  const argList& args,
492  const word& systemName,
493  const word& constantName,
494  const bool enableFunctionObjects,
495  const bool enableLibs
496 )
497 :
498  TimePaths(args, systemName, constantName),
499 
500  objectRegistry(*this),
501 
502  loopProfiling_(nullptr),
503  libs_(),
504 
505  controlDict_
506  (
507  IOobject
508  (
509  ctrlDictName,
510  system(),
511  *this,
514  false
515  )
516  ),
517 
518  startTimeIndex_(0),
519  startTime_(0),
520  endTime_(0),
521 
522  stopAt_(saEndTime),
523  writeControl_(wcTimeStep),
524  writeInterval_(GREAT),
525  purgeWrite_(0),
526  subCycling_(0),
527  writeOnce_(false),
528  sigWriteNow_(*this, true),
529  sigStopAtWriteNow_(*this, true),
530  writeStreamOption_(IOstream::ASCII),
531  graphFormat_("raw"),
532  runTimeModifiable_(false),
533  functionObjects_(*this, false)
534 {
535  // Functions
536  //
537  // * '-withFunctionObjects' exists and used = enable
538  // * '-noFunctionObjects' exists and used = disable
539  // * default: no functions if there is no way to enable/disable them
540  if
541  (
542  argList::validOptions.found("withFunctionObjects")
543  ? args.found("withFunctionObjects")
544  : argList::validOptions.found("noFunctionObjects")
545  ? !args.found("noFunctionObjects")
546  : false
547  )
548  {
549  if (enableFunctionObjects)
550  {
551  functionObjects_.on();
552  }
553  }
554 
555  // Libraries
556  //
557  // * enable by default unless '-no-libs' option was used
558  if (!args.found("no-libs"))
559  {
560  if (enableLibs)
561  {
562  libs_.open(controlDict_, "libs");
563  }
564  }
565 
566  // Explicitly set read flags on objectRegistry so anything constructed
567  // from it reads as well (e.g. fvSolution).
569 
570  setControls();
571 
572  // '-profiling' = force profiling, ignore controlDict entry
573  setMonitoring(args.found("profiling"));
574 }
575 
576 
578 (
579  const dictionary& dict,
580  const fileName& rootPath,
581  const fileName& caseName,
582  const word& systemName,
583  const word& constantName,
584  const bool enableFunctionObjects,
585  const bool enableLibs
586 )
587 :
588  TimePaths
589  (
590  rootPath,
591  caseName,
592  systemName,
593  constantName
594  ),
595 
596  objectRegistry(*this),
597 
598  loopProfiling_(nullptr),
599  libs_(),
600 
601  controlDict_
602  (
603  IOobject
604  (
605  controlDictName,
606  system(),
607  *this,
610  false
611  ),
612  dict
613  ),
614 
615  startTimeIndex_(0),
616  startTime_(0),
617  endTime_(0),
618 
619  stopAt_(saEndTime),
620  writeControl_(wcTimeStep),
621  writeInterval_(GREAT),
622  purgeWrite_(0),
623  subCycling_(0),
624  writeOnce_(false),
625  sigWriteNow_(*this, true),
626  sigStopAtWriteNow_(*this, true),
627  writeStreamOption_(IOstream::ASCII),
628  graphFormat_("raw"),
629  runTimeModifiable_(false),
630  functionObjects_(*this, false)
631 {
632  if (enableFunctionObjects)
633  {
634  functionObjects_.on();
635  }
636 
637  if (enableLibs)
638  {
639  libs_.open(controlDict_, "libs");
640  }
641 
642 
643  // Explicitly set read flags on objectRegistry so anything constructed
644  // from it reads as well (e.g. fvSolution).
646 
647  // Since could not construct regIOobject with setting:
648  controlDict_.readOpt() = IOobject::MUST_READ_IF_MODIFIED;
649 
650  setControls();
651  setMonitoring();
652 }
653 
654 
656 (
657  const fileName& rootPath,
658  const fileName& caseName,
659  const word& systemName,
660  const word& constantName,
661  const bool enableFunctionObjects,
662  const bool enableLibs
663 )
664 :
665  TimePaths
666  (
667  rootPath,
668  caseName,
669  systemName,
670  constantName
671  ),
672 
673  objectRegistry(*this),
674 
675  loopProfiling_(nullptr),
676  libs_(),
677 
678  controlDict_
679  (
680  IOobject
681  (
682  controlDictName,
683  system(),
684  *this,
687  false
688  )
689  ),
690 
691  startTimeIndex_(0),
692  startTime_(0),
693  endTime_(0),
694 
695  stopAt_(saEndTime),
696  writeControl_(wcTimeStep),
697  writeInterval_(GREAT),
698  purgeWrite_(0),
699  subCycling_(0),
700  writeOnce_(false),
701  writeStreamOption_(IOstream::ASCII),
702  graphFormat_("raw"),
703  runTimeModifiable_(false),
704  functionObjects_(*this, false)
705 {
706  if (enableFunctionObjects)
707  {
708  functionObjects_.on();
709  }
710 
711  if (enableLibs)
712  {
713  libs_.open(controlDict_, "libs");
714  }
715 
716  setMonitoring(); // for profiling etc
717 }
718 
719 
720 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
721 
723 {
724  return
726  (
727  fileName("."), // root-path
728  fileName("."), // case-name
729  false, // No enableFunctionObjects
730  false // No enableLibs
731  );
732 }
733 
734 
736 {
737  return
739  (
740  caseDir.path(), // root-path
741  caseDir.name(), // case-name
742  false, // No enableFunctionObjects
743  false // No enableLibs
744  );
745 }
746 
747 
749 {
750  return
752  (
754  args,
755  false, // No enableFunctionObjects
756  false // No enableLibs
757  );
758 }
759 
760 
761 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
762 
764 {
765  deleteDemandDrivenData(loopProfiling_);
766 
767  forAllReverse(controlDict_.watchIndices(), i)
768  {
769  fileHandler().removeWatch(controlDict_.watchIndices()[i]);
770  }
771 
772  // Destroy function objects first
773  functionObjects_.clear();
774 
775  // Clean up profiling
776  profiling::stop(*this);
777 
778  // Ensure all owned objects are also cleaned up now
780 }
781 
782 
783 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
784 
785 Foam::word Foam::Time::timeName(const scalar t, const int precision)
786 {
787  std::ostringstream buf;
788  buf.setf(ios_base::fmtflags(format_), ios_base::floatfield);
789  buf.precision(precision);
790  buf << t;
791  return buf.str();
792 }
793 
794 
796 {
797  return dimensionedScalar::name();
798 }
799 
800 
802 (
803  const fileName& dir,
804  const word& name,
805  const IOobject::readOption rOpt,
806  const word& stopInstance
807 ) const
808 {
809  IOobject startIO
810  (
811  name, // name might be empty!
812  timeName(),
813  dir,
814  *this,
815  rOpt
816  );
817 
818  IOobject io
819  (
820  fileHandler().findInstance
821  (
822  startIO,
823  timeOutputValue(),
824  stopInstance
825  )
826  );
827  return io.instance();
828 }
829 
830 
832 (
833  const fileName& directory,
834  const instant& t
835 ) const
836 {
837  // Simplified version: use findTimes (readDir + sort). The expensive
838  // bit is the readDir, not the sorting. Tbd: avoid calling findInstancePath
839  // from filePath.
840 
841  instantList timeDirs = findTimes(path(), constant());
842  // Note:
843  // - times will include constant (with value 0) as first element.
844  // For backwards compatibility make sure to find 0 in preference
845  // to constant.
846  // - list is sorted so could use binary search
847 
848  forAllReverse(timeDirs, i)
849  {
850  if (t.equal(timeDirs[i].value()))
851  {
852  return timeDirs[i].name();
853  }
854  }
855 
856  return word::null;
857 }
858 
859 
861 {
862  return findInstancePath(path(), t);
863 }
864 
865 
866 Foam::label Foam::Time::startTimeIndex() const
867 {
868  return startTimeIndex_;
869 }
870 
871 
873 {
874  return dimensionedScalar("startTime", dimTime, startTime_);
875 }
876 
877 
879 {
880  return dimensionedScalar("endTime", dimTime, endTime_);
881 }
882 
883 
885 {
886  return stopAt_;
887 }
888 
889 
890 bool Foam::Time::run() const
891 {
892  deleteDemandDrivenData(loopProfiling_);
893 
894  bool isRunning = value() < (endTime_ - 0.5*deltaT_);
895 
896  if (!subCycling_)
897  {
898  // Only execute when the condition is no longer true
899  // ie, when exiting the control loop
900  if (!isRunning && timeIndex_ != startTimeIndex_)
901  {
902  // Ensure functionObjects execute on last time step
903  // (and hence write uptodate functionObjectProperties)
904  {
905  addProfiling(fo, "functionObjects.execute()");
906  functionObjects_.execute();
907  }
908  {
909  addProfiling(fo, "functionObjects.end()");
910  functionObjects_.end();
911  }
912  }
913  }
914 
915  if (isRunning)
916  {
917  if (!subCycling_)
918  {
919  const_cast<Time&>(*this).readModifiedObjects();
920 
921  if (timeIndex_ == startTimeIndex_)
922  {
923  addProfiling(functionObjects, "functionObjects.start()");
924  functionObjects_.start();
925  }
926  else
927  {
928  addProfiling(functionObjects, "functionObjects.execute()");
929  functionObjects_.execute();
930  }
931 
932  // Check if the execution of functionObjects require re-reading
933  // any files. This moves effect of e.g. 'timeActivatedFileUpdate'
934  // one time step forward. Note that we cannot call
935  // readModifiedObjects from within timeActivatedFileUpdate since
936  // it might re-read the functionObjects themselves (and delete
937  // the timeActivatedFileUpdate one)
938  if (functionObjects_.filesModified())
939  {
940  const_cast<Time&>(*this).readModifiedObjects();
941  }
942  }
943 
944  // Update the "is-running" status following the
945  // possible side-effects from functionObjects
946  isRunning = value() < (endTime_ - 0.5*deltaT_);
947 
948  // (re)trigger profiling
949  if (profiling::active())
950  {
951  loopProfiling_ =
952  new profilingTrigger("time.run() " + objectRegistry::name());
953  }
954  }
955 
956  return isRunning;
957 }
958 
959 
961 {
962  const bool isRunning = run();
963 
964  if (isRunning)
965  {
966  operator++();
967  }
968 
969  return isRunning;
970 }
971 
972 
973 bool Foam::Time::end() const
974 {
975  return value() > (endTime_ + 0.5*deltaT_);
976 }
977 
978 
979 bool Foam::Time::stopAt(const stopAtControls stopCtrl) const
980 {
981  if (stopCtrl == stopAtControls::saUnknown)
982  {
983  return false;
984  }
985 
986  const bool changed = (stopAt_ != stopCtrl);
987  stopAt_ = stopCtrl;
988  endTime_ = GREAT;
989 
990  // Adjust endTime
991  if (stopCtrl == stopAtControls::saEndTime)
992  {
993  controlDict_.readEntry("endTime", endTime_);
994  }
995 
996  return changed;
997 }
998 
999 
1001 {
1002  return controlDict_.getOrDefault("adjustTimeStep", false);
1003 }
1004 
1005 
1007 {
1008  value() = t.value();
1009  dimensionedScalar::name() = t.dimensionedScalar::name();
1010  timeIndex_ = t.timeIndex_;
1011  fileHandler().setTime(*this);
1012 }
1013 
1014 
1015 void Foam::Time::setTime(const instant& inst, const label newIndex)
1016 {
1017  value() = inst.value();
1018  dimensionedScalar::name() = inst.name();
1019  timeIndex_ = newIndex;
1020 
1021  IOdictionary timeDict
1022  (
1023  IOobject
1024  (
1025  "time",
1026  timeName(),
1027  "uniform",
1028  *this,
1031  false
1032  )
1033  );
1034 
1035  timeDict.readIfPresent("deltaT", deltaT_);
1036  timeDict.readIfPresent("deltaT0", deltaT0_);
1037  timeDict.readIfPresent("index", timeIndex_);
1038  fileHandler().setTime(*this);
1039 }
1040 
1041 
1042 void Foam::Time::setTime(const dimensionedScalar& newTime, const label newIndex)
1043 {
1044  setTime(newTime.value(), newIndex);
1045 }
1046 
1047 
1048 void Foam::Time::setTime(const scalar newTime, const label newIndex)
1049 {
1050  value() = newTime;
1051  dimensionedScalar::name() = timeName(timeToUserTime(newTime));
1052  timeIndex_ = newIndex;
1053  fileHandler().setTime(*this);
1054 }
1055 
1056 
1058 {
1059  setEndTime(endTime.value());
1060 }
1061 
1062 
1063 void Foam::Time::setEndTime(const scalar endTime)
1064 {
1065  endTime_ = endTime;
1066 }
1067 
1068 
1071  const dimensionedScalar& deltaT,
1072  const bool adjust
1073 )
1074 {
1075  setDeltaT(deltaT.value(), adjust);
1076 }
1077 
1078 
1079 void Foam::Time::setDeltaT(const scalar deltaT, const bool adjust)
1080 {
1081  deltaT_ = deltaT;
1082  deltaTchanged_ = true;
1083 
1084  if (adjust)
1085  {
1086  adjustDeltaT();
1087  }
1088 }
1089 
1090 
1091 Foam::TimeState Foam::Time::subCycle(const label nSubCycles)
1092 {
1093  prevTimeState_.set(new TimeState(*this)); // Fatal if already set
1094 
1095  setTime(*this - deltaT(), (timeIndex() - 1)*nSubCycles);
1096  deltaT_ /= nSubCycles;
1097  deltaT0_ /= nSubCycles;
1098  deltaTSave_ = deltaT0_;
1099 
1100  subCycling_ = nSubCycles;
1101 
1102  return prevTimeState();
1103 }
1104 
1105 
1106 void Foam::Time::subCycleIndex(const label index)
1107 {
1108  // Only permit adjustment if sub-cycling was already active
1109  // and if the index is valid (positive, non-zero).
1110  // This avoids potential mixups for deleting.
1111 
1112  if (subCycling_ && index > 0)
1113  {
1114  subCycling_ = index;
1115  }
1116 }
1117 
1118 
1120 {
1121  if (subCycling_)
1122  {
1123  TimeState::operator=(prevTimeState());
1124  prevTimeState_.clear();
1125  }
1126 
1127  subCycling_ = 0;
1128 }
1129 
1130 
1131 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1132 
1134 {
1135  return operator+=(deltaT.value());
1136 }
1137 
1138 
1139 Foam::Time& Foam::Time::operator+=(const scalar deltaT)
1140 {
1141  setDeltaT(deltaT);
1142  return operator++();
1143 }
1144 
1145 
1147 {
1148  deltaT0_ = deltaTSave_;
1149  deltaTSave_ = deltaT_;
1150 
1151  // Save old time value and name
1152  const scalar oldTimeValue = timeToUserTime(value());
1153  const word oldTimeName = dimensionedScalar::name();
1154 
1155  // Increment time
1156  setTime(value() + deltaT_, timeIndex_ + 1);
1157 
1158  if (!subCycling_)
1159  {
1160  // If the time is very close to zero reset to zero
1161  if (mag(value()) < 10*SMALL*deltaT_)
1162  {
1163  setTime(0.0, timeIndex_);
1164  }
1165 
1166  if (sigStopAtWriteNow_.active() || sigWriteNow_.active())
1167  {
1168  // A signal might have been sent on one processor only
1169  // Reduce so all decide the same.
1170 
1171  label flag = 0;
1172  if (sigStopAtWriteNow_.active() && stopAt_ == saWriteNow)
1173  {
1174  flag += 1;
1175  }
1176  if (sigWriteNow_.active() && writeOnce_)
1177  {
1178  flag += 2;
1179  }
1180  reduce(flag, maxOp<label>());
1181 
1182  if (flag & 1)
1183  {
1184  stopAt_ = saWriteNow;
1185  }
1186  if (flag & 2)
1187  {
1188  writeOnce_ = true;
1189  }
1190  }
1191 
1192  writeTime_ = false;
1193 
1194  switch (writeControl_)
1195  {
1196  case wcNone:
1197  case wcUnknown:
1198  break;
1199 
1200  case wcTimeStep:
1201  writeTime_ = !(timeIndex_ % label(writeInterval_));
1202  break;
1203 
1204  case wcRunTime:
1205  case wcAdjustableRunTime:
1206  {
1207  const label writeIndex = label
1208  (
1209  ((value() - startTime_) + 0.5*deltaT_)
1210  / writeInterval_
1211  );
1212 
1213  if (writeIndex > writeTimeIndex_)
1214  {
1215  writeTime_ = true;
1216  writeTimeIndex_ = writeIndex;
1217  }
1218  }
1219  break;
1220 
1221  case wcCpuTime:
1222  {
1223  const label writeIndex = label
1224  (
1225  returnReduce(elapsedCpuTime(), maxOp<double>())
1226  / writeInterval_
1227  );
1228  if (writeIndex > writeTimeIndex_)
1229  {
1230  writeTime_ = true;
1231  writeTimeIndex_ = writeIndex;
1232  }
1233  }
1234  break;
1235 
1236  case wcClockTime:
1237  {
1238  const label writeIndex = label
1239  (
1240  returnReduce(elapsedClockTime(), maxOp<double>())
1241  / writeInterval_
1242  );
1243  if (writeIndex > writeTimeIndex_)
1244  {
1245  writeTime_ = true;
1246  writeTimeIndex_ = writeIndex;
1247  }
1248  }
1249  break;
1250  }
1251 
1252 
1253  // Check if endTime needs adjustment to stop at the next run()/end()
1254  if (!end())
1255  {
1256  if (stopAt_ == saNoWriteNow)
1257  {
1258  endTime_ = value();
1259  }
1260  else if (stopAt_ == saWriteNow)
1261  {
1262  endTime_ = value();
1263  writeTime_ = true;
1264  }
1265  else if (stopAt_ == saNextWrite && writeTime_ == true)
1266  {
1267  endTime_ = value();
1268  }
1269  }
1270 
1271  // Override writeTime if one-shot writing
1272  if (writeOnce_)
1273  {
1274  writeTime_ = true;
1275  writeOnce_ = false;
1276  }
1277 
1278  // Adjust the precision of the time directory name if necessary
1279  if (writeTime_)
1280  {
1281  // Tolerance used when testing time equivalence
1282  const scalar timeTol =
1283  max(min(pow(10.0, -precision_), 0.1*deltaT_), SMALL);
1284 
1285  // User-time equivalent of deltaT
1286  const scalar userDeltaT = timeToUserTime(deltaT_);
1287 
1288  // Time value obtained by reading timeName
1289  scalar timeNameValue = -VGREAT;
1290 
1291  // Check that new time representation differs from old one
1292  // reinterpretation of the word
1293  if
1294  (
1295  readScalar(dimensionedScalar::name(), timeNameValue)
1296  && (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
1297  )
1298  {
1299  int oldPrecision = precision_;
1300  while
1301  (
1302  precision_ < maxPrecision_
1303  && readScalar(dimensionedScalar::name(), timeNameValue)
1304  && (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
1305  )
1306  {
1307  precision_++;
1308  setTime(value(), timeIndex());
1309  }
1310 
1311  if (precision_ != oldPrecision)
1312  {
1314  << "Increased the timePrecision from " << oldPrecision
1315  << " to " << precision_
1316  << " to distinguish between timeNames at time "
1318  << endl;
1319 
1320  if (precision_ == maxPrecision_)
1321  {
1322  // Reached maxPrecision limit
1324  << "Current time name " << dimensionedScalar::name()
1325  << nl
1326  << " The maximum time precision has been reached"
1327  " which might result in overwriting previous"
1328  " results."
1329  << endl;
1330  }
1331 
1332  // Check if round-off error caused time-reversal
1333  scalar oldTimeNameValue = -VGREAT;
1334  if
1335  (
1336  readScalar(oldTimeName, oldTimeNameValue)
1337  && (
1338  sign(timeNameValue - oldTimeNameValue)
1339  != sign(deltaT_)
1340  )
1341  )
1342  {
1344  << "Current time name " << dimensionedScalar::name()
1345  << " is set to an instance prior to the "
1346  "previous one "
1347  << oldTimeName << nl
1348  << " This might result in temporal "
1349  "discontinuities."
1350  << endl;
1351  }
1352  }
1353  }
1354  }
1355  }
1356 
1357  return *this;
1358 }
1359 
1360 
1362 {
1363  return operator++();
1364 }
1365 
1366 
1367 // ************************************************************************* //
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:508
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::Time::Time
Time(const word &ctrlDictName, const argList &args, const bool enableFunctionObjects=true, const bool enableLibs=true)
Construct from dictionary name to read and argument list.
Definition: TimeI.H:31
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:57
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:129
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:703
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:70
Foam::Time::end
virtual bool end() const
Return true if end of run,.
Definition: Time.C:973
Foam::labelMax
constexpr label labelMax
Definition: label.H:61
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:598
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:191
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:427
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:415
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:406
Foam::Time::stopAt
virtual stopAtControls stopAt() const
Return the stop control information.
Definition: Time.C:884
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:1170
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:350
Foam::dimensioned< scalar >::value
const scalar & value() const
Return const reference to value.
Definition: dimensionedType.C:434
Foam::Instant::equal
bool equal(scalar val) const
True if values are equal (includes SMALL for rounding)
Definition: Instant.C:59
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:795
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:763
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:1091
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:1057
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:513
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:1133
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:210
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:960
Foam::Time::operator++
virtual Time & operator++()
Prefix increment,.
Definition: Time.C:1146
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:121
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 - no functionObjects or libraries.
Definition: Time.C:722
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:802
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:574
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:445
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:1070
IOdictionary.H
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::Time::findInstancePath
word findInstancePath(const fileName &directory, const instant &t) const
Definition: Time.C:832
Foam::Time::readModifiedObjects
void readModifiedObjects()
Read the objects that have been modified.
Definition: TimeIO.C:452
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
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:385
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:1006
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:309
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:392
Foam::Time::isAdjustTimeStep
virtual bool isAdjustTimeStep() const
Return true if adjustTimeStep is true.
Definition: Time.C:1000
registerSwitch.H
Foam::Time::stopAtControls
stopAtControls
Definition: Time.H:97
timeIndex
label timeIndex
Definition: getTimeIndex.H:4
Foam::Time::endTime
virtual dimensionedScalar endTime() const
Return end time.
Definition: Time.C:878
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:351
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:1119
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:310
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:122
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:890
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:872
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:298
Foam::Time::startTimeIndex
virtual label startTimeIndex() const
Return start time index.
Definition: Time.C:866
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:1106
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157