mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-externalCoupled' into 'develop'
preliminary improvements for externalCoupled See merge request Development/OpenFOAM-plus!175
This commit is contained in:
@ -309,7 +309,7 @@ int main(int argc, char *argv[])
|
||||
if
|
||||
(
|
||||
matchName != "perfect"
|
||||
&& !slidingInterface::typeOfMatchNames.hasEnum(matchName)
|
||||
&& !slidingInterface::typeOfMatchNames.found(matchName)
|
||||
)
|
||||
{
|
||||
Info<< "Error: unknown match type - " << matchName
|
||||
|
||||
@ -229,7 +229,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
|
||||
word patchMapMethod;
|
||||
if (meshToMesh::interpolationMethodNames_.hasEnum(mapMethod))
|
||||
if (meshToMesh::interpolationMethodNames_.found(mapMethod))
|
||||
{
|
||||
// Lookup corresponding AMI method
|
||||
meshToMesh::interpolationMethod method =
|
||||
|
||||
@ -1577,7 +1577,7 @@ int main(int argc, char *argv[])
|
||||
{ booleanSurface::DIFFERENCE, "difference" }
|
||||
};
|
||||
|
||||
if (!validActions.hasEnum(action))
|
||||
if (!validActions.found(action))
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unsupported action " << action << endl
|
||||
|
||||
@ -284,6 +284,7 @@ $(Time)/Time.C
|
||||
$(Time)/TimeIO.C
|
||||
$(Time)/findTimes.C
|
||||
$(Time)/subCycleTime.C
|
||||
$(Time)/subLoopTime.C
|
||||
$(Time)/findInstance.C
|
||||
$(Time)/timeSelector.C
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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_
|
||||
@ -1201,7 +1226,7 @@ Foam::Time& Foam::Time::operator++()
|
||||
// reinterpretation of the word
|
||||
if
|
||||
(
|
||||
readScalar(dimensionedScalar::name().c_str(), timeNameValue)
|
||||
readScalar(dimensionedScalar::name(), timeNameValue)
|
||||
&& (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
|
||||
)
|
||||
{
|
||||
@ -1209,7 +1234,7 @@ Foam::Time& Foam::Time::operator++()
|
||||
while
|
||||
(
|
||||
precision_ < maxPrecision_
|
||||
&& readScalar(dimensionedScalar::name().c_str(), timeNameValue)
|
||||
&& readScalar(dimensionedScalar::name(), timeNameValue)
|
||||
&& (mag(timeNameValue - oldTimeValue - userDeltaT) > timeTol)
|
||||
)
|
||||
{
|
||||
@ -1242,7 +1267,7 @@ Foam::Time& Foam::Time::operator++()
|
||||
scalar oldTimeNameValue = -VGREAT;
|
||||
if
|
||||
(
|
||||
readScalar(oldTimeName.c_str(), oldTimeNameValue)
|
||||
readScalar(oldTimeName, oldTimeNameValue)
|
||||
&& (
|
||||
sign(timeNameValue - oldTimeNameValue)
|
||||
!= sign(deltaT_)
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
85
src/OpenFOAM/db/Time/subLoopTime.C
Normal file
85
src/OpenFOAM/db/Time/subLoopTime.C
Normal file
@ -0,0 +1,85 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||
\\/ 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 "subLoopTime.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::subLoopTime::subLoopTime(Time& runTime, const label nCycles)
|
||||
:
|
||||
time_(runTime),
|
||||
index_(0),
|
||||
total_(nCycles)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::subLoopTime::~subLoopTime()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::subLoopTime::status() const
|
||||
{
|
||||
return (index_ < total_);
|
||||
}
|
||||
|
||||
|
||||
void Foam::subLoopTime::stop()
|
||||
{
|
||||
// If called manually, ensure status() will return false
|
||||
index_ = total_ + 1;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::subLoopTime::loop()
|
||||
{
|
||||
const bool active = (index_ < total_); // as per status()
|
||||
|
||||
if (active)
|
||||
{
|
||||
operator++();
|
||||
}
|
||||
else if (index_)
|
||||
{
|
||||
// Not active, the loop condition has now exiting on the last subloop
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
|
||||
Foam::subLoopTime& Foam::subLoopTime::operator++()
|
||||
{
|
||||
++index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
137
src/OpenFOAM/db/Time/subLoopTime.H
Normal file
137
src/OpenFOAM/db/Time/subLoopTime.H
Normal file
@ -0,0 +1,137 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
||||
\\/ 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/>.
|
||||
|
||||
Class
|
||||
Foam::subLoopTime
|
||||
|
||||
Description
|
||||
A class for managing sub-loops referencing Time.
|
||||
|
||||
SourceFiles
|
||||
subLoopTime.C
|
||||
|
||||
SeeAlso
|
||||
subCycleTime
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef subLoopTime_H
|
||||
#define subLoopTime_H
|
||||
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class subLoopTime Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class subLoopTime
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
subLoopTime(const subLoopTime&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const subLoopTime&) = delete;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
Time& time_;
|
||||
|
||||
//- The current sub-cycle index
|
||||
label index_;
|
||||
|
||||
//- The total number of cycles in the sub-cycle
|
||||
label total_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from time with fixed number of cycles
|
||||
// \param runTime the top-level time
|
||||
// \param nCycles the number of times to loop
|
||||
subLoopTime(Time& runTime, const label nCycles);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~subLoopTime();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The current cycle index
|
||||
inline label index() const
|
||||
{
|
||||
return index_;
|
||||
}
|
||||
|
||||
//- The total number of cycles
|
||||
inline label nCycles() const
|
||||
{
|
||||
return total_;
|
||||
}
|
||||
|
||||
//- Return true if looping is active
|
||||
bool status() const;
|
||||
|
||||
//- Force terminate the loop
|
||||
void stop();
|
||||
|
||||
//- True if looping is active, increments the index.
|
||||
// Example usage,
|
||||
// \code
|
||||
// while (control.loop())
|
||||
// {
|
||||
// solve;
|
||||
// }
|
||||
// \endcode
|
||||
bool loop();
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Prefix increment
|
||||
subLoopTime& operator++();
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -117,7 +117,7 @@ bool Foam::functionEntries::inputMode::execute
|
||||
const word modeName(is);
|
||||
|
||||
// Behaviour like Enum lookupOrFailsafe()
|
||||
if (selectableNames.hasEnum(modeName))
|
||||
if (selectableNames.found(modeName))
|
||||
{
|
||||
entry::globalInputMode = selectableNames[modeName];
|
||||
}
|
||||
|
||||
@ -105,12 +105,8 @@ Foam::instantList Foam::fileOperation::sortTimes
|
||||
// Read and parse all the entries in the directory
|
||||
forAll(dirEntries, i)
|
||||
{
|
||||
//IStringStream timeStream(dirEntries[i]);
|
||||
//token timeToken(timeStream);
|
||||
|
||||
//if (timeToken.isNumber() && timeStream.eof())
|
||||
scalar timeValue;
|
||||
if (readScalar(dirEntries[i].c_str(), timeValue))
|
||||
if (readScalar(dirEntries[i], timeValue))
|
||||
{
|
||||
Times[nTimes].value() = timeValue;
|
||||
Times[nTimes].name() = dirEntries[i];
|
||||
|
||||
@ -291,25 +291,24 @@ Foam::fileOperations::masterUncollatedFileOperation::splitProcessorPath
|
||||
local = objectPath.substr(pos+9);
|
||||
}
|
||||
|
||||
label proci;
|
||||
|
||||
pos = local.find('/');
|
||||
if (pos == string::npos)
|
||||
{
|
||||
// processorXXX without local
|
||||
label proci;
|
||||
if (Foam::read(local.c_str(), proci))
|
||||
if (Foam::read(local, proci))
|
||||
{
|
||||
local.clear();
|
||||
return proci;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
string procName(local.substr(0, pos));
|
||||
label proci;
|
||||
if (Foam::read(procName.c_str(), proci))
|
||||
else if (Foam::read(local.substr(0, pos), proci))
|
||||
{
|
||||
local = local.substr(pos+1);
|
||||
return proci;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -63,10 +63,10 @@ class data
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
data(const data&);
|
||||
data(const data&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const data&);
|
||||
void operator=(const data&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
@ -83,27 +83,24 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
//- Return the dictionary of solver performance data which
|
||||
//- includes initial and final residuals for convergence checking
|
||||
const dictionary& solverPerformanceDict() const;
|
||||
|
||||
//- Return the dictionary of solver performance data
|
||||
// which includes initial and final residuals for convergence
|
||||
// checking
|
||||
const dictionary& solverPerformanceDict() const;
|
||||
//- Add/set the solverPerformance entry for the named field
|
||||
template<class Type>
|
||||
void setSolverPerformance
|
||||
(
|
||||
const word& name,
|
||||
const SolverPerformance<Type>& sp
|
||||
) const;
|
||||
|
||||
//- Add/set the solverPerformance entry for the named field
|
||||
template<class Type>
|
||||
void setSolverPerformance
|
||||
(
|
||||
const word& name,
|
||||
const SolverPerformance<Type>&
|
||||
) const;
|
||||
|
||||
//- Add/set the solverPerformance entry, using its fieldName
|
||||
template<class Type>
|
||||
void setSolverPerformance
|
||||
(
|
||||
const SolverPerformance<Type>&
|
||||
) const;
|
||||
//- Add/set the solverPerformance entry, using its fieldName
|
||||
template<class Type>
|
||||
void setSolverPerformance
|
||||
(
|
||||
const SolverPerformance<Type>& sp
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -87,10 +87,8 @@ const Foam::word& Foam::Enum<EnumType>::getName(const EnumType e) const
|
||||
{
|
||||
return word::null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return names_[idx];
|
||||
}
|
||||
|
||||
return names_[idx];
|
||||
}
|
||||
|
||||
|
||||
@ -233,16 +231,14 @@ EnumType Foam::Enum<EnumType>::lookupOrFailsafe
|
||||
const word enumName(dict.lookup(key));
|
||||
const label idx = getIndex(enumName);
|
||||
|
||||
if (idx < 0)
|
||||
{
|
||||
IOWarningInFunction(dict)
|
||||
<< "bad " << key <<" specifier " << enumName
|
||||
<< " using " << getName(deflt) << endl;
|
||||
}
|
||||
else
|
||||
if (idx >= 0)
|
||||
{
|
||||
return EnumType(values_[idx]);
|
||||
}
|
||||
|
||||
IOWarningInFunction(dict)
|
||||
<< "bad " << key <<" specifier " << enumName
|
||||
<< " using " << getName(deflt) << endl;
|
||||
}
|
||||
|
||||
return deflt;
|
||||
|
||||
@ -25,10 +25,11 @@ Class
|
||||
Foam::Enum
|
||||
|
||||
Description
|
||||
A Enum is a wrapper around a list of names/values that represent
|
||||
particular enumeration values.
|
||||
Enum is a wrapper around a list of names/values that represent particular
|
||||
enumeration values.
|
||||
|
||||
SourceFiles
|
||||
EnumI.H
|
||||
Enum.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -111,7 +112,7 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
// Access
|
||||
|
||||
//- The number of lookup names for the enumeration
|
||||
inline label size() const;
|
||||
@ -129,20 +130,28 @@ public:
|
||||
inline const List<int>& values() const;
|
||||
|
||||
|
||||
// Query
|
||||
// Query
|
||||
|
||||
//- Test if there is an enumeration corresponding to the given name.
|
||||
inline bool found(const word& enumName) const;
|
||||
|
||||
//- Test if there is a name corresponding to the given enumeration.
|
||||
inline bool found(const EnumType e) const;
|
||||
|
||||
//- Test if there is an enumeration corresponding to the given name.
|
||||
// \deprecated Use found() - for compatibility with NamedEnum
|
||||
inline bool hasEnum(const word& enumName) const;
|
||||
|
||||
//- Test if there is a name corresponding to the given enumeration.
|
||||
// \deprecated Use found() - for compatibility with NamedEnum
|
||||
inline bool hasName(const EnumType e) const;
|
||||
|
||||
|
||||
// Lookup
|
||||
// Lookup
|
||||
|
||||
//- Lookup the key in the dictionary and return the corresponding
|
||||
//- enumeration element based on its name.
|
||||
// Fatal if anything is incorrect.
|
||||
// FatalError if anything is incorrect.
|
||||
EnumType lookup
|
||||
(
|
||||
const word& key,
|
||||
@ -152,7 +161,7 @@ public:
|
||||
//- Find the key in the dictionary and return the corresponding
|
||||
//- enumeration element based on its name.
|
||||
// Return the default value if the key was not found in the dictionary.
|
||||
// Fatal if the enumerated name was incorrect.
|
||||
// FatalError if the enumerated name was incorrect.
|
||||
EnumType lookupOrDefault
|
||||
(
|
||||
const word& key,
|
||||
@ -173,7 +182,7 @@ public:
|
||||
) const;
|
||||
|
||||
|
||||
// IO
|
||||
// IO
|
||||
|
||||
//- Read a word from Istream and return the corresponding enumeration
|
||||
EnumType read(Istream& is) const;
|
||||
@ -193,13 +202,23 @@ public:
|
||||
// Member Operators
|
||||
|
||||
//- Return the enumeration corresponding to the given name
|
||||
// Fatal if the name cannot be found.
|
||||
inline const EnumType operator[](const word& name) const;
|
||||
// FatalError if the name is not found.
|
||||
// Identical to getEnum()
|
||||
inline EnumType operator[](const word& enumName) const;
|
||||
|
||||
//- Return the first name corresponding to the given enumeration.
|
||||
// Returns an empty word on failure.
|
||||
// Identical to getName()
|
||||
inline const word& operator[](const EnumType e) const;
|
||||
|
||||
//- Return the enumeration corresponding to the given name or deflt
|
||||
//- if the name is not found.
|
||||
inline EnumType operator()
|
||||
(
|
||||
const word& enumName,
|
||||
const EnumType deflt
|
||||
) const;
|
||||
|
||||
|
||||
// IOstream operators
|
||||
|
||||
|
||||
@ -53,6 +53,20 @@ inline const Foam::List<int>& Foam::Enum<EnumType>::values() const
|
||||
}
|
||||
|
||||
|
||||
template<class EnumType>
|
||||
inline bool Foam::Enum<EnumType>::found(const word& enumName) const
|
||||
{
|
||||
return getIndex(enumName) >= 0;
|
||||
}
|
||||
|
||||
|
||||
template<class EnumType>
|
||||
inline bool Foam::Enum<EnumType>::found(const EnumType e) const
|
||||
{
|
||||
return getIndex(e) >= 0;
|
||||
}
|
||||
|
||||
|
||||
template<class EnumType>
|
||||
inline bool Foam::Enum<EnumType>::hasEnum(const word& enumName) const
|
||||
{
|
||||
@ -81,12 +95,12 @@ inline Foam::Ostream& Foam::Enum<EnumType>::writeList
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class EnumType>
|
||||
inline const EnumType Foam::Enum<EnumType>::operator[]
|
||||
inline EnumType Foam::Enum<EnumType>::operator[]
|
||||
(
|
||||
const word& name
|
||||
const word& enumName
|
||||
) const
|
||||
{
|
||||
return getEnum(name);
|
||||
return getEnum(enumName);
|
||||
}
|
||||
|
||||
|
||||
@ -100,4 +114,22 @@ inline const Foam::word& Foam::Enum<EnumType>::operator[]
|
||||
}
|
||||
|
||||
|
||||
template<class EnumType>
|
||||
inline EnumType Foam::Enum<EnumType>::operator()
|
||||
(
|
||||
const word& enumName,
|
||||
const EnumType deflt
|
||||
) const
|
||||
{
|
||||
const label idx = getIndex(enumName);
|
||||
|
||||
if (idx >= 0)
|
||||
{
|
||||
return EnumType(values_[idx]);
|
||||
}
|
||||
|
||||
return deflt;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -176,7 +176,7 @@ bool Foam::UPstream::init(int& argc, char**& argv)
|
||||
int bufSize = 0;
|
||||
|
||||
const std::string str = Foam::getEnv("MPI_BUFFER_SIZE");
|
||||
if (str.empty() || !Foam::read(str.c_str(), bufSize) || bufSize <= 0)
|
||||
if (str.empty() || !Foam::read(str, bufSize) || bufSize <= 0)
|
||||
{
|
||||
bufSize = mpiBufferSize;
|
||||
}
|
||||
|
||||
@ -377,7 +377,7 @@ bool Foam::fileFormats::FIREMeshReader::readGeometry(const scalar scaleFactor)
|
||||
IOstream::streamFormat fmt = IOstream::ASCII;
|
||||
|
||||
const word ext = geometryFile_.ext();
|
||||
bool supported = FIRECore::file3dExtensions.hasEnum(ext);
|
||||
bool supported = FIRECore::file3dExtensions.found(ext);
|
||||
if (supported)
|
||||
{
|
||||
FIRECore::fileExt3d fireFileType = FIRECore::file3dExtensions[ext];
|
||||
|
||||
@ -278,7 +278,7 @@ bool Foam::fileFormats::FIREMeshWriter::write(const fileName& meshName) const
|
||||
{
|
||||
const word ext = baseName.ext();
|
||||
|
||||
if (FIRECore::file3dExtensions.hasEnum(ext))
|
||||
if (FIRECore::file3dExtensions.found(ext))
|
||||
{
|
||||
FIRECore::fileExt3d fireFileType = FIRECore::file3dExtensions[ext];
|
||||
if (fireFileType == FIRECore::fileExt3d::POLY_ASCII)
|
||||
|
||||
@ -40,17 +40,51 @@ namespace Foam
|
||||
Foam::word Foam::externalFileCoupler::lockName = "OpenFOAM";
|
||||
|
||||
|
||||
// file-scope
|
||||
// check file (must exist) for "status=done" content
|
||||
static bool checkIsDone(const std::string& lck)
|
||||
namespace Foam
|
||||
{
|
||||
std::string content;
|
||||
std::ifstream is(lck);
|
||||
is >> content;
|
||||
|
||||
return (content.find("done") != std::string::npos);
|
||||
// file-scope
|
||||
// Read file contents and return a stop control as follows:
|
||||
// - contains "done" (should actually be status=done, but we are generous) :
|
||||
// The master (OpenFOAM) has signalled that it is done. Report as <endTime>
|
||||
//
|
||||
// - action=writeNow, action=nextWrite action=noWriteNow :
|
||||
// The slave has signalled that it is done and wants the master to exit with
|
||||
// the specified type of action. Report as corresponding <action>.
|
||||
//
|
||||
// Anything else (empty file, no action=, etc) is reported as <unknown>.
|
||||
//
|
||||
static enum Time::stopAtControls getStopAction(const std::string& filename)
|
||||
{
|
||||
// Slurp entire input file (must exist) as a single string
|
||||
std::string fileContent;
|
||||
|
||||
std::ifstream is(filename);
|
||||
std::getline(is, fileContent, '\0');
|
||||
|
||||
if (fileContent.find("done") != std::string::npos)
|
||||
{
|
||||
return Time::stopAtControls::saEndTime;
|
||||
}
|
||||
|
||||
const auto equals = fileContent.find('=');
|
||||
|
||||
if (equals != std::string::npos)
|
||||
{
|
||||
const word actionName(word::validate(fileContent.substr(equals+1)));
|
||||
|
||||
return
|
||||
Time::stopAtControlNames
|
||||
(
|
||||
actionName,
|
||||
Time::stopAtControls::saUnknown
|
||||
);
|
||||
}
|
||||
|
||||
return Time::stopAtControls::saUnknown;
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
@ -141,7 +175,8 @@ bool Foam::externalFileCoupler::readDict(const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
void Foam::externalFileCoupler::useMaster(const bool wait) const
|
||||
enum Foam::Time::stopAtControls
|
||||
Foam::externalFileCoupler::useMaster(const bool wait) const
|
||||
{
|
||||
const bool wasInit = initialized();
|
||||
runState_ = MASTER;
|
||||
@ -163,18 +198,20 @@ void Foam::externalFileCoupler::useMaster(const bool wait) const
|
||||
|
||||
std::ofstream os(lck);
|
||||
os << "status=openfoam\n";
|
||||
os.flush();
|
||||
}
|
||||
}
|
||||
|
||||
if (wait)
|
||||
{
|
||||
waitForMaster();
|
||||
return waitForMaster();
|
||||
}
|
||||
|
||||
return Time::stopAtControls::saUnknown;
|
||||
}
|
||||
|
||||
|
||||
void Foam::externalFileCoupler::useSlave(const bool wait) const
|
||||
enum Foam::Time::stopAtControls
|
||||
Foam::externalFileCoupler::useSlave(const bool wait) const
|
||||
{
|
||||
const bool wasInit = initialized();
|
||||
runState_ = SLAVE;
|
||||
@ -194,19 +231,23 @@ void Foam::externalFileCoupler::useSlave(const bool wait) const
|
||||
|
||||
if (wait)
|
||||
{
|
||||
waitForSlave();
|
||||
return waitForSlave();
|
||||
}
|
||||
|
||||
return Time::stopAtControls::saUnknown;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::externalFileCoupler::waitForMaster() const
|
||||
enum Foam::Time::stopAtControls
|
||||
Foam::externalFileCoupler::waitForMaster() const
|
||||
{
|
||||
if (!initialized())
|
||||
{
|
||||
useMaster(); // was not initialized
|
||||
}
|
||||
|
||||
bool isDone = false;
|
||||
auto action = Time::stopAtControls::saUnknown;
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
const fileName lck(lockFile());
|
||||
@ -221,9 +262,11 @@ bool Foam::externalFileCoupler::waitForMaster() const
|
||||
if (prevTime < modTime)
|
||||
{
|
||||
prevTime = modTime;
|
||||
isDone = checkIsDone(lck);
|
||||
if (isDone)
|
||||
|
||||
if (Time::stopAtControls::saEndTime == getStopAction(lck))
|
||||
{
|
||||
// Found 'done' - slave should not wait for master
|
||||
action = Time::stopAtControls::saEndTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -231,21 +274,24 @@ bool Foam::externalFileCoupler::waitForMaster() const
|
||||
}
|
||||
}
|
||||
|
||||
// MPI barrier
|
||||
Pstream::scatter(isDone);
|
||||
label intAction(action);
|
||||
|
||||
return !isDone;
|
||||
Pstream::scatter(intAction); // Also acts as MPI barrier
|
||||
|
||||
return Time::stopAtControls(intAction);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::externalFileCoupler::waitForSlave() const
|
||||
enum Foam::Time::stopAtControls
|
||||
Foam::externalFileCoupler::waitForSlave() const
|
||||
{
|
||||
if (!initialized())
|
||||
{
|
||||
useSlave(); // was not initialized
|
||||
}
|
||||
|
||||
bool isDone = false;
|
||||
auto action = Time::stopAtControls::saUnknown;
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
const fileName lck(lockFile());
|
||||
@ -267,16 +313,16 @@ bool Foam::externalFileCoupler::waitForSlave() const
|
||||
Log << type() << ": wait time = " << totalTime << endl;
|
||||
}
|
||||
|
||||
// But check for status=done content in the file
|
||||
isDone = checkIsDone(lck);
|
||||
action = getStopAction(lck);
|
||||
|
||||
Log << type() << ": found lock file " << lck << endl;
|
||||
}
|
||||
|
||||
// MPI barrier
|
||||
Pstream::scatter(isDone);
|
||||
label intAction(action);
|
||||
|
||||
return !isDone;
|
||||
Pstream::scatter(intAction); // Also acts as MPI barrier
|
||||
|
||||
return Time::stopAtControls(intAction);
|
||||
}
|
||||
|
||||
|
||||
@ -308,12 +354,10 @@ void Foam::externalFileCoupler::shutdown() const
|
||||
{
|
||||
if (Pstream::master() && runState_ == MASTER && Foam::isDir(commsDir_))
|
||||
{
|
||||
const fileName lck(lockFile());
|
||||
|
||||
Log << type() << ": lock file status=done" << endl;
|
||||
std::ofstream os(lck);
|
||||
|
||||
std::ofstream os(lockFile());
|
||||
os << "status=done\n";
|
||||
os.flush();
|
||||
}
|
||||
|
||||
runState_ = DONE; // Avoid re-triggering in destructor
|
||||
|
||||
@ -60,21 +60,26 @@ Description
|
||||
A typical coupling loop would look like this (on the master-side):
|
||||
\verbatim
|
||||
initialize - master takes control
|
||||
write data for slave
|
||||
use slave, wait for slave
|
||||
cleanup old data from master
|
||||
read data from slave
|
||||
use master
|
||||
writeDataMaster() - write data for slave
|
||||
useSlave()
|
||||
waitForSlave()
|
||||
removeDataMaster() - cleanup old data from master [optional?]
|
||||
readDataMaster() - read data from slave
|
||||
useMaster()
|
||||
\endverbatim
|
||||
|
||||
On the slave-side:
|
||||
\verbatim
|
||||
wait for master
|
||||
read data from master
|
||||
write data for master
|
||||
use master
|
||||
waitForMaster()
|
||||
readDataSlave() - read data from master
|
||||
writeDataSlave() - write data for master
|
||||
useMaster()
|
||||
\endverbatim
|
||||
|
||||
Note that since the waitForSlave() method not only waits for the lock file
|
||||
to be reinstated but also does a simple check of its contents, it can
|
||||
also serve to communicate some control from the slave to the master.
|
||||
|
||||
SourceFiles
|
||||
externalFileCoupler.C
|
||||
externalFileCouplerI.H
|
||||
@ -86,6 +91,7 @@ SourceFiles
|
||||
|
||||
#include "fileName.H"
|
||||
#include "dictionary.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -177,7 +183,7 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Initialization
|
||||
// Initialization
|
||||
|
||||
//- True if state has been initialized
|
||||
inline bool initialized() const;
|
||||
@ -186,7 +192,7 @@ public:
|
||||
inline bool slaveFirst() const;
|
||||
|
||||
|
||||
// File locations
|
||||
// File locations
|
||||
|
||||
//- Return the file path to the base communications directory
|
||||
inline const fileName& commDirectory() const;
|
||||
@ -198,36 +204,57 @@ public:
|
||||
inline fileName lockFile() const;
|
||||
|
||||
|
||||
// Settings
|
||||
// Settings
|
||||
|
||||
//- Read communication settings from dictionary
|
||||
bool readDict(const dictionary& dict);
|
||||
|
||||
|
||||
// Handshaking
|
||||
// Handshaking
|
||||
|
||||
//- Create lock file to indicate that OpenFOAM is in charge
|
||||
// Optionally wait for master to complete as well.
|
||||
void useMaster(const bool wait=false) const;
|
||||
// \param wait - wait for master to complete.
|
||||
//
|
||||
// \return Time::stopAtControls::saUnknown if not waiting, otherwise
|
||||
// as per the waitForMaster() description.
|
||||
enum Time::stopAtControls useMaster(const bool wait=false) const;
|
||||
|
||||
//- Remove lock file to indicate that the external program is in charge
|
||||
// Optionally wait for slave to complete as well.
|
||||
void useSlave(const bool wait=false) const;
|
||||
// \param wait - wait for slave to complete.
|
||||
//
|
||||
// \return Time::stopAtControls::saUnknown if not waiting, otherwise
|
||||
// as per the waitForSlave() description.
|
||||
enum Time::stopAtControls useSlave(const bool wait=false) const;
|
||||
|
||||
|
||||
//- Wait for master to complete.
|
||||
// This is when the lock file disappears, or exists but has
|
||||
// "status=done" content.
|
||||
// \return False if lock file contains "status=done"
|
||||
bool waitForMaster() const;
|
||||
// \c status=done content.
|
||||
//
|
||||
// \return Time::stopAtControls::saUnknown or if lock file
|
||||
// contained \c status=done it returns
|
||||
// Time::stopAtControls::saEndTime
|
||||
enum Time::stopAtControls waitForMaster() const;
|
||||
|
||||
//- Wait for slave to complete.
|
||||
// This is when the lock file appears.
|
||||
// \return False if lock file contains "status=done"
|
||||
bool waitForSlave() const;
|
||||
//
|
||||
// When the lock file appears, it is checked for the following
|
||||
// content which corresponds to particular return values:
|
||||
// - \c status=done
|
||||
// \return Foam::Time::saEndTime
|
||||
// - \c action=writeNow
|
||||
// \return Foam::Time::saWriteNow
|
||||
// - \c action=nextWrite
|
||||
// \return Foam::Time::saNextWrite
|
||||
// - \c action=noNextWrite
|
||||
// \return Foam::Time::saNoNextWrite
|
||||
// - Anything else (empty file, no action= or status=, etc)
|
||||
// \return Foam::Time::saUnknown
|
||||
enum Time::stopAtControls waitForSlave() const;
|
||||
|
||||
|
||||
// File creation, removal
|
||||
// File creation, removal
|
||||
|
||||
//- Read data files on master (OpenFOAM).
|
||||
// These data files are normally created by the slave.
|
||||
@ -251,13 +278,13 @@ public:
|
||||
//- Remove data files written by slave (external program)
|
||||
virtual void removeDataSlave() const;
|
||||
|
||||
//- Generate status=done in lock (only when run-state = master)
|
||||
|
||||
//- Generate \c status=done in lock (only when run-state = master)
|
||||
void shutdown() const;
|
||||
|
||||
//- Remove files written by OpenFOAM
|
||||
void removeDirectory() const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -24,7 +24,6 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "pimpleControl.H"
|
||||
#include "Switch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -42,12 +41,12 @@ void Foam::pimpleControl::read()
|
||||
|
||||
const dictionary& pimpleDict = dict();
|
||||
|
||||
solveFlow_ = pimpleDict.lookupOrDefault<Switch>("solveFlow", true);
|
||||
solveFlow_ = pimpleDict.lookupOrDefault("solveFlow", true);
|
||||
nCorrPIMPLE_ = pimpleDict.lookupOrDefault<label>("nOuterCorrectors", 1);
|
||||
nCorrPISO_ = pimpleDict.lookupOrDefault<label>("nCorrectors", 1);
|
||||
SIMPLErho_ = pimpleDict.lookupOrDefault<Switch>("SIMPLErho", false);
|
||||
SIMPLErho_ = pimpleDict.lookupOrDefault("SIMPLErho", false);
|
||||
turbOnFinalIterOnly_ =
|
||||
pimpleDict.lookupOrDefault<Switch>("turbOnFinalIterOnly", true);
|
||||
pimpleDict.lookupOrDefault("turbOnFinalIterOnly", true);
|
||||
}
|
||||
|
||||
|
||||
@ -60,41 +59,42 @@ bool Foam::pimpleControl::criteriaSatisfied()
|
||||
}
|
||||
|
||||
|
||||
bool storeIni = this->storeInitialResiduals();
|
||||
const bool storeIni = this->storeInitialResiduals();
|
||||
|
||||
bool achieved = true;
|
||||
bool checked = false; // safety that some checks were indeed performed
|
||||
|
||||
const dictionary& solverDict = mesh_.solverPerformanceDict();
|
||||
forAllConstIter(dictionary, solverDict, iter)
|
||||
forAllConstIters(solverDict, iter)
|
||||
{
|
||||
const word& variableName = iter().keyword();
|
||||
const label fieldi = applyToField(variableName);
|
||||
const entry& solverPerfDictEntry = *iter;
|
||||
|
||||
const word& fieldName = solverPerfDictEntry.keyword();
|
||||
const label fieldi = applyToField(fieldName);
|
||||
|
||||
if (fieldi != -1)
|
||||
{
|
||||
scalar residual = 0;
|
||||
const scalar firstResidual =
|
||||
maxResidual(variableName, iter().stream(), residual);
|
||||
Pair<scalar> residuals = maxResidual(solverPerfDictEntry);
|
||||
|
||||
checked = true;
|
||||
|
||||
if (storeIni)
|
||||
{
|
||||
residualControl_[fieldi].initialResidual = firstResidual;
|
||||
}
|
||||
|
||||
const bool absCheck = residual < residualControl_[fieldi].absTol;
|
||||
scalar relative = 0.0;
|
||||
bool relCheck = false;
|
||||
|
||||
scalar relative = 0.0;
|
||||
if (!storeIni)
|
||||
const bool absCheck =
|
||||
(residuals.last() < residualControl_[fieldi].absTol);
|
||||
|
||||
if (storeIni)
|
||||
{
|
||||
residualControl_[fieldi].initialResidual = residuals.first();
|
||||
}
|
||||
else
|
||||
{
|
||||
const scalar iniRes =
|
||||
residualControl_[fieldi].initialResidual
|
||||
+ ROOTVSMALL;
|
||||
(residualControl_[fieldi].initialResidual + ROOTVSMALL);
|
||||
|
||||
relative = residual/iniRes;
|
||||
relCheck = relative < residualControl_[fieldi].relTol;
|
||||
relative = residuals.last() / iniRes;
|
||||
relCheck = (relative < residualControl_[fieldi].relTol);
|
||||
}
|
||||
|
||||
achieved = achieved && (absCheck || relCheck);
|
||||
@ -103,11 +103,11 @@ bool Foam::pimpleControl::criteriaSatisfied()
|
||||
{
|
||||
Info<< algorithmName_ << " loop:" << endl;
|
||||
|
||||
Info<< " " << variableName
|
||||
Info<< " " << fieldName
|
||||
<< " PIMPLE iter " << corr_
|
||||
<< ": ini res = "
|
||||
<< residualControl_[fieldi].initialResidual
|
||||
<< ", abs tol = " << residual
|
||||
<< ", abs tol = " << residuals.last()
|
||||
<< " (" << residualControl_[fieldi].absTol << ")"
|
||||
<< ", rel tol = " << relative
|
||||
<< " (" << residualControl_[fieldi].relTol << ")"
|
||||
@ -135,50 +135,46 @@ Foam::pimpleControl::pimpleControl(fvMesh& mesh, const word& dictName)
|
||||
{
|
||||
read();
|
||||
|
||||
Info<< nl
|
||||
<< algorithmName_;
|
||||
|
||||
if (nCorrPIMPLE_ > 1)
|
||||
{
|
||||
Info<< nl;
|
||||
if (residualControl_.empty())
|
||||
{
|
||||
Info<< algorithmName_ << ": no residual control data found. "
|
||||
Info<< ": no residual control data found. "
|
||||
<< "Calculations will employ " << nCorrPIMPLE_
|
||||
<< " corrector loops" << nl << endl;
|
||||
<< " corrector loops" << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< algorithmName_ << ": max iterations = " << nCorrPIMPLE_
|
||||
<< endl;
|
||||
forAll(residualControl_, i)
|
||||
Info<< ": max iterations = " << nCorrPIMPLE_ << nl;
|
||||
|
||||
for (const fieldData& ctrl : residualControl_)
|
||||
{
|
||||
Info<< " field " << residualControl_[i].name << token::TAB
|
||||
<< ": relTol " << residualControl_[i].relTol
|
||||
<< ", tolerance " << residualControl_[i].absTol
|
||||
Info<< " field " << ctrl.name << token::TAB
|
||||
<< ": relTol " << ctrl.relTol
|
||||
<< ", tolerance " << ctrl.absTol
|
||||
<< nl;
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< nl << algorithmName_ << ": Operating solver in PISO mode" << nl
|
||||
<< endl;
|
||||
Info<< ": Operating solver in PISO mode" << nl;
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::pimpleControl::~pimpleControl()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::pimpleControl::loop()
|
||||
{
|
||||
read();
|
||||
|
||||
corr_++;
|
||||
++corr_;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -187,7 +183,7 @@ bool Foam::pimpleControl::loop()
|
||||
|
||||
if (corr_ == nCorrPIMPLE_ + 1)
|
||||
{
|
||||
if ((!residualControl_.empty()) && (nCorrPIMPLE_ != 1))
|
||||
if (!residualControl_.empty() && (nCorrPIMPLE_ != 1))
|
||||
{
|
||||
Info<< algorithmName_ << ": not converged within "
|
||||
<< nCorrPIMPLE_ << " iterations" << endl;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -57,10 +57,10 @@ class pimpleControl
|
||||
// Private member functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
pimpleControl(const pimpleControl&);
|
||||
pimpleControl(const pimpleControl&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const pimpleControl&);
|
||||
void operator=(const pimpleControl&) = delete;
|
||||
|
||||
|
||||
protected:
|
||||
@ -116,7 +116,7 @@ public:
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~pimpleControl();
|
||||
virtual ~pimpleControl() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
@ -151,7 +151,7 @@ public:
|
||||
//- Return true for first PIMPLE (outer) iteration
|
||||
inline bool firstIter() const;
|
||||
|
||||
//- Return true fore final PIMPLE (outer) iteration
|
||||
//- Return true for final PIMPLE (outer) iteration
|
||||
inline bool finalIter() const;
|
||||
|
||||
//- Return true for final inner iteration
|
||||
|
||||
@ -51,7 +51,7 @@ inline bool Foam::pimpleControl::SIMPLErho() const
|
||||
|
||||
inline bool Foam::pimpleControl::correct()
|
||||
{
|
||||
corrPISO_++;
|
||||
++corrPISO_;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -62,11 +62,9 @@ inline bool Foam::pimpleControl::correct()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
corrPISO_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
corrPISO_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -53,26 +53,29 @@ bool Foam::simpleControl::criteriaSatisfied()
|
||||
bool checked = false; // safety that some checks were indeed performed
|
||||
|
||||
const dictionary& solverDict = mesh_.solverPerformanceDict();
|
||||
forAllConstIter(dictionary, solverDict, iter)
|
||||
forAllConstIters(solverDict, iter)
|
||||
{
|
||||
const word& variableName = iter().keyword();
|
||||
const label fieldi = applyToField(variableName);
|
||||
const entry& solverPerfDictEntry = *iter;
|
||||
|
||||
const word& fieldName = solverPerfDictEntry.keyword();
|
||||
const label fieldi = applyToField(fieldName);
|
||||
|
||||
if (fieldi != -1)
|
||||
{
|
||||
scalar lastResidual = 0;
|
||||
const scalar residual =
|
||||
maxResidual(variableName, iter().stream(), lastResidual);
|
||||
|
||||
Pair<scalar> residuals = maxResidual(solverPerfDictEntry);
|
||||
checked = true;
|
||||
|
||||
bool absCheck = residual < residualControl_[fieldi].absTol;
|
||||
const bool absCheck =
|
||||
(residuals.first() < residualControl_[fieldi].absTol);
|
||||
|
||||
achieved = achieved && absCheck;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< algorithmName_ << " solution statistics:" << endl;
|
||||
|
||||
Info<< " " << variableName << ": tolerance = " << residual
|
||||
Info<< " " << fieldName << ": tolerance = "
|
||||
<< residuals.first()
|
||||
<< " (" << residualControl_[fieldi].absTol << ")"
|
||||
<< endl;
|
||||
}
|
||||
@ -85,64 +88,53 @@ bool Foam::simpleControl::criteriaSatisfied()
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::simpleControl::simpleControl(fvMesh& mesh)
|
||||
Foam::simpleControl::simpleControl(fvMesh& mesh, const word& dictName)
|
||||
:
|
||||
solutionControl(mesh, "SIMPLE"),
|
||||
solutionControl(mesh, dictName),
|
||||
initialised_(false)
|
||||
{
|
||||
read();
|
||||
|
||||
Info<< nl;
|
||||
Info<< nl
|
||||
<< algorithmName_;
|
||||
|
||||
if (residualControl_.empty())
|
||||
{
|
||||
Info<< algorithmName_ << ": no convergence criteria found. "
|
||||
<< "Calculations will run for "
|
||||
Info<< ": no convergence criteria found. Calculations will run for "
|
||||
<< mesh_.time().endTime().value() - mesh_.time().startTime().value()
|
||||
<< " steps." << nl << endl;
|
||||
<< " steps." << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< algorithmName_ << ": convergence criteria" << nl;
|
||||
forAll(residualControl_, i)
|
||||
Info<< ": convergence criteria" << nl;
|
||||
for (const fieldData& ctrl : residualControl_)
|
||||
{
|
||||
Info<< " field " << residualControl_[i].name << token::TAB
|
||||
<< " tolerance " << residualControl_[i].absTol
|
||||
Info<< " field " << ctrl.name << token::TAB
|
||||
<< " tolerance " << ctrl.absTol
|
||||
<< nl;
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::simpleControl::~simpleControl()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::simpleControl::loop()
|
||||
{
|
||||
read();
|
||||
|
||||
Time& time = const_cast<Time&>(mesh_.time());
|
||||
Time& runTime = const_cast<Time&>(mesh_.time());
|
||||
|
||||
if (initialised_)
|
||||
if (initialised_ && criteriaSatisfied())
|
||||
{
|
||||
if (criteriaSatisfied())
|
||||
{
|
||||
Info<< nl << algorithmName_ << " solution converged in "
|
||||
<< time.timeName() << " iterations" << nl << endl;
|
||||
Info<< nl
|
||||
<< algorithmName_
|
||||
<< " solution converged in "
|
||||
<< runTime.timeName() << " iterations" << nl << endl;
|
||||
|
||||
// Set to finalise calculation
|
||||
time.writeAndEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
storePrevIterFields();
|
||||
}
|
||||
// Set to finalise calculation
|
||||
runTime.writeAndEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -150,8 +142,7 @@ bool Foam::simpleControl::loop()
|
||||
storePrevIterFields();
|
||||
}
|
||||
|
||||
|
||||
return time.loop();
|
||||
return runTime.loop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -74,10 +74,10 @@ private:
|
||||
// Private member functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
simpleControl(const simpleControl&);
|
||||
simpleControl(const simpleControl&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const simpleControl&);
|
||||
void operator=(const simpleControl&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
@ -90,19 +90,19 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh
|
||||
simpleControl(fvMesh& mesh);
|
||||
//- Construct from mesh and the name of control sub-dictionary
|
||||
simpleControl(fvMesh& mesh, const word& dictName="SIMPLE");
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~simpleControl();
|
||||
virtual ~simpleControl() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Solution control
|
||||
|
||||
//- Loop loop
|
||||
//- SIMPLE loop
|
||||
virtual bool loop();
|
||||
};
|
||||
|
||||
|
||||
@ -148,11 +148,7 @@ Foam::label Foam::solutionControl::applyToField
|
||||
{
|
||||
forAll(residualControl_, i)
|
||||
{
|
||||
if (useRegEx && residualControl_[i].name.match(fieldName))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
else if (residualControl_[i].name == fieldName)
|
||||
if (residualControl_[i].name.match(fieldName, !useRegEx))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
@ -173,42 +169,68 @@ void Foam::solutionControl::storePrevIterFields() const
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::solutionControl::maxTypeResidual
|
||||
Foam::Pair<Foam::scalar> Foam::solutionControl::maxResidual
|
||||
(
|
||||
const word& fieldName,
|
||||
ITstream& data,
|
||||
scalar& firstRes,
|
||||
scalar& lastRes
|
||||
const entry& solverPerfDictEntry
|
||||
) const
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
if (mesh_.foundObject<fieldType>(fieldName))
|
||||
{
|
||||
const List<SolverPerformance<Type>> sp(data);
|
||||
firstRes = cmptMax(sp.first().initialResidual());
|
||||
lastRes = cmptMax(sp.last().initialResidual());
|
||||
}
|
||||
return maxResidual(mesh_, solverPerfDictEntry);
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::solutionControl::maxResidual
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
bool Foam::solutionControl::maxTypeResidual
|
||||
(
|
||||
const word& fieldName,
|
||||
ITstream& data,
|
||||
scalar& lastRes
|
||||
) const
|
||||
const fvMesh& fvmesh,
|
||||
const entry& solverPerfDictEntry,
|
||||
Pair<scalar>& residuals
|
||||
)
|
||||
{
|
||||
scalar firstRes = 0;
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
maxTypeResidual<scalar>(fieldName, data, firstRes, lastRes);
|
||||
maxTypeResidual<vector>(fieldName, data, firstRes, lastRes);
|
||||
maxTypeResidual<sphericalTensor>(fieldName, data, firstRes, lastRes);
|
||||
maxTypeResidual<symmTensor>(fieldName, data, firstRes, lastRes);
|
||||
maxTypeResidual<tensor>(fieldName, data, firstRes, lastRes);
|
||||
const word& fieldName = solverPerfDictEntry.keyword();
|
||||
|
||||
return firstRes;
|
||||
if (fvmesh.foundObject<fieldType>(fieldName))
|
||||
{
|
||||
const List<SolverPerformance<Type>> sp(solverPerfDictEntry.stream());
|
||||
|
||||
residuals.first() = cmptMax(sp.first().initialResidual());
|
||||
residuals.last() = cmptMax(sp.last().initialResidual());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Foam::Pair<Foam::scalar> Foam::solutionControl::maxResidual
|
||||
(
|
||||
const fvMesh& fvmesh,
|
||||
const entry& solverPerfDictEntry
|
||||
)
|
||||
{
|
||||
Pair<scalar> residuals(0,0);
|
||||
|
||||
// Check with builtin short-circuit
|
||||
const bool ok =
|
||||
(
|
||||
maxTypeResidual<scalar>(fvmesh, solverPerfDictEntry, residuals)
|
||||
|| maxTypeResidual<vector>(fvmesh, solverPerfDictEntry, residuals)
|
||||
|| maxTypeResidual<sphericalTensor>(fvmesh, solverPerfDictEntry, residuals)
|
||||
|| maxTypeResidual<symmTensor>(fvmesh, solverPerfDictEntry, residuals)
|
||||
|| maxTypeResidual<tensor>(fvmesh, solverPerfDictEntry, residuals)
|
||||
);
|
||||
|
||||
if (!ok && solutionControl::debug)
|
||||
{
|
||||
Info<<"no residual for " << solverPerfDictEntry.keyword()
|
||||
<< " on mesh " << fvmesh.name() << nl;
|
||||
}
|
||||
|
||||
return residuals;
|
||||
}
|
||||
|
||||
|
||||
@ -235,10 +257,4 @@ Foam::solutionControl::solutionControl(fvMesh& mesh, const word& algorithmName)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::solutionControl::~solutionControl()
|
||||
{}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -33,6 +33,7 @@ Description
|
||||
#define solutionControl_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
#include "Pair.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -49,6 +50,7 @@ class solutionControl
|
||||
{
|
||||
public:
|
||||
|
||||
//- Simple convenient storage of field residuals
|
||||
struct fieldData
|
||||
{
|
||||
wordRe name;
|
||||
@ -58,6 +60,20 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Extract maximum residual for the solver performance entry,
|
||||
//- provided the corresponding volume field is available on the mesh.
|
||||
//
|
||||
// \return initial residual as first member, the final residual
|
||||
// as the second (or last) member
|
||||
static Pair<scalar> maxResidual
|
||||
(
|
||||
const fvMesh& fvmesh,
|
||||
const entry& dataDictEntry
|
||||
);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
@ -126,30 +142,34 @@ protected:
|
||||
template<class Type>
|
||||
void storePrevIter() const;
|
||||
|
||||
//- Initial and final residual of the specified field-name,
|
||||
//- provided that the corresponding volume field is available
|
||||
//- on the fvMesh.
|
||||
//
|
||||
// Populate residuals with initial residual as first member and
|
||||
// the final residual as second (last) member.
|
||||
template<class Type>
|
||||
void maxTypeResidual
|
||||
static bool maxTypeResidual
|
||||
(
|
||||
const word& fieldName,
|
||||
ITstream& data,
|
||||
scalar& firstRes,
|
||||
scalar& lastRes
|
||||
) const;
|
||||
const fvMesh& fvmesh,
|
||||
const entry& solverPerfDictEntry,
|
||||
Pair<scalar>& residuals
|
||||
);
|
||||
|
||||
scalar maxResidual
|
||||
(
|
||||
const word& fieldName,
|
||||
ITstream& data,
|
||||
scalar& lastRes
|
||||
) const;
|
||||
//- Extract the maximum residual for the specified field
|
||||
//
|
||||
// \return initial residual as first member, the final residual
|
||||
// as second (last) member
|
||||
Pair<scalar> maxResidual(const entry& solverPerfDictEntry) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
solutionControl(const solutionControl&);
|
||||
solutionControl(const solutionControl&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const solutionControl&);
|
||||
void operator=(const solutionControl&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
@ -168,7 +188,7 @@ public:
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~solutionControl();
|
||||
virtual ~solutionControl() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
@ -81,7 +81,7 @@ inline bool Foam::solutionControl::frozenFlow() const
|
||||
|
||||
inline bool Foam::solutionControl::correctNonOrthogonal()
|
||||
{
|
||||
corrNonOrtho_++;
|
||||
++corrNonOrtho_;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -93,11 +93,9 @@ inline bool Foam::solutionControl::correctNonOrthogonal()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
corrNonOrtho_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
corrNonOrtho_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -460,6 +460,42 @@ void Foam::functionObjects::externalCoupled::initCoupling()
|
||||
}
|
||||
|
||||
|
||||
void Foam::functionObjects::externalCoupled::performCoupling()
|
||||
{
|
||||
// Ensure coupling has been initialised
|
||||
initCoupling();
|
||||
|
||||
// Write data for external source
|
||||
writeDataMaster();
|
||||
|
||||
// Signal external source to execute (by removing lock file)
|
||||
// - Wait for slave to provide data
|
||||
useSlave();
|
||||
|
||||
// Wait for response - and catch any abort information sent from slave
|
||||
const auto action = waitForSlave();
|
||||
|
||||
// Remove old data files from OpenFOAM
|
||||
removeDataMaster();
|
||||
|
||||
// Read data passed back from external source
|
||||
readDataMaster();
|
||||
|
||||
// Signal external source to wait (by creating the lock file)
|
||||
useMaster();
|
||||
|
||||
// Process any abort information sent from slave
|
||||
if
|
||||
(
|
||||
action != time_.stopAt()
|
||||
&& action != Time::stopAtControls::saUnknown
|
||||
)
|
||||
{
|
||||
time_.stopAt(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::functionObjects::externalCoupled::externalCoupled
|
||||
@ -483,46 +519,16 @@ Foam::functionObjects::externalCoupled::externalCoupled
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::functionObjects::externalCoupled::~externalCoupled()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::functionObjects::externalCoupled::execute()
|
||||
{
|
||||
if (!initialisedCoupling_ || time_.timeIndex() % calcFrequency_ == 0)
|
||||
{
|
||||
// Initialise the coupling
|
||||
initCoupling();
|
||||
|
||||
// Write data for external source
|
||||
writeDataMaster();
|
||||
|
||||
// Signal external source to execute (by removing lock file)
|
||||
// - Wait for slave to provide data
|
||||
useSlave();
|
||||
|
||||
// Wait for response
|
||||
waitForSlave();
|
||||
|
||||
// Remove old data files from OpenFOAM
|
||||
removeDataMaster();
|
||||
|
||||
// Read data passed back from external source
|
||||
readDataMaster();
|
||||
|
||||
// Signal external source to wait (by creating the lock file)
|
||||
useMaster();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
performCoupling();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -282,6 +282,9 @@ private:
|
||||
|
||||
static void checkOrder(const wordList& regionNames);
|
||||
|
||||
//- Perform the coupling with necessary initialization etc.
|
||||
void performCoupling();
|
||||
|
||||
//- Disallow default bitwise copy constructor
|
||||
externalCoupled(const externalCoupled&) = delete;
|
||||
|
||||
@ -313,7 +316,7 @@ public:
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~externalCoupled();
|
||||
virtual ~externalCoupled() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
@ -72,7 +72,7 @@ void Foam::functionObjects::mapFields::createInterpolation
|
||||
);
|
||||
const fvMesh& mapRegion = mapRegionPtr_();
|
||||
const word mapMethodName(dict.lookup("mapMethod"));
|
||||
if (!meshToMesh::interpolationMethodNames_.hasEnum(mapMethodName))
|
||||
if (!meshToMesh::interpolationMethodNames_.found(mapMethodName))
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< type() << " " << name() << ": unknown map method "
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -187,6 +187,8 @@ void Foam::lumpedPointDisplacementPointPatchVectorField::updateCoeffs()
|
||||
return;
|
||||
}
|
||||
|
||||
enum Time::stopAtControls action = Time::stopAtControls::saUnknown;
|
||||
|
||||
const bool masterPatch = (movement().ownerId() == this->patch().index());
|
||||
if (masterPatch)
|
||||
{
|
||||
@ -250,13 +252,14 @@ void Foam::lumpedPointDisplacementPointPatchVectorField::updateCoeffs()
|
||||
{
|
||||
movement().writeData(forces, moments);
|
||||
|
||||
// signal external source to execute
|
||||
// Signal external source to execute
|
||||
movement().coupler().useSlave();
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for slave to provide data - includes MPI barrier
|
||||
movement().coupler().waitForSlave();
|
||||
// Wait for slave to provide data (includes MPI barrier)
|
||||
// and catch any abort information sent from slave
|
||||
action = movement().coupler().waitForSlave();
|
||||
|
||||
// Read data passed back from external source - includes MPI barrier
|
||||
const_cast<lumpedPointMovement&>(movement()).readState();
|
||||
@ -271,6 +274,16 @@ void Foam::lumpedPointDisplacementPointPatchVectorField::updateCoeffs()
|
||||
this->operator==(tdisp);
|
||||
|
||||
fixedValuePointPatchField<vector>::updateCoeffs();
|
||||
|
||||
// Process any abort information sent from slave
|
||||
if
|
||||
(
|
||||
action != this->db().time().stopAt()
|
||||
&& action != Time::stopAtControls::saUnknown
|
||||
)
|
||||
{
|
||||
this->db().time().stopAt(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user