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 
204  Info<< " ";
205  objects[i]->writeData(Info);
206  Info<< endl;
207  }
208  }
209  }
210  }
211 
212 
213  // Dimension sets
214  if (controlDict_.found("DimensionSets"))
215  {
216  InfoHeader
217  << "Overriding DimensionSets according to "
218  << controlDict_.name() << endl;
219 
221  dict.merge(controlDict_.subDict("DimensionSets"));
222 
224 
225  simpleObjectRegistryEntry* objPtr = objects.lookupPtr("DimensionSets");
226 
227  if (objPtr)
228  {
229  InfoHeader << controlDict_.subDict("DimensionSets") << endl;
230 
231  const List<simpleRegIOobject*>& objects = *objPtr;
232 
233  forAll(objects, i)
234  {
236  os << dict;
237  IStringStream is(os.str());
238  objects[i]->readData(is);
239  }
240  }
241  }
242 
243 
244  if (!deltaTchanged_)
245  {
246  deltaT_ = readScalar(controlDict_.lookup("deltaT"));
247  }
248 
249  if (controlDict_.found("writeControl"))
250  {
252  (
253  controlDict_.lookup("writeControl")
254  );
255  }
256 
257  scalar oldWriteInterval = writeInterval_;
258 
259  if (controlDict_.readIfPresent("writeInterval", writeInterval_))
260  {
261  if
262  (
264  && label(writeInterval_) < 1
265  )
266  {
267  FatalIOErrorInFunction(controlDict_)
268  << "writeInterval < 1 for writeControl timeStep"
269  << exit(FatalIOError);
270  }
271  }
272  else
273  {
274  controlDict_.lookup("writeFrequency") >> writeInterval_;
275  }
276 
277 
278  if (oldWriteInterval != writeInterval_)
279  {
280  switch (writeControl_)
281  {
284  // Recalculate writeTimeIndex_ to be in units of current
285  // writeInterval.
287  (
289  * oldWriteInterval
291  );
292  break;
293 
294  default:
295  break;
296  }
297  }
298 
299  if (controlDict_.readIfPresent("purgeWrite", purgeWrite_))
300  {
301  if (purgeWrite_ < 0)
302  {
304  << "invalid value for purgeWrite " << purgeWrite_
305  << ", should be >= 0, setting to 0"
306  << endl;
307 
308  purgeWrite_ = 0;
309  }
310  }
311 
312  if (controlDict_.found("timeFormat"))
313  {
314  const word formatName(controlDict_.lookup("timeFormat"));
315 
316  if (formatName == "general")
317  {
319  }
320  else if (formatName == "fixed")
321  {
323  }
324  else if (formatName == "scientific")
325  {
327  }
328  else
329  {
331  << "unsupported time format " << formatName
332  << endl;
333  }
334  }
335 
336  controlDict_.readIfPresent("timePrecision", precision_);
337 
338  // stopAt at 'endTime' or a specified value
339  // if nothing is specified, the endTime is zero
340  if (controlDict_.found("stopAt"))
341  {
342  stopAt_ = stopAtControlNames_.read(controlDict_.lookup("stopAt"));
343 
345  {
346  controlDict_.lookup("endTime") >> endTime_;
347  }
348  else
349  {
350  endTime_ = great;
351  }
352  }
353  else if (!controlDict_.readIfPresent("endTime", endTime_))
354  {
355  endTime_ = 0;
356  }
357 
359 
360  if (controlDict_.found("writeVersion"))
361  {
362  writeVersion_ = IOstream::versionNumber
363  (
364  controlDict_.lookup("writeVersion")
365  );
366  }
367 
368  if (controlDict_.found("writeFormat"))
369  {
370  writeFormat_ = IOstream::formatEnum
371  (
372  controlDict_.lookup("writeFormat")
373  );
374  }
375 
376  if (controlDict_.found("writePrecision"))
377  {
379  (
380  readUint(controlDict_.lookup("writePrecision"))
381  );
382 
385 
388 
389  FatalError().precision(IOstream::defaultPrecision());
390  FatalIOError.error::operator()().precision
391  (
393  );
394  }
395 
396  if (controlDict_.found("writeCompression"))
397  {
398  writeCompression_ = IOstream::compressionEnum
399  (
400  controlDict_.lookup("writeCompression")
401  );
402 
403  if
404  (
405  writeFormat_ == IOstream::BINARY
406  && writeCompression_ == IOstream::COMPRESSED
407  )
408  {
409  IOWarningInFunction(controlDict_)
410  << "Selecting compressed binary is inefficient and ineffective"
411  ", resetting to uncompressed binary"
412  << endl;
413 
414  writeCompression_ = IOstream::UNCOMPRESSED;
415  }
416  }
417 
418  controlDict_.readIfPresent("graphFormat", graphFormat_);
419  controlDict_.readIfPresent("runTimeModifiable", runTimeModifiable_);
420 
421 
422 
423 
424  if (!runTimeModifiable_ && controlDict_.watchIndices().size())
425  {
426  forAllReverse(controlDict_.watchIndices(), i)
427  {
428  fileHandler().removeWatch(controlDict_.watchIndices()[i]);
429  }
430  controlDict_.watchIndices().clear();
431  }
432 }
433 
434 
436 {
437  if (controlDict_.regIOobject::read())
438  {
439  readDict();
440 
441  if (runTimeModifiable_)
442  {
443  // For IOdictionary the call to regIOobject::read() would have
444  // already updated all the watchIndices via the addWatch but
445  // controlDict_ is an unwatchedIOdictionary so will only have
446  // stored the dependencies as files.
447  fileHandler().addWatches(controlDict_, controlDict_.files());
448  }
449  controlDict_.files().clear();
450 
451  return true;
452  }
453  else
454  {
455  return false;
456  }
457 }
458 
459 
461 {
462  if (runTimeModifiable_)
463  {
464  // Get state of all monitored objects (=registered objects with a
465  // valid filePath).
466  // Note: requires same ordering in objectRegistries on different
467  // processors!
469  (
470  (
473  ),
475  );
476 
477  // Time handling is special since controlDict_ is the one dictionary
478  // that is not registered to any database.
479 
480  if (controlDict_.readIfModified())
481  {
482  readDict();
483  functionObjects_.read();
484 
485  if (runTimeModifiable_)
486  {
487  // For IOdictionary the call to regIOobject::read() would have
488  // already updated all the watchIndices via the addWatch but
489  // controlDict_ is an unwatchedIOdictionary so will only have
490  // stored the dependencies as files.
491 
492  fileHandler().addWatches(controlDict_, controlDict_.files());
493  }
494  controlDict_.files().clear();
495  }
496 
497  bool registryModified = objectRegistry::modified();
498 
499  if (registryModified)
500  {
502  }
503  }
504 }
505 
506 
508 {
509  const word tmName(timeName());
510 
511  IOdictionary timeDict
512  (
513  IOobject
514  (
515  "time",
516  tmName,
517  "uniform",
518  *this,
521  false
522  )
523  );
524 
525  timeDict.add("value", timeName(timeToUserTime(value()), maxPrecision_));
526  timeDict.add("name", string(tmName));
527  timeDict.add("index", timeIndex_);
528  timeDict.add("deltaT", timeToUserTime(deltaT_));
529  timeDict.add("deltaT0", timeToUserTime(deltaT0_));
530 
531  return timeDict.regIOobject::writeObject
532  (
536  true
537  );
538 }
539 
540 
542 (
546  const bool write
547 ) const
548 {
549  if (writeTime())
550  {
551  bool writeOK = writeTimeDict();
552 
553  if (writeOK)
554  {
555  writeOK = objectRegistry::writeObject(fmt, ver, cmp, write);
556  }
557 
558  if (writeOK)
559  {
560  // Does the writeTime trigger purging?
561  if (writeTime_ && purgeWrite_)
562  {
563  if
564  (
565  previousWriteTimes_.size() == 0
566  || previousWriteTimes_.top() != timeName()
567  )
568  {
570  }
571 
572  while (previousWriteTimes_.size() > purgeWrite_)
573  {
575  (
577  (
579  )
580  );
581  }
582  }
583  }
584 
585  return writeOK;
586  }
587  else
588  {
589  return false;
590  }
591 }
592 
593 
595 {
596  writeTime_ = true;
597  return write();
598 }
599 
600 
602 {
604  endTime_ = value();
605 
606  return writeNow();
607 }
608 
609 
611 {
612  writeOnce_ = true;
613 }
614 
615 
616 // ************************************************************************* //
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:438
#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:601
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
writeControl writeControl_
Definition: Time.H:127
void readModifiedObjects()
Read the objects that have been modified.
virtual int precision() const
Get precision of output field.
Definition: OSstream.C:293
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:129
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:163
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:256
#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:425
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:636
label writeTimeIndex_
Definition: TimeState.H:60
dictionary & dimensionedConstants()
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:821
static const int maxPrecision_
Maximum time directory name precision.
Definition: Time.H:160
fileName path() const
Return complete path.
Definition: IOobject.C:390
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:699
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:507
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:131
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:542
static int precision_
Time directory name precision.
Definition: Time.H:157
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:124
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:121
const fileOperation & fileHandler()
Get current file handler.
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if successful.
Definition: doubleScalar.H:68
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:154
FIFOStack< word > previousWriteTimes_
Definition: Time.H:132
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:211
prefixOSstream Perr(cerr, "Perr")
Definition: IOstreams.H:54
static const NamedEnum< stopAtControl, 4 > stopAtControlNames_
Definition: Time.H:123
const word & name() const
Return const reference to name.
void readModifiedObjects()
Read the objects that have been modified.
Definition: TimeIO.C:460
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:610
static const NamedEnum< writeControl, 5 > writeControlNames_
Definition: Time.H:126
unsigned int readUint(Istream &)
Definition: uintIO.C:31
dictionary & dimensionSystems()
Top level dictionary.
Definition: dimensionSets.C:79
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:435
#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:135
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:124
bool merge(const dictionary &)
Merge entries from the given dictionary.
Definition: dictionary.C:1097
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:594
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:583
label timeIndex_
Definition: TimeState.H:55
IOerror FatalIOError