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