objectRegistry.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-2024 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 "objectRegistry.H"
27 #include "Time.H"
28 #include "IOmanip.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
35 }
36 
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 bool Foam::objectRegistry::parentNotTime() const
41 {
42  return (&parent_ != dynamic_cast<const objectRegistry*>(&time_));
43 }
44 
45 
46 void Foam::objectRegistry::readCacheTemporaryObjects() const
47 {
48  if
49  (
50  !cacheTemporaryObjectsSet_
51  && time_.controlDict().found("cacheTemporaryObjects")
52  )
53  {
54  cacheTemporaryObjectsSet_ = true;
55 
56  const dictionary& controlDict = time_.controlDict();
57 
58  wordList cacheTemporaryObjects;
59 
60  if (controlDict.isDict("cacheTemporaryObjects"))
61  {
62  if(controlDict.subDict("cacheTemporaryObjects").found(name()))
63  {
64  controlDict.subDict("cacheTemporaryObjects").lookup(name())
65  >> cacheTemporaryObjects;
66  }
67  }
68  else
69  {
70  controlDict.lookup("cacheTemporaryObjects")
71  >> cacheTemporaryObjects;
72  }
73 
74  forAll(cacheTemporaryObjects, i)
75  {
76  cacheTemporaryObjects_.insert
77  (
78  cacheTemporaryObjects[i],
79  {false, false}
80  );
81  }
82  }
83 }
84 
85 
86 void Foam::objectRegistry::deleteCachedObject(regIOobject& cachedOb) const
87 {
88  cachedOb.release();
89  cachedOb.checkOut();
90  cachedOb.rename(cachedOb.name() + "Cached");
91  delete &cachedOb;
92 }
93 
94 
95 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
96 
98 (
99  const Time& t,
100  const label nIoObjects
101 )
102 :
104  (
105  IOobject
106  (
107  string::validate<word>(t.caseName()),
108  t.path(),
109  t,
110  IOobject::NO_READ,
111  IOobject::AUTO_WRITE,
112  false
113  ),
114  true // to flag that this is the top-level regIOobject
115  ),
116  HashTable<regIOobject*>(nIoObjects),
117  time_(t),
118  parent_(t),
119  dbDir_(name()),
120  event_(1),
121  cacheTemporaryObjectsSet_(false)
122 {}
123 
124 
126 (
127  const IOobject& io,
128  const label nIoObjects
129 )
130 :
131  regIOobject(io),
132  HashTable<regIOobject*>(nIoObjects),
133  time_(io.time()),
134  parent_(io.db()),
135  dbDir_(parent_.dbDir()/local()/name()),
136  event_(1),
137  cacheTemporaryObjectsSet_(false)
138 {
140 }
141 
142 
143 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
144 
146 {
147  cacheTemporaryObjects_.clear();
148  clear();
149 }
150 
151 
152 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
153 
155 (
156  const word& instance,
157  const fileName& local
158 ) const
159 {
160  // Note: can only be called with relative instance since is word type
161  return rootPath()/caseName()/instance/dbDir()/local;
162 }
163 
164 
166 {
167  wordList objectNames(size());
168 
169  label count=0;
170  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
171  {
172  if (iter()->type() == ClassName)
173  {
174  objectNames[count++] = iter.key();
175  }
176  }
177 
178  objectNames.setSize(count);
179 
180  return objectNames;
181 }
182 
183 
185 {
186  wordList sortedLst = toc(ClassName);
187  sort(sortedLst);
188 
189  return sortedLst;
190 }
191 
192 
194 (
195  const word& name,
196  const bool forceCreate
197 ) const
198 {
199  if (forceCreate && !foundObject<objectRegistry>(name))
200  {
201  objectRegistry* fieldsCachePtr = new objectRegistry
202  (
203  IOobject
204  (
205  name,
206  time().constant(),
207  *this,
210  )
211  );
212  fieldsCachePtr->store();
213  }
214  return lookupObject<objectRegistry>(name);
215 }
216 
217 
219 {
220  label curEvent = event_++;
221 
222  if (event_ == labelMax)
223  {
224  if (objectRegistry::debug)
225  {
227  << "Event counter has overflowed. "
228  << "Resetting counter on all dependent objects." << nl
229  << "This might cause extra evaluations." << endl;
230  }
231 
232  // Reset event counter
233  curEvent = 1;
234  event_ = 2;
235 
236  for (const_iterator iter = begin(); iter != end(); ++iter)
237  {
238  const regIOobject& io = *iter();
239 
240  if (objectRegistry::debug)
241  {
242  Pout<< "objectRegistry::getEvent() : "
243  << "resetting count on " << iter.key() << endl;
244  }
245 
246  if (io.eventNo() != 0)
247  {
248  const_cast<regIOobject&>(io).eventNo() = curEvent;
249  }
250  }
251  }
252 
253  return curEvent;
254 }
255 
256 
258 {
259  if (objectRegistry::debug)
260  {
261  Pout<< "objectRegistry::checkIn(regIOobject&) : "
262  << name() << " : checking in " << io.name()
263  << " of type " << io.type()
264  << endl;
265  }
266 
267  // Delete cached object with the same name as io and if it is in the
268  // cacheTemporaryObjects list
269  if (cacheTemporaryObjects_.size())
270  {
271  HashTable<Pair<bool>>::iterator cacheIter
272  (
273  cacheTemporaryObjects_.find(io.name())
274  );
275 
276  if (cacheIter != cacheTemporaryObjects_.end())
277  {
278  iterator iter = const_cast<objectRegistry&>(*this).find(io.name());
279 
280  if (iter != end() && iter() != &io && iter()->ownedByRegistry())
281  {
282  if (objectRegistry::debug)
283  {
284  Pout<< "objectRegistry::checkIn(regIOobject&) : "
285  << name() << " : deleting cached object " << iter.key()
286  << endl;
287  }
288 
289  cacheIter().first() = false;
290  deleteCachedObject(*iter());
291  }
292  }
293  }
294 
295  return const_cast<objectRegistry&>(*this).insert(io.name(), &io);
296 }
297 
298 
300 {
301  iterator iter = const_cast<objectRegistry&>(*this).find(io.name());
302 
303  if (iter != end())
304  {
305  if (objectRegistry::debug)
306  {
307  Pout<< "objectRegistry::checkOut(regIOobject&) : "
308  << name() << " : checking out " << iter.key()
309  << endl;
310  }
311 
312  if (iter() != &io)
313  {
314  if (objectRegistry::debug)
315  {
317  << name() << " : attempt to checkOut copy of "
318  << iter.key()
319  << endl;
320  }
321 
322  return false;
323  }
324  else
325  {
326  regIOobject* object = iter();
327 
328  bool hasErased = const_cast<objectRegistry&>(*this).erase(iter);
329 
330  if (io.ownedByRegistry())
331  {
332  delete object;
333  }
334 
335  return hasErased;
336  }
337  }
338  else
339  {
340  if (objectRegistry::debug)
341  {
342  Pout<< "objectRegistry::checkOut(regIOobject&) : "
343  << name() << " : could not find " << io.name()
344  << " in registry " << name()
345  << endl;
346  }
347  }
348 
349  return false;
350 }
351 
352 
354 {
355  List<regIOobject*> myObjects(size());
356  label nMyObjects = 0;
357 
358  for (iterator iter = begin(); iter != end(); ++iter)
359  {
360  if (iter()->ownedByRegistry())
361  {
362  myObjects[nMyObjects++] = iter();
363  }
364  }
365 
366  for (label i=0; i < nMyObjects; i++)
367  {
368  checkOut(*myObjects[i]);
369  }
370 }
371 
372 
374 (
375  const word& name
376 ) const
377 {
378  if (!cacheTemporaryObjects_.found(name))
379  {
380  cacheTemporaryObjects_.insert(name, {false, false});
381  }
382 }
383 
384 
386 (
387  const word& name
388 ) const
389 {
390  return cacheTemporaryObjects_.found(name);
391 }
392 
393 
395 (
396  const regIOobject& ob
397 ) const
398 {
399  if (cacheTemporaryObjects_.size())
400  {
401  HashTable<Pair<bool>>::iterator iter
402  (
403  cacheTemporaryObjects_.find(ob.name())
404  );
405 
406  // If object ob if is in the cacheTemporaryObjects list
407  // and has been cached reset the cached flag
408  if (iter != cacheTemporaryObjects_.end())
409  {
410  iter().first() = false;
411  }
412  }
413 }
414 
415 
417 {
418  bool enabled = cacheTemporaryObjects_.size();
419 
421  {
422  const objectRegistry* orPtr_ =
423  dynamic_cast<const objectRegistry*>(iter());
424 
425  // Protect against re-searching the top-level registry
426  if (orPtr_ && orPtr_ != this)
427  {
428  enabled = orPtr_->checkCacheTemporaryObjects() || enabled;
429  }
430  }
431 
432  if (enabled)
433  {
434  forAllIter
435  (
436  typename HashTable<Pair<bool>>,
437  cacheTemporaryObjects_,
438  iter
439  )
440  {
441  if (!iter().second())
442  {
443  Warning
444  << "Could not find temporary object " << iter.key()
445  << " in registry " << name() << nl
446  << "Available temporary objects "
447  << temporaryObjects_
448  << endl;
449  }
450  else
451  {
452  iter().second() = false;
453  }
454  }
455 
456  temporaryObjects_.clear();
457  }
458 
459  return enabled;
460 }
461 
462 
463 void Foam::objectRegistry::rename(const word& newName)
464 {
465  regIOobject::rename(newName);
466 
467  // adjust dbDir_ as well
468  string::size_type i = dbDir_.rfind('/');
469 
470  if (i == string::npos)
471  {
472  dbDir_ = newName;
473  }
474  else
475  {
476  dbDir_.replace(i+1, string::npos, newName);
477  }
478 }
479 
480 
482 {
484  {
485  if (iter()->modified())
486  {
487  return true;
488  }
489  }
490 
491  return false;
492 }
493 
494 
496 {
497  dependents_.setSize(size());
498 
499  label count=0;
501  {
502  if (iter()->dependenciesModified())
503  {
504  dependents_[count++] = iter();
505  }
506  }
507  dependents_.setSize(count);
508 
509  return count != 0;
510 }
511 
512 
514 {
515  bool modified = false;
516 
517  for (iterator iter = begin(); iter != end(); ++iter)
518  {
519  if (objectRegistry::debug)
520  {
521  Pout<< "objectRegistry::readModifiedObjects() : "
522  << name() << " : Considering reading object "
523  << iter.key() << endl;
524  }
525 
526  modified = modified || iter()->readIfModified();
527  }
528 
529  return modified;
530 }
531 
532 
534 {
535  bool readOk = true;
536 
537  forAll(dependents_, i)
538  {
539  dependents_[i]->read();
540  }
541 
542  return readOk;
543 }
544 
545 
547 {
548  dependenciesModified();
549 
550  const bool modified = readIfModified();
551 
552  // If any objects have been modified and re-read, read the dependants
553  if (modified)
554  {
556  }
557 }
558 
559 
561 {
563  (
564  sorted()
565  );
566 
567  forAll(sortedObjects, i)
568  {
569  os << " " << setf(ios_base::left)
570  << setw(39) << sortedObjects[i].key()
571  << ' ' << sortedObjects[i]()->type()
572  << endl;
573  }
574 }
575 
576 
578 (
582  const bool write
583 ) const
584 {
585  bool ok = true;
586 
588  {
589  if (objectRegistry::debug)
590  {
591  Pout<< "objectRegistry::write() : "
592  << name() << " : Considering writing object "
593  << iter.key()
594  << " of type " << iter()->type()
595  << " with writeOpt " << iter()->writeOpt()
596  << " to file " << iter()->objectPath()
597  << endl;
598  }
599 
600  if (iter()->writeOpt() != NO_WRITE)
601  {
602  ok = iter()->writeObject(fmt, ver, cmp, write) && ok;
603  }
604  }
605 
606  return ok;
607 }
608 
609 
610 // ************************************************************************* //
Istream and Ostream manipulators taking arguments.
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:459
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
An STL-conforming hash table.
Definition: HashTable.H:127
List< word > sortedToc() const
Return the table of contents as a sorted list.
Definition: HashTable.C:242
bool erase(const iterator &)
Erase a hashedEntry specified by given iterator.
Definition: HashTable.C:445
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:167
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
writeOption writeOpt() const
Definition: IOobject.H:370
const word & name() const
Return name.
Definition: IOobject.H:310
Version number type.
Definition: IOstream.H:97
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:87
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:194
void setSize(const label)
Reset size of List.
Definition: List.C:281
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
A class for handling file names.
Definition: fileName.H:82
Registry of regIOobjects.
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write) const
Write the objects.
wordList toc() const
Return the list of names of the IOobjects of given type.
const objectRegistry & subRegistry(const word &name, const bool forceCreate=false) const
Lookup and return a const sub-objectRegistry. Optionally create.
void printToc(Ostream &os) const
Print the list of object names and their type.
virtual bool modified() const
Return true if any of the object's files have been modified.
objectRegistry(const Time &db, const label nIoObjects=128)
Construct the time objectRegistry given an initial estimate.
virtual bool dependenciesModified() const
Cache pointers to objects who's dependencies have been modified.
virtual ~objectRegistry()
Destructor.
bool checkCacheTemporaryObjects() const
Check that all objects in the cacheTemporaryObjects set.
bool cacheTemporaryObject(const word &name) const
Return true if given name is in the cacheTemporaryObjects set.
virtual bool readIfModified()
Read object if modified.
fileName path() const
Return complete path.
Definition: regIOobject.C:199
void clear()
Remove all regIOobject owned by the registry.
void resetCacheTemporaryObject(const regIOobject &ob) const
Reset the cache state of the given object.
void readModifiedObjects()
Read the objects that have been modified.
void addTemporaryObject(const word &name) const
Add the given name to the set of temporary objects to cache.
virtual void rename(const word &newName)
Rename.
virtual bool read()
Read dependent objects.
label getEvent() const
Return new event number.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:55
bool ownedByRegistry() const
Is this object owned by the registry?
Definition: regIOobjectI.H:34
label eventNo() const
Event number at last update.
Definition: regIOobjectI.H:89
bool checkOut()
Remove object from registry.
Definition: regIOobject.C:241
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:417
void store()
Transfer ownership of this object to its registry.
Definition: regIOobjectI.H:40
bool checkIn()
Add object to registry.
Definition: regIOobject.C:205
A class for handling character strings derived from std::string.
Definition: string.H:79
string & replace(const string &oldStr, const string &newStr, size_type start=0)
In this string replace first occurrence of sub-string oldStr.
Definition: string.C:64
A class for handling words, derived from string.
Definition: word.H:62
#define ClassName(TypeNameString)
Add typeName information from argument TypeNameString to a class.
Definition: className.H:65
tUEqn clear()
#define WarningInFunction
Report a warning using Foam::Warning.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
Namespace for OpenFOAM.
List< word > wordList
A List of words.
Definition: fileName.H:54
Smanip< ios_base::fmtflags > setf(const ios_base::fmtflags flags)
Definition: IOmanip.H:164
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
void sort(UList< T > &)
Definition: UList.C:115
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
static const label labelMax
Definition: label.H:62
static const char nl
Definition: Ostream.H:266
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
messageStream Warning
runTime controlDict().lookup("adjustTimeStep") >> adjustTimeStep
thermo validate(args.executable(), "h")
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112