Files
OpenFOAM-12/src/OpenFOAM/db/Time/TimeIO.C
Henry Weller bbc00ccd2e OpenFOAM: Simplified the handling of global switches and constants
to improve robustness and maintainability.  Now all switches and constants are
set correctly on constructions without the need for dynamic update after the
system/controlDict is read.  This significantly simplifies the code and make it
much easier to add new switches, constants and settings without the need to
ensure they are registered to a database for update.
2020-11-06 19:25:49 +00:00

380 lines
9.3 KiB
C++

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "Time.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::Time::readDict()
{
word application;
if (controlDict_.readIfPresent("application", application))
{
// Do not override if already set so external application can override
setEnv("FOAM_APPLICATION", application, false);
}
if (!deltaTchanged_)
{
deltaT_ = controlDict_.lookup<scalar>("deltaT");
}
if (controlDict_.found("writeControl"))
{
writeControl_ = writeControlNames_.read
(
controlDict_.lookup("writeControl")
);
}
scalar oldWriteInterval = writeInterval_;
if (controlDict_.readIfPresent("writeInterval", writeInterval_))
{
if
(
writeControl_ == writeControl::timeStep
&& label(writeInterval_) < 1
)
{
FatalIOErrorInFunction(controlDict_)
<< "writeInterval < 1 for writeControl timeStep"
<< exit(FatalIOError);
}
}
else
{
controlDict_.lookup("writeFrequency") >> writeInterval_;
}
if (oldWriteInterval != writeInterval_)
{
switch (writeControl_)
{
case writeControl::runTime:
case writeControl::adjustableRunTime:
// Recalculate writeTimeIndex_ to be in units of current
// writeInterval.
writeTimeIndex_ = label
(
writeTimeIndex_
* oldWriteInterval
/ writeInterval_
);
break;
default:
break;
}
}
if (controlDict_.readIfPresent("purgeWrite", purgeWrite_))
{
if (purgeWrite_ < 0)
{
WarningInFunction
<< "invalid value for purgeWrite " << purgeWrite_
<< ", should be >= 0, setting to 0"
<< endl;
purgeWrite_ = 0;
}
}
if (controlDict_.found("timeFormat"))
{
const word formatName(controlDict_.lookup("timeFormat"));
if (formatName == "general")
{
format_ = format::general;
}
else if (formatName == "fixed")
{
format_ = format::fixed;
}
else if (formatName == "scientific")
{
format_ = format::scientific;
}
else
{
WarningInFunction
<< "unsupported time format " << formatName
<< endl;
}
}
controlDict_.readIfPresent("timePrecision", precision_);
// stopAt at 'endTime' or a specified value
// if nothing is specified, the endTime is zero
if (controlDict_.found("stopAt"))
{
stopAt_ = stopAtControlNames_.read(controlDict_.lookup("stopAt"));
if (stopAt_ == stopAtControl::endTime)
{
controlDict_.lookup("endTime") >> endTime_;
}
else
{
endTime_ = great;
}
}
else if (!controlDict_.readIfPresent("endTime", endTime_))
{
endTime_ = 0;
}
dimensionedScalar::name() = timeName(value());
if (controlDict_.found("writeVersion"))
{
writeVersion_ = IOstream::versionNumber
(
controlDict_.lookup("writeVersion")
);
}
if (controlDict_.found("writeFormat"))
{
writeFormat_ = IOstream::formatEnum
(
controlDict_.lookup("writeFormat")
);
}
if (controlDict_.found("writePrecision"))
{
IOstream::defaultPrecision
(
controlDict_.lookup<unsigned int>("writePrecision")
);
Sout.precision(IOstream::defaultPrecision());
Serr.precision(IOstream::defaultPrecision());
Pout.precision(IOstream::defaultPrecision());
Perr.precision(IOstream::defaultPrecision());
FatalError().precision(IOstream::defaultPrecision());
FatalIOError.error::operator()().precision
(
IOstream::defaultPrecision()
);
}
if (controlDict_.found("writeCompression"))
{
writeCompression_ = IOstream::compressionEnum
(
controlDict_.lookup("writeCompression")
);
if
(
writeFormat_ == IOstream::BINARY
&& writeCompression_ == IOstream::COMPRESSED
)
{
IOWarningInFunction(controlDict_)
<< "Selecting compressed binary is inefficient and ineffective"
", resetting to uncompressed binary"
<< endl;
writeCompression_ = IOstream::UNCOMPRESSED;
}
}
controlDict_.readIfPresent("graphFormat", graphFormat_);
controlDict_.readIfPresent("runTimeModifiable", runTimeModifiable_);
}
bool Foam::Time::read()
{
if (controlDict_.regIOobject::read())
{
readDict();
return true;
}
else
{
return false;
}
}
void Foam::Time::readModifiedObjects()
{
if (runTimeModifiable_)
{
// Get state of all monitored objects (=registered objects with a
// valid filePath).
// Note: requires same ordering in objectRegistries on different
// processors!
fileHandler().updateStates
(
(
regIOobject::fileModificationChecking == inotifyMaster
|| regIOobject::fileModificationChecking == timeStampMaster
),
Pstream::parRun()
);
// Time handling is special since controlDict_ is the one dictionary
// that is not registered to any database.
if (controlDict_.readIfModified())
{
readDict();
functionObjects_.read();
}
bool registryModified = objectRegistry::modified();
if (registryModified)
{
objectRegistry::readModifiedObjects();
}
}
}
bool Foam::Time::writeTimeDict() const
{
const word tmName(timeName());
IOdictionary timeDict
(
IOobject
(
"time",
tmName,
"uniform",
*this,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
)
);
timeDict.add("value", timeName(timeToUserTime(value()), maxPrecision_));
timeDict.add("name", string(tmName));
timeDict.add("index", timeIndex_);
timeDict.add("deltaT", timeToUserTime(deltaT_));
timeDict.add("deltaT0", timeToUserTime(deltaT0_));
return timeDict.regIOobject::writeObject
(
IOstream::ASCII,
IOstream::currentVersion,
IOstream::UNCOMPRESSED,
true
);
}
bool Foam::Time::writeObject
(
IOstream::streamFormat fmt,
IOstream::versionNumber ver,
IOstream::compressionType cmp,
const bool write
) const
{
if (writeTime())
{
bool writeOK = writeTimeDict();
if (writeOK)
{
writeOK = objectRegistry::writeObject(fmt, ver, cmp, write);
}
if (writeOK)
{
// Does the writeTime trigger purging?
if (writeTime_ && purgeWrite_)
{
if
(
previousWriteTimes_.size() == 0
|| previousWriteTimes_.top() != timeName()
)
{
previousWriteTimes_.push(timeName());
}
while (previousWriteTimes_.size() > purgeWrite_)
{
fileHandler().rmDir
(
fileHandler().filePath
(
objectRegistry::path(previousWriteTimes_.pop())
)
);
}
}
}
return writeOK;
}
else
{
return false;
}
}
bool Foam::Time::writeNow()
{
writeTime_ = true;
return write();
}
bool Foam::Time::writeAndEnd()
{
stopAt_ = stopAtControl::writeNow;
endTime_ = value();
return writeNow();
}
void Foam::Time::writeOnce()
{
writeOnce_ = true;
}
// ************************************************************************* //