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