Loading...
Searching...
No Matches
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-2025 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// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
145
146// A file is 'outside' of the case if it has been specified using an
147// absolute path.
148//
149// Like 'fileName::isAbsolute' but with even fewer checks since the
150// swapping of '\\' with '/' will have already occurred.
151static inline bool file_isOutsideCase(const std::string& str)
152{
153 return !str.empty() &&
154 (
155 // Starts with '/'
156 (str[0] == '/')
157
158#ifdef _WIN32
159 // Filesytem root - eg, d:/path
160 || (
161 (str.length() > 2 && str[1] == ':')
162 && (str[2] == '/')
163 )
164#endif
165 );
166}
167
168
169// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
170
172(
173 const fileName& path,
174 fileName& instance,
176 word& name
177)
178{
179 // Convert explicit relative file-system path to absolute file-system path.
180 if (path.starts_with("./") || path.starts_with("../"))
181 {
182 fileName absPath(cwd()/path);
183 absPath.clean(); // Remove unneeded ".."
184
185 return fileNameComponents(absPath, instance, local, name);
186 }
187
188 instance.clear();
189 local.clear();
190 name.clear();
191
192 // Called with directory
193 if (isDir(path))
194 {
196 << " called with directory: " << path << endl;
197
198 return false;
199 }
200
201 const auto first = path.find('/');
202 const auto last = path.rfind('/');
203
204 // The raw length of name (without validating for word chars)
205 auto nameLen = path.size();
206
207 if (first == std::string::npos)
208 {
209 // No '/' found (or empty entirely)
210 // => no instance or local
211
213 }
214 else if
215 (
216 first == 0
217 #ifdef _WIN32
218 || (first == 2 && path[1] == ':') // Eg, d:/path
219 #endif
220 )
221 {
222 // Absolute path (starts with '/' or 'd:/')
223 // => no local
224
225 instance = path.substr(0, last);
226
227 const std::string ending = path.substr(last+1);
228 nameLen = ending.size(); // The raw length of name
229 name = word::validate(ending);
230 }
231 else
232 {
233 // Normal case.
234 // First part is instance, remainder is local
235 instance = path.substr(0, first);
236
237 if (last > first)
238 {
239 // With local
240 local = path.substr(first+1, last-first-1);
241 }
242
243 const std::string ending = path.substr(last+1);
244 nameLen = ending.size(); // The raw length of name
245 name = word::validate(ending);
246 }
247
248 // Check for valid (and stripped) name, regardless of the debug level
249 if (!nameLen || nameLen != name.size())
250 {
252 << "has invalid word for name: \"" << name
253 << "\"\nwhile processing path: " << path << endl;
254
255 return false;
256 }
257
258 return true;
259}
260
261
263(
264 const IOobject& io,
265 const fileName& altFile,
266 const word& ioName
267)
268{
269 if (altFile.empty())
270 {
271 return io;
272 }
273
274 // Construct from file path instead
275
276 fileName altPath = altFile;
277
278 if (isDir(altPath))
279 {
280 // Resolve directories as well
281
282 if (ioName.empty())
283 {
284 altPath /= io.name();
285 }
286 else
287 {
288 altPath /= ioName;
289 }
290 }
291 altPath.expand();
292
293
294 return
296 (
297 altPath,
298 io.db(),
299 io.readOpt(),
300 io.writeOpt(),
301 io.registerObject(),
302 io.globalObject()
303 );
304}
305
306
308{
309 const auto i = name.rfind('.');
310
311 if (i == std::string::npos || i == 0)
312 {
313 return word();
314 }
315
316 return name.substr(i+1);
317}
318
319
321{
322 const auto i = name.rfind('.');
323
324 if (i == std::string::npos || i == 0)
325 {
326 return name;
327 }
328
329 return name.substr(0, i);
330}
331
332
333// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
334
335Foam::IOobject::IOobject(const objectRegistry& registry, IOobjectOption ioOpt)
336:
337 IOobjectOption(ioOpt),
338 objState_(objectState::GOOD),
339 sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
340 sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
341 db_(registry)
342{}
343
344
345Foam::IOobject::IOobject
346(
347 const word& name,
348 const fileName& instance,
349 const objectRegistry& registry,
350 IOobjectOption ioOpt
351)
352:
353 IOobject(registry, ioOpt)
354{
355 name_ = name;
356 instance_ = instance;
357
358 if (objectRegistry::debug)
361 << "Constructing IOobject: " << name_ << endl;
362 }
363}
364
365
366Foam::IOobject::IOobject
367(
368 const word& name,
369 const fileName& instance,
370 const fileName& local,
371 const objectRegistry& registry,
372 IOobjectOption ioOpt
373)
374:
375 IOobject(registry, ioOpt)
376{
377 name_ = name;
378 instance_ = instance;
379 local_ = local;
380
381 if (objectRegistry::debug)
384 << "Constructing IOobject: " << name_ << endl;
385 }
386}
387
388
389Foam::IOobject::IOobject
390(
391 const fileName& path,
392 const objectRegistry& registry,
393 IOobjectOption ioOpt
394)
395:
396 IOobject(registry, ioOpt)
397{
398 if (!fileNameComponents(path, instance_, local_, name_))
399 {
401 << " invalid path specification"
402 << exit(FatalError);
403 }
404
405 if (objectRegistry::debug)
408 << "Constructing IOobject: " << name_ << endl;
409 }
410}
411
412
413Foam::IOobject::IOobject
414(
415 const IOobject& io,
416 const objectRegistry& registry
417)
418:
419 IOobjectOption(static_cast<IOobjectOption>(io)),
420 objState_(io.objState_),
421 sizeofLabel_(io.sizeofLabel_),
422 sizeofScalar_(io.sizeofScalar_),
423
424 name_(io.name_),
425 headerClassName_(io.headerClassName_),
426 note_(io.note_),
427 instance_(io.instance_),
428 local_(io.local_),
429
430 db_(registry)
431{}
432
433
434Foam::IOobject::IOobject
435(
436 const IOobject& io,
437 const word& name
438)
439:
440 IOobjectOption(static_cast<IOobjectOption>(io)),
441 objState_(io.objState_),
442 sizeofLabel_(io.sizeofLabel_),
443 sizeofScalar_(io.sizeofScalar_),
444
445 name_(name),
446 headerClassName_(io.headerClassName_),
447 note_(io.note_),
448 instance_(io.instance_),
449 local_(io.local_),
451 db_(io.db_)
452{}
453
454
455// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
458{
459 return db_;
460}
461
464{
465 return db_.time();
466}
467
470{
471 return time().rootPath();
472}
473
476{
477 return time().caseName();
478}
479
480
482{
483 return time().globalCaseName();
484}
485
486
489{
490 return time().caseName(layout);
491}
492
493
494Foam::scalar Foam::IOobject::instanceValue() const
495{
496 scalar val(0);
497
498 // Only makes sense for a relative instance (word type)
499 if (Foam::readScalar(instance_, val))
501 return val;
502 }
503 return 0;
504}
505
506
508{
509 if (file_isOutsideCase(instance()))
510 {
511 return instance();
513
514 // == time().path()/instance()/db_.dbDir()/local();
515 return rootPath()/caseName()/instance()/db_.dbDir()/local();
516}
517
518
520{
521 if (file_isOutsideCase(instance()))
522 {
523 return instance();
525
526 // == time().globalPath()/instance()/db_.dbDir()/local();
527 return rootPath()/globalCaseName()/instance()/db_.dbDir()/local();
528}
529
530
532{
533 if (file_isOutsideCase(instance()))
534 {
535 return instance();
537
538 // == time().path(layout)/instance()/db_.dbDir()/local();
539 return rootPath()/caseName(layout)/instance()/db_.dbDir()/local();
540}
541
542
544(
545 const word& instance,
546 const fileName& local
547) const
548{
549 // Note: can only be called with relative instance since is word type
550 return rootPath()/caseName()/instance/db_.dbDir()/local;
551}
552
553
555(
556 const word& instance,
557 const fileName& local
558) const
559{
560 // Note: can only be called with relative instance since is word type
561 return rootPath()/globalCaseName()/instance/db_.dbDir()/local;
562}
563
564
566(
568 const word& instance,
569 const fileName& local
570) const
571{
572 // Note: can only be called with relative instance since is word type
573 return rootPath()/caseName(layout)/instance/db_.dbDir()/local;
574}
575
576
578(
580 const word& instance
581) const
582{
583 // Note: can only be called with relative instance since is word type
584 return rootPath()/caseName(layout)/instance/db_.dbDir()/local()/name();
585}
586
587
589{
590 if (file_isOutsideCase(instance()))
591 {
592 return instance()/name();
593 }
594
595 return instance()/db_.dbDir()/local()/name();
596}
597
598
600(
601 const word& typeName,
602 const bool search
603) const
604{
605 // Do not check for undecomposed files
606 return fileHandler().filePath(false, *this, typeName, search);
607}
608
609
611(
612 const word& typeName,
613 const bool search
614) const
615{
616 // Check for undecomposed files
617 return fileHandler().filePath(true, *this, typeName, search);
618}
619
620
621// Foam::fileName Foam::IOobject::filePath
622// (
623// const bool isGlobal,
624// const word& typeName,
625// const bool search
626// ) const
627// {
628// return fileHandler().filePath(isGlobal, *this, typeName, search);
629// }
630
631
632void Foam::IOobject::setBad(const string& s)
633{
634 if (objState_ != objectState::GOOD)
635 {
637 << "Recurrent failure for object " << s
638 << exit(FatalError);
639 }
640
641 if (error::level)
642 {
644 << "Broken object " << s << info() << endl;
645 }
646
647 objState_ = objectState::BAD;
648}
649
650
651void Foam::IOobject::resetHeader(const word& newName)
652{
653 if (!newName.empty())
654 {
655 name_ = newName;
656 }
657 objState_ = objectState::GOOD;
658 sizeofLabel_ = static_cast<unsigned char>(sizeof(label));
659 sizeofScalar_ = static_cast<unsigned char>(sizeof(scalar));
660 headerClassName_.clear();
661 note_.clear();
662}
663
664
665// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
666
668{
669 readOpt(io.readOpt());
670 writeOpt(io.writeOpt());
671 // No change to registerObject
672 globalObject(io.globalObject());
673
674 objState_ = io.objState_;
675 sizeofLabel_ = io.sizeofLabel_;
676 sizeofScalar_ = io.sizeofScalar_;
677
678 name_ = io.name_;
679 headerClassName_ = io.headerClassName_;
680 note_ = io.note_;
681 instance_ = io.instance_;
682 local_ = io.local_;
683}
684
685
686// ************************************************************************* //
static bool file_isOutsideCase(const std::string &str)
Definition IOobject.C:144
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition Enum.H:57
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
constexpr IOobjectOption(readOption rOpt=readOption::NO_READ, writeOption wOpt=writeOption::NO_WRITE, registerOption registerObject=registerOption::REGISTER, bool globalObject=false) noexcept
Default construct (NO_READ, NO_WRITE, REGISTER, non-global) or construct with specified options.
bool globalObject() const noexcept
True if object is treated the same for all processors.
readOption readOpt() const noexcept
Get the read option.
writeOption writeOpt() const noexcept
Get the write option.
Layout
The layout of the case structure.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
objectState
Enumeration defining the valid states of an IOobject.
Definition IOobject.H:200
const Time & time() const noexcept
Return Time associated with the objectRegistry.
Definition IOobject.C:456
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
const fileName & rootPath() const noexcept
Return the Time::rootPath().
Definition IOobject.C:462
fileCheckTypes
Enumeration defining the file checking options (time-stamp | inotify) | (all | masterOnly).
Definition IOobject.H:210
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition IOobject.C:450
void resetHeader(const word &newName=word::null)
Clear various bits (headerClassName, note, sizeof...) that would be obtained when reading from a file...
Definition IOobject.C:644
InfoProxy< IOobject > info() const noexcept
Return info proxy, for printing information to a stream.
Definition IOobject.H:1041
scalar instanceValue() const
Return the scalar value of the instance component (or 0), which often corresponds to a time index/val...
Definition IOobject.C:487
static char scopeSeparator
Character for scoping object names (':' or '_').
Definition IOobject.H:353
fileName globalFilePath(const word &typeName, const bool search=true) const
Redirect to fileHandler filePath, searching up if in parallel.
Definition IOobject.C:604
void operator=(const IOobject &io)
Copy assignment, copies all values (except the registry).
Definition IOobject.C:660
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:256
static bool fileNameComponents(const fileName &path, fileName &instance, fileName &local, word &name)
Split path into instance, local, name components.
Definition IOobject.C:165
const fileName & local() const noexcept
Read access to local path component.
Definition IOobjectI.H:301
fileName objectRelPath() const
The object path relative to the case.
Definition IOobject.C:581
fileName localFilePath(const word &typeName, const bool search=true) const
Redirect to fileHandler filePath, searching locally.
Definition IOobject.C:593
word group() const
Return group (extension part of name).
Definition IOobjectI.H:211
const fileName & instance() const noexcept
Read access to instance path component.
Definition IOobjectI.H:289
const fileName & globalCaseName() const noexcept
Return the Time::globalCaseName().
Definition IOobject.C:474
static float fileModificationSkew
Time skew (seconds) for file modification checks.
Definition IOobject.H:363
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition IOobject.H:358
static const Enum< fileCheckTypes > fileCheckTypesNames
Names for the fileCheckTypes.
Definition IOobject.H:218
fileName path() const
The complete path for the object (with instance, local,...).
Definition IOobject.C:500
word member() const
Return member (name without the extension).
Definition IOobjectI.H:217
static int maxFileModificationPolls
Max number of times to poll for file modification changes.
Definition IOobject.H:368
fileName objectPath() const
The complete path + object name.
Definition IOobjectI.H:313
void setBad(const string &s)
Set the object state to bad.
Definition IOobject.C:625
const fileName & caseName() const noexcept
Return the Time::caseName().
Definition IOobject.C:468
fileName globalPath() const
The complete global path for the object (with instance, local,...).
Definition IOobject.C:512
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
A class for handling file names.
Definition fileName.H:75
static bool clean(std::string &str)
Cleanup filename string, possibly applies other transformations such as changing the path separator e...
Definition fileName.C:192
static int level
The output level (verbosity) of messages.
Registry of regIOobjects.
Abstract base class for registered object with I/O. Used in debug symbol registration.
string & expand(const bool allowEmpty=false)
Inplace expand initial tags, tildes, and all occurrences of environment variables as per stringOps::e...
Definition string.C:166
A class for handling words, derived from Foam::string.
Definition word.H:66
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition word.C:39
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
bool local
Definition EEqn.H:20
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
const auto & io
auto & name
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))
#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:228
float floatOptimisationSwitch(const char *name, const float deflt=0)
Lookup optimisation switch or add default value.
Definition debug.C:240
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition debug.C:234
Namespace for OpenFOAM.
fileName cwd()
The physical or logical current working directory path name.
Definition POSIX.C:592
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler().
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition POSIX.C:862
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition fileName.C:642
#define registerOptSwitch(Name, Type, SwitchVar)
const bool writeData(pdfDictionary.get< bool >("writeData"))