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