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-2026 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_(isTime ? 0 : db().getEvent()) // Don't get event for Time
48 {
49  // Register with objectRegistry if requested
50  if (registerObject())
51  {
52  checkIn();
53  }
54 }
55 
56 
58 (
59  const word& newName,
60  const IOobject& io,
61  const bool registerObject
62 )
63 :
64  IOobject(newName, io.instance(), io.local(), io.db()),
65  registered_(false),
66  ownedByRegistry_(false),
67  watchIndices_(),
68  eventNo_(db().getEvent())
69 {
70  if (registerObject)
71  {
72  checkIn();
73  }
74 }
75 
76 
78 :
79  IOobject(rio),
80  registered_(false),
81  ownedByRegistry_(false),
82  watchIndices_(rio.watchIndices_),
83  eventNo_(db().getEvent())
84 {
85  // Do not register copy with objectRegistry
86 }
87 
88 
90 :
91  IOobject(rio),
92  registered_(false),
93  ownedByRegistry_(false),
94  watchIndices_(),
95  eventNo_(db().getEvent())
96 {
97  if (rio.registered_)
98  {
99  rio.checkOut();
100  checkIn();
101  }
102 }
103 
104 
105 Foam::regIOobject::regIOobject(const regIOobject& rio, bool registerCopy)
106 :
107  IOobject(rio),
108  registered_(false),
109  ownedByRegistry_(false),
110  watchIndices_(),
111  eventNo_(db().getEvent())
112 {
113  if (registerCopy)
114  {
115  if (rio.registered_)
116  {
117  const_cast<regIOobject&>(rio).checkOut();
118  }
119  checkIn();
120  }
121 }
122 
123 
124 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
125 
127 {
128  if (objectRegistry::debug)
129  {
130  if (this == &db())
131  {
132  Pout<< "Destroying objectRegistry " << name()
133  << " in directory "
134  << rootPath()/caseName()/instance()
135  << endl;
136  }
137  else
138  {
139  Pout<< "Destroying regIOobject " << name()
140  << " in directory " << path()
141  << endl;
142  }
143  }
144 
145  db().resetCacheTemporaryObject(*this);
146 
147  // Check out of objectRegistry if not owned by the registry
148  if (!ownedByRegistry_)
149  {
150  checkOut();
151  }
152 }
153 
154 
155 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
156 
158 {
159  return false;
160 }
161 
162 
164 {
165  return global();
166 }
167 
168 
170 {
171  return IOobject::caseName(globalFile());
172 }
173 
174 
176 {
177  return IOobject::path(globalFile());
178 }
179 
180 
182 {
183  if (!registered_)
184  {
185  // multiple checkIn of same object is disallowed - this would mess up
186  // any mapping
187  registered_ = db().checkIn(*this);
188 
189  // check-in on defaultRegion is allowed to fail, since subsetted meshes
190  // are created with the same name as their originating mesh
191  if (!registered_ && debug && name() != polyMesh::defaultRegion)
192  {
193  if (debug == 2)
194  {
195  // for ease of finding where attempted duplicate check-in
196  // originated
198  << "failed to register object " << objectPath()
199  << " the name already exists in the objectRegistry" << endl
200  << "Contents:" << db().sortedToc()
201  << abort(FatalError);
202  }
203  else
204  {
206  << "failed to register object " << objectPath()
207  << " the name already exists in the objectRegistry"
208  << endl;
209  }
210  }
211  }
212 
213  return registered_;
214 }
215 
216 
218 {
219  if (registered_)
220  {
221  registered_ = false;
222 
223  forAllReverse(watchIndices_, i)
224  {
225  fileHandler().removeWatch(watchIndices_[i]);
226  }
227  watchIndices_.clear();
228  return db().checkOut(*this);
229  }
230 
231  return false;
232 }
233 
234 
236 {
237  if
238  (
239  registered_
240  && readOpt() == MUST_READ_IF_MODIFIED
241  && time().runTimeModifiable()
242  )
243  {
244  fileName f = filePath();
245  if (!f.size())
246  {
247  // We don't have this file but would like to re-read it.
248  // Possibly if master-only reading mode.
249  f = objectPath();
250  }
251 
252  label index = fileHandler().findWatch(watchIndices_, f);
253  if (index != -1)
254  {
255  FatalErrorIn("regIOobject::addWatch()")
256  << "Object " << objectPath() << " of type " << type()
257  << " already watched with index " << watchIndices_[index]
258  << abort(FatalError);
259  }
260 
261  // If master-only reading only the master will have all dependencies
262  // so scatter these to slaves
263  bool masterOnly =
264  global()
265  && (
266  regIOobject::fileModificationChecking == timeStampMaster
267  || regIOobject::fileModificationChecking == inotifyMaster
268  );
269 
270  if (masterOnly && Pstream::parRun())
271  {
272  // Get master watched files
273  fileNameList watchFiles;
274  if (Pstream::master())
275  {
276  watchFiles.setSize(watchIndices_.size());
277  forAll(watchIndices_, i)
278  {
279  watchFiles[i] = fileHandler().getFile(watchIndices_[i]);
280  }
281  }
282  Pstream::scatter(watchFiles);
283 
284  if (!Pstream::master())
285  {
286  // unregister current ones
287  forAllReverse(watchIndices_, i)
288  {
289  fileHandler().removeWatch(watchIndices_[i]);
290  }
291 
292  watchIndices_.clear();
293  forAll(watchFiles, i)
294  {
295  watchIndices_.append(fileHandler().addWatch(watchFiles[i]));
296  }
297  }
298  }
299 
300  watchIndices_.append(fileHandler().addWatch(f));
301  }
302 }
303 
304 
306 {
307  if (a.eventNo() >= eventNo_)
308  {
309  return false;
310  }
311  else
312  {
313  return true;
314  }
315 }
316 
317 
319 (
320  const regIOobject& a,
321  const regIOobject& b
322 ) const
323 {
324  if
325  (
326  a.eventNo() >= eventNo_
327  || b.eventNo() >= eventNo_
328  )
329  {
330  return false;
331  }
332  else
333  {
334  return true;
335  }
336 }
337 
338 
340 (
341  const regIOobject& a,
342  const regIOobject& b,
343  const regIOobject& c
344 ) const
345 {
346  if
347  (
348  a.eventNo() >= eventNo_
349  || b.eventNo() >= eventNo_
350  || c.eventNo() >= eventNo_
351  )
352  {
353  return false;
354  }
355  else
356  {
357  return true;
358  }
359 }
360 
361 
363 (
364  const regIOobject& a,
365  const regIOobject& b,
366  const regIOobject& c,
367  const regIOobject& d
368 ) const
369 {
370  if
371  (
372  a.eventNo() >= eventNo_
373  || b.eventNo() >= eventNo_
374  || c.eventNo() >= eventNo_
375  || d.eventNo() >= eventNo_
376  )
377  {
378  return false;
379  }
380  else
381  {
382  return true;
383  }
384 }
385 
386 
388 {
389  eventNo_ = db().getEvent();
390 }
391 
392 
393 void Foam::regIOobject::rename(const word& newName)
394 {
395  // Only rename the object if the name is different
396  // avoiding the checkOut/checkIn
397  if (newName != name())
398  {
399  const bool ownedByRegistry0 = ownedByRegistry();
400  release();
401 
402  // Check out of objectRegistry
403  checkOut();
404 
405  IOobject::rename(newName);
406 
407  if (registerObject())
408  {
409  // Re-register object with objectRegistry
410  if (ownedByRegistry0)
411  {
412  store();
413  }
414  else
415  {
416  checkIn();
417  }
418  }
419  }
420 }
421 
422 
424 {
425  return IOobject::filePath(globalFile());
426 }
427 
428 
430 {
431  // Note: Should be consistent with typeIOobject<Type>::headerOk()
432 
433  bool ok = true;
434 
435  const fileName fName(filePath());
436 
437  ok = Foam::fileHandler().readHeader(*this, fName, type());
438 
439  if (IOobject::debug && (!ok || headerClassName() != type()))
440  {
441  IOWarningInFunction(fName)
442  << "failed to read header of file " << objectPath()
443  << endl;
444  }
445 
446  return ok;
447 }
448 
449 
450 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:461
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:339
bool & registerObject()
Register object created from this IOobject with registry if true.
Definition: IOobject.H:343
fileName filePath(const bool global) const
Return complete path + object name if the file exists.
Definition: IOobject.C:409
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:223
virtual void rename(const word &newName)
Rename.
Definition: IOobject.H:337
fileName path(const bool global) const
Return complete path including the processor sub-directory.
Definition: IOobject.C:383
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:260
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:169
void setUpToDate()
Set up to date (obviously)
Definition: regIOobject.C:387
virtual bool global() const
Return true if object is global, i.e. same for all processors.
Definition: regIOobject.C:157
fileName filePath() const
Return complete path + object name if the file exists.
Definition: regIOobject.C:423
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:305
bool headerOk()
Read and check header info.
Definition: regIOobject.C:429
virtual bool globalFile() const
Return true if object is global, i.e. same for all processors.
Definition: regIOobject.C:163
fileName path() const
Return complete path.
Definition: regIOobject.C:175
bool checkOut()
Remove object from registry.
Definition: regIOobject.C:217
virtual ~regIOobject()
Destructor.
Definition: regIOobject.C:126
void addWatch()
Add file watch on object (if registered and READ_IF_MODIFIED)
Definition: regIOobject.C:235
uint64_t eventNo() const
Event number at last update.
Definition: regIOobjectI.H:89
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:393
bool checkIn()
Add object to registry.
Definition: regIOobject.C:181
A class for handling words, derived from string.
Definition: word.H:63
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:329
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
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.
const dimensionSet time
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:288
errorManip< error > abort(error &err)
Definition: errorManip.H:131
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
error FatalError
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
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)