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

View File

@ -44,12 +44,14 @@ const Foam::Enum
< <
Foam::Time::stopAtControls Foam::Time::stopAtControls
> >
Foam::Time::stopAtControlNames_ Foam::Time::stopAtControlNames
{ {
{ stopAtControls::saEndTime, "endTime" }, { stopAtControls::saEndTime, "endTime" },
{ stopAtControls::saNoWriteNow, "noWriteNow" }, { stopAtControls::saNoWriteNow, "noWriteNow" },
{ stopAtControls::saWriteNow, "writeNow" }, { stopAtControls::saWriteNow, "writeNow" },
{ stopAtControls::saNextWrite, "nextWrite" }, { 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::writeControls
> >
Foam::Time::writeControlNames_ Foam::Time::writeControlNames
{ {
{ writeControls::wcTimeStep, "timeStep" }, { writeControls::wcTimeStep, "timeStep" },
{ writeControls::wcRunTime, "runTime" }, { writeControls::wcRunTime, "runTime" },
@ -433,8 +435,8 @@ Foam::Time::Time
writeControl_(wcTimeStep), writeControl_(wcTimeStep),
writeInterval_(GREAT), writeInterval_(GREAT),
purgeWrite_(0), purgeWrite_(0),
subCycling_(0),
writeOnce_(false), writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this), sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this), sigStopAtWriteNow_(true, *this),
@ -502,8 +504,8 @@ Foam::Time::Time
writeControl_(wcTimeStep), writeControl_(wcTimeStep),
writeInterval_(GREAT), writeInterval_(GREAT),
purgeWrite_(0), purgeWrite_(0),
subCycling_(0),
writeOnce_(false), writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this), sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this), sigStopAtWriteNow_(true, *this),
@ -581,8 +583,8 @@ Foam::Time::Time
writeControl_(wcTimeStep), writeControl_(wcTimeStep),
writeInterval_(GREAT), writeInterval_(GREAT),
purgeWrite_(0), purgeWrite_(0),
subCycling_(0),
writeOnce_(false), writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this), sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this), sigStopAtWriteNow_(true, *this),
@ -651,9 +653,8 @@ Foam::Time::Time
writeControl_(wcTimeStep), writeControl_(wcTimeStep),
writeInterval_(GREAT), writeInterval_(GREAT),
purgeWrite_(0), purgeWrite_(0),
subCycling_(0),
writeOnce_(false), writeOnce_(false),
subCycling_(false),
writeFormat_(IOstream::ASCII), writeFormat_(IOstream::ASCII),
writeVersion_(IOstream::currentVersion), writeVersion_(IOstream::currentVersion),
writeCompression_(IOstream::UNCOMPRESSED), 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 bool Foam::Time::run() const
{ {
deleteDemandDrivenData(loopProfiling_); 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); if (stopCtrl == stopAtControls::saUnknown)
stopAt_ = sa; {
return false;
}
// adjust endTime const bool changed = (stopAt_ != stopCtrl);
if (sa == saEndTime) stopAt_ = stopCtrl;
endTime_ = GREAT;
// Adjust endTime
if (stopCtrl == stopAtControls::saEndTime)
{ {
controlDict_.lookup("endTime") >> endTime_; controlDict_.lookup("endTime") >> endTime_;
} }
else
{
endTime_ = GREAT;
}
return changed; return changed;
} }
@ -1018,26 +1028,41 @@ void Foam::Time::setDeltaT(const scalar deltaT, const bool adjust)
Foam::TimeState Foam::Time::subCycle(const label nSubCycles) Foam::TimeState Foam::Time::subCycle(const label nSubCycles)
{ {
subCycling_ = true; prevTimeState_.set(new TimeState(*this)); // Fatal if already set
prevTimeState_.reset(new TimeState(*this));
setTime(*this - deltaT(), (timeIndex() - 1)*nSubCycles); setTime(*this - deltaT(), (timeIndex() - 1)*nSubCycles);
deltaT_ /= nSubCycles; deltaT_ /= nSubCycles;
deltaT0_ /= nSubCycles; deltaT0_ /= nSubCycles;
deltaTSave_ = deltaT0_; deltaTSave_ = deltaT0_;
subCycling_ = nSubCycles;
return prevTimeState(); 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() void Foam::Time::endSubCycle()
{ {
if (subCycling_) if (subCycling_)
{ {
subCycling_ = false;
TimeState::operator=(prevTimeState()); TimeState::operator=(prevTimeState());
prevTimeState_.clear(); prevTimeState_.clear();
} }
subCycling_ = 0;
} }
@ -1113,7 +1138,7 @@ Foam::Time& Foam::Time::operator++()
case wcRunTime: case wcRunTime:
case wcAdjustableRunTime: case wcAdjustableRunTime:
{ {
label writeIndex = label const label writeIndex = label
( (
((value() - startTime_) + 0.5*deltaT_) ((value() - startTime_) + 0.5*deltaT_)
/ writeInterval_ / writeInterval_
@ -1129,7 +1154,7 @@ Foam::Time& Foam::Time::operator++()
case wcCpuTime: case wcCpuTime:
{ {
label writeIndex = label const label writeIndex = label
( (
returnReduce(elapsedCpuTime(), maxOp<double>()) returnReduce(elapsedCpuTime(), maxOp<double>())
/ writeInterval_ / writeInterval_
@ -1144,7 +1169,7 @@ Foam::Time& Foam::Time::operator++()
case wcClockTime: case wcClockTime:
{ {
label writeIndex = label const label writeIndex = label
( (
returnReduce(label(elapsedClockTime()), maxOp<label>()) returnReduce(label(elapsedClockTime()), maxOp<label>())
/ writeInterval_ / writeInterval_

View File

@ -75,6 +75,47 @@ class Time
public objectRegistry, public objectRegistry,
public TimeState 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 // Private data
//- Profiling trigger for time-loop (for run, loop) //- Profiling trigger for time-loop (for run, loop)
@ -88,36 +129,6 @@ class Time
unwatchedIOdictionary controlDict_; 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:
// Protected data // Protected data
@ -126,34 +137,31 @@ protected:
scalar startTime_; scalar startTime_;
mutable scalar endTime_; mutable scalar endTime_;
static const Enum<stopAtControls> stopAtControlNames_;
mutable stopAtControls stopAt_; mutable stopAtControls stopAt_;
static const Enum<writeControls> writeControlNames_;
writeControls writeControl_; writeControls writeControl_;
scalar writeInterval_; scalar writeInterval_;
label purgeWrite_; label purgeWrite_;
mutable FIFOStack<word> previousWriteTimes_; 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 // One-shot writing
bool writeOnce_; bool writeOnce_;
//- Is the time currently being sub-cycled?
bool subCycling_;
//- If time is being sub-cycled this is the previous TimeState //- If time is being sub-cycled this is the previous TimeState
autoPtr<TimeState> prevTimeState_; autoPtr<TimeState> prevTimeState_;
//- Signal handler for one-shot writing upon signal
sigWriteNow sigWriteNow_;
// Signal handlers for writing //- Signal handler for write and clean exit upon signal
sigStopAtWriteNow sigStopAtWriteNow_;
//- Enable one-shot writing upon signal
sigWriteNow sigWriteNow_;
//- Enable write and clean exit upon signal
sigStopAtWriteNow sigStopAtWriteNow_;
//- Time directory name format //- Time directory name format
@ -165,6 +173,7 @@ protected:
//- Maximum time directory name precision //- Maximum time directory name precision
static const int maxPrecision_; static const int maxPrecision_;
//- Adjust the time step so that writing occurs at the specified time //- Adjust the time step so that writing occurs at the specified time
void adjustDeltaT(); void adjustDeltaT();
@ -179,7 +188,7 @@ protected:
virtual void readDict(); virtual void readDict();
//- Find IOobject in the objectPath //- Find IOobject in the objectPath
static bool exists(IOobject&); static bool exists(IOobject& io);
private: private:
@ -423,6 +432,9 @@ public:
//- Return end time //- Return end time
virtual dimensionedScalar endTime() const; virtual dimensionedScalar endTime() const;
//- Return the stop control information
virtual stopAtControls stopAt() const;
//- Return the list of function objects //- Return the list of function objects
const functionObjectList& functionObjects() const const functionObjectList& functionObjects() const
{ {
@ -441,8 +453,12 @@ public:
return libs_; return libs_;
} }
//- Return true if time currently being sub-cycled, otherwise false //- Zero (tests as false) if time is not being sub-cycled,
bool subCycling() const //- 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_; return subCycling_;
} }
@ -498,10 +514,13 @@ public:
// Edit // Edit
//- Adjust the current stopAtControl. Note that this value //- Adjust the current stopAtControl.
// only persists until the next time the dictionary is read. // \param stopCtrl the new stop control, whereby
// Return true if the stopAtControl changed. // stopAtControls::saUnknown is treated as a no-op.
virtual bool stopAt(const stopAtControls sa) const; // \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 //- Reset the time and time-index to those of the given time
virtual void setTime(const Time& t); virtual void setTime(const Time& t);
@ -542,6 +561,13 @@ public:
//- Set time to sub-cycle for the given number of steps //- Set time to sub-cycle for the given number of steps
virtual TimeState subCycle(const label nSubCycles); 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 //- Reset time after sub-cycling back to previous TimeState
virtual void endSubCycle(); virtual void endSubCycle();

View File

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

View File

@ -27,13 +27,14 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::subCycleTime::subCycleTime(Time& t, const label nSubCycles) Foam::subCycleTime::subCycleTime(Time& runTime, const label nCycles)
: :
time_(t), time_(runTime),
nSubCycles_(nSubCycles), index_(0),
subCycleIndex_(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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::subCycleTime::status() const
{
return (index_ <= total_);
}
bool Foam::subCycleTime::end() const bool Foam::subCycleTime::end() const
{ {
return subCycleIndex_ > nSubCycles_; return (index_ > total_); // or !(status())
} }
void Foam::subCycleTime::endSubCycle() void Foam::subCycleTime::endSubCycle()
{ {
time_.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++() Foam::subCycleTime& Foam::subCycleTime::operator++()
{ {
time_++; ++time_;
subCycleIndex_++; ++index_;
// Register index change with Time, in case someone wants this information
time_.subCycleIndex(index_);
return *this; return *this;
} }

View File

@ -50,17 +50,22 @@ class subCycleTime
{ {
// Private data // Private data
//- Reference to the underlying time
Time& time_; Time& time_;
label nSubCycles_; //- Current index in the sub-cycle
label subCycleIndex_; label index_;
//- Total number of cycles in the sub-cycle
label total_;
public: public:
// Constructors // Constructors
//- Construct from original time and number of sub-cycles //- Construct referencing the original time and number of sub-cycles
subCycleTime(Time&, const label nSubCycles); subCycleTime(Time& runTime, const label nCycle);
//- Destructor //- Destructor
@ -69,23 +74,36 @@ public:
// Member functions // 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 //- Return true if the number of sub-cycles has been reached
bool end() const; bool end() const;
//- End the sub-cycling and reset the time-state //- End the sub-cycling and reset the time-state
void endSubCycle(); void endSubCycle();
//- Return the total number of sub-cycles //- True if looping is active, increments the index.
label nSubCycles() const // Example usage,
{ // \code
return nSubCycles_; // while (subcycle.loop())
} // {
// solve;
//- Return the current sub-cycle index // }
label index() const // \endcode
{ bool loop();
return subCycleIndex_;
}
// Member operators // Member operators
@ -93,7 +111,7 @@ public:
//- Prefix increment //- Prefix increment
subCycleTime& operator++(); subCycleTime& operator++();
//- Postfix increment //- Postfix increment, this is identical to the prefix increment
subCycleTime& operator++(int); 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 * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
// file-scope // file-scope
@ -126,12 +114,6 @@ Foam::functionObjects::abort::abort
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::abort::~abort()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::abort::read(const dictionary& dict) bool Foam::functionObjects::abort::read(const dictionary& dict)
@ -145,7 +127,7 @@ bool Foam::functionObjects::abort::read(const dictionary& dict)
const auto oldAction = action_; const auto oldAction = action_;
action_ = actionNames_.lookupOrDefault action_ = Time::stopAtControlNames.lookupOrDefault
( (
"action", "action",
dict, dict,

View File

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