TimeIO.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) 2016-2021 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 "argList.H"
31#include "Pstream.H"
34#include "profiling.H"
35#include "IOdictionary.H"
36#include "fileOperation.H"
37#include "fstreamPointer.H"
38
39#include <iomanip>
40
41// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
42
43namespace Foam
44{
45
46// Output seconds as day-hh:mm:ss
47static std::ostream& printTimeHMS(std::ostream& os, double seconds)
48{
49 const unsigned long ss = seconds;
50
51 // days
52 const auto dd = (ss / 86400);
53
54 if (dd) os << dd << '-';
55
56 // hours
57 const int hh = ((ss / 3600) % 24);
58
59 if (dd || hh)
60 {
61 os << std::setw(2) << std::setfill('0')
62 << hh << ':';
63 }
64
65 // minutes
66 os << std::setw(2) << std::setfill('0')
67 << ((ss / 60) % 60) << ':';
68
69 // seconds
70 os << std::setw(2) << std::setfill('0')
71 << (ss % 60);
72
73
74 // 1/100th seconds. As none or 2 decimal places
75 const int hundredths = int(100 * (seconds - ss)) % 100;
76
77 if (hundredths)
78 {
79 os << '.' << std::setw(2) << std::setfill('0') << hundredths;
80 }
81
82 return os;
83}
84
85} // End namespace Foam
86
87
88// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
89
91{
92 word application;
93 if (controlDict_.readIfPresent("application", application))
94 {
95 // Do not override if already set so external application can override
96 setEnv("FOAM_APPLICATION", application, false);
97 }
98
99 // Check for local switches and settings
100
101 const dictionary* localDict = nullptr;
102
103 // DebugSwitches
104 if
105 (
106 (localDict = controlDict_.findDict("DebugSwitches")) != nullptr
107 && localDict->size()
108 )
109 {
111 << "Overriding DebugSwitches according to "
112 << controlDict_.name() << nl;
113
114 debug::debugObjects().setValues(*localDict, true);
115 }
116
117
118 // InfoSwitches
119 if
120 (
121 (localDict = controlDict_.findDict("InfoSwitches")) != nullptr
122 && localDict->size()
123 )
124 {
126 << "Overriding InfoSwitches according to "
127 << controlDict_.name() << nl;
128
129 debug::infoObjects().setValues(*localDict, true);
130 }
131
132 // OptimisationSwitches
133 if
134 (
135 (localDict = controlDict_.findDict("OptimisationSwitches")) != nullptr
136 && localDict->size()
137 )
138 {
140 << "Overriding OptimisationSwitches according to "
141 << controlDict_.name() << nl;
142
143 debug::optimisationObjects().setValues(*localDict, true);
144 }
145
146
147 // Handle fileHandler explicitly since it affects local dictionary
148 // monitoring.
149 word fileHandlerName;
150 if
151 (
152 localDict
153 && localDict->readIfPresent("fileHandler", fileHandlerName)
154 && fileHandler().type() != fileHandlerName
155 )
156 {
157 DetailInfo << "Overriding fileHandler to " << fileHandlerName << nl;
158
159 // Remove old watches since destroying the file
160 fileNameList oldWatched(controlDict_.watchIndices().size());
161 forAllReverse(controlDict_.watchIndices(), i)
162 {
163 const label watchi = controlDict_.watchIndices()[i];
164 oldWatched[i] = fileHandler().getFile(watchi);
165 fileHandler().removeWatch(watchi);
166 }
167 controlDict_.watchIndices().clear();
168
169 // The new handler, with verbosity
170 autoPtr<fileOperation> newHandler =
171 fileOperation::New(fileHandlerName, true);
172
173 if (TimePaths::distributed() && newHandler)
174 {
175 newHandler->distributed(true);
176 }
177
178 // Installing the new handler
179 Foam::fileHandler(std::move(newHandler));
180
181 // Reinstall old watches
182 fileHandler().addWatches(controlDict_, oldWatched);
183 }
184
185
186 // DimensionedConstants.
187 // - special case since it may change both the 'unitSet' and the
188 // individual values
189 if
190 (
191
192 (localDict = controlDict_.findDict("DimensionedConstants")) != nullptr
193 && localDict->size()
194 )
195 {
197 << "Overriding DimensionedConstants according to "
198 << controlDict_.name() << nl;
199
201
202 // Change in-memory
203 dimensionedConstants().merge(*localDict);
204
205 IStringStream dummyIs("");
206
207 forAllConstIters(objs, iter)
208 {
209 const List<simpleRegIOobject*>& objects = *iter;
210
211 for (simpleRegIOobject* obj : objects)
212 {
213 obj->readData(dummyIs);
214
215 if (Foam::infoDetailLevel > 0)
216 {
217 Info<< " ";
218 obj->writeData(Info);
219 Info<< nl;
220 }
221 }
222 }
223 }
224
225
226 // DimensionSets
227 if
228 (
229 (localDict = controlDict_.findDict("DimensionSets")) != nullptr
230 && localDict->size()
231 )
232 {
234 << "Overriding DimensionSets according to "
235 << controlDict_.name() << nl;
236
238
240 dict.merge(*localDict);
241
242 simpleObjectRegistryEntry* objPtr = objs.find("DimensionSets");
243
244 if (objPtr)
245 {
246 DetailInfo << *localDict << nl;
247
248 const List<simpleRegIOobject*>& objects = *objPtr;
249
250 for (simpleRegIOobject* obj : objects)
251 {
253 os << dict;
254 IStringStream is(os.str());
255 obj->readData(is);
256 }
257 }
258 }
259
260
261 if (!deltaTchanged_)
262 {
263 controlDict_.readEntry("deltaT", deltaT_);
264 }
265
267 (
268 "writeControl",
269 controlDict_,
271 );
272
273 scalar oldWriteInterval = writeInterval_;
274
275 if (controlDict_.readIfPresent("writeInterval", writeInterval_))
276 {
277 if (writeControl_ == wcTimeStep && label(writeInterval_) < 1)
278 {
279 FatalIOErrorInFunction(controlDict_)
280 << "writeInterval < 1 for writeControl timeStep"
281 << exit(FatalIOError);
282 }
283 }
284 else
285 {
286 controlDict_.readEntry("writeFrequency", writeInterval_);
287 }
288
289
290 if (oldWriteInterval != writeInterval_)
291 {
292 switch (writeControl_)
293 {
294 case wcRunTime:
296 // Recalculate writeTimeIndex_ to be in units of current
297 // writeInterval.
298 writeTimeIndex_ = label
299 (
301 * oldWriteInterval
303 );
304 break;
305
306 default:
307 break;
308 }
309 }
310
311 if (controlDict_.readIfPresent("purgeWrite", purgeWrite_))
312 {
313 if (purgeWrite_ < 0)
314 {
316 << "invalid value for purgeWrite " << purgeWrite_
317 << ", should be >= 0, setting to 0"
318 << endl;
319
320 purgeWrite_ = 0;
321 }
322 }
323
324 if (controlDict_.found("timeFormat"))
325 {
326 const word formatName(controlDict_.get<word>("timeFormat"));
327
328 if (formatName == "general")
329 {
331 }
332 else if (formatName == "fixed")
333 {
334 format_ = fixed;
335 }
336 else if (formatName == "scientific")
337 {
339 }
340 else
341 {
343 << "unsupported time format " << formatName
344 << endl;
345 }
346 }
347
348 controlDict_.readIfPresent("timePrecision", precision_);
349
350 // stopAt at 'endTime' or a specified value
351 // if nothing is specified, the endTime is zero
352 if (stopAtControlNames.readIfPresent("stopAt", controlDict_, stopAt_))
353 {
354 if (stopAt_ == saEndTime)
355 {
356 controlDict_.readEntry("endTime", endTime_);
357 }
358 else
359 {
360 endTime_ = GREAT;
361 }
362 }
363 else if (!controlDict_.readIfPresent("endTime", endTime_))
364 {
365 endTime_ = 0;
366 }
367
369
370 if (controlDict_.found("writeVersion"))
371 {
372 writeStreamOption_.version(controlDict_.get<token>("writeVersion"));
373 }
374
375 if (controlDict_.found("writeFormat"))
376 {
377 writeStreamOption_.format(controlDict_.get<word>("writeFormat"));
378 }
379
380 if (controlDict_.found("writePrecision"))
381 {
383 (
384 controlDict_.get<unsigned int>("writePrecision")
385 );
386
389
392
395 }
396
397 if (controlDict_.found("writeCompression"))
398 {
399 writeStreamOption_.compression
400 (
401 controlDict_.get<word>("writeCompression")
402 );
403
404 if (writeStreamOption_.compression() == IOstreamOption::COMPRESSED)
405 {
406 if (writeStreamOption_.format() == IOstreamOption::BINARY)
407 {
408 IOWarningInFunction(controlDict_)
409 << "Disabled binary format compression"
410 << " (inefficient/ineffective)"
411 << endl;
412
413 writeStreamOption_.compression(IOstreamOption::UNCOMPRESSED);
414 }
416 {
417 IOWarningInFunction(controlDict_)
418 << "Disabled output compression"
419 << " (missing libz support)"
420 << endl;
421
422 writeStreamOption_.compression(IOstreamOption::UNCOMPRESSED);
423 }
424 }
425 }
426
427 controlDict_.readIfPresent("graphFormat", graphFormat_);
428 controlDict_.readIfPresent("runTimeModifiable", runTimeModifiable_);
429
430
431 if (!runTimeModifiable_ && controlDict_.watchIndices().size())
432 {
433 forAllReverse(controlDict_.watchIndices(), i)
434 {
435 fileHandler().removeWatch(controlDict_.watchIndices()[i]);
436 }
437 controlDict_.watchIndices().clear();
438 }
439}
440
441
443{
444 if (controlDict_.regIOobject::read())
445 {
446 // Read contents
447 readDict();
448 functionObjects_.read();
449
450 if (runTimeModifiable_)
451 {
452 // For IOdictionary the call to regIOobject::read() would have
453 // already updated all the watchIndices via the addWatch but
454 // controlDict_ is an unwatchedIOdictionary so will only have
455 // stored the dependencies as files.
456 fileHandler().addWatches(controlDict_, controlDict_.files());
457 }
458 controlDict_.files().clear();
459
460 return true;
461 }
462
463 return false;
464}
465
466
468{
469 if (runTimeModifiable_)
470 {
471 // Get state of all monitored objects (=registered objects with a
472 // valid filePath).
473 // Note: requires same ordering in objectRegistries on different
474 // processors!
476 (
477 (
480 ),
482 );
483 // Time handling is special since controlDict_ is the one dictionary
484 // that is not registered to any database.
485
486 if (controlDict_.readIfModified())
487 {
488 readDict();
489 functionObjects_.read();
490
491 if (runTimeModifiable_)
492 {
493 // For IOdictionary the call to regIOobject::read() would have
494 // already updated all the watchIndices via the addWatch but
495 // controlDict_ is an unwatchedIOdictionary so will only have
496 // stored the dependencies as files.
497
498 fileHandler().addWatches(controlDict_, controlDict_.files());
499 }
500 controlDict_.files().clear();
501 }
502
503 bool registryModified = objectRegistry::modified();
504
505 if (registryModified)
506 {
508 }
509 }
510}
511
512
514{
515 addProfiling(writing, "objectRegistry::writeObject");
516
517 const word tmName(timeName());
518
519 IOdictionary timeDict
520 (
522 (
523 "time",
524 tmName,
525 "uniform",
526 *this,
529 false
530 )
531 );
532
533 timeDict.add("value", timeName(timeToUserTime(value()), maxPrecision_));
534 timeDict.add("name", string(tmName));
535 timeDict.add("index", timeIndex_);
536 timeDict.add("deltaT", timeToUserTime(deltaT_));
537 timeDict.add("deltaT0", timeToUserTime(deltaT0_));
538
539 return timeDict.regIOobject::writeObject
540 (
542 true
543 );
544}
545
546
548(
549 IOstreamOption streamOpt,
550 const bool valid
551) const
552{
553 if (writeTime())
554 {
555 bool writeOK = writeTimeDict();
556
557 if (writeOK)
558 {
559 writeOK = objectRegistry::writeObject(streamOpt, valid);
560 }
561
562 if (writeOK)
563 {
564 // Does the writeTime trigger purging?
565 if (writeTime_ && purgeWrite_)
566 {
567 if
568 (
569 previousWriteTimes_.empty()
570 || previousWriteTimes_.top() != timeName()
571 )
572 {
573 previousWriteTimes_.push(timeName());
574 }
575
576 while (previousWriteTimes_.size() > purgeWrite_)
577 {
579 (
580 fileHandler().filePath
581 (
582 objectRegistry::path(previousWriteTimes_.pop())
583 )
584 );
585 }
586 }
587 }
588
589 return writeOK;
590 }
591
592 return false;
593}
594
595
597{
598 writeTime_ = true;
599 return write();
600}
601
602
604{
605 stopAt_ = saWriteNow;
606 endTime_ = value();
607
608 return writeNow();
609}
610
611
613{
614 writeOnce_ = true;
615}
616
617
619{
620 switch (printExecutionFormat_)
621 {
622 case 1:
623 {
624 os << "ExecutionTime = ";
625 printTimeHMS(os.stdStream(), elapsedCpuTime());
626
627 os << " ClockTime = ";
628 printTimeHMS(os.stdStream(), elapsedClockTime());
629 }
630 break;
631
632 default:
633 {
634 os << "ExecutionTime = " << elapsedCpuTime() << " s"
635 << " ClockTime = " << elapsedClockTime() << " s";
636 }
637 break;
638 }
639
640 os << nl << endl;
641
642 return os;
643}
644
645
646// ************************************************************************* //
T * find(const word &keyword)
Find and return an entry, nullptr on failure.
bool readIfPresent(const word &key, const dictionary &dict, EnumType &val) const
Find an entry if present, and assign to T val.
Definition: EnumI.H:132
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:303
The IOstreamOption is a simple container for options an IOstream can normally have.
versionNumber version() const noexcept
Get the stream version.
compressionType compression() const noexcept
Get the stream compression.
streamFormat format() const noexcept
Get the current stream format.
@ ASCII
"ascii" (normal default)
@ UNCOMPRESSED
compression = false
@ COMPRESSED
compression = true
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:342
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
Definition: StringStream.H:112
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
virtual std::ostream & stdStream()
Access to underlying std::ostream.
Definition: OFstream.C:102
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:57
virtual int precision() const
Get precision of output field.
Definition: OSstream.C:326
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:231
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
bool distributed() const noexcept
Definition: TimePathsI.H:30
bool deltaTchanged_
Definition: TimeState.H:64
scalar deltaT_
Definition: TimeState.H:60
label writeTimeIndex_
Definition: TimeState.H:58
virtual void readDict()
Read the control dictionary and set the write controls etc.
Definition: TimeIO.C:90
static int precision_
Time directory name precision.
Definition: Time.H:186
virtual bool writeTimeDict() const
Write time dictionary to the <time>/uniform directory.
Definition: TimeIO.C:513
bool writeAndEnd()
Write the objects now (not at end of iteration) and end the run.
Definition: TimeIO.C:603
static const Enum< stopAtControls > stopAtControlNames
Names for stopAtControls.
Definition: Time.H:119
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
@ wcTimeStep
"timeStep"
Definition: Time.H:87
@ wcAdjustableRunTime
"adjustable" / "adjustableRunTime"
Definition: Time.H:89
@ wcRunTime
"runTime"
Definition: Time.H:88
stopAtControls stopAt_
Definition: Time.H:155
bool writeNow()
Definition: TimeIO.C:596
scalar writeInterval_
Definition: Time.H:159
void writeOnce()
Write the objects once (one shot) and continue the run.
Definition: TimeIO.C:612
@ general
default float notation
Definition: Time.H:109
@ scientific
scientific notation
Definition: Time.H:111
@ fixed
fixed-point notation
Definition: Time.H:110
static fmtflags format_
Time directory name format.
Definition: Time.H:183
label purgeWrite_
Definition: Time.H:161
@ saEndTime
Stop when Time reaches prescribed endTime.
Definition: Time.H:99
writeControls writeControl_
Definition: Time.H:157
virtual word timeName() const
Return current time name.
Definition: Time.C:790
scalar endTime_
Definition: Time.H:153
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
Definition: TimeIO.C:548
static const Enum< writeControls > writeControlNames
Names for writeControls.
Definition: Time.H:116
Ostream & printExecutionTime(OSstream &os) const
Print the elapsed ExecutionTime (cpu-time), ClockTime.
Definition: TimeIO.C:618
void readModifiedObjects()
Read the objects that have been modified.
Definition: TimeIO.C:467
virtual bool read()
Read control dictionary, update controls and time.
Definition: TimeIO.C:442
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
const word & name() const
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary pointer if present.
Definition: dictionaryI.H:127
bool merge(const dictionary &dict)
Merge entries from the given dictionary.
Definition: dictionary.C:812
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionaryI.H:87
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:640
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
const scalar & value() const
Return const reference to value.
const word & name() const
Return const reference to name.
OSstream & stream()
Return OSstream for output operations.
Definition: error.C:304
virtual void addWatches(regIOobject &, const fileNameList &) const
Helper: add watches for list of regIOobjects.
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
virtual bool rmDir(const fileName &dir, const bool silent=false) const =0
Remove a directory and its contents.
virtual void updateStates(const bool masterOnly, const bool syncPar) const
Update state of all files.
virtual fileName getFile(const label) const
Get name of file being watched (using handle)
virtual bool modified() const
Return true if any of the object's files have been modified.
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write the objects using stream options.
void readModifiedObjects()
Read the objects that have been modified.
static bool supports_gz()
True if compiled with libz support.
const labelList & watchIndices() const noexcept
Read access to file-monitoring handles.
Definition: regIOobjectI.H:202
Object registry for simpleRegIOobject. Maintains ordering.
void setValues(const dictionary &dict, bool report=false)
Set values (invoke callbacks) from dictionary entries.
Abstract base class for registered object with I/O. Used in debug symbol registration.
A token holds an item read from Istream.
Definition: token.H:69
A class for handling words, derived from Foam::string.
Definition: word.H:68
Dictionary reading and supplying the dimensioned constants used within OpenFOAM, particularly for the...
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#define DetailInfo
Definition: evalEntry.C:37
OBJstream os(runTime.globalPath()/outputName)
word timeName
Definition: getTimeIndex.H:3
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
simpleObjectRegistry & infoObjects()
Access to registered InfoSwitch objects.
Definition: debug.C:302
simpleObjectRegistry & dimensionSetObjects()
Access to registered DimensionSets objects.
Definition: debug.C:324
simpleObjectRegistry & dimensionedConstantObjects()
Access to registered DimensionedConstants objects.
Definition: debug.C:335
simpleObjectRegistry & optimisationObjects()
Access to registered OptimisationSwitch objects.
Definition: debug.C:313
simpleObjectRegistry & debugObjects()
Access to registered DebugSwitch objects.
Definition: debug.C:291
Namespace for OpenFOAM.
const fileOperation & fileHandler()
Get current file handler.
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable, return true on success.
Definition: MSwindows.C:395
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
messageStream Info
Information stream (stdout output on master, null elsewhere)
dictionary & dimensionSystems()
Top level dictionary.
Definition: dimensionSets.C:93
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:598
OSstream Sout
OSstream wrapped stdout (std::cout)
static std::ostream & printTimeHMS(std::ostream &os, double seconds)
Definition: TimeIO.C:47
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
OSstream Serr
OSstream wrapped stderr (std::cerr)
IOerror FatalIOError
int infoDetailLevel
Global for selective suppression of Info output.
error FatalError
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dictionary & dimensionedConstants()
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
runTime write()
#define addProfiling(name, descr)
Define profiling trigger with specified name and description string.
dictionary dict
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:346
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Definition: stdFoam.H:278