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-2018 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  {
262  {
263  FatalIOErrorInFunction(controlDict_)
264  << "writeInterval < 1 for writeControl timeStep"
265  << exit(FatalIOError);
266  }
267  }
268  else
269  {
270  controlDict_.lookup("writeFrequency") >> writeInterval_;
271  }
272 
273 
274  if (oldWriteInterval != writeInterval_)
275  {
276  switch (writeControl_)
277  {
278  case wcRunTime:
279  case wcAdjustableRunTime:
280  // Recalculate writeTimeIndex_ to be in units of current
281  // writeInterval.
283  (
285  * oldWriteInterval
287  );
288  break;
289 
290  default:
291  break;
292  }
293  }
294 
295  if (controlDict_.readIfPresent("purgeWrite", purgeWrite_))
296  {
297  if (purgeWrite_ < 0)
298  {
300  << "invalid value for purgeWrite " << purgeWrite_
301  << ", should be >= 0, setting to 0"
302  << endl;
303 
304  purgeWrite_ = 0;
305  }
306  }
307 
308  if (controlDict_.found("timeFormat"))
309  {
310  const word formatName(controlDict_.lookup("timeFormat"));
311 
312  if (formatName == "general")
313  {
314  format_ = general;
315  }
316  else if (formatName == "fixed")
317  {
318  format_ = fixed;
319  }
320  else if (formatName == "scientific")
321  {
323  }
324  else
325  {
327  << "unsupported time format " << formatName
328  << endl;
329  }
330  }
331 
332  controlDict_.readIfPresent("timePrecision", precision_);
333 
334  // stopAt at 'endTime' or a specified value
335  // if nothing is specified, the endTime is zero
336  if (controlDict_.found("stopAt"))
337  {
338  stopAt_ = stopAtControlNames_.read(controlDict_.lookup("stopAt"));
339 
340  if (stopAt_ == saEndTime)
341  {
342  controlDict_.lookup("endTime") >> endTime_;
343  }
344  else
345  {
346  endTime_ = great;
347  }
348  }
349  else if (!controlDict_.readIfPresent("endTime", endTime_))
350  {
351  endTime_ = 0;
352  }
353 
355 
356  if (controlDict_.found("writeVersion"))
357  {
358  writeVersion_ = IOstream::versionNumber
359  (
360  controlDict_.lookup("writeVersion")
361  );
362  }
363 
364  if (controlDict_.found("writeFormat"))
365  {
366  writeFormat_ = IOstream::formatEnum
367  (
368  controlDict_.lookup("writeFormat")
369  );
370  }
371 
372  if (controlDict_.found("writePrecision"))
373  {
375  (
376  readUint(controlDict_.lookup("writePrecision"))
377  );
378 
381 
384 
385  FatalError().precision(IOstream::defaultPrecision());
386  FatalIOError.error::operator()().precision
387  (
389  );
390  }
391 
392  if (controlDict_.found("writeCompression"))
393  {
394  writeCompression_ = IOstream::compressionEnum
395  (
396  controlDict_.lookup("writeCompression")
397  );
398 
399  if
400  (
401  writeFormat_ == IOstream::BINARY
402  && writeCompression_ == IOstream::COMPRESSED
403  )
404  {
405  IOWarningInFunction(controlDict_)
406  << "Selecting compressed binary is inefficient and ineffective"
407  ", resetting to uncompressed binary"
408  << endl;
409 
410  writeCompression_ = IOstream::UNCOMPRESSED;
411  }
412  }
413 
414  controlDict_.readIfPresent("graphFormat", graphFormat_);
415  controlDict_.readIfPresent("runTimeModifiable", runTimeModifiable_);
416 
417 
418 
419 
420  if (!runTimeModifiable_ && controlDict_.watchIndices().size())
421  {
422  forAllReverse(controlDict_.watchIndices(), i)
423  {
424  fileHandler().removeWatch(controlDict_.watchIndices()[i]);
425  }
426  controlDict_.watchIndices().clear();
427  }
428 }
429 
430 
432 {
433  if (controlDict_.regIOobject::read())
434  {
435  readDict();
436 
437  if (runTimeModifiable_)
438  {
439  // For IOdictionary the call to regIOobject::read() would have
440  // already updated all the watchIndices via the addWatch but
441  // controlDict_ is an unwatchedIOdictionary so will only have
442  // stored the dependencies as files.
443  fileHandler().addWatches(controlDict_, controlDict_.files());
444  }
445  controlDict_.files().clear();
446 
447  return true;
448  }
449  else
450  {
451  return false;
452  }
453 }
454 
455 
457 {
458  if (runTimeModifiable_)
459  {
460  // Get state of all monitored objects (=registered objects with a
461  // valid filePath).
462  // Note: requires same ordering in objectRegistries on different
463  // processors!
465  (
466  (
469  ),
471  );
472 
473  // Time handling is special since controlDict_ is the one dictionary
474  // that is not registered to any database.
475 
476  if (controlDict_.readIfModified())
477  {
478  readDict();
479  functionObjects_.read();
480 
481  if (runTimeModifiable_)
482  {
483  // For IOdictionary the call to regIOobject::read() would have
484  // already updated all the watchIndices via the addWatch but
485  // controlDict_ is an unwatchedIOdictionary so will only have
486  // stored the dependencies as files.
487 
488  fileHandler().addWatches(controlDict_, controlDict_.files());
489  }
490  controlDict_.files().clear();
491  }
492 
493  bool registryModified = objectRegistry::modified();
494 
495  if (registryModified)
496  {
498  }
499  }
500 }
501 
502 
504 {
505  const word tmName(timeName());
506 
507  IOdictionary timeDict
508  (
509  IOobject
510  (
511  "time",
512  tmName,
513  "uniform",
514  *this,
517  false
518  )
519  );
520 
521  timeDict.add("value", timeName(timeToUserTime(value()), maxPrecision_));
522  timeDict.add("name", string(tmName));
523  timeDict.add("index", timeIndex_);
524  timeDict.add("deltaT", timeToUserTime(deltaT_));
525  timeDict.add("deltaT0", timeToUserTime(deltaT0_));
526 
527  return timeDict.regIOobject::writeObject
528  (
532  true
533  );
534 }
535 
536 
538 (
542  const bool valid
543 ) const
544 {
545  if (writeTime())
546  {
547  bool writeOK = writeTimeDict();
548 
549  if (writeOK)
550  {
551  writeOK = objectRegistry::writeObject(fmt, ver, cmp, valid);
552  }
553 
554  if (writeOK)
555  {
556  // Does the writeTime trigger purging?
557  if (writeTime_ && purgeWrite_)
558  {
559  if
560  (
561  previousWriteTimes_.size() == 0
562  || previousWriteTimes_.top() != timeName()
563  )
564  {
566  }
567 
568  while (previousWriteTimes_.size() > purgeWrite_)
569  {
571  (
573  (
575  )
576  );
577  }
578  }
579  }
580 
581  return writeOK;
582  }
583  else
584  {
585  return false;
586  }
587 }
588 
589 
591 {
592  writeTime_ = true;
593  return write();
594 }
595 
596 
598 {
600  endTime_ = value();
601 
602  return writeNow();
603 }
604 
605 
607 {
608  writeOnce_ = true;
609 }
610 
611 
612 // ************************************************************************* //
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:431
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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.
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
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool valid) const
Write the objects.
bool writeAndEnd()
Write the objects now (not at end of iteration) and end the run.
Definition: TimeIO.C:597
stopAtControls stopAt_
Definition: Time.H:124
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
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:137
set endTime to stop immediately w/ writing
Definition: Time.H:102
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:60
#define InfoHeader
Report write to Foam::Info if the local log switch is true.
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.
static fmtflags format_
Time directory name format.
Definition: Time.H:154
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:440
const labelList & watchIndices() const
Return file-monitoring handles.
Definition: regIOobjectI.H:91
virtual fileName filePath() const
Return complete path + object name if the file exists.
Definition: regIOobject.C:424
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
writeControls writeControl_
Definition: Time.H:127
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:814
virtual fileName::Type type(const fileName &, const bool followLink=true) const =0
Return the file type: DIRECTORY, FILE or LINK.
static const int maxPrecision_
Maximum time directory name precision.
Definition: Time.H:160
fileName path() const
Return complete path.
Definition: IOobject.C:397
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:692
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:503
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
static const NamedEnum< stopAtControls, 4 > stopAtControlNames_
Definition: Time.H:123
const fileNameList & files() const
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
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:193
FIFOStack< word > previousWriteTimes_
Definition: Time.H:132
virtual void readDict()
Read the control dictionary and set the write controls etc.
Definition: TimeIO.C:35
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:214
prefixOSstream Perr(cerr, "Perr")
Definition: IOstreams.H:54
const word & name() const
Return const reference to name.
static const NamedEnum< writeControls, 5 > writeControlNames_
Definition: Time.H:126
void readModifiedObjects()
Read the objects that have been modified.
Definition: TimeIO.C:456
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:606
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:397
virtual bool read()
Read control dictionary, update controls and time.
Definition: TimeIO.C:431
#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.
stop when Time reaches the prescribed endTime
Definition: Time.H:100
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
bool merge(const dictionary &)
Merge entries from the given dictionary.
Definition: dictionary.C:1090
Enum read(Istream &) const
Read a word from Istream and return the corresponding.
Definition: NamedEnum.C:61
virtual bool writeObject(IOstream::streamFormat, IOstream::versionNumber, IOstream::compressionType, const bool valid) const
Write using given format, version and compression.
Definition: TimeIO.C:538
#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 valid=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
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:114
bool writeNow()
Write the objects now (not at end of iteration) and continue.
Definition: TimeIO.C:590
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:576
label timeIndex_
Definition: TimeState.H:55
IOerror FatalIOError