Loading...
Searching...
No Matches
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-2023 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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 "IOdictionary.H"
36#include <sstream>
37
38// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
39
40namespace Foam
41{
43}
44
45const Foam::Enum
46<
48>
50({
51 { stopAtControls::saEndTime, "endTime" },
52 { stopAtControls::saNoWriteNow, "noWriteNow" },
53 { stopAtControls::saWriteNow, "writeNow" },
54 { stopAtControls::saNextWrite, "nextWrite" },
55 // Leave saUnknown untabulated - fallback to flag unknown settings
56});
57
58
59const Foam::Enum
60<
62>
64({
65 { writeControls::wcNone, "none" },
66 { writeControls::wcTimeStep, "timeStep" },
67 { writeControls::wcRunTime, "runTime" },
68 { writeControls::wcAdjustableRunTime, "adjustable" },
69 { writeControls::wcAdjustableRunTime, "adjustableRunTime" },
70 { writeControls::wcClockTime, "clockTime" },
71 { writeControls::wcCpuTime, "cpuTime" },
72 // Leave wcUnknown untabulated - fallback to flag unknown settings
73});
74
75
77(
78 IOstreamOption::floatFormat::general
79);
80
82
83const int Foam::Time::maxPrecision_(3 - log10(SMALL));
84
86
88(
89 Foam::debug::infoSwitch("printExecutionFormat", 0)
90);
91
93(
94 "printExecutionFormat",
95 int,
97);
98
99
100// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
101
103{
104 bool adjustTime = false;
105 scalar timeToNextWrite = VGREAT;
106
108 {
109 adjustTime = true;
110 timeToNextWrite = max
111 (
112 0.0,
114 );
115 }
116
117 if (adjustTime)
118 {
119 scalar nSteps = timeToNextWrite/deltaT_;
120
121 // For tiny deltaT the label can overflow!
122 if (nSteps < scalar(labelMax))
123 {
124 // nSteps can be < 1 so make sure at least 1
125 label nStepsToNextWrite = max(1, round(nSteps));
126
127 scalar newDeltaT = timeToNextWrite/nStepsToNextWrite;
128
129 // Control the increase of the time step to within a factor of 2
130 // and the decrease within a factor of 5.
131 if (newDeltaT >= deltaT_)
132 {
133 deltaT_ = min(newDeltaT, 2.0*deltaT_);
134 }
135 else
136 {
137 deltaT_ = max(newDeltaT, 0.2*deltaT_);
138 }
140 }
141
142 functionObjects_.adjustTimeStep();
143}
144
145
147{
148 // default is to resume calculation from "latestTime"
149 const word startFrom = controlDict_.getOrDefault<word>
150 (
151 "startFrom",
152 "latestTime"
153 );
154
155 if (startFrom == "startTime")
156 {
157 controlDict_.readEntry("startTime", startTime_);
158 }
159 else
160 {
161 // Search directory for valid time directories
162 instantList timeDirs = findTimes(path(), constant());
163
164 const label nTimes = timeDirs.size();
165
166 if (startFrom == "firstTime")
167 {
168 if (nTimes > 1 && timeDirs.front().name() == constant())
169 {
170 startTime_ = timeDirs[1].value();
171 }
172 else if (nTimes)
173 {
174 startTime_ = timeDirs.front().value();
175 }
176 }
177 else if (startFrom == "latestTime")
178 {
179 if (nTimes)
180 {
181 startTime_ = timeDirs.back().value();
182 }
183 }
184 else
185 {
186 FatalIOErrorInFunction(controlDict_)
187 << "expected startTime, firstTime or latestTime"
188 << " found '" << startFrom << "'"
189 << exit(FatalIOError);
190 }
191 }
192
193 setTime(startTime_, 0);
194
195 readDict();
196 deltaTSave_ = deltaT_;
197 deltaT0_ = deltaT_;
198
199 // Check if time directory exists
200 // If not increase time precision to see if it is formatted differently.
201 // Note: - do not use raw fileHandler().exists(...) since does not check
202 // alternative processorsDDD directories naming
203 // - do not look for compressed (is directory)
204
205 const fileName timeDir(fileHandler().filePath(timePath(), false));
206 if (returnReduceAnd(timeDir.empty()))
207 {
208 const int oldPrecision = precision_;
209 int requiredPrecision = -1;
211 for
212 (
213 precision_ = maxPrecision_;
214 precision_ > oldPrecision;
215 --precision_
216 )
217 {
218 // Update the time formatting
219 setTime(startTime_, 0);
220
221 word newTime(timeName());
222 if (newTime == oldTime)
223 {
224 break;
225 }
226 oldTime = std::move(newTime);
227
228 // Does a time directory exist with the new format?
229 const fileName timeDir(fileHandler().filePath(timePath(), false));
230 if (returnReduceOr(!timeDir.empty()))
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 (
280 (
281 "time",
282 timeName(),
283 "uniform",
284 *this,
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."
345 }
346 }
347 }
348}
349
350
351void 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 (
368 (
369 "profiling",
370 timeName(),
371 "uniform",
372 *this,
376 ),
377 *this
378 );
379 }
380 else if
381 (
382 profilingDict
383 && profilingDict->getOrDefault("active", true)
384 )
385 {
387 (
388 *profilingDict,
390 (
391 "profiling",
392 timeName(),
393 "uniform",
394 *this,
398 ),
399 *this
400 );
401 }
402
403 // Time objects not registered so do like objectRegistry::checkIn ourselves.
404 if (runTimeModifiable_)
405 {
406 // Monitor all files that controlDict depends on
407 // Files might have been set during token reading so only on master
408 // processor. Broadcast names to all processors
409 // (even although they are only checked on master)
410 // so that the watched states are synchronised
411
412 Pstream::broadcast(controlDict_.files(), UPstream::worldComm);
413 fileHandler().addWatches(controlDict_, controlDict_.files());
414 }
415
416 // Clear dependent files - not needed now
417 controlDict_.files().clear();
418}
419
420
421// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
422
424(
425 const word& ctrlDictName,
426 const fileName& rootPath,
427 const fileName& caseName,
428 const word& systemDirName,
429 const word& constantDirName,
430 const bool enableFunctionObjects,
431 const bool enableLibs,
432 IOobjectOption::readOption rOpt // (default: READ_MODIFIED)
433)
434:
435 TimePaths(rootPath, caseName, systemDirName, constantDirName),
436 objectRegistry(*this),
437 loopProfiling_(nullptr),
438 libs_(),
439
440 controlDict_
441 (
443 (
444 ctrlDictName,
445 system(),
446 *this,
447 rOpt,
448 IOobjectOption::NO_WRITE,
449 IOobjectOption::NO_REGISTER
450 )
451 ),
452
453 startTimeIndex_(0),
454 startTime_(0),
455 endTime_(0),
456
457 stopAt_(saEndTime),
458 writeControl_(wcTimeStep),
459 writeInterval_(GREAT),
460 purgeWrite_(0),
461 subCycling_(0),
462 writeOnce_(false),
463 sigWriteNow_(*this, true),
464 sigStopAtWriteNow_(*this, true),
465 writeStreamOption_(IOstreamOption::ASCII),
466 graphFormat_("raw"),
467 runTimeModifiable_(false),
468 cacheTemporaryObjects_(true),
469 functionObjects_(*this, false)
470{
471 if (enableFunctionObjects)
472 {
473 functionObjects_.on();
474 }
475
476 if (enableLibs)
477 {
478 libs_.open("libs", controlDict_);
479 }
480
481 // Explicitly set read flags on objectRegistry so anything constructed
482 // from it reads as well (e.g. fvSolution).
484
485 setControls();
487}
488
489
491(
492 const word& ctrlDictName,
493 const argList& args,
494 const word& systemDirName,
495 const word& constantDirName,
496 const bool enableFunctionObjects,
497 const bool enableLibs,
498 IOobjectOption::readOption rOpt // (default: READ_MODIFIED)
499)
500:
501 TimePaths(args, systemDirName, constantDirName),
502 objectRegistry(*this),
503 loopProfiling_(nullptr),
504 libs_(),
505
506 controlDict_
507 (
509 (
510 ctrlDictName,
511 system(),
512 *this,
513 rOpt,
514 IOobjectOption::NO_WRITE,
515 IOobjectOption::NO_REGISTER
516 )
517 ),
518
519 startTimeIndex_(0),
520 startTime_(0),
521 endTime_(0),
522
523 stopAt_(saEndTime),
524 writeControl_(wcTimeStep),
525 writeInterval_(GREAT),
526 purgeWrite_(0),
527 subCycling_(0),
528 writeOnce_(false),
529 sigWriteNow_(*this, true),
530 sigStopAtWriteNow_(*this, true),
531 writeStreamOption_(IOstreamOption::ASCII),
532 graphFormat_("raw"),
533 runTimeModifiable_(false),
534 cacheTemporaryObjects_(true),
535 functionObjects_(*this, false)
536{
537 // Functions
538 //
539 // * '-withFunctionObjects' exists and used = enable
540 // * '-noFunctionObjects' exists and used = disable
541 // * default: no functions if there is no way to enable/disable them
542 if (enableFunctionObjects && args.allowFunctionObjects())
543 {
544 functionObjects_.on();
545 }
546
547 // Libraries
548 //
549 // * enable by default unless '-no-libs' option was used
550 if (enableLibs && args.allowLibs())
551 {
552 libs_.open("libs", controlDict_);
553 }
554
555 // Explicitly set read flags on objectRegistry so anything constructed
556 // from it reads as well (e.g. fvSolution).
558
560
561 // '-profiling' = force profiling, ignore controlDict entry
562 setMonitoring(args.found("profiling"));
563}
564
565
567(
568 const dictionary& dict,
569 const fileName& rootPath,
570 const fileName& caseName,
571 const word& systemDirName,
572 const word& constantDirName,
573 const bool enableFunctionObjects,
574 const bool enableLibs,
575 IOobjectOption::readOption rOpt // (default: READ_MODIFIED)
576)
577:
578 TimePaths(rootPath, caseName, systemDirName, constantDirName),
579 objectRegistry(*this),
580 loopProfiling_(nullptr),
581 libs_(),
582
583 controlDict_
584 (
585 // Construct no-read, copying initial contents
587 (
588 Time::controlDictName,
589 system(),
590 *this,
591 IOobjectOption::NO_READ,
592 IOobjectOption::NO_WRITE,
593 IOobjectOption::NO_REGISTER
594 ),
595 dict
596 ),
597
598 startTimeIndex_(0),
599 startTime_(0),
600 endTime_(0),
601
602 stopAt_(saEndTime),
603 writeControl_(wcTimeStep),
604 writeInterval_(GREAT),
605 purgeWrite_(0),
606 subCycling_(0),
607 writeOnce_(false),
608 sigWriteNow_(*this, true),
609 sigStopAtWriteNow_(*this, true),
610 writeStreamOption_(IOstreamOption::ASCII),
611 graphFormat_("raw"),
612 runTimeModifiable_(false),
613 cacheTemporaryObjects_(true),
614 functionObjects_(*this, false)
615{
616 if (enableFunctionObjects)
617 {
618 functionObjects_.on();
619 }
620
621 if (enableLibs)
622 {
623 libs_.open("libs", controlDict_);
624 }
625
626
627 // Explicitly set read flags on objectRegistry so anything constructed
628 // from it reads as well (e.g. fvSolution).
630
631 // Since could not construct controlDict with setting:
632 controlDict_.readOpt(rOpt);
633
634 setControls();
636}
637
638
640(
641 const fileName& rootPath,
642 const fileName& caseName,
643 const word& systemDirName,
644 const word& constantDirName,
645 const bool enableFunctionObjects,
646 const bool enableLibs
647)
648:
649 TimePaths(rootPath, caseName, systemDirName, constantDirName),
650 objectRegistry(*this),
651 loopProfiling_(nullptr),
652 libs_(),
653
654 controlDict_
655 (
657 (
658 Time::controlDictName,
659 system(),
660 *this,
661 IOobjectOption::NO_READ,
662 IOobjectOption::NO_WRITE,
663 IOobjectOption::NO_REGISTER
664 )
665 ),
666
667 startTimeIndex_(0),
668 startTime_(0),
669 endTime_(0),
670
671 stopAt_(saEndTime),
672 writeControl_(wcTimeStep),
673 writeInterval_(GREAT),
674 purgeWrite_(0),
675 subCycling_(0),
676 writeOnce_(false),
677 writeStreamOption_(IOstreamOption::ASCII),
678 graphFormat_("raw"),
679 runTimeModifiable_(false),
680 cacheTemporaryObjects_(true),
681 functionObjects_(*this, false)
682{
683 if (enableFunctionObjects)
684 {
685 functionObjects_.on();
686 }
687
688 if (enableLibs)
689 {
690 libs_.open("libs", controlDict_);
691 }
693 setMonitoring(); // for profiling etc
694}
695
696
697// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
698
700{
701 loopProfiling_.reset(nullptr);
702
703 forAllReverse(controlDict_.watchIndices(), i)
704 {
705 fileHandler().removeWatch(controlDict_.watchIndices()[i]);
706 }
707
708 // Destroy function objects first
709 functionObjects_.clear();
710
711 // Clean up profiling
712 profiling::stop(*this);
713
714 // Ensure all owned objects are also cleaned up now
716}
717
718
719// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
720
721Foam::word Foam::Time::timeName(const scalar t, const int precision)
722{
723 std::ostringstream buf;
724 buf.setf(std::ios_base::fmtflags(format_), std::ios_base::floatfield);
725 buf.precision(precision);
726 buf << t;
727 return buf.str();
728}
729
730
732(
733 const fileName& directory,
734 const word& name,
736 const word& stopInstance,
737 const bool constant_fallback
738) const
739{
740 // Note: name can be empty (ie, search for directory only)
741 IOobject startIO(name, timeName(), directory, *this, rOpt);
742
743 // Searching starts based on the current output time
744 scalar startValue = timeOutputValue();
745
747 (
748 fileHandler().findInstance
749 (
750 startIO,
751 startValue,
752 stopInstance,
753 constant_fallback
754 )
755 );
756 return io.instance();
757}
758
760Foam::label Foam::Time::startTimeIndex() const
761{
762 return startTimeIndex_;
763}
764
769}
770
775}
776
779{
780 return stopAt_;
781}
782
783
784bool Foam::Time::run() const
785{
786 loopProfiling_.reset(nullptr);
787
788 bool isRunning = value() < (endTime_ - 0.5*deltaT_);
789
790 if (!subCycling_)
791 {
792 // Only execute when the condition is no longer true
793 // ie, when exiting the control loop
794 if (!isRunning && timeIndex_ != startTimeIndex_)
795 {
796 // Ensure functionObjects execute on last time step
797 // (and hence write uptodate functionObjectProperties)
798 {
799 addProfiling(fo, "functionObjects.execute()");
800 functionObjects_.execute();
801 }
802 {
803 addProfiling(fo, "functionObjects.end()");
804 functionObjects_.end();
805 }
806
807 if (cacheTemporaryObjects_)
808 {
809 cacheTemporaryObjects_ = checkCacheTemporaryObjects();
810 }
811 }
812 }
813
814 if (isRunning)
815 {
816 if (!subCycling_)
817 {
818 const_cast<Time&>(*this).readModifiedObjects();
819
820 if (timeIndex_ == startTimeIndex_)
821 {
822 addProfiling(functionObjects, "functionObjects.start()");
823 functionObjects_.start();
824 }
825 else
826 {
827 addProfiling(functionObjects, "functionObjects.execute()");
828 functionObjects_.execute();
829 }
830
831 // Check if the execution of functionObjects require re-reading
832 // any files. This moves effect of e.g. 'timeActivatedFileUpdate'
833 // one time step forward. Note that we cannot call
834 // readModifiedObjects from within timeActivatedFileUpdate since
835 // it might re-read the functionObjects themselves (and delete
836 // the timeActivatedFileUpdate one)
837 if (functionObjects_.filesModified())
838 {
839 const_cast<Time&>(*this).readModifiedObjects();
840 }
841
842 if (cacheTemporaryObjects_)
843 {
844 cacheTemporaryObjects_ = checkCacheTemporaryObjects();
845 }
846 }
847
848 // Update the "is-running" status following the
849 // possible side-effects from functionObjects
850 isRunning = value() < (endTime_ - 0.5*deltaT_);
851
852 // (re)trigger profiling
853 if (profiling::active())
854 {
855 loopProfiling_.reset
856 (
857 new profilingTrigger("time.run() " + objectRegistry::name())
858 );
860 }
861
862 return isRunning;
863}
864
865
866bool Foam::Time::loop()
867{
868 const bool isRunning = run();
869
870 if (isRunning)
871 {
873 }
874
875 return isRunning;
876}
877
879bool Foam::Time::end() const
880{
881 return value() > (endTime_ + 0.5*deltaT_);
882}
883
884
885bool Foam::Time::stopAt(const stopAtControls stopCtrl) const
886{
887 if (stopCtrl == stopAtControls::saUnknown)
888 {
889 return false;
890 }
891
892 const bool changed = (stopAt_ != stopCtrl);
893 stopAt_ = stopCtrl;
894 endTime_ = GREAT;
895
896 // Adjust endTime
897 if (stopCtrl == stopAtControls::saEndTime)
898 {
899 controlDict_.readEntry("endTime", endTime_);
900 }
901
902 return changed;
903}
904
907{
908 return controlDict_.getOrDefault("adjustTimeStep", false);
909}
910
911
913{
914 resetTimeState(t.timeName(), t.value(), t.timeIndex());
915 fileHandler().setTime(*this);
916}
917
918
919void Foam::Time::setTime(const instant& inst, const label newIndex)
920{
921 resetTimeState(inst.name(), inst.value(), newIndex);
922
923 IOdictionary timeDict
924 (
926 (
927 "time",
928 timeName(),
929 "uniform",
930 *this,
934 )
935 );
936
937 timeDict.readIfPresent("deltaT", deltaT_);
938 timeDict.readIfPresent("deltaT0", deltaT0_);
939 timeDict.readIfPresent("index", timeIndex_);
940 fileHandler().setTime(*this);
941}
942
944void Foam::Time::setTime(const dimensionedScalar& newTime, const label newIndex)
945{
946 setTime(newTime.value(), newIndex);
947}
948
949
950void Foam::Time::setTime(const scalar newTime, const label newIndex)
951{
952 resetTimeState
953 (
954 timeName(timeToUserTime(newTime)),
955 newTime,
956 newIndex
957 );
958 fileHandler().setTime(*this);
959}
960
965}
966
968void Foam::Time::setEndTime(const scalar endTime)
969{
971}
972
973
975(
976 const dimensionedScalar& deltaT,
977 const bool adjust
978)
979{
980 setDeltaT(deltaT.value(), adjust);
981}
982
983
984void Foam::Time::setDeltaT(const scalar deltaT, const bool adjust)
985{
986 deltaT_ = deltaT;
987 deltaTchanged_ = true;
988
989 if (adjust)
990 {
991 adjustDeltaT();
992 }
993}
994
995
996Foam::TimeState Foam::Time::subCycle(const label nSubCycles)
997{
998 #ifdef FULLDEBUG
999 if (prevTimeState_)
1000 {
1002 << "previous time state already set" << nl
1003 << exit(FatalError);
1004 }
1005 #endif
1006
1007 prevTimeState_.reset(new TimeState(*this));
1008
1009 setTime(*this - deltaT(), (timeIndex() - 1)*nSubCycles);
1010 deltaT_ /= nSubCycles;
1011 deltaT0_ /= nSubCycles;
1012 deltaTSave_ = deltaT0_;
1014 subCycling_ = nSubCycles;
1015
1016 return prevTimeState();
1017}
1018
1019
1020void Foam::Time::subCycleIndex(const label index)
1021{
1022 // Only permit adjustment if sub-cycling was already active
1023 // and if the index is valid (positive, non-zero).
1024 // This avoids potential mixups for deleting.
1025
1026 if (subCycling_ && index > 0)
1027 {
1028 subCycling_ = index;
1029 }
1030}
1031
1032
1034{
1035 if (subCycling_)
1036 {
1037 TimeState::operator=(prevTimeState());
1038 prevTimeState_.reset(nullptr);
1039 }
1041 subCycling_ = 0;
1042}
1043
1044
1045// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1048{
1049 return operator+=(deltaT.value());
1050}
1051
1052
1054{
1056 return operator++();
1057}
1058
1059
1061{
1062 deltaT0_ = deltaTSave_;
1063 deltaTSave_ = deltaT_;
1064
1065 // Save old time value and name
1066 const scalar oldTimeValue = timeToUserTime(value());
1067 const word oldTimeName = dimensionedScalar::name();
1068
1069 // Increment time
1070 setTime(value() + deltaT_, timeIndex_ + 1);
1071
1072 if (!subCycling_)
1073 {
1074 // If the time is very close to zero reset to zero
1075 if (mag(value()) < 10*SMALL*deltaT_)
1076 {
1077 setTime(0.0, timeIndex_);
1078 }
1079
1080 if (sigStopAtWriteNow_.active() || sigWriteNow_.active())
1081 {
1082 // A signal might have been sent on one processor only
1083 // Reduce so all decide the same.
1084
1085 label flag = 0;
1086 if (sigStopAtWriteNow_.active() && stopAt_ == saWriteNow)
1087 {
1088 flag += 1;
1089 }
1090 if (sigWriteNow_.active() && writeOnce_)
1091 {
1092 flag += 2;
1093 }
1094 reduce(flag, maxOp<label>());
1095
1096 if (flag & 1)
1097 {
1098 stopAt_ = saWriteNow;
1099 }
1100 if (flag & 2)
1101 {
1102 writeOnce_ = true;
1103 }
1104 }
1105
1106 writeTime_ = false;
1107
1108 switch (writeControl_)
1109 {
1110 case wcNone:
1111 case wcUnknown:
1112 break;
1113
1114 case wcTimeStep:
1115 writeTime_ = !(timeIndex_ % label(writeInterval_));
1116 break;
1117
1118 case wcRunTime:
1119 case wcAdjustableRunTime:
1120 {
1121 const label writeIndex = label
1122 (
1123 ((value() - startTime_) + 0.5*deltaT_)
1124 / writeInterval_
1125 );
1126
1127 if (writeIndex > writeTimeIndex_)
1128 {
1129 writeTime_ = true;
1130 writeTimeIndex_ = writeIndex;
1131 }
1132 }
1133 break;
1134
1135 case wcCpuTime:
1136 {
1137 const label writeIndex = label
1138 (
1139 returnReduce(elapsedCpuTime(), maxOp<double>())
1140 / writeInterval_
1141 );
1142 if (writeIndex > writeTimeIndex_)
1143 {
1144 writeTime_ = true;
1145 writeTimeIndex_ = writeIndex;
1146 }
1147 }
1148 break;
1149
1150 case wcClockTime:
1151 {
1152 const label writeIndex = label
1153 (
1154 returnReduce(elapsedClockTime(), maxOp<double>())
1155 / writeInterval_
1156 );
1157 if (writeIndex > writeTimeIndex_)
1158 {
1159 writeTime_ = true;
1160 writeTimeIndex_ = writeIndex;
1161 }
1162 }
1163 break;
1164 }
1165
1166
1167 // Check if endTime needs adjustment to stop at the next run()/end()
1168 if (!end())
1169 {
1170 if (stopAt_ == saNoWriteNow)
1171 {
1172 endTime_ = value();
1173 }
1174 else if (stopAt_ == saWriteNow)
1175 {
1176 endTime_ = value();
1177 writeTime_ = true;
1178 }
1179 else if (stopAt_ == saNextWrite && writeTime_ == true)
1180 {
1181 endTime_ = value();
1182 }
1183 }
1184
1185 // Override writeTime if one-shot writing
1186 if (writeOnce_)
1187 {
1188 writeTime_ = true;
1189 writeOnce_ = false;
1190 }
1191
1192 // Adjust the precision of the time directory name if necessary
1193 if (writeTime_)
1194 {
1195 // User-time equivalent of deltaT
1196 const scalar userDeltaT =
1197 timeToUserTime(value()) - timeToUserTime(value() - deltaT_);
1198
1199 // Tolerance used when testing time equivalence
1200 const scalar timeTol =
1201 max(min(pow(scalar(10), -precision_), 0.1*userDeltaT), SMALL);
1202
1203 // Time value obtained by reading timeName
1204 scalar timeNameValue = -VGREAT;
1205
1206 // Check that new time representation differs from old one
1207 // reinterpretation of the word
1208 if
1209 (
1210 readScalar(dimensionedScalar::name(), timeNameValue)
1211 && (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
1212 )
1213 {
1214 int oldPrecision = precision_;
1215 while
1216 (
1217 precision_ < maxPrecision_
1218 && readScalar(dimensionedScalar::name(), timeNameValue)
1219 && (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
1220 )
1221 {
1222 precision_++;
1223 setTime(value(), timeIndex());
1224 }
1225
1226 if (precision_ != oldPrecision)
1227 {
1229 << "Increased the timePrecision from " << oldPrecision
1230 << " to " << precision_
1231 << " to distinguish between timeNames at time "
1233 << endl;
1234
1235 if (precision_ == maxPrecision_)
1236 {
1237 // Reached maxPrecision limit
1239 << "Current time name " << dimensionedScalar::name()
1240 << nl
1241 << " The maximum time precision has been reached"
1242 " which might result in overwriting previous"
1243 " results."
1244 << endl;
1245 }
1246
1247 // Check if round-off error caused time-reversal
1248 scalar oldTimeNameValue = -VGREAT;
1249 if
1250 (
1251 readScalar(oldTimeName, oldTimeNameValue)
1252 && (
1253 sign(timeNameValue - oldTimeNameValue)
1254 != sign(deltaT_)
1255 )
1256 )
1257 {
1259 << "Current time name " << dimensionedScalar::name()
1260 << " is set to an instance prior to the "
1261 "previous one "
1262 << oldTimeName << nl
1263 << " This might result in temporal "
1264 "discontinuities."
1265 << endl;
1266 }
1267 }
1268 }
1270 }
1271
1272 return *this;
1273}
1274
1275
1276Foam::Time& Foam::Time::operator++(int)
1277{
1278 return operator++();
1279}
1280
1281
1282// ************************************************************************* //
Inter-processor communication reduction functions.
if(patchID !=-1)
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition Enum.H:57
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
@ NO_REGISTER
Do not request registration (bool: false).
@ REGISTER
Request registration (bool: true).
readOption readOpt() const noexcept
Get the read option.
readOption
Enumeration defining read preferences.
@ NO_READ
Nothing to be read.
@ LAZY_READ
Reading is optional [identical to READ_IF_PRESENT].
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
A simple container for options an IOstream can normally have.
floatFormat
Float formats (eg, time directory name formats).
scalar value() const noexcept
The value (const access).
Definition Instant.H:139
const T & name() const noexcept
The name/key (const access).
Definition Instant.H:149
Address the time paths without using the Time class.
Definition TimePaths.H:53
const word & system() const noexcept
Return system name.
Definition TimePathsI.H:137
const word & constant() const noexcept
Return constant name.
Definition TimePathsI.H:131
static instantList findTimes(const fileName &directory, const word &constantDirName="constant")
Search a given directory for valid time directories.
Definition TimePaths.C:109
TimePaths(const bool processorCase, const fileName &rootPath, const bool distributed, const fileName &globalCaseName, const fileName &caseName, const word &systemDirName="system", const word &constantDirName="constant")
Construct from all components.
Definition TimePaths.C:62
The time value with time-stepping information, user-defined remapping, etc.
Definition TimeState.H:50
TimeState()
Construct a zero time state, using the current time formatting.
Definition TimeState.C:27
virtual scalar timeToUserTime(const scalar t) const
Convert the real-time (s) into user-time (e.g. CA deg).
Definition TimeState.C:48
bool deltaTchanged_
Definition TimeState.H:71
scalar deltaTSave_
Definition TimeState.H:69
label writeTimeIndex_
Definition TimeState.H:65
scalar timeOutputValue() const
Return the current user-time value. (ie, after applying any timeToUserTime() conversion).
Definition TimeStateI.H:24
void resetTimeState(const word &newName, const scalar newValue, const label newIndex)
Reset some of TimeState (name, value, index).
Definition TimeState.H:81
label timeIndex() const noexcept
Return the current time index.
Definition TimeStateI.H:43
dimensionedScalar deltaT() const
Return time step.
Definition TimeStateI.H:61
scalar deltaT0_
Definition TimeState.H:68
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
virtual bool isAdjustTimeStep() const
Return true if adjustTimeStep is true.
Definition Time.C:899
virtual bool run() const
Return true if run should continue,.
Definition Time.C:777
virtual void readDict()
Read the control dictionary and set the write controls etc.
Definition TimeIO.C:84
static int precision_
Time directory name precision.
Definition Time.H:201
virtual void setDeltaT(const dimensionedScalar &deltaT, const bool adjust=true)
Reset time step, normally also calling adjustDeltaT().
Definition Time.C:968
static const Enum< stopAtControls > stopAtControlNames
Names for stopAtControls.
Definition Time.H:113
virtual dimensionedScalar startTime() const
Return start time.
Definition Time.C:759
static IOstreamOption::floatFormat format_
Format for time directory names (general | fixed | scientific).
Definition Time.H:196
writeControls
Write control options.
Definition Time.H:82
@ wcTimeStep
"timeStep"
Definition Time.H:84
@ wcUnknown
Dummy no-op.
Definition Time.H:89
@ wcCpuTime
"cpuTime"
Definition Time.H:88
@ wcAdjustableRunTime
"adjustable" / "adjustableRunTime"
Definition Time.H:86
@ wcNone
"none"
Definition Time.H:83
@ wcRunTime
"runTime"
Definition Time.H:85
@ wcClockTime
"clockTime"
Definition Time.H:87
stopAtControls stopAt_
Definition Time.H:159
sigStopAtWriteNow sigStopAtWriteNow_
Signal handler for write and clean exit upon signal.
Definition Time.H:191
void setMonitoring(const bool forceProfiling=false)
Set file monitoring, profiling, etc.
Definition Time.C:344
void adjustDeltaT()
Adjust the time step so that writing occurs at the specified time.
Definition Time.C:95
scalar writeInterval_
Definition Time.H:163
static int printExecutionFormat_
Style for "ExecutionTime = " output.
Definition Time.H:124
const fileName & rootPath() const noexcept
The root path.
Definition TimePathsI.H:66
static const int maxPrecision_
Maximum time directory name precision.
Definition Time.H:206
autoPtr< TimeState > prevTimeState_
If time is being sub-cycled this is the previous TimeState.
Definition Time.H:181
word findInstance(const fileName &directory, const word &name=word::null, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, const word &stopInstance=word::null, const bool constant_fallback=true) const
Return time instance (location) of directory containing the file name (eg, used in reading mesh data)...
Definition Time.C:725
label purgeWrite_
Definition Time.H:165
stopAtControls
Stop-run control options, which are primarily used when altering the stopAt condition.
Definition Time.H:97
@ saNoWriteNow
Adjust endTime to stop immediately w/o writing.
Definition Time.H:99
@ saWriteNow
adjust endTime to stop immediately w/ writing
Definition Time.H:100
@ saUnknown
Dummy no-op. Do not change current value.
Definition Time.H:102
@ saEndTime
Stop when Time reaches prescribed endTime.
Definition Time.H:98
@ saNextWrite
stop at the next data write interval
Definition Time.H:101
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition Time.C:714
writeControls writeControl_
Definition Time.H:161
sigWriteNow sigWriteNow_
Signal handler for one-shot writing upon signal.
Definition Time.H:186
void setControls()
Set the controls from the current controlDict.
Definition Time.C:139
static word controlDictName
The default control dictionary name (normally "controlDict").
Definition Time.H:267
scalar endTime_
Definition Time.H:157
virtual void setEndTime(const dimensionedScalar &endTime)
Reset end time.
Definition Time.C:955
const functionObjectList & functionObjects() const noexcept
Return the list of function objects.
Definition Time.H:714
static const Enum< writeControls > writeControlNames
Names for writeControls.
Definition Time.H:108
bool writeOnce_
Definition Time.H:176
virtual stopAtControls stopAt() const
Return the stop control information.
Definition Time.C:771
virtual label startTimeIndex() const
Return start time index.
Definition Time.C:753
label subCycling_
The total number of sub-cycles, the current sub-cycle index, or 0 if time is not being sub-cycled.
Definition Time.H:173
label startTimeIndex_
Definition Time.H:153
virtual void endSubCycle()
Reset time after sub-cycling back to previous TimeState.
Definition Time.C:1026
virtual void subCycleIndex(const label index)
Adjust the reported sub-cycle index.
Definition Time.C:1013
virtual Time & operator++()
Prefix increment,.
Definition Time.C:1053
const TimeState & prevTimeState() const
Return previous TimeState if time is being sub-cycled.
Definition Time.H:743
scalar startTime_
Definition Time.H:155
void readModifiedObjects()
Read the objects that have been modified.
Definition TimeIO.C:459
fileName timePath() const
Return current time path = path/timeName.
Definition Time.H:512
virtual TimeState subCycle(const label nSubCycles)
Set time to sub-cycle for the given number of steps.
Definition Time.C:989
virtual bool loop()
Return true if run should continue and if so increment time.
Definition Time.C:859
virtual dimensionedScalar endTime() const
Return end time.
Definition Time.C:765
const word & timeName() const noexcept
The current time name.
Definition TimeStateI.H:30
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition Time.C:905
virtual ~Time()
Destructor.
Definition Time.C:692
virtual bool end() const
Return true if end of run,.
Definition Time.C:872
const fileName & caseName() const noexcept
The case name.
Definition TimePathsI.H:78
virtual Time & operator+=(const dimensionedScalar &deltaT)
Set deltaT to that specified and increment time via operator++().
Definition Time.C:1040
Time(const word &ctrlDictName, const argList &args, const bool enableFunctionObjects=true, const bool enableLibs=true, IOobjectOption::readOption rOpt=IOobjectOption::READ_MODIFIED)
Construct from argument list, reading from specified control dictionary name.
Definition TimeI.H:24
T & back()
Access last element of the list, position [size()-1].
Definition UListI.H:253
T & front()
Access first element of the list, position [0].
Definition UListI.H:239
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition UPstream.H:1706
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
Definition UPstream.H:1697
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition UPstream.H:1069
@ broadcast
broadcast [MPI]
Definition UPstream.H:189
Extract command arguments and options from the supplied argc and argv parameters.
Definition argList.H:119
double elapsedClockTime() const
Returns wall-clock time since clock instantiation.
Definition clock.C:115
double elapsedCpuTime() const
Return CPU time [seconds] from the start.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and it is a dictionary) otherwise return nullptr...
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
void clear()
Clear the dictionary.
Definition dictionary.C:862
const word & name() const noexcept
const scalar & value() const noexcept
bool open(bool verbose=true)
Open named, but unopened libraries. These names will normally have been added with push_back().
A class for handling file names.
Definition fileName.H:75
bool adjustTimeStep()
Called at the end of Time::adjustDeltaT() if adjustTime is true.
void on()
Switch the function objects on.
An instant of time. Contains the time value and name. Uses Foam::Time when formatting the name.
Definition instant.H:56
Registry of regIOobjects.
bool checkCacheTemporaryObjects() const
Check that all objects specified in the cacheTemporaryObjects were also cached.
void clear()
Clear all entries from the registry.
Triggers for starting/stopping code profiling.
static bool active() noexcept
True if profiling is allowed and is active.
Definition profiling.C:107
static void stop(const Time &owner)
Stop profiling, cleanup pool if possible.
Definition profiling.C:168
static void initialize(const IOobject &ioObj, const Time &owner)
Singleton to initialize profiling pool, everything enabled.
Definition profiling.C:142
virtual fileName filePath() const
Return complete path + object name if the file exists.
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
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()
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
const auto & io
runTimeSource setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex)
word timeName
Definition getTimeIndex.H:3
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
const char * end
Definition SVGTools.H:223
Different types of constants.
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition debug.C:228
dictionary & controlDict()
The central control dictionary, the contents of which are either taken directly from the FOAM_CONTROL...
Definition debug.C:142
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
Namespace for OpenFOAM.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
dimensionedScalar sign(const dimensionedScalar &ds)
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
Definition POSIX.C:1704
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler().
dimensionedScalar log10(const dimensionedScalar &ds)
List< instant > instantList
List of instants.
Definition instantList.H:41
constexpr label labelMax
Definition label.H:55
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
bool returnReduceAnd(const bool value, const int communicator=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:26
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
label timeIndex
#define addProfiling(Name,...)
Define profiling trigger with specified name and description string. The description is generated by ...
#define registerInfoSwitch(Name, Type, SwitchVar)
dictionary dict
Foam::argList args(argc, argv)
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition stdFoam.H:315