TimeIO.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
6  \\/ M anipulation |
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 "Pstream.H"
28 #include "simpleObjectRegistry.H"
29 #include "dimensionedConstants.H"
30 #include "IOdictionary.H"
31 #include "fileOperation.H"
32 
33 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
34 
36 {
37  word application;
38  if (controlDict_.readIfPresent("application", application))
39  {
40  // Do not override if already set so external application can override
41  setEnv("FOAM_APPLICATION", application, false);
42  }
43 
44 
45  // Check for local switches and settings
46  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47 
48  // Debug switches
49  if (controlDict_.found("DebugSwitches"))
50  {
52  << "Overriding DebugSwitches according to " << controlDict_.name()
53  << endl;
54 
56  const dictionary& localSettings = controlDict_.subDict("DebugSwitches");
57  forAllConstIter(dictionary, localSettings, iter)
58  {
59  const word& name = iter().keyword();
60 
61  simpleObjectRegistryEntry* objPtr = objects.lookupPtr(name);
62 
63  if (objPtr)
64  {
65  InfoHeader << " " << iter() << endl;
66 
67  const List<simpleRegIOobject*>& objects = *objPtr;
68 
69  if (iter().isDict())
70  {
71  forAll(objects, i)
72  {
74  os << iter().dict();
75  IStringStream is(os.str());
76  objects[i]->readData(is);
77  }
78  }
79  else
80  {
81  forAll(objects, i)
82  {
83  objects[i]->readData(iter().stream());
84  }
85  }
86  }
87  }
88  }
89 
90  // Optimisation Switches
91  if (controlDict_.found("OptimisationSwitches"))
92  {
94  << "Overriding OptimisationSwitches according to "
95  << controlDict_.name() << endl;
96 
98  const dictionary& localSettings = controlDict_.subDict
99  (
100  "OptimisationSwitches"
101  );
102  forAllConstIter(dictionary, localSettings, iter)
103  {
104  const word& name = iter().keyword();
105 
106  simpleObjectRegistryEntry* objPtr = objects.lookupPtr(name);
107 
108  if (objPtr)
109  {
110  InfoHeader << " " << iter() << endl;
111 
112  const List<simpleRegIOobject*>& objects = *objPtr;
113 
114  if (iter().isDict())
115  {
116  forAll(objects, i)
117  {
119  os << iter().dict();
120  IStringStream is(os.str());
121  objects[i]->readData(is);
122  }
123  }
124  else
125  {
126  forAll(objects, i)
127  {
128  objects[i]->readData(iter().stream());
129  }
130  }
131  }
132  }
133 
134 
135  // Handle fileHandler override explicitly since interacts with
136  // local dictionary monitoring.
137  word fileHandlerName;
138  if
139  (
140  localSettings.readIfPresent("fileHandler", fileHandlerName)
141  && fileHandler().type() != fileHandlerName
142  )
143  {
144  // Remove the old watches since destroying the file
145  fileNameList oldWatchedFiles(controlDict_.watchIndices());
146  forAllReverse(controlDict_.watchIndices(), i)
147  {
148  label watchi = controlDict_.watchIndices()[i];
149  oldWatchedFiles[i] = fileHandler().getFile(watchi);
150  fileHandler().removeWatch(watchi);
151  }
152  controlDict_.watchIndices().clear();
153 
154  // Installing the new handler
155  InfoHeader
156  << "Overriding fileHandler to " << fileHandlerName << endl;
157 
158  autoPtr<fileOperation> handler
159  (
161  (
162  fileHandlerName,
163  true
164  )
165  );
166  Foam::fileHandler(handler);
167 
168  // Reinstall old watches
169  fileHandler().addWatches(controlDict_, oldWatchedFiles);
170  }
171  }
172 
173 
174  // DimensionedConstants. Handled as a special case since both e.g.
175  // the 'unitSet' might be changed and the individual values
176  if (controlDict_.found("DimensionedConstants"))
177  {
178  InfoHeader
179  << "Overriding DimensionedConstants according to "
180  << controlDict_.name() << endl;
181 
182  // Change in-memory
184  (
185  controlDict_.subDict("DimensionedConstants")
186  );
187 
188 
190 
191  IStringStream dummyIs("");
192 
193  forAllConstIter(simpleObjectRegistry, objects, iter)
194  {
195  const List<simpleRegIOobject*>& objects = *iter;
196 
197  forAll(objects, i)
198  {
199  objects[i]->readData(dummyIs);
200 
201  if (writeInfoHeader)
202  {
203  Info<< " ";
204  objects[i]->writeData(Info);
205  Info<< endl;
206  }
207  }
208  }
209  }
210 
211 
212  // Dimension sets
213  if (controlDict_.found("DimensionSets"))
214  {
215  InfoHeader
216  << "Overriding DimensionSets according to "
217  << controlDict_.name() << endl;
218 
220  dict.merge(controlDict_.subDict("DimensionSets"));
221 
223 
224  simpleObjectRegistryEntry* objPtr = objects.lookupPtr("DimensionSets");
225 
226  if (objPtr)
227  {
228  InfoHeader << controlDict_.subDict("DimensionSets") << endl;
229 
230  const List<simpleRegIOobject*>& objects = *objPtr;
231 
232  forAll(objects, i)
233  {
235  os << dict;
236  IStringStream is(os.str());
237  objects[i]->readData(is);
238  }
239  }
240  }
241 
242 
243  if (!deltaTchanged_)
244  {
245  deltaT_ = controlDict_.lookup<scalar>("deltaT");
246  }
247 
248  if (controlDict_.found("writeControl"))
249  {
251  (
252  controlDict_.lookup("writeControl")
253  );
254  }
255 
256  scalar oldWriteInterval = writeInterval_;
257 
258  if (controlDict_.readIfPresent("writeInterval", writeInterval_))
259  {
260  if
261  (
263  && label(writeInterval_) < 1
264  )
265  {
266  FatalIOErrorInFunction(controlDict_)
267  << "writeInterval < 1 for writeControl timeStep"
268  << exit(FatalIOError);
269  }
270  }
271  else
272  {
273  controlDict_.lookup("writeFrequency") >> writeInterval_;
274  }
275 
276 
277  if (oldWriteInterval != writeInterval_)
278  {
279  switch (writeControl_)
280  {
283  // Recalculate writeTimeIndex_ to be in units of current
284  // writeInterval.
286  (
288  * oldWriteInterval
290  );
291  break;
292 
293  default:
294  break;
295  }
296  }
297 
298  if (controlDict_.readIfPresent("purgeWrite", purgeWrite_))
299  {
300  if (purgeWrite_ < 0)
301  {
303  << "invalid value for purgeWrite " << purgeWrite_
304  << ", should be >= 0, setting to 0"
305  << endl;
306 
307  purgeWrite_ = 0;
308  }
309  }
310 
311  if (controlDict_.found("timeFormat"))
312  {
313  const word formatName(controlDict_.lookup("timeFormat"));
314 
315  if (formatName == "general")
316  {
318  }
319  else if (formatName == "fixed")
320  {
322  }
323  else if (formatName == "scientific")
324  {
326  }
327  else
328  {
330  << "unsupported time format " << formatName
331  << endl;
332  }
333  }
334 
335  controlDict_.readIfPresent("timePrecision", precision_);
336 
337  // stopAt at 'endTime' or a specified value
338  // if nothing is specified, the endTime is zero
339  if (controlDict_.found("stopAt"))
340  {
341  stopAt_ = stopAtControlNames_.read(controlDict_.lookup("stopAt"));
342 
344  {
345  controlDict_.lookup("endTime") >> endTime_;
346  }
347  else
348  {
349  endTime_ = great;
350  }
351  }
352  else if (!controlDict_.readIfPresent("endTime", endTime_))
353  {
354  endTime_ = 0;
355  }
356 
358 
359  if (controlDict_.found("writeVersion"))
360  {
361  writeVersion_ = IOstream::versionNumber
362  (
363  controlDict_.lookup("writeVersion")
364  );
365  }
366 
367  if (controlDict_.found("writeFormat"))
368  {
369  writeFormat_ = IOstream::formatEnum
370  (
371  controlDict_.lookup("writeFormat")
372  );
373  }
374 
375  if (controlDict_.found("writePrecision"))
376  {
378  (
379  controlDict_.lookup<uint>("writePrecision")
380  );
381 
384 
387 
388  FatalError().precision(IOstream::defaultPrecision());
389  FatalIOError.error::operator()().precision
390  (
392  );
393  }
394 
395  if (controlDict_.found("writeCompression"))
396  {
397  writeCompression_ = IOstream::compressionEnum
398  (
399  controlDict_.lookup("writeCompression")
400  );
401 
402  if
403  (
404  writeFormat_ == IOstream::BINARY
405  && writeCompression_ == IOstream::COMPRESSED
406  )
407  {
408  IOWarningInFunction(controlDict_)
409  << "Selecting compressed binary is inefficient and ineffective"
410  ", resetting to uncompressed binary"
411  << endl;
412 
413  writeCompression_ = IOstream::UNCOMPRESSED;
414  }
415  }
416 
417  controlDict_.readIfPresent("graphFormat", graphFormat_);
418  controlDict_.readIfPresent("runTimeModifiable", runTimeModifiable_);
419 
420 
421 
422 
423  if (!runTimeModifiable_ && controlDict_.watchIndices().size())
424  {
425  forAllReverse(controlDict_.watchIndices(), i)
426  {
427  fileHandler().removeWatch(controlDict_.watchIndices()[i]);
428  }
429  controlDict_.watchIndices().clear();
430  }
431 }
432 
433 
435 {
436  if (controlDict_.regIOobject::read())
437  {
438  readDict();
439 
440  if (runTimeModifiable_)
441  {
442  // For IOdictionary the call to regIOobject::read() would have
443  // already updated all the watchIndices via the addWatch but
444  // controlDict_ is an unwatchedIOdictionary so will only have
445  // stored the dependencies as files.
446  fileHandler().addWatches(controlDict_, controlDict_.files());
447  }
448  controlDict_.files().clear();
449 
450  return true;
451  }
452  else
453  {
454  return false;
455  }
456 }
457 
458 
460 {
461  if (runTimeModifiable_)
462  {
463  // Get state of all monitored objects (=registered objects with a
464  // valid filePath).
465  // Note: requires same ordering in objectRegistries on different
466  // processors!
468  (
469  (
472  ),
474  );
475 
476  // Time handling is special since controlDict_ is the one dictionary
477  // that is not registered to any database.
478 
479  if (controlDict_.readIfModified())
480  {
481  readDict();
482  functionObjects_.read();
483 
484  if (runTimeModifiable_)
485  {
486  // For IOdictionary the call to regIOobject::read() would have
487  // already updated all the watchIndices via the addWatch but
488  // controlDict_ is an unwatchedIOdictionary so will only have
489  // stored the dependencies as files.
490 
491  fileHandler().addWatches(controlDict_, controlDict_.files());
492  }
493  controlDict_.files().clear();
494  }
495 
496  bool registryModified = objectRegistry::modified();
497 
498  if (registryModified)
499  {
501  }
502  }
503 }
504 
505 
507 {
508  const word tmName(timeName());
509 
510  IOdictionary timeDict
511  (
512  IOobject
513  (
514  "time",
515  tmName,
516  "uniform",
517  *this,
520  false
521  )
522  );
523 
524  timeDict.add("value", timeName(timeToUserTime(value()), maxPrecision_));
525  timeDict.add("name", string(tmName));
526  timeDict.add("index", timeIndex_);
527  timeDict.add("deltaT", timeToUserTime(deltaT_));
528  timeDict.add("deltaT0", timeToUserTime(deltaT0_));
529 
530  return timeDict.regIOobject::writeObject
531  (
535  true
536  );
537 }
538 
539 
541 (
545  const bool write
546 ) const
547 {
548  if (writeTime())
549  {
550  bool writeOK = writeTimeDict();
551 
552  if (writeOK)
553  {
554  writeOK = objectRegistry::writeObject(fmt, ver, cmp, write);
555  }
556 
557  if (writeOK)
558  {
559  // Does the writeTime trigger purging?
560  if (writeTime_ && purgeWrite_)
561  {
562  if
563  (
564  previousWriteTimes_.size() == 0
565  || previousWriteTimes_.top() != timeName()
566  )
567  {
569  }
570 
571  while (previousWriteTimes_.size() > purgeWrite_)
572  {
574  (
576  (
578  )
579  );
580  }
581  }
582  }
583 
584  return writeOK;
585  }
586  else
587  {
588  return false;
589  }
590 }
591 
592 
594 {
595  writeTime_ = true;
596  return write();
597 }
598 
599 
601 {
603  endTime_ = value();
604 
605  return writeNow();
606 }
607 
608 
610 {
611  writeOnce_ = true;
612 }
613 
614 
615 // ************************************************************************* //
bool read()
Read and set the function objects if their data have changed.
dictionary dict
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:667
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
static streamFormat formatEnum(const word &)
Return stream format of given format name.
Definition: IOstream.C:39
virtual bool rmDir(const fileName &) const =0
Remove a directory and its contents.
stop when Time reaches the prescribed endTime
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
scalar deltaT_
Definition: TimeState.H:56
static compressionType compressionEnum(const word &)
Return compression of given compression name.
Definition: IOstream.C:61
bool writeAndEnd()
Write the objects now (not at end of iteration) and end the run.
Definition: TimeIO.C:600
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
writeControl writeControl_
Definition: Time.H:123
void readModifiedObjects()
Read the objects that have been modified.
virtual int precision() const
Get precision of output field.
Definition: OSstream.C:246
Dictionary reading and supplying the dimensioned constants used within OpenFOAM, particularly for the...
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:158
scalar writeInterval_
Definition: Time.H:125
bool writeInfoHeader
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
#define InfoHeader
Report write to Foam::Info if the local log switch is true.
set endTime to stop immediately w/ writing
static unsigned int defaultPrecision()
Return the default precision.
Definition: IOstream.H:461
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
virtual bool modified() const
Return true if any of the object&#39;s files have been modified.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:446
const labelList & watchIndices() const
Return file-monitoring handles.
Definition: regIOobjectI.H:94
virtual fileName filePath() const
Return complete path + object name if the file exists.
Definition: regIOobject.C:415
const T * lookupPtr(const word &) const
Find and return an entry if present, otherwise return nullptr.
simpleObjectRegistry & debugObjects()
Get access to registered debug switch objects.
Definition: debug.C:338
virtual word timeName() const
Return current time name.
Definition: Time.C:632
label writeTimeIndex_
Definition: TimeState.H:60
simpleObjectRegistry & optimisationObjects()
Get access to registered optimisation switch objects.
Definition: debug.C:360
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:1056
static const int maxPrecision_
Maximum time directory name precision.
Definition: Time.H:156
fileName path() const
Return complete path.
Definition: IOobject.C:358
dictionary & dimensionedConstants()
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:52
static autoPtr< fileOperation > New(const word &type, const bool verbose)
Select type.
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:934
virtual scalar timeToUserTime(const scalar t) const
Convert the real-time (s) into user-time (e.g. CA deg)
Definition: TimeState.C:58
virtual bool writeTimeDict() const
Write time dictionary to the <time>/uniform directory.
Definition: TimeIO.C:506
bool writeTime() const
Return true if this is a write time.
Definition: TimeStateI.H:65
scalar deltaT0_
Definition: TimeState.H:58
virtual void updateStates(const bool masterOnly, const bool syncPar) const
Update state of all files.
label purgeWrite_
Definition: Time.H:127
const fileNameList & files() const
virtual bool writeObject(IOstream::streamFormat, IOstream::versionNumber, IOstream::compressionType, const bool write) const
Write using given format, version and compression.
Definition: TimeIO.C:541
static int precision_
Time directory name precision.
Definition: Time.H:153
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
A class for handling words, derived from string.
Definition: word.H:59
virtual bool readIfModified()
Read object if modified (as set by call to modified)
virtual fileName getFile(const label) const
Get name of file being watched (using handle)
const scalar & value() const
Return const reference to value.
bool readIfPresent(const word &, T &, bool recursive=false, bool patternMatch=true) const
Find an entry if present, and assign to T.
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:86
virtual void addWatches(regIOobject &, const fileNameList &) const
Helper: add watches for list of regIOobjects.
scalar endTime_
Definition: Time.H:117
const fileOperation & fileHandler()
Get current file handler.
const word & name() const
Name function is needed to disambiguate those inherited.
OSstream Sout(cout, "Sout")
Definition: IOstreams.H:51
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
virtual fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true) const =0
Return the file type: directory, file or link.
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:193
static format format_
Time directory name format.
Definition: Time.H:150
FIFOStack< word > previousWriteTimes_
Definition: Time.H:128
virtual void readDict()
Read the control dictionary and set the write controls etc.
Definition: TimeIO.C:35
objects
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:219
prefixOSstream Perr(cerr, "Perr")
Definition: IOstreams.H:54
static const NamedEnum< stopAtControl, 4 > stopAtControlNames_
Definition: Time.H:119
const word & name() const
Return const reference to name.
void readModifiedObjects()
Read the objects that have been modified.
Definition: TimeIO.C:459
simpleObjectRegistry & dimensionSetObjects()
Get access to registered dimensionSets switch objects.
Definition: debug.C:371
bool deltaTchanged_
Definition: TimeState.H:59
void writeOnce()
Write the objects once (one shot) and continue the run.
Definition: TimeIO.C:609
static const NamedEnum< writeControl, 5 > writeControlNames_
Definition: Time.H:122
dictionary & dimensionSystems()
Top level dictionary.
Definition: dimensionSets.C:85
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
virtual bool read()
Read control dictionary, update controls and time.
Definition: TimeIO.C:434
#define WarningInFunction
Report a warning using Foam::Warning.
static const versionNumber currentVersion
Current version number.
Definition: IOstream.H:206
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:331
Object registry for simpleRegIOobject. Maintains ordering.
bool writeOnce_
Definition: Time.H:131
Input from memory buffer stream.
Definition: IStringStream.H:49
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
simpleObjectRegistry & dimensionedConstantObjects()
Get access to registered dimensionedConstant switch objects.
Definition: debug.C:382
string str() const
Return the string.
Version number type.
Definition: IOstream.H:96
OSstream Serr(cerr, "Serr")
Definition: IOstreams.H:52
messageStream Info
stopAtControl stopAt_
Definition: Time.H:120
bool merge(const dictionary &)
Merge entries from the given dictionary.
Definition: dictionary.C:1343
Enum read(Istream &) const
Read a word from Istream and return the corresponding.
Definition: NamedEnum.C:61
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
virtual bool write(const bool write=true) const
Write using setting from DB.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:92
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write) const
Write the objects.
Output to memory buffer stream.
Definition: OStringStream.H:49
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
Definition: POSIX.C:115
bool writeNow()
Write the objects now (not at end of iteration) and continue.
Definition: TimeIO.C:593
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:812
label timeIndex_
Definition: TimeState.H:55
IOerror FatalIOError