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 {
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,
109  IOobject::NO_READ,
110  IOobject::AUTO_WRITE,
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 {
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 // ************************************************************************* //
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< Key > sortedToc() const
Return the table of contents as a sorted list.
Definition: HashTable.C:217
bool erase(const iterator &)
Erase a hashedEntry specified by given iterator.
Definition: HashTable.C:371
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:202
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:142
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 ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:65
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 sortedNames() const
Return the sorted list of names of the IOobjects.
const objectRegistry & subRegistry(const word &name, const bool forceCreate=false) const
Lookup and return a const sub-objectRegistry. Optionally create.
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 ~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.
wordList names() const
Return the list of names of the IOobjects.
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.
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
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:251
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
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
static const char nl
Definition: Ostream.H:260
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