IOobject.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2016-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "IOobject.H"
30#include "Time.H"
31#include "Istream.H"
32#include "registerSwitch.H"
33
34// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35
36namespace Foam
37{
39}
40
41bool Foam::IOobject::bannerEnabled_(true);
42
44(
45 #ifdef _WIN32
46 // Windows: using ':' causes scoping conflicts with d:/path etc
47 Foam::debug::infoSwitch("scopeSeparator", '_')
48 #else
49 Foam::debug::infoSwitch("scopeSeparator", ':')
50 #endif
51);
52
53const Foam::Enum
54<
56>
58({
59 { fileCheckTypes::timeStamp, "timeStamp" },
60 { fileCheckTypes::timeStampMaster, "timeStampMaster" },
61 { fileCheckTypes::inotify, "inotify" },
62 { fileCheckTypes::inotifyMaster, "inotifyMaster" },
63});
64
65// Default fileCheck type
67(
68 fileCheckTypesNames.get
69 (
70 "fileModificationChecking",
71 debug::optimisationSwitches()
72 )
73);
74
75
77(
78 Foam::debug::floatOptimisationSwitch("fileModificationSkew", 30)
79);
81(
82 "fileModificationSkew",
83 float,
85);
86
88(
89 Foam::debug::optimisationSwitch("maxFileModificationPolls", 1)
90);
92(
93 "maxFileModificationPolls",
94 int,
96);
97
98
100namespace Foam
101{
102 // Register re-reader
103 class addfileModificationCheckingToOpt
104 :
106 {
107 public:
108
109 addfileModificationCheckingToOpt
110 (const addfileModificationCheckingToOpt&) = delete;
111
112 void operator=
113 (const addfileModificationCheckingToOpt&) = delete;
114
115 explicit addfileModificationCheckingToOpt(const char* name)
116 :
117 ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
118 {}
119
120 virtual ~addfileModificationCheckingToOpt() = default;
121
122 virtual void readData(Foam::Istream& is)
123 {
124 IOobject::fileModificationChecking =
125 IOobject::fileCheckTypesNames.read(is);
126 }
127
128 virtual void writeData(Foam::Ostream& os) const
129 {
130 os << IOobject::fileCheckTypesNames
131 [IOobject::fileModificationChecking];
132 }
133 };
134
135 addfileModificationCheckingToOpt addfileModificationCheckingToOpt_
136 (
137 "fileModificationChecking"
138 );
139
140} // End namespace Foam
142
143
144// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
145
147(
148 const fileName& path,
149 fileName& instance,
150 fileName& local,
151 word& name
152)
153{
154 // Convert explicit relative file-system path to absolute file-system path.
155 if (path.starts_with("./") || path.starts_with("../"))
156 {
157 fileName absPath(cwd()/path);
158 absPath.clean(); // Remove unneeded ".."
159
160 return fileNameComponents(absPath, instance, local, name);
161 }
162
163 instance.clear();
164 local.clear();
165 name.clear();
166
167 // Called with directory
168 if (isDir(path))
169 {
171 << " called with directory: " << path << endl;
172
173 return false;
174 }
175
176 const auto first = path.find('/');
177 const auto last = path.rfind('/');
178
179 // The raw length of name (without validating for word chars)
180 auto nameLen = path.size();
181
182 if (first == std::string::npos)
183 {
184 // No '/' found (or empty entirely)
185 // => no instance or local
186
188 }
189 else if
190 (
191 first == 0
192 #ifdef _WIN32
193 || (first == 2 && path[1] == ':') // Eg, d:/path
194 #endif
195 )
196 {
197 // Absolute path (starts with '/' or 'd:/')
198 // => no local
199
200 instance = path.substr(0, last);
201
202 const std::string ending = path.substr(last+1);
203 nameLen = ending.size(); // The raw length of name
204 name = word::validate(ending);
205 }
206 else
207 {
208 // Normal case.
209 // First part is instance, remainder is local
210 instance = path.substr(0, first);
211
212 if (last > first)
213 {
214 // With local
215 local = path.substr(first+1, last-first-1);
216 }
217
218 const std::string ending = path.substr(last+1);
219 nameLen = ending.size(); // The raw length of name
220 name = word::validate(ending);
221 }
222
223 // Check for valid (and stripped) name, regardless of the debug level
224 if (!nameLen || nameLen != name.size())
225 {
227 << "has invalid word for name: \"" << name
228 << "\"\nwhile processing path: " << path << endl;
229
230 return false;
231 }
232
233 return true;
234}
235
236
238(
239 const IOobject& io,
240 const fileName& altFile,
241 const word& ioName
242)
243{
244 if (altFile.empty())
245 {
246 return io;
247 }
248
249 // Construct from file path instead
250
251 fileName altPath = altFile;
252
253 if (isDir(altPath))
254 {
255 // Resolve directories as well
256
257 if (ioName.empty())
258 {
259 altPath /= io.name();
260 }
261 else
262 {
263 altPath /= ioName;
264 }
265 }
266 altPath.expand();
267
268
269 return
271 (
272 altPath,
273 io.db(),
274 io.readOpt(),
275 io.writeOpt(),
278 );
279}
280
281
283{
284 const auto i = name.rfind('.');
285
286 if (i == std::string::npos || i == 0)
287 {
288 return word::null;
289 }
290
291 return name.substr(i+1);
292}
293
294
296{
297 const auto i = name.rfind('.');
298
299 if (i == std::string::npos || i == 0)
300 {
301 return name;
302 }
303
304 return name.substr(0, i);
305}
306
307
308// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
309
311(
312 const word& name,
313 const fileName& instance,
314 const objectRegistry& registry,
315 readOption rOpt,
316 writeOption wOpt,
317 bool registerObject,
318 bool globalObject
319)
320:
321 name_(name),
322 headerClassName_(typeName),
323 note_(),
324 instance_(instance),
325 local_(),
326 rOpt_(rOpt),
327 wOpt_(wOpt),
328 registerObject_(registerObject),
329 globalObject_(globalObject),
330 objState_(objectState::GOOD),
331 sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
332 sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
333
334 db_(registry)
335{
336 if (objectRegistry::debug)
337 {
339 << "Constructing IOobject called " << name_
340 << " of type " << headerClassName_
341 << endl;
342 }
343}
344
345
347(
348 const word& name,
349 const fileName& instance,
350 const fileName& local,
351 const objectRegistry& registry,
352 readOption rOpt,
353 writeOption wOpt,
354 bool registerObject,
355 bool globalObject
356)
357:
358 name_(name),
359 headerClassName_(typeName),
360 note_(),
361 instance_(instance),
362 local_(local),
363 rOpt_(rOpt),
364 wOpt_(wOpt),
365 registerObject_(registerObject),
366 globalObject_(globalObject),
367 objState_(objectState::GOOD),
368 sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
369 sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
370
371 db_(registry)
372{
373 if (objectRegistry::debug)
374 {
376 << "Constructing IOobject called " << name_
377 << " of type " << headerClassName_
378 << endl;
379 }
380}
381
382
384(
385 const fileName& path,
386 const objectRegistry& registry,
387 readOption rOpt,
388 writeOption wOpt,
389 bool registerObject,
390 bool globalObject
391)
392:
393 name_(),
394 headerClassName_(typeName),
395 note_(),
396 instance_(),
397 local_(),
398 rOpt_(rOpt),
399 wOpt_(wOpt),
400 registerObject_(registerObject),
401 globalObject_(globalObject),
402 objState_(objectState::GOOD),
403 sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
404 sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
405
406 db_(registry)
407{
408 if (!fileNameComponents(path, instance_, local_, name_))
409 {
411 << " invalid path specification"
412 << exit(FatalError);
413 }
414
415 if (objectRegistry::debug)
416 {
418 << "Constructing IOobject called " << name_
419 << " of type " << headerClassName_
420 << endl;
421 }
422}
423
424
426(
427 const IOobject& io,
428 const objectRegistry& registry
429)
430:
431 name_(io.name_),
432 headerClassName_(io.headerClassName_),
433 note_(io.note_),
434 instance_(io.instance_),
435 local_(io.local_),
436 rOpt_(io.rOpt_),
437 wOpt_(io.wOpt_),
438 registerObject_(io.registerObject_),
439 globalObject_(io.globalObject_),
440 objState_(io.objState_),
441 sizeofLabel_(io.sizeofLabel_),
442 sizeofScalar_(io.sizeofScalar_),
443
444 db_(registry)
445{}
446
447
449(
450 const IOobject& io,
451 const word& name
452)
453:
454 name_(name),
455 headerClassName_(io.headerClassName_),
456 note_(io.note_),
457 instance_(io.instance_),
458 local_(io.local_),
459 rOpt_(io.rOpt_),
460 wOpt_(io.wOpt_),
461 registerObject_(io.registerObject_),
462 globalObject_(io.globalObject_),
463 objState_(io.objState_),
464 sizeofLabel_(io.sizeofLabel_),
465 sizeofScalar_(io.sizeofScalar_),
466
467 db_(io.db_)
468{}
469
470
472(
473 const IOobject& io,
474 const word& name,
475 const fileName& local
476)
477:
479{
480 local_ = local;
481}
482
483
485(
486 const IOobject& io,
487 readOption rOpt,
488 writeOption wOpt
489)
490:
491 IOobject(io)
492{
493 rOpt_ = rOpt;
494 wOpt_ = wOpt;
495}
496
497
498// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
499
501{
502 return db_;
503}
504
505
507{
508 return db_.time();
509}
510
511
513{
514 return time().rootPath();
515}
516
517
519{
520 return time().caseName();
521}
522
523
525{
526 // A file is 'outside' of the case if it has been specified using an
527 // absolute path
528
529 const auto first = instance().find('/');
530
531 if
532 (
533 first == 0
534 #ifdef _WIN32
535 || (first == 2 && instance()[1] == ':') // Eg, d:/path
536 #endif
537 )
538 {
539 // Absolute path (starts with '/' or 'd:/')
540 return instance();
541 }
542
543 return rootPath()/caseName()/instance()/db_.dbDir()/local();
544}
545
546
548(
549 const word& instance,
550 const fileName& local
551) const
552{
553 // Note: can only be called with relative instance since is word type
554 return rootPath()/caseName()/instance/db_.dbDir()/local;
555}
556
557
559{
560 // A file is 'outside' of the case if it has been specified using an
561 // absolute path
562
563 const auto first = instance().find('/');
564
565 if
566 (
567 first == 0
568 #ifdef _WIN32
569 || (first == 2 && instance()[1] == ':') // Eg, d:/path
570 #endif
571 )
572 {
573 // Absolute path (starts with '/' or 'd:/')
574 return instance()/name();
575 }
576
577 return instance()/db_.dbDir()/local()/name();
578}
579
580
582(
583 const word& typeName,
584 const bool search
585) const
586{
587 // Do not check for undecomposed files
588 return fileHandler().filePath(false, *this, typeName, search);
589}
590
591
593(
594 const word& typeName,
595 const bool search
596) const
597{
598 // Check for undecomposed files
599 return fileHandler().filePath(true, *this, typeName, search);
600}
601
602
603void Foam::IOobject::setBad(const string& s)
604{
605 if (objState_ != objectState::GOOD)
606 {
608 << "Recurrent failure for object " << s
609 << exit(FatalError);
610 }
611
612 if (error::level)
613 {
615 << "Broken object " << s << info() << endl;
616 }
617
618 objState_ = objectState::BAD;
619}
620
621
622// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
623
625{
626 name_ = io.name_;
627 headerClassName_ = io.headerClassName_;
628 note_ = io.note_;
629 instance_ = io.instance_;
630 local_ = io.local_;
631 rOpt_ = io.rOpt_;
632 wOpt_ = io.wOpt_;
633 globalObject_ = io.globalObject_;
634 objState_ = io.objState_;
635 sizeofLabel_ = io.sizeofLabel_;
636 sizeofScalar_ = io.sizeofScalar_;
637}
638
639
640// ************************************************************************* //
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: Enum.H:61
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
objectState
Enumeration defining the valid states of an IOobject.
Definition: IOobject.H:193
const fileName & caseName() const
Return the Time::caseName()
Definition: IOobject.C:518
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:65
const Time & time() const
Return Time associated with the objectRegistry.
Definition: IOobject.C:506
readOption readOpt() const noexcept
The read option.
Definition: IOobjectI.H:164
bool globalObject() const noexcept
Is object same for all processors?
Definition: IOobjectI.H:121
fileCheckTypes
Enumeration defining the file checking options.
Definition: IOobject.H:200
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition: IOobject.C:500
bool registerObject() const noexcept
Should object created with this IOobject be registered?
Definition: IOobjectI.H:107
static char scopeSeparator
Character for scoping object names (':' or '_')
Definition: IOobject.H:300
fileName globalFilePath(const word &typeName, const bool search=true) const
Helper for filePath that searches up if in parallel.
Definition: IOobject.C:593
void operator=(const IOobject &io)
Copy assignment, copies all values (except the registry)
Definition: IOobject.C:624
static IOobject selectIO(const IOobject &io, const fileName &altFile, const word &ioName="")
Return the IOobject, but also consider an alternative file name.
Definition: IOobject.C:238
static bool fileNameComponents(const fileName &path, fileName &instance, fileName &local, word &name)
Split path into instance, local, name components.
Definition: IOobject.C:147
const fileName & local() const noexcept
Read access to local path component.
Definition: IOobjectI.H:208
fileName objectRelPath() const
The object path relative to the root.
Definition: IOobject.C:558
fileName localFilePath(const word &typeName, const bool search=true) const
Helper for filePath that searches locally.
Definition: IOobject.C:582
word group() const
Return group (extension part of name)
Definition: IOobjectI.H:71
const fileName & instance() const noexcept
Read access to instance path component.
Definition: IOobjectI.H:196
writeOption
Enumeration defining the write options.
Definition: IOobject.H:186
static float fileModificationSkew
Time skew (seconds) for file modification checks.
Definition: IOobject.H:306
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:303
static const Enum< fileCheckTypes > fileCheckTypesNames
Names for the fileCheckTypes.
Definition: IOobject.H:208
fileName path() const
The complete path.
Definition: IOobject.C:524
word member() const
Return member (name without the extension)
Definition: IOobjectI.H:77
const fileName & rootPath() const
Return the Time::rootPath()
Definition: IOobject.C:512
static int maxFileModificationPolls
Max number of times to poll for file modification changes.
Definition: IOobject.H:309
writeOption writeOpt() const noexcept
The write option.
Definition: IOobjectI.H:179
readOption
Enumeration defining the read options.
Definition: IOobject.H:177
void setBad()
Set stream state to be 'bad'.
Definition: IOstream.H:369
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
A class for handling file names.
Definition: fileName.H:76
static bool clean(std::string &str)
Definition: fileName.C:199
virtual fileName filePath(const bool checkGlobal, const IOobject &, const word &typeName, const bool search=true) const =0
Search for an object. checkGlobal : also check undecomposed case.
virtual void validate()
Validate the turbulence fields after construction.
Definition: kkLOmega.C:597
static int level
The output level (verbosity) of messages.
Registry of regIOobjects.
const Time & time() const noexcept
Return time registry.
Abstract base class for registered object with I/O. Used in debug symbol registration.
bool starts_with(const std::string &s) const
True if string starts with the given prefix (cf. C++20)
Definition: string.H:297
string & expand(const bool allowEmpty=false)
Definition: string.C:173
A class for handling words, derived from Foam::string.
Definition: word.H:68
static const word null
An empty word.
Definition: word.H:80
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
#define WarningInFunction
Report a warning using Foam::Warning.
#define InfoInFunction
Report an information message using Foam::Info.
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:231
float floatOptimisationSwitch(const char *name, const float deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:243
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:237
Namespace for OpenFOAM.
const fileOperation & fileHandler()
Get current file handler.
fileName cwd()
The physical or logical current working directory path name.
Definition: MSwindows.C:476
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
const direction noexcept
Definition: Scalar.H:223
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:651
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:624
#define registerOptSwitch(Name, Type, SwitchVar)
const bool writeData(pdfDictionary.get< bool >("writeData"))