ENH: improvements to Time

- expose the names of write and stopAt controls for reuse elsewhere and
  provide a stopAtControls enum for 'unknown'

- track the requested number of sub-cycles (was previously a bool)
This commit is contained in:
Mark Olesen 2017-11-28 10:11:06 +01:00
parent fab9fb4332
commit ca5b0dcbaa
8 changed files with 205 additions and 132 deletions

View File

@ -112,10 +112,10 @@ class subCycle
// Private Member Functions
//- Disallow default bitwise copy construct
subCycle(const subCycle<GeometricField>&);
subCycle(const subCycle<GeometricField>&) = delete;
//- Disallow default bitwise assignment
void operator=(const subCycle<GeometricField>&);
void operator=(const subCycle<GeometricField>&) = delete;
public:
@ -123,10 +123,10 @@ public:
// Constructors
//- Construct field and number of sub-cycles
subCycle(GeometricField& gf, const label nSubCycles)
subCycle(GeometricField& gf, const label nCycles)
:
subCycleField<GeometricField>(gf),
subCycleTime(const_cast<Time&>(gf.time()), nSubCycles)
subCycleTime(const_cast<Time&>(gf.time()), nCycles)
{
// Update the field time index to correspond to the sub-cycle time
this->updateTimeIndex();

View File

@ -44,12 +44,14 @@ const Foam::Enum
<
Foam::Time::stopAtControls
>
Foam::Time::stopAtControlNames_
Foam::Time::stopAtControlNames
{
{ stopAtControls::saEndTime, "endTime" },
{ stopAtControls::saNoWriteNow, "noWriteNow" },
{ stopAtControls::saWriteNow, "writeNow" },
{ stopAtControls::saNextWrite, "nextWrite" },
// NOTE: stopAtControls::saUnknown is left untabulated here so that it can
// be used as fallback value to flag unknown settings
};
@ -57,7 +59,7 @@ const Foam::Enum
<
Foam::Time::writeControls
>
Foam::Time::writeControlNames_
Foam::Time::writeControlNames
{
{ writeControls::wcTimeStep, "timeStep" },
{ writeControls::wcRunTime, "runTime" },
@ -433,8 +435,8 @@ Foam::Time::Time
writeControl_(wcTimeStep),
writeInterval_(GREAT),
purgeWrite_(0),
subCycling_(0),
writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this),
@ -502,8 +504,8 @@ Foam::Time::Time
writeControl_(wcTimeStep),
writeInterval_(GREAT),
purgeWrite_(0),
subCycling_(0),
writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this),
@ -581,8 +583,8 @@ Foam::Time::Time
writeControl_(wcTimeStep),
writeInterval_(GREAT),
purgeWrite_(0),
subCycling_(0),
writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this),
@ -651,9 +653,8 @@ Foam::Time::Time
writeControl_(wcTimeStep),
writeInterval_(GREAT),
purgeWrite_(0),
subCycling_(0),
writeOnce_(false),
subCycling_(false),
writeFormat_(IOstream::ASCII),
writeVersion_(IOstream::currentVersion),
writeCompression_(IOstream::UNCOMPRESSED),
@ -825,6 +826,12 @@ Foam::dimensionedScalar Foam::Time::endTime() const
}
Foam::Time::stopAtControls Foam::Time::stopAt() const
{
return stopAt_;
}
bool Foam::Time::run() const
{
deleteDemandDrivenData(loopProfiling_);
@ -913,20 +920,23 @@ bool Foam::Time::end() const
}
bool Foam::Time::stopAt(const stopAtControls sa) const
bool Foam::Time::stopAt(const stopAtControls stopCtrl) const
{
const bool changed = (stopAt_ != sa);
stopAt_ = sa;
if (stopCtrl == stopAtControls::saUnknown)
{
return false;
}
// adjust endTime
if (sa == saEndTime)
const bool changed = (stopAt_ != stopCtrl);
stopAt_ = stopCtrl;
endTime_ = GREAT;
// Adjust endTime
if (stopCtrl == stopAtControls::saEndTime)
{
controlDict_.lookup("endTime") >> endTime_;
}
else
{
endTime_ = GREAT;
}
return changed;
}
@ -1018,26 +1028,41 @@ void Foam::Time::setDeltaT(const scalar deltaT, const bool adjust)
Foam::TimeState Foam::Time::subCycle(const label nSubCycles)
{
subCycling_ = true;
prevTimeState_.reset(new TimeState(*this));
prevTimeState_.set(new TimeState(*this)); // Fatal if already set
setTime(*this - deltaT(), (timeIndex() - 1)*nSubCycles);
deltaT_ /= nSubCycles;
deltaT0_ /= nSubCycles;
deltaTSave_ = deltaT0_;
subCycling_ = nSubCycles;
return prevTimeState();
}
void Foam::Time::subCycleIndex(const label index)
{
// Only permit adjustment if sub-cycling was already active
// and if the index is valid (positive, non-zero).
// This avoids potential mixups for deleting.
if (subCycling_ && index > 0)
{
subCycling_ = index;
}
}
void Foam::Time::endSubCycle()
{
if (subCycling_)
{
subCycling_ = false;
TimeState::operator=(prevTimeState());
prevTimeState_.clear();
}
subCycling_ = 0;
}
@ -1113,7 +1138,7 @@ Foam::Time& Foam::Time::operator++()
case wcRunTime:
case wcAdjustableRunTime:
{
label writeIndex = label
const label writeIndex = label
(
((value() - startTime_) + 0.5*deltaT_)
/ writeInterval_
@ -1129,7 +1154,7 @@ Foam::Time& Foam::Time::operator++()
case wcCpuTime:
{
label writeIndex = label
const label writeIndex = label
(
returnReduce(elapsedCpuTime(), maxOp<double>())
/ writeInterval_
@ -1144,7 +1169,7 @@ Foam::Time& Foam::Time::operator++()
case wcClockTime:
{
label writeIndex = label
const label writeIndex = label
(
returnReduce(label(elapsedClockTime()), maxOp<label>())
/ writeInterval_

View File

@ -75,6 +75,47 @@ class Time
public objectRegistry,
public TimeState
{
public:
//- Write control options
enum writeControls
{
wcTimeStep, //!< "timeStep"
wcRunTime, //!< "runTime"
wcAdjustableRunTime, //!< "adjustableRunTime"
wcClockTime, //!< "clockTime"
wcCpuTime //!< "cpuTime"
};
//- Stop-run control options, which are primarily used when
//- altering the stopAt condition.
enum stopAtControls
{
saEndTime, //!< Stop when Time reaches prescribed endTime
saNoWriteNow, //!< Adjust endTime to stop immediately w/o writing
saWriteNow, //!< adjust endTime to stop immediately w/ writing
saNextWrite, //!< stop at the next data write interval
saUnknown //!< Dummy no-op. Do not change current value.
};
//- Supported time directory name formats
enum fmtflags
{
general = 0, //!< default float notation
fixed = ios_base::fixed, //!< fixed-point notation
scientific = ios_base::scientific //!< scientific notation
};
//- Names for writeControls
static const Enum<writeControls> writeControlNames;
//- Names for stopAtControls
static const Enum<stopAtControls> stopAtControlNames;
private:
// Private data
//- Profiling trigger for time-loop (for run, loop)
@ -88,36 +129,6 @@ class Time
unwatchedIOdictionary controlDict_;
public:
//- Write control options
enum writeControls
{
wcTimeStep,
wcRunTime,
wcAdjustableRunTime,
wcClockTime,
wcCpuTime
};
//- Stop-run control options
enum stopAtControls
{
saEndTime, //!< stop when Time reaches the prescribed endTime
saNoWriteNow, //!< set endTime to stop immediately w/o writing
saWriteNow, //!< set endTime to stop immediately w/ writing
saNextWrite //!< stop the next time data are written
};
//- Supported time directory name formats
enum fmtflags
{
general = 0,
fixed = ios_base::fixed,
scientific = ios_base::scientific
};
protected:
// Protected data
@ -126,34 +137,31 @@ protected:
scalar startTime_;
mutable scalar endTime_;
static const Enum<stopAtControls> stopAtControlNames_;
mutable stopAtControls stopAt_;
static const Enum<writeControls> writeControlNames_;
writeControls writeControl_;
scalar writeInterval_;
label purgeWrite_;
mutable FIFOStack<word> previousWriteTimes_;
//- The total number of sub-cycles, the current sub-cycle index,
//- or 0 if time is not being sub-cycled
label subCycling_;
// One-shot writing
bool writeOnce_;
//- Is the time currently being sub-cycled?
bool subCycling_;
//- If time is being sub-cycled this is the previous TimeState
autoPtr<TimeState> prevTimeState_;
//- Signal handler for one-shot writing upon signal
sigWriteNow sigWriteNow_;
// Signal handlers for writing
//- Enable one-shot writing upon signal
sigWriteNow sigWriteNow_;
//- Enable write and clean exit upon signal
sigStopAtWriteNow sigStopAtWriteNow_;
//- Signal handler for write and clean exit upon signal
sigStopAtWriteNow sigStopAtWriteNow_;
//- Time directory name format
@ -165,6 +173,7 @@ protected:
//- Maximum time directory name precision
static const int maxPrecision_;
//- Adjust the time step so that writing occurs at the specified time
void adjustDeltaT();
@ -179,7 +188,7 @@ protected:
virtual void readDict();
//- Find IOobject in the objectPath
static bool exists(IOobject&);
static bool exists(IOobject& io);
private:
@ -423,6 +432,9 @@ public:
//- Return end time
virtual dimensionedScalar endTime() const;
//- Return the stop control information
virtual stopAtControls stopAt() const;
//- Return the list of function objects
const functionObjectList& functionObjects() const
{
@ -441,8 +453,12 @@ public:
return libs_;
}
//- Return true if time currently being sub-cycled, otherwise false
bool subCycling() const
//- Zero (tests as false) if time is not being sub-cycled,
//- otherwise the current sub-cycle index or the total number of
//- sub-cycles.
// The interpretation of non-zero values is dependent on the
// routine.
label subCycling() const
{
return subCycling_;
}
@ -498,10 +514,13 @@ public:
// Edit
//- Adjust the current stopAtControl. Note that this value
// only persists until the next time the dictionary is read.
// Return true if the stopAtControl changed.
virtual bool stopAt(const stopAtControls sa) const;
//- Adjust the current stopAtControl.
// \param stopCtrl the new stop control, whereby
// stopAtControls::saUnknown is treated as a no-op.
// \note this value only persists until the next time the
// dictionary is read.
// \return true if the stopAt() value was changed.
virtual bool stopAt(const stopAtControls stopCtrl) const;
//- Reset the time and time-index to those of the given time
virtual void setTime(const Time& t);
@ -542,6 +561,13 @@ public:
//- Set time to sub-cycle for the given number of steps
virtual TimeState subCycle(const label nSubCycles);
//- Adjust the reported sub-cycle index.
// \param index is the sub-cycle index.
// This index is ignored sub-cycling was
// not already registered, or if the index is zero or
// negative.
virtual void subCycleIndex(const label index);
//- Reset time after sub-cycling back to previous TimeState
virtual void endSubCycle();

View File

@ -240,7 +240,7 @@ void Foam::Time::readDict()
if (controlDict_.found("writeControl"))
{
writeControl_ = writeControlNames_.lookup
writeControl_ = writeControlNames.lookup
(
"writeControl",
controlDict_
@ -328,7 +328,7 @@ void Foam::Time::readDict()
// if nothing is specified, the endTime is zero
if (controlDict_.found("stopAt"))
{
stopAt_ = stopAtControlNames_.lookup("stopAt", controlDict_);
stopAt_ = stopAtControlNames.lookup("stopAt", controlDict_);
if (stopAt_ == saEndTime)
{
@ -439,10 +439,8 @@ bool Foam::Time::read()
return true;
}
else
{
return false;
}
return false;
}
@ -567,10 +565,8 @@ bool Foam::Time::writeObject
return writeOK;
}
else
{
return false;
}
return false;
}

View File

@ -27,13 +27,14 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::subCycleTime::subCycleTime(Time& t, const label nSubCycles)
Foam::subCycleTime::subCycleTime(Time& runTime, const label nCycles)
:
time_(t),
nSubCycles_(nSubCycles),
subCycleIndex_(0)
time_(runTime),
index_(0),
total_(nCycles)
{
time_.subCycle(nSubCycles_);
// Could avoid 0 or 1 nCycles here on construction
time_.subCycle(nCycles);
}
@ -47,15 +48,38 @@ Foam::subCycleTime::~subCycleTime()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::subCycleTime::status() const
{
return (index_ <= total_);
}
bool Foam::subCycleTime::end() const
{
return subCycleIndex_ > nSubCycles_;
return (index_ > total_); // or !(status())
}
void Foam::subCycleTime::endSubCycle()
{
time_.endSubCycle();
// If called manually, ensure status() will return false
index_ = total_ + 1;
}
bool Foam::subCycleTime::loop()
{
const bool active = status();
if (active)
{
operator++();
}
return active;
}
@ -63,8 +87,12 @@ void Foam::subCycleTime::endSubCycle()
Foam::subCycleTime& Foam::subCycleTime::operator++()
{
time_++;
subCycleIndex_++;
++time_;
++index_;
// Register index change with Time, in case someone wants this information
time_.subCycleIndex(index_);
return *this;
}

View File

@ -50,17 +50,22 @@ class subCycleTime
{
// Private data
//- Reference to the underlying time
Time& time_;
label nSubCycles_;
label subCycleIndex_;
//- Current index in the sub-cycle
label index_;
//- Total number of cycles in the sub-cycle
label total_;
public:
// Constructors
//- Construct from original time and number of sub-cycles
subCycleTime(Time&, const label nSubCycles);
//- Construct referencing the original time and number of sub-cycles
subCycleTime(Time& runTime, const label nCycle);
//- Destructor
@ -69,23 +74,36 @@ public:
// Member functions
//- Return the current sub-cycle index
inline label index() const
{
return index_;
}
//- Return the total number of sub-cycles
inline label nSubCycles() const
{
return total_;
}
//- True if the sub-cycle is active.
bool status() const;
//- Return true if the number of sub-cycles has been reached
bool end() const;
//- End the sub-cycling and reset the time-state
void endSubCycle();
//- Return the total number of sub-cycles
label nSubCycles() const
{
return nSubCycles_;
}
//- Return the current sub-cycle index
label index() const
{
return subCycleIndex_;
}
//- True if looping is active, increments the index.
// Example usage,
// \code
// while (subcycle.loop())
// {
// solve;
// }
// \endcode
bool loop();
// Member operators
@ -93,7 +111,7 @@ public:
//- Prefix increment
subCycleTime& operator++();
//- Postfix increment
//- Postfix increment, this is identical to the prefix increment
subCycleTime& operator++(int);
};

View File

@ -49,18 +49,6 @@ namespace functionObjects
}
const Foam::Enum
<
Foam::Time::stopAtControls
>
Foam::functionObjects::abort::actionNames_
{
{ Time::stopAtControls::saNoWriteNow, "noWriteNow" },
{ Time::stopAtControls::saWriteNow, "writeNow" },
{ Time::stopAtControls::saNextWrite, "nextWrite" },
};
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
// file-scope
@ -126,12 +114,6 @@ Foam::functionObjects::abort::abort
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::abort::~abort()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::abort::read(const dictionary& dict)
@ -145,7 +127,7 @@ bool Foam::functionObjects::abort::read(const dictionary& dict)
const auto oldAction = action_;
action_ = actionNames_.lookupOrDefault
action_ = Time::stopAtControlNames.lookupOrDefault
(
"action",
dict,

View File

@ -30,6 +30,7 @@ Group
Description
Watches for presence of the named file in the $FOAM_CASE directory
and aborts the calculation if it is present.
The presence of the abort file is only checked on the master process.
Currently the following action types are supported:
@ -73,9 +74,6 @@ class abort
{
// Private data
//- A subset of Time stopAtControls
static const Enum<Time::stopAtControls> actionNames_;
//- Reference to the Time
const Time& time_;
@ -116,7 +114,7 @@ public:
//- Destructor
virtual ~abort();
virtual ~abort() = default;
// Member Functions