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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "Time.H"
27 #include "PstreamReduceOps.H"
28 #include "argList.H"
29 
30 #include <sstream>
31 
32 // * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(Time, 0);
37 
38  template<>
39  const char* Foam::NamedEnum
40  <
42  4
43  >::names[] =
44  {
45  "endTime",
46  "noWriteNow",
47  "writeNow",
48  "nextWrite"
49  };
50 
51  template<>
52  const char* Foam::NamedEnum
53  <
55  5
56  >::names[] =
57  {
58  "timeStep",
59  "runTime",
60  "adjustableRunTime",
61  "clockTime",
62  "cpuTime"
63  };
64 }
65 
68 
71 
73 
75 
76 const int Foam::Time::maxPrecision_(3 - log10(SMALL));
77 
79 
80 
81 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
82 
84 {
85  bool adjustTime = false;
86  scalar timeToNextWrite = VGREAT;
87 
89  {
90  adjustTime = true;
91  timeToNextWrite = max
92  (
93  0.0,
95  );
96  }
98  {
99  adjustTime = true;
100  timeToNextWrite = max
101  (
102  0.0,
103  min
104  (
105  timeToNextWrite,
107  - (value() - startTime_)
108  )
109  );
110  }
111 
112  if (adjustTime)
113  {
114  scalar nSteps = timeToNextWrite/deltaT_ - SMALL;
115 
116  // For tiny deltaT the label can overflow!
117  if (nSteps < labelMax)
118  {
119  label nStepsToNextWrite = label(nSteps) + 1;
120 
121  scalar newDeltaT = timeToNextWrite/nStepsToNextWrite;
122 
123  // Control the increase of the time step to within a factor of 2
124  // and the decrease within a factor of 5.
125  if (newDeltaT >= deltaT_)
126  {
127  deltaT_ = min(newDeltaT, 2.0*deltaT_);
128  }
129  else
130  {
131  deltaT_ = max(newDeltaT, 0.2*deltaT_);
132  }
133  }
134  }
135 
137 }
138 
139 
141 {
142  // default is to resume calculation from "latestTime"
143  const word startFrom = controlDict_.lookupOrDefault<word>
144  (
145  "startFrom",
146  "latestTime"
147  );
148 
149  if (startFrom == "startTime")
150  {
151  controlDict_.lookup("startTime") >> startTime_;
152  }
153  else
154  {
155  // Search directory for valid time directories
156  instantList timeDirs = findTimes(path(), constant());
157 
158  if (startFrom == "firstTime")
159  {
160  if (timeDirs.size())
161  {
162  if (timeDirs[0].name() == constant() && timeDirs.size() >= 2)
163  {
164  startTime_ = timeDirs[1].value();
165  }
166  else
167  {
168  startTime_ = timeDirs[0].value();
169  }
170  }
171  }
172  else if (startFrom == "latestTime")
173  {
174  if (timeDirs.size())
175  {
176  startTime_ = timeDirs.last().value();
177  }
178  }
179  else
180  {
181  FatalIOErrorInFunction(controlDict_)
182  << "expected startTime, firstTime or latestTime"
183  << " found '" << startFrom << "'"
184  << exit(FatalIOError);
185  }
186  }
187 
188  setTime(startTime_, 0);
189 
190  readDict();
191  deltaTSave_ = deltaT_;
192  deltaT0_ = deltaT_;
193 
194  // Check if time directory exists
195  // If not increase time precision to see if it is formatted differently.
196  if (!exists(timePath(), false))
197  {
198  int oldPrecision = precision_;
199  int requiredPrecision = -1;
200  bool found = false;
201  for
202  (
203  precision_ = maxPrecision_;
204  precision_ > oldPrecision;
205  precision_--
206  )
207  {
208  // Update the time formatting
209  setTime(startTime_, 0);
210 
211  // Check the existence of the time directory with the new format
212  found = exists(timePath(), false);
213 
214  if (found)
215  {
216  requiredPrecision = precision_;
217  }
218  }
219 
220  if (requiredPrecision > 0)
221  {
222  // Update the time precision
223  precision_ = requiredPrecision;
224 
225  // Update the time formatting
226  setTime(startTime_, 0);
227 
229  << "Increasing the timePrecision from " << oldPrecision
230  << " to " << precision_
231  << " to support the formatting of the current time directory "
232  << timeName() << nl << endl;
233  }
234  else
235  {
236  // Could not find time directory so assume it is not present
237  precision_ = oldPrecision;
238 
239  // Revert the time formatting
240  setTime(startTime_, 0);
241  }
242  }
243 
244  if (Pstream::parRun())
245  {
246  scalar sumStartTime = startTime_;
247  reduce(sumStartTime, sumOp<scalar>());
248  if
249  (
250  mag(Pstream::nProcs()*startTime_ - sumStartTime)
251  > Pstream::nProcs()*deltaT_/10.0
252  )
253  {
254  FatalIOErrorInFunction(controlDict_)
255  << "Start time is not the same for all processors" << nl
256  << "processor " << Pstream::myProcNo() << " has startTime "
257  << startTime_ << exit(FatalIOError);
258  }
259  }
260 
261  IOdictionary timeDict
262  (
263  IOobject
264  (
265  "time",
266  timeName(),
267  "uniform",
268  *this,
271  false
272  )
273  );
274 
275  // Read and set the deltaT only if time-step adjustment is active
276  // otherwise use the deltaT from the controlDict
277  if (controlDict_.lookupOrDefault<Switch>("adjustTimeStep", false))
278  {
279  if (timeDict.readIfPresent("deltaT", deltaT_))
280  {
281  deltaTSave_ = deltaT_;
282  deltaT0_ = deltaT_;
283  }
284  }
285 
286  timeDict.readIfPresent("deltaT0", deltaT0_);
287 
288  if (timeDict.readIfPresent("index", startTimeIndex_))
289  {
290  timeIndex_ = startTimeIndex_;
291  }
292 
293 
294  // Check if values stored in time dictionary are consistent
295 
296  // 1. Based on time name
297  bool checkValue = true;
298 
299  string storedTimeName;
300  if (timeDict.readIfPresent("name", storedTimeName))
301  {
302  if (storedTimeName == timeName())
303  {
304  // Same time. No need to check stored value
305  checkValue = false;
306  }
307  }
308 
309  // 2. Based on time value
310  // (consistent up to the current time writing precision so it won't
311  // trigger if we just change the write precision)
312  if (checkValue)
313  {
314  scalar storedTimeValue;
315  if (timeDict.readIfPresent("value", storedTimeValue))
316  {
317  word storedTimeName(timeName(storedTimeValue));
318 
319  if (storedTimeName != timeName())
320  {
321  IOWarningInFunction(timeDict)
322  << "Time read from time dictionary " << storedTimeName
323  << " differs from actual time " << timeName() << '.' << nl
324  << " This may cause unexpected database behaviour."
325  << " If you are not interested" << nl
326  << " in preserving time state delete"
327  << " the time dictionary."
328  << endl;
329  }
330  }
331  }
332 }
333 
334 
335 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
336 
338 (
339  const word& controlDictName,
340  const fileName& rootPath,
341  const fileName& caseName,
342  const word& systemName,
343  const word& constantName,
344  const bool enableFunctionObjects
345 )
346 :
347  TimePaths
348  (
349  rootPath,
350  caseName,
351  systemName,
352  constantName
353  ),
354 
355  objectRegistry(*this),
356 
357  libs_(),
358 
359  controlDict_
360  (
361  IOobject
362  (
363  controlDictName,
364  system(),
365  *this,
368  false
369  )
370  ),
371 
372  startTimeIndex_(0),
373  startTime_(0),
374  endTime_(0),
375 
376  stopAt_(saEndTime),
377  writeControl_(wcTimeStep),
378  writeInterval_(GREAT),
379  secondaryWriteControl_(wcTimeStep),
380  secondaryWriteInterval_(labelMax/10.0), // bit less to allow calculations
381  purgeWrite_(0),
382  secondaryPurgeWrite_(0),
383  writeOnce_(false),
384  subCycling_(false),
385  sigWriteNow_(true, *this),
386  sigStopAtWriteNow_(true, *this),
387 
388  writeFormat_(IOstream::ASCII),
389  writeVersion_(IOstream::currentVersion),
390  writeCompression_(IOstream::UNCOMPRESSED),
391  graphFormat_("raw"),
392  runTimeModifiable_(false),
393 
394  functionObjects_(*this, enableFunctionObjects)
395 {
396  libs_.open(controlDict_, "libs");
397 
398  // Explicitly set read flags on objectRegistry so anything constructed
399  // from it reads as well (e.g. fvSolution).
401 
402  setControls();
403 
404  // Time objects not registered so do like objectRegistry::checkIn ourselves.
405  if (runTimeModifiable_)
406  {
407  monitorPtr_.reset
408  (
409  new fileMonitor
410  (
412  || regIOobject::fileModificationChecking == inotifyMaster
413  )
414  );
415 
416  // File might not exist yet.
417  fileName f(controlDict_.filePath());
418 
419  if (!f.size())
420  {
421  // We don't have this file but would like to re-read it.
422  // Possibly if in master-only reading mode. Use a non-existing
423  // file to keep fileMonitor synced.
424  f = controlDict_.objectPath();
425  }
426 
427  controlDict_.watchIndex() = addWatch(f);
428  }
429 }
430 
431 
433 (
434  const word& controlDictName,
435  const argList& args,
436  const word& systemName,
437  const word& constantName
438 )
439 :
440  TimePaths
441  (
443  args.rootPath(),
445  args.caseName(),
446  systemName,
447  constantName
448  ),
449 
450  objectRegistry(*this),
451 
452  libs_(),
453 
454  controlDict_
455  (
456  IOobject
457  (
458  controlDictName,
459  system(),
460  *this,
463  false
464  )
465  ),
466 
467  startTimeIndex_(0),
468  startTime_(0),
469  endTime_(0),
470 
471  stopAt_(saEndTime),
472  writeControl_(wcTimeStep),
473  writeInterval_(GREAT),
474  secondaryWriteControl_(wcTimeStep),
475  secondaryWriteInterval_(labelMax/10.0),
476  purgeWrite_(0),
477  secondaryPurgeWrite_(0),
478  writeOnce_(false),
479  subCycling_(false),
480  sigWriteNow_(true, *this),
481  sigStopAtWriteNow_(true, *this),
482 
483  writeFormat_(IOstream::ASCII),
484  writeVersion_(IOstream::currentVersion),
485  writeCompression_(IOstream::UNCOMPRESSED),
486  graphFormat_("raw"),
487  runTimeModifiable_(false),
488 
489  functionObjects_
490  (
491  *this,
492  argList::validOptions.found("withFunctionObjects")
493  ? args.optionFound("withFunctionObjects")
494  : !args.optionFound("noFunctionObjects")
495  )
496 {
497  libs_.open(controlDict_, "libs");
498 
499  // Explicitly set read flags on objectRegistry so anything constructed
500  // from it reads as well (e.g. fvSolution).
502 
503  setControls();
504 
505  // Time objects not registered so do like objectRegistry::checkIn ourselves.
506  if (runTimeModifiable_)
507  {
508  monitorPtr_.reset
509  (
510  new fileMonitor
511  (
513  || regIOobject::fileModificationChecking == inotifyMaster
514  )
515  );
516 
517  // File might not exist yet.
518  fileName f(controlDict_.filePath());
519 
520  if (!f.size())
521  {
522  // We don't have this file but would like to re-read it.
523  // Possibly if in master-only reading mode. Use a non-existing
524  // file to keep fileMonitor synced.
525  f = controlDict_.objectPath();
526  }
527 
528  controlDict_.watchIndex() = addWatch(f);
529  }
530 }
531 
532 
534 (
535  const dictionary& dict,
536  const fileName& rootPath,
537  const fileName& caseName,
538  const word& systemName,
539  const word& constantName,
540  const bool enableFunctionObjects
541 )
542 :
543  TimePaths
544  (
545  rootPath,
546  caseName,
547  systemName,
548  constantName
549  ),
550 
551  objectRegistry(*this),
552 
553  libs_(),
554 
555  controlDict_
556  (
557  IOobject
558  (
559  controlDictName,
560  system(),
561  *this,
564  false
565  ),
566  dict
567  ),
568 
569  startTimeIndex_(0),
570  startTime_(0),
571  endTime_(0),
572 
573  stopAt_(saEndTime),
574  writeControl_(wcTimeStep),
575  writeInterval_(GREAT),
576  secondaryWriteControl_(wcTimeStep),
577  secondaryWriteInterval_(labelMax/10.0),
578  purgeWrite_(0),
579  secondaryPurgeWrite_(0),
580  writeOnce_(false),
581  subCycling_(false),
582  sigWriteNow_(true, *this),
583  sigStopAtWriteNow_(true, *this),
584 
585  writeFormat_(IOstream::ASCII),
586  writeVersion_(IOstream::currentVersion),
587  writeCompression_(IOstream::UNCOMPRESSED),
588  graphFormat_("raw"),
589  runTimeModifiable_(false),
590 
591  functionObjects_(*this, enableFunctionObjects)
592 {
593  libs_.open(controlDict_, "libs");
594 
595 
596  // Explicitly set read flags on objectRegistry so anything constructed
597  // from it reads as well (e.g. fvSolution).
599 
600  // Since could not construct regIOobject with setting:
601  controlDict_.readOpt() = IOobject::MUST_READ_IF_MODIFIED;
602 
603  setControls();
604 
605  // Time objects not registered so do like objectRegistry::checkIn ourselves.
606  if (runTimeModifiable_)
607  {
608  monitorPtr_.reset
609  (
610  new fileMonitor
611  (
613  || regIOobject::fileModificationChecking == inotifyMaster
614  )
615  );
616 
617  // File might not exist yet.
618  fileName f(controlDict_.filePath());
619 
620  if (!f.size())
621  {
622  // We don't have this file but would like to re-read it.
623  // Possibly if in master-only reading mode. Use a non-existing
624  // file to keep fileMonitor synced.
625  f = controlDict_.objectPath();
626  }
627 
628  controlDict_.watchIndex() = addWatch(f);
629  }
630 }
631 
632 
634 (
635  const fileName& rootPath,
636  const fileName& caseName,
637  const word& systemName,
638  const word& constantName,
639  const bool enableFunctionObjects
640 )
641 :
642  TimePaths
643  (
644  rootPath,
645  caseName,
646  systemName,
647  constantName
648  ),
649 
650  objectRegistry(*this),
651 
652  libs_(),
653 
654  controlDict_
655  (
656  IOobject
657  (
658  controlDictName,
659  system(),
660  *this,
663  false
664  )
665  ),
666 
667  startTimeIndex_(0),
668  startTime_(0),
669  endTime_(0),
670 
671  stopAt_(saEndTime),
672  writeControl_(wcTimeStep),
673  writeInterval_(GREAT),
674  secondaryWriteControl_(wcTimeStep),
675  secondaryWriteInterval_(labelMax/10.0),
676  purgeWrite_(0),
677  secondaryPurgeWrite_(0),
678  writeOnce_(false),
679  subCycling_(false),
680 
681  writeFormat_(IOstream::ASCII),
682  writeVersion_(IOstream::currentVersion),
683  writeCompression_(IOstream::UNCOMPRESSED),
684  graphFormat_("raw"),
685  runTimeModifiable_(false),
686 
687  functionObjects_(*this, enableFunctionObjects)
688 {
689  libs_.open(controlDict_, "libs");
690 }
691 
692 
693 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
694 
696 {
697  if (controlDict_.watchIndex() != -1)
698  {
699  removeWatch(controlDict_.watchIndex());
700  }
701 
702  // destroy function objects first
703  functionObjects_.clear();
704 }
705 
706 
707 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
708 
710 {
711  return monitorPtr_().addWatch(fName);
712 }
713 
714 
715 bool Foam::Time::removeWatch(const label watchIndex) const
716 {
717  return monitorPtr_().removeWatch(watchIndex);
718 }
719 
720 const Foam::fileName& Foam::Time::getFile(const label watchIndex) const
721 {
722  return monitorPtr_().getFile(watchIndex);
723 }
724 
725 
727 (
728  const label watchFd
729 ) const
730 {
731  return monitorPtr_().getState(watchFd);
732 }
733 
734 
735 void Foam::Time::setUnmodified(const label watchFd) const
736 {
737  monitorPtr_().setUnmodified(watchFd);
738 }
739 
740 
741 Foam::word Foam::Time::timeName(const scalar t, const int precision)
742 {
743  std::ostringstream buf;
744  buf.setf(ios_base::fmtflags(format_), ios_base::floatfield);
745  buf.precision(precision);
746  buf << t;
747  return buf.str();
748 }
749 
750 
752 {
753  return dimensionedScalar::name();
754 }
755 
756 
757 // Search the construction path for times
759 {
760  return findTimes(path(), constant());
761 }
762 
763 
765 {
766  const fileName directory = path();
767  const word& constantName = constant();
768 
769  // Read directory entries into a list
770  fileNameList dirEntries(readDir(directory, fileName::DIRECTORY));
771 
772  forAll(dirEntries, i)
773  {
774  scalar timeValue;
775  if (readScalar(dirEntries[i].c_str(), timeValue) && t.equal(timeValue))
776  {
777  return dirEntries[i];
778  }
779  }
780 
781  if (t.equal(0.0))
782  {
783  // Looking for 0 or constant. 0 already checked above.
784  if (isDir(directory/constantName))
785  {
786  return constantName;
787  }
788  }
789 
790  return word::null;
791 }
792 
793 
795 {
796  instantList timeDirs = findTimes(path(), constant());
797 
798  // there is only one time (likely "constant") so return it
799  if (timeDirs.size() == 1)
800  {
801  return timeDirs[0];
802  }
803 
804  if (t < timeDirs[1].value())
805  {
806  return timeDirs[1];
807  }
808  else if (t > timeDirs.last().value())
809  {
810  return timeDirs.last();
811  }
812 
813  label nearestIndex = -1;
814  scalar deltaT = GREAT;
815 
816  for (label timei=1; timei < timeDirs.size(); ++timei)
817  {
818  scalar diff = mag(timeDirs[timei].value() - t);
819  if (diff < deltaT)
820  {
821  deltaT = diff;
822  nearestIndex = timei;
823  }
824  }
825 
826  return timeDirs[nearestIndex];
827 }
828 
829 
830 // This should work too,
831 // if we don't worry about checking "constant" explicitly
832 //
833 // Foam::instant Foam::Time::findClosestTime(const scalar t) const
834 // {
835 // instantList timeDirs = findTimes(path(), constant());
836 // label timeIndex = min(findClosestTimeIndex(timeDirs, t), 0, constant());
837 // return timeDirs[timeIndex];
838 // }
839 
841 (
842  const instantList& timeDirs,
843  const scalar t,
844  const word& constantName
845 )
846 {
847  label nearestIndex = -1;
848  scalar deltaT = GREAT;
849 
850  forAll(timeDirs, timei)
851  {
852  if (timeDirs[timei].name() == constantName) continue;
853 
854  scalar diff = mag(timeDirs[timei].value() - t);
855  if (diff < deltaT)
856  {
857  deltaT = diff;
858  nearestIndex = timei;
859  }
860  }
861 
862  return nearestIndex;
863 }
864 
865 
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 
884 bool Foam::Time::run() const
885 {
886  bool running = value() < (endTime_ - 0.5*deltaT_);
887 
888  if (!subCycling_)
889  {
890  // only execute when the condition is no longer true
891  // ie, when exiting the control loop
892  if (!running && timeIndex_ != startTimeIndex_)
893  {
894  // Ensure functionObjects execute on last time step
895  // (and hence write uptodate functionObjectProperties)
896  functionObjects_.execute();
897 
898  functionObjects_.end();
899  }
900  }
901 
902  if (running)
903  {
904  if (!subCycling_)
905  {
906  const_cast<Time&>(*this).readModifiedObjects();
907 
908  if (timeIndex_ == startTimeIndex_)
909  {
910  functionObjects_.start();
911  }
912  else
913  {
914  functionObjects_.execute();
915  }
916  }
917 
918  // Update the "running" status following the
919  // possible side-effects from functionObjects
920  running = value() < (endTime_ - 0.5*deltaT_);
921  }
922 
923  return running;
924 }
925 
926 
928 {
929  bool running = run();
930 
931  if (running)
932  {
933  operator++();
934  }
935 
936  return running;
937 }
938 
939 
940 bool Foam::Time::end() const
941 {
942  return value() > (endTime_ + 0.5*deltaT_);
943 }
944 
945 
946 bool Foam::Time::stopAt(const stopAtControls sa) const
947 {
948  const bool changed = (stopAt_ != sa);
949  stopAt_ = sa;
950 
951  // adjust endTime
952  if (sa == saEndTime)
953  {
954  controlDict_.lookup("endTime") >> endTime_;
955  }
956  else
957  {
958  endTime_ = GREAT;
959  }
960  return changed;
961 }
962 
963 
964 void Foam::Time::setTime(const Time& t)
965 {
966  value() = t.value();
967  dimensionedScalar::name() = t.dimensionedScalar::name();
968  timeIndex_ = t.timeIndex_;
969 }
970 
971 
972 void Foam::Time::setTime(const instant& inst, const label newIndex)
973 {
974  value() = inst.value();
975  dimensionedScalar::name() = inst.name();
976  timeIndex_ = newIndex;
977 
978  IOdictionary timeDict
979  (
980  IOobject
981  (
982  "time",
983  timeName(),
984  "uniform",
985  *this,
988  false
989  )
990  );
991 
992  timeDict.readIfPresent("deltaT", deltaT_);
993  timeDict.readIfPresent("deltaT0", deltaT0_);
994  timeDict.readIfPresent("index", timeIndex_);
995 }
996 
997 
998 void Foam::Time::setTime(const dimensionedScalar& newTime, const label newIndex)
999 {
1000  setTime(newTime.value(), newIndex);
1001 }
1002 
1003 
1004 void Foam::Time::setTime(const scalar newTime, const label newIndex)
1005 {
1006  value() = newTime;
1007  dimensionedScalar::name() = timeName(timeToUserTime(newTime));
1008  timeIndex_ = newIndex;
1009 }
1010 
1011 
1013 {
1014  setEndTime(endTime.value());
1015 }
1016 
1017 
1018 void Foam::Time::setEndTime(const scalar endTime)
1019 {
1020  endTime_ = endTime;
1021 }
1022 
1023 
1026  const dimensionedScalar& deltaT,
1027  const bool bAdjustDeltaT
1028 )
1029 {
1030  setDeltaT(deltaT.value(), bAdjustDeltaT);
1031 }
1032 
1033 
1034 void Foam::Time::setDeltaT(const scalar deltaT, const bool bAdjustDeltaT)
1035 {
1036  deltaT_ = deltaT;
1037  deltaTchanged_ = true;
1038 
1039  if (bAdjustDeltaT)
1040  {
1041  adjustDeltaT();
1042  }
1043 }
1044 
1045 
1047 {
1048  subCycling_ = true;
1049  prevTimeState_.set(new TimeState(*this));
1050 
1051  setTime(*this - deltaT(), (timeIndex() - 1)*nSubCycles);
1052  deltaT_ /= nSubCycles;
1053  deltaT0_ /= nSubCycles;
1054  deltaTSave_ = deltaT0_;
1055 
1056  return prevTimeState();
1057 }
1058 
1059 
1061 {
1062  if (subCycling_)
1063  {
1064  subCycling_ = false;
1065  TimeState::operator=(prevTimeState());
1066  prevTimeState_.clear();
1067  }
1068 }
1069 
1070 
1071 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1072 
1074 {
1075  return operator+=(deltaT.value());
1076 }
1077 
1078 
1079 Foam::Time& Foam::Time::operator+=(const scalar deltaT)
1080 {
1081  setDeltaT(deltaT);
1082  return operator++();
1083 }
1084 
1085 
1087 {
1088  deltaT0_ = deltaTSave_;
1089  deltaTSave_ = deltaT_;
1090 
1091  // Save old time value and name
1092  const scalar oldTimeValue = timeToUserTime(value());
1093  const word oldTimeName = dimensionedScalar::name();
1094 
1095  // Increment time
1096  setTime(value() + deltaT_, timeIndex_ + 1);
1097 
1098  if (!subCycling_)
1099  {
1100  // If the time is very close to zero reset to zero
1101  if (mag(value()) < 10*SMALL*deltaT_)
1102  {
1103  setTime(0.0, timeIndex_);
1104  }
1105 
1106  if (sigStopAtWriteNow_.active() || sigWriteNow_.active())
1107  {
1108  // A signal might have been sent on one processor only
1109  // Reduce so all decide the same.
1110 
1111  label flag = 0;
1112  if (sigStopAtWriteNow_.active() && stopAt_ == saWriteNow)
1113  {
1114  flag += 1;
1115  }
1116  if (sigWriteNow_.active() && writeOnce_)
1117  {
1118  flag += 2;
1119  }
1120  reduce(flag, maxOp<label>());
1121 
1122  if (flag & 1)
1123  {
1124  stopAt_ = saWriteNow;
1125  }
1126  if (flag & 2)
1127  {
1128  writeOnce_ = true;
1129  }
1130  }
1131 
1132 
1133  outputTime_ = false;
1134  primaryOutputTime_ = false;
1135  secondaryOutputTime_ = false;
1136 
1137  switch (writeControl_)
1138  {
1139  case wcTimeStep:
1140  primaryOutputTime_ = !(timeIndex_ % label(writeInterval_));
1141  break;
1142 
1143  case wcRunTime:
1144  case wcAdjustableRunTime:
1145  {
1146  label outputIndex = label
1147  (
1148  ((value() - startTime_) + 0.5*deltaT_)
1149  / writeInterval_
1150  );
1151 
1152  if (outputIndex > outputTimeIndex_)
1153  {
1154  primaryOutputTime_ = true;
1155  outputTimeIndex_ = outputIndex;
1156  }
1157  }
1158  break;
1159 
1160  case wcCpuTime:
1161  {
1162  label outputIndex = label
1163  (
1164  returnReduce(elapsedCpuTime(), maxOp<double>())
1165  / writeInterval_
1166  );
1167  if (outputIndex > outputTimeIndex_)
1168  {
1169  primaryOutputTime_ = true;
1170  outputTimeIndex_ = outputIndex;
1171  }
1172  }
1173  break;
1174 
1175  case wcClockTime:
1176  {
1177  label outputIndex = label
1178  (
1179  returnReduce(label(elapsedClockTime()), maxOp<label>())
1180  / writeInterval_
1181  );
1182  if (outputIndex > outputTimeIndex_)
1183  {
1184  primaryOutputTime_ = true;
1185  outputTimeIndex_ = outputIndex;
1186  }
1187  }
1188  break;
1189  }
1190 
1191 
1192  // Adapt for secondaryWrite controls
1193  switch (secondaryWriteControl_)
1194  {
1195  case wcTimeStep:
1196  secondaryOutputTime_ =
1197  !(timeIndex_ % label(secondaryWriteInterval_));
1198  break;
1199 
1200  case wcRunTime:
1201  case wcAdjustableRunTime:
1202  {
1203  label outputIndex = label
1204  (
1205  ((value() - startTime_) + 0.5*deltaT_)
1206  / secondaryWriteInterval_
1207  );
1208 
1209  if (outputIndex > secondaryOutputTimeIndex_)
1210  {
1211  secondaryOutputTime_ = true;
1212  secondaryOutputTimeIndex_ = outputIndex;
1213  }
1214  }
1215  break;
1216 
1217  case wcCpuTime:
1218  {
1219  label outputIndex = label
1220  (
1221  returnReduce(elapsedCpuTime(), maxOp<double>())
1222  / secondaryWriteInterval_
1223  );
1224  if (outputIndex > secondaryOutputTimeIndex_)
1225  {
1226  secondaryOutputTime_ = true;
1227  secondaryOutputTimeIndex_ = outputIndex;
1228  }
1229  }
1230  break;
1231 
1232  case wcClockTime:
1233  {
1234  label outputIndex = label
1235  (
1236  returnReduce(label(elapsedClockTime()), maxOp<label>())
1237  / secondaryWriteInterval_
1238  );
1239  if (outputIndex > secondaryOutputTimeIndex_)
1240  {
1241  secondaryOutputTime_ = true;
1242  secondaryOutputTimeIndex_ = outputIndex;
1243  }
1244  }
1245  break;
1246  }
1247 
1248 
1249  outputTime_ = primaryOutputTime_ || secondaryOutputTime_;
1250 
1251 
1252  // Check if endTime needs adjustment to stop at the next run()/end()
1253  if (!end())
1254  {
1255  if (stopAt_ == saNoWriteNow)
1256  {
1257  endTime_ = value();
1258  }
1259  else if (stopAt_ == saWriteNow)
1260  {
1261  endTime_ = value();
1262  outputTime_ = true;
1263  primaryOutputTime_ = true;
1264  }
1265  else if (stopAt_ == saNextWrite && outputTime_ == true)
1266  {
1267  endTime_ = value();
1268  }
1269  }
1270 
1271  // Override outputTime if one-shot writing
1272  if (writeOnce_)
1273  {
1274  primaryOutputTime_ = true;
1275  outputTime_ = true;
1276  writeOnce_ = false;
1277  }
1278 
1279  // Adjust the precision of the time directory name if necessary
1280  if (outputTime_)
1281  {
1282  // Tolerance used when testing time equivalence
1283  const scalar timeTol =
1284  max(min(pow(10.0, -precision_), 0.1*deltaT_), SMALL);
1285 
1286  // User-time equivalent of deltaT
1287  const scalar userDeltaT = timeToUserTime(deltaT_);
1288 
1289  // Time value obtained by reading timeName
1290  scalar timeNameValue = -VGREAT;
1291 
1292  // Check that new time representation differs from old one
1293  // reinterpretation of the word
1294  if
1295  (
1296  readScalar(dimensionedScalar::name().c_str(), timeNameValue)
1297  && (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
1298  )
1299  {
1300  int oldPrecision = precision_;
1301  while
1302  (
1303  precision_ < maxPrecision_
1304  && readScalar(dimensionedScalar::name().c_str(), timeNameValue)
1305  && (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
1306  )
1307  {
1308  precision_++;
1309  setTime(value(), timeIndex());
1310  }
1311 
1312  if (precision_ != oldPrecision)
1313  {
1315  << "Increased the timePrecision from " << oldPrecision
1316  << " to " << precision_
1317  << " to distinguish between timeNames at time "
1319  << endl;
1320 
1321  if (precision_ == maxPrecision_)
1322  {
1323  // Reached maxPrecision limit
1325  << "Current time name " << dimensionedScalar::name()
1326  << nl
1327  << " The maximum time precision has been reached"
1328  " which might result in overwriting previous"
1329  " results."
1330  << endl;
1331  }
1332 
1333  // Check if round-off error caused time-reversal
1334  scalar oldTimeNameValue = -VGREAT;
1335  if
1336  (
1337  readScalar(oldTimeName.c_str(), oldTimeNameValue)
1338  && (
1339  sign(timeNameValue - oldTimeNameValue)
1340  != sign(deltaT_)
1341  )
1342  )
1343  {
1345  << "Current time name " << dimensionedScalar::name()
1346  << " is set to an instance prior to the "
1347  "previous one "
1348  << oldTimeName << nl
1349  << " This might result in temporal "
1350  "discontinuities."
1351  << endl;
1352  }
1353  }
1354  }
1355  }
1356 
1357  functionObjects_.timeSet();
1358  }
1359 
1360  return *this;
1361 }
1362 
1363 
1365 {
1366  return operator++();
1367 }
1368 
1369 
1370 // ************************************************************************* //
Foam::Time::functionObjects_
functionObjectList functionObjects_
Function objects executed at start and on ++, +=.
Definition: Time.H:205
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:53
Foam::Time::writeControls
writeControls
Write control options.
Definition: Time.H:91
Foam::maxOp
Definition: ops.H:172
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
Foam::Time::format_
static fmtflags format_
Time directory name format.
Definition: Time.H:169
Foam::Time::general
@ general
Definition: Time.H:112
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:60
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
Foam::functionObjectList::adjustTimeStep
virtual bool adjustTimeStep()
Called at the end of Time::adjustDeltaT() if adjustTime is true.
Definition: functionObjectList.C:276
Foam::Time::setEndTime
virtual void setEndTime(const dimensionedScalar &)
Reset end time.
Definition: Time.C:1012
Foam::Time::end
virtual bool end() const
Return true if end of run,.
Definition: Time.C:940
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::exists
bool exists(const fileName &, const bool checkGzip=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:608
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:86
Foam::Time::findInstancePath
word findInstancePath(const instant &) const
Search the case for the time directory path.
Definition: Time.C:764
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::dictionary::readIfPresent
bool readIfPresent(const word &, T &, bool recursive=false, bool patternMatch=true) const
Find an entry if present, and assign to T.
Definition: dictionaryTemplates.C:94
Foam::instant::equal
bool equal(const scalar) const
Comparison used for instants to be equal.
Definition: instant.C:59
Foam::Time::times
instantList times() const
Search the case for valid time directories.
Definition: Time.C:758
Time.H
Foam::labelMax
static const label labelMax
Definition: label.H:62
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:387
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::Time::operator+=
virtual Time & operator+=(const dimensionedScalar &)
Set deltaT to that specified and increment time via operator++()
Definition: Time.C:1073
Foam::dimensioned::name
const word & name() const
Return const reference to name.
Definition: dimensionedType.C:235
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:97
Foam::fileMonitor::fileState
fileState
Enumeration defining the file state.
Definition: fileMonitor.H:69
Foam::Time::findClosestTimeIndex
static label findClosestTimeIndex(const instantList &, const scalar, const word &constantName="constant")
Search instantList for the time index closest to the given time.
Definition: Time.C:841
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:261
Foam::Time::getState
fileMonitor::fileState getState(const label) const
Get current state of file (using handle)
Definition: Time.C:727
Foam::Time::addWatch
label addWatch(const fileName &) const
Add watching of a file. Returns handle.
Definition: Time.C:709
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::sign
dimensionedScalar sign(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:179
Foam::IOstream::currentVersion
static const versionNumber currentVersion
Current version number.
Definition: IOstream.H:206
setTime
runTimeSource setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex)
Foam::Time::fmtflags
fmtflags
Supported time directory name formats.
Definition: Time.H:110
Foam::Time::wcAdjustableRunTime
@ wcAdjustableRunTime
Definition: Time.H:95
Foam::Time::maxPrecision_
static const int maxPrecision_
Maximum time directory name precision.
Definition: Time.H:175
Foam::Time::secondaryWriteInterval_
scalar secondaryWriteInterval_
Definition: Time.H:138
Foam::argList::rootPath
const fileName & rootPath() const
Return root path.
Definition: argListI.H:36
Foam::instant::name
const word & name() const
Name (const access)
Definition: instant.H:124
Foam::IOobject::NO_WRITE
@ NO_WRITE
Definition: IOobject.H:118
constant
Constant dispersed-phase particle diameter model.
Foam::argList::parRunControl
const ParRunControl & parRunControl() const
Return parRunControl.
Definition: argListI.H:54
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:50
Foam::diff
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition: triad.C:407
Foam::IOobject::MUST_READ_IF_MODIFIED
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:109
Foam::dimTime
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:51
Foam::Time::timeName
virtual word timeName() const
Return current time name.
Definition: Time.C:751
Foam::IOstream::ASCII
@ ASCII
Definition: IOstream.H:88
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::Time::adjustDeltaT
void adjustDeltaT()
Adjust the time step so that writing occurs at the specified time.
Definition: Time.C:83
Foam::TimeState
The time value with time-stepping information, user-defined remapping, etc.
Definition: TimeState.H:49
Foam::Time::setUnmodified
void setUnmodified(const label) const
Set current state of file (using handle) to unmodified.
Definition: Time.C:735
Foam::Time::~Time
virtual ~Time()
Destructor.
Definition: Time.C:695
Foam::Time::subCycle
virtual TimeState subCycle(const label nSubCycles)
Set time to sub-cycle for the given number of steps.
Definition: Time.C:1046
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:59
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::log10
dimensionedScalar log10(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:254
argList.H
Foam::fileMonitor
Checking for changes to files.
Definition: fileMonitor.H:61
Foam::Time::stopAtControlNames_
static const NamedEnum< stopAtControls, 4 > stopAtControlNames_
Definition: Time.H:126
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:41
Foam::pow
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Definition: dimensionedScalar.C:73
timeIndex
label timeIndex
Definition: getTimeIndex.H:4
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::Time::secondaryWriteControl_
writeControls secondaryWriteControl_
Definition: Time.H:136
Foam::argList::validOptions
static HashTable< string > validOptions
A list of valid options.
Definition: argList.H:146
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
Foam::Time::loop
virtual bool loop()
Return true if run should continue and if so increment time.
Definition: Time.C:927
Foam::Time::setTime
virtual void setTime(const Time &)
Reset the time and time-index to those of the given time.
Definition: Time.C:964
Foam::Time::operator++
virtual Time & operator++()
Prefix increment,.
Definition: Time.C:1086
Foam::dimensioned
Generic dimensioned Type class.
Definition: dimensionedScalarFwd.H:41
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::isDir
bool isDir(const fileName &)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:615
Foam::TimeState::secondaryOutputTimeIndex_
label secondaryOutputTimeIndex_
Definition: TimeState.H:66
PstreamReduceOps.H
Foam::Time::precision_
static int precision_
Time directory name precision.
Definition: Time.H:172
Foam::TimePaths
A class for addressing time paths without using the Time class.
Definition: TimePaths.H:49
Foam::Time::stopAt
virtual bool stopAt(const stopAtControls) const
Adjust the current stopAtControl. Note that this value.
Definition: Time.C:946
Foam::TimeState::outputTimeIndex_
label outputTimeIndex_
Definition: TimeState.H:62
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
found
bool found
Definition: TABSMDCalcMethod2.H:32
Foam::regIOobject::fileModificationChecking
static fileCheckTypes fileModificationChecking
Definition: regIOobject.H:128
Foam::instant::value
scalar value() const
Value (const access)
Definition: instant.H:112
timeDirs
static instantList timeDirs
Definition: globalFoam.H:44
Foam::Time::readModifiedObjects
void readModifiedObjects()
Read the objects that have been modified.
Definition: TimeIO.C:450
Foam::sumOp
Definition: ops.H:162
Foam::readScalar
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
Definition: doubleScalar.H:63
f
labelList f(nPoints)
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::Time::writeInterval_
scalar writeInterval_
Definition: Time.H:132
Foam::Time::findClosestTime
instant findClosestTime(const scalar) const
Search the case for the time closest to the given time.
Definition: Time.C:794
Foam::Time::removeWatch
bool removeWatch(const label) const
Remove watch on a file (using handle)
Definition: Time.C:715
Foam::Time::writeControlNames_
static const NamedEnum< writeControls, 5 > writeControlNames_
Definition: Time.H:129
Foam::fileName::DIRECTORY
@ DIRECTORY
Definition: fileName.H:86
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
Foam::Time::startTime_
scalar startTime_
Definition: Time.H:123
Foam::argList::optionFound
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:108
Foam::TimeState::timeIndex_
label timeIndex_
Definition: TimeState.H:56
Foam::IOstream::UNCOMPRESSED
@ UNCOMPRESSED
Definition: IOstream.H:195
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:330
Foam::argList::caseName
const fileName & caseName() const
Return case name (parallel run) or global case (serial run)
Definition: argListI.H:42
Foam::Time::stopAtControls
stopAtControls
Stop-run control options.
Definition: Time.H:101
Foam::ParRunControl::parRun
bool parRun() const
Definition: parRun.H:77
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:64
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::Time::endSubCycle
virtual void endSubCycle()
Reset time after sub-cycling back to previous TimeState.
Definition: Time.C:1060
Foam::Time::setControls
void setControls()
Set the controls from the current controlDict.
Definition: Time.C:140
Foam::readDir
fileNameList readDir(const fileName &, const fileName::Type=fileName::FILE, const bool filtergz=true)
Read a directory and return the entries as a string list.
Definition: POSIX.C:660
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:271
Foam::Time::Time
Time(const word &name, const argList &args, const word &systemName="system", const word &constantName="constant")
Construct given name of dictionary to read and argument list.
Definition: Time.C:433
args
Foam::argList args(argc, argv)
Foam::Time::controlDictName
static word controlDictName
The default control dictionary name (normally "controlDict")
Definition: Time.H:213
Foam::IOobject::READ_IF_PRESENT
@ READ_IF_PRESENT
Definition: IOobject.H:110
Foam::Time::writeControl_
writeControls writeControl_
Definition: Time.H:130
Foam::Time::run
virtual bool run() const
Return true if run should continue,.
Definition: Time.C:884
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::TimeState::deltaT_
scalar deltaT_
Definition: TimeState.H:57
Foam::Time::startTime
virtual dimensionedScalar startTime() const
Return start time.
Definition: Time.C:872
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:259
Foam::system
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1155
Foam::argList::globalCaseName
const fileName & globalCaseName() const
Return case name.
Definition: argListI.H:48
Foam::Time::startTimeIndex
virtual label startTimeIndex() const
Return start time index.
Definition: Time.C:866
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::NamedEnum
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:52
Foam::Time::setDeltaT
virtual void setDeltaT(const dimensionedScalar &, const bool adjustDeltaT=true)
Reset time step.
Definition: Time.C:1025
Foam::Time::getFile
const fileName & getFile(const label) const
Get name of file being watched (using handle)
Definition: Time.C:720