regIOobject.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-2023 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 "regIOobject.H"
27 #include "Time.H"
28 #include "polyMesh.H"
29 #include "fileOperation.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
36 }
37 
38 
39 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
40 
41 Foam::regIOobject::regIOobject(const IOobject& io, const bool isTime)
42 :
43  IOobject(io),
44  registered_(false),
45  ownedByRegistry_(false),
46  watchIndices_(),
47  eventNo_ // Do not get event for top level Time database
48  (
49  isTime
50  ? 0
51  : db().getEvent()
52  )
53 {
54  // Register with objectRegistry if requested
55  if (registerObject())
56  {
57  checkIn();
58  }
59 }
60 
61 
63 :
64  IOobject(rio),
65  registered_(false),
66  ownedByRegistry_(false),
67  watchIndices_(rio.watchIndices_),
68  eventNo_(db().getEvent())
69 {
70  // Do not register copy with objectRegistry
71 }
72 
73 
75 :
76  IOobject(rio),
77  registered_(false),
78  ownedByRegistry_(false),
79  watchIndices_(),
80  eventNo_(db().getEvent())
81 {
82  if (rio.registered_)
83  {
84  const_cast<regIOobject&>(rio).checkOut();
85  checkIn();
86  }
87 }
88 
89 
90 Foam::regIOobject::regIOobject(const regIOobject& rio, bool registerCopy)
91 :
92  IOobject(rio),
93  registered_(false),
94  ownedByRegistry_(false),
95  watchIndices_(),
96  eventNo_(db().getEvent())
97 {
98  if (registerCopy)
99  {
100  if (rio.registered_)
101  {
102  const_cast<regIOobject&>(rio).checkOut();
103  }
104  checkIn();
105  }
106 }
107 
108 
110 (
111  const word& newName,
112  const regIOobject& rio,
113  bool registerCopy
114 )
115 :
116  IOobject(newName, rio.instance(), rio.local(), rio.db()),
117  registered_(false),
118  ownedByRegistry_(false),
119  watchIndices_(),
120  eventNo_(db().getEvent())
121 {
122  if (registerCopy)
123  {
124  checkIn();
125  }
126 }
127 
128 
130 (
131  const IOobject& io,
132  const regIOobject& rio
133 )
134 :
135  IOobject(io),
136  registered_(false),
137  ownedByRegistry_(false),
138  watchIndices_(),
139  eventNo_(db().getEvent())
140 {
141  if (registerObject())
142  {
143  checkIn();
144  }
145 }
146 
147 
148 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
149 
151 {
152  if (objectRegistry::debug)
153  {
154  if (this == &db())
155  {
156  Pout<< "Destroying objectRegistry " << name()
157  << " in directory "
158  << rootPath()/caseName()/instance()
159  << endl;
160  }
161  else
162  {
163  Pout<< "Destroying regIOobject " << name()
164  << " in directory " << path()
165  << endl;
166  }
167  }
168 
169  db().resetCacheTemporaryObject(*this);
170 
171  // Check out of objectRegistry if not owned by the registry
172  if (!ownedByRegistry_)
173  {
174  checkOut();
175  }
176 }
177 
178 
179 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
180 
182 {
183  return false;
184 }
185 
186 
188 {
189  return global();
190 }
191 
192 
194 {
195  return IOobject::caseName(globalFile());
196 }
197 
198 
200 {
201  return IOobject::path(globalFile());
202 }
203 
204 
206 {
207  if (!registered_)
208  {
209  // multiple checkin of same object is disallowed - this would mess up
210  // any mapping
211  registered_ = db().checkIn(*this);
212 
213  // check-in on defaultRegion is allowed to fail, since subsetted meshes
214  // are created with the same name as their originating mesh
215  if (!registered_ && debug && name() != polyMesh::defaultRegion)
216  {
217  if (debug == 2)
218  {
219  // for ease of finding where attempted duplicate check-in
220  // originated
222  << "failed to register object " << objectPath()
223  << " the name already exists in the objectRegistry" << endl
224  << "Contents:" << db().sortedToc()
225  << abort(FatalError);
226  }
227  else
228  {
230  << "failed to register object " << objectPath()
231  << " the name already exists in the objectRegistry"
232  << endl;
233  }
234  }
235  }
236 
237  return registered_;
238 }
239 
240 
242 {
243  if (registered_)
244  {
245  registered_ = false;
246 
247  forAllReverse(watchIndices_, i)
248  {
249  fileHandler().removeWatch(watchIndices_[i]);
250  }
251  watchIndices_.clear();
252  return db().checkOut(*this);
253  }
254 
255  return false;
256 }
257 
258 
260 {
261  if
262  (
263  registered_
264  && readOpt() == MUST_READ_IF_MODIFIED
265  && time().runTimeModifiable()
266  )
267  {
268  fileName f = filePath();
269  if (!f.size())
270  {
271  // We don't have this file but would like to re-read it.
272  // Possibly if master-only reading mode.
273  f = objectPath();
274  }
275 
276  label index = fileHandler().findWatch(watchIndices_, f);
277  if (index != -1)
278  {
279  FatalErrorIn("regIOobject::addWatch()")
280  << "Object " << objectPath() << " of type " << type()
281  << " already watched with index " << watchIndices_[index]
282  << abort(FatalError);
283  }
284 
285  // If master-only reading only the master will have all dependencies
286  // so scatter these to slaves
287  bool masterOnly =
288  global()
289  && (
290  regIOobject::fileModificationChecking == timeStampMaster
291  || regIOobject::fileModificationChecking == inotifyMaster
292  );
293 
294  if (masterOnly && Pstream::parRun())
295  {
296  // Get master watched files
297  fileNameList watchFiles;
298  if (Pstream::master())
299  {
300  watchFiles.setSize(watchIndices_.size());
301  forAll(watchIndices_, i)
302  {
303  watchFiles[i] = fileHandler().getFile(watchIndices_[i]);
304  }
305  }
306  Pstream::scatter(watchFiles);
307 
308  if (!Pstream::master())
309  {
310  // unregister current ones
311  forAllReverse(watchIndices_, i)
312  {
313  fileHandler().removeWatch(watchIndices_[i]);
314  }
315 
316  watchIndices_.clear();
317  forAll(watchFiles, i)
318  {
319  watchIndices_.append(fileHandler().addWatch(watchFiles[i]));
320  }
321  }
322  }
323 
324  watchIndices_.append(fileHandler().addWatch(f));
325  }
326 }
327 
328 
330 {
331  if (a.eventNo() >= eventNo_)
332  {
333  return false;
334  }
335  else
336  {
337  return true;
338  }
339 }
340 
341 
343 (
344  const regIOobject& a,
345  const regIOobject& b
346 ) const
347 {
348  if
349  (
350  a.eventNo() >= eventNo_
351  || b.eventNo() >= eventNo_
352  )
353  {
354  return false;
355  }
356  else
357  {
358  return true;
359  }
360 }
361 
362 
364 (
365  const regIOobject& a,
366  const regIOobject& b,
367  const regIOobject& c
368 ) const
369 {
370  if
371  (
372  a.eventNo() >= eventNo_
373  || b.eventNo() >= eventNo_
374  || c.eventNo() >= eventNo_
375  )
376  {
377  return false;
378  }
379  else
380  {
381  return true;
382  }
383 }
384 
385 
387 (
388  const regIOobject& a,
389  const regIOobject& b,
390  const regIOobject& c,
391  const regIOobject& d
392 ) const
393 {
394  if
395  (
396  a.eventNo() >= eventNo_
397  || b.eventNo() >= eventNo_
398  || c.eventNo() >= eventNo_
399  || d.eventNo() >= eventNo_
400  )
401  {
402  return false;
403  }
404  else
405  {
406  return true;
407  }
408 }
409 
410 
412 {
413  eventNo_ = db().getEvent();
414 }
415 
416 
417 void Foam::regIOobject::rename(const word& newName)
418 {
419  // Only rename the object if the name is different
420  // avoiding the checkOut/checkIn
421  if (newName != name())
422  {
423  const bool ownedByRegistry0 = ownedByRegistry();
424  release();
425 
426  // Check out of objectRegistry
427  checkOut();
428 
429  IOobject::rename(newName);
430 
431  if (registerObject())
432  {
433  // Re-register object with objectRegistry
434  if (ownedByRegistry0)
435  {
436  store();
437  }
438  else
439  {
440  checkIn();
441  }
442  }
443  }
444 }
445 
446 
448 {
449  return IOobject::filePath(type(), globalFile());
450 }
451 
452 
454 {
455  // Note: Should be consistent with typeIOobject<Type>::headerOk()
456 
457  bool ok = true;
458 
459  const fileName fName(filePath());
460 
461  ok = Foam::fileHandler().readHeader(*this, fName, type());
462 
463  if (IOobject::debug && (!ok || headerClassName() != type()))
464  {
465  IOWarningInFunction(fName)
466  << "failed to read header of file " << objectPath()
467  << endl;
468  }
469 
470  return ok;
471 }
472 
473 
474 void Foam::regIOobject::operator=(const IOobject& io)
475 {
476  // Close any file
477  isPtr_.clear();
478 
479  const bool ownedByRegistry0 = ownedByRegistry();
480  release();
481 
482  // Check out of objectRegistry
483  checkOut();
484 
486 
487  if (registerObject())
488  {
489  // Re-register object with objectRegistry
490  if (ownedByRegistry0)
491  {
492  store();
493  }
494  else
495  {
496  checkIn();
497  }
498  }
499 }
500 
501 
502 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:446
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const fileName & caseName(const bool global) const
Definition: IOobject.C:342
fileName filePath(const word &typeName, const bool global) const
Return complete path + object name if the file exists.
Definition: IOobject.C:407
bool & registerObject()
Register object created from this IOobject with registry if true.
Definition: IOobject.H:346
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:226
virtual void rename(const word &newName)
Rename.
Definition: IOobject.H:340
void operator=(const IOobject &)
Definition: IOobject.C:435
fileName path(const bool global) const
Return complete path including the processor sub-directory.
Definition: IOobject.C:380
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
A class for handling file names.
Definition: fileName.H:82
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
virtual label findWatch(const labelList &watchIndices, const fileName &) const
Find index (or -1) of file in list of handles.
virtual bool readHeader(IOobject &, const fileName &, const word &typeName) const =0
Read object header from supplied file.
virtual fileName getFile(const label) const
Get name of file being watched (using handle)
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:266
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:55
const fileName & caseName() const
Definition: regIOobject.C:193
void setUpToDate()
Set up to date (obviously)
Definition: regIOobject.C:411
virtual bool global() const
Return true if object is global, i.e. same for all processors.
Definition: regIOobject.C:181
fileName filePath() const
Return complete path + object name if the file exists.
Definition: regIOobject.C:447
regIOobject(const IOobject &, const bool isTime=false)
Construct from IOobject. Optional flag for if IOobject is the.
Definition: regIOobject.C:41
bool upToDate(const regIOobject &) const
Return true if up-to-date with respect to given object.
Definition: regIOobject.C:329
bool headerOk()
Read and check header info.
Definition: regIOobject.C:453
label eventNo() const
Event number at last update.
Definition: regIOobjectI.H:89
virtual bool globalFile() const
Return true if object is global, i.e. same for all processors.
Definition: regIOobject.C:187
fileName path() const
Return complete path.
Definition: regIOobject.C:199
bool checkOut()
Remove object from registry.
Definition: regIOobject.C:241
virtual ~regIOobject()
Destructor.
Definition: regIOobject.C:150
void addWatch()
Add file watch on object (if registered and READ_IF_MODIFIED)
Definition: regIOobject.C:259
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:417
bool checkIn()
Add object to registry.
Definition: regIOobject.C:205
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:301
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
volScalarField & b
Definition: createFields.H:27
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
Namespace for OpenFOAM.
const fileOperation & fileHandler()
Get current file handler.
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
errorManip< error > abort(error &err)
Definition: errorManip.H:131
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
error FatalError
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
labelList f(nPoints)