functionObject: Fixed bugs in function object time-step adjustment
The logic governing function objects' ability to change the time-step has been modified so that it is compatible with the time-step adjustment done in the Time class. The behaviour has been split into a method which sets the step directly, and another which moidifies the time until the next write operation (i.e., the time that the solver "aims" for). This fixes an issue where the adjustments in Time and the function objects interfere and cause the time step to decrease exponentially down to machine precision. It also means that the set-time-step function object now does not break the adjustable run-time setting. This resolves bug report https://bugs.openfoam.org/view.php?id=2820
This commit is contained in:
@ -83,27 +83,20 @@ Foam::word Foam::Time::controlDictName("controlDict");
|
||||
|
||||
void Foam::Time::adjustDeltaT()
|
||||
{
|
||||
bool adjustTime = false;
|
||||
scalar timeToNextWrite = vGreat;
|
||||
|
||||
if (writeControl_ == wcAdjustableRunTime)
|
||||
{
|
||||
adjustTime = true;
|
||||
timeToNextWrite = max
|
||||
scalar timeToNextWrite = max
|
||||
(
|
||||
0.0,
|
||||
(writeTimeIndex_ + 1)*writeInterval_ - (value() - startTime_)
|
||||
);
|
||||
}
|
||||
|
||||
if (adjustTime)
|
||||
{
|
||||
scalar nSteps = timeToNextWrite/deltaT_ - small;
|
||||
timeToNextWrite = min(timeToNextWrite, functionObjects_.timeToNextWrite());
|
||||
|
||||
scalar nSteps = timeToNextWrite/deltaT_;
|
||||
|
||||
// For tiny deltaT the label can overflow!
|
||||
if (nSteps < labelMax)
|
||||
{
|
||||
label nStepsToNextWrite = label(nSteps) + 1;
|
||||
label nStepsToNextWrite = label(nSteps + 0.5);
|
||||
|
||||
scalar newDeltaT = timeToNextWrite/nStepsToNextWrite;
|
||||
|
||||
@ -120,9 +113,6 @@ void Foam::Time::adjustDeltaT()
|
||||
}
|
||||
}
|
||||
|
||||
functionObjects_.adjustTimeStep();
|
||||
}
|
||||
|
||||
|
||||
void Foam::Time::setControls()
|
||||
{
|
||||
@ -921,28 +911,32 @@ void Foam::Time::setEndTime(const scalar endTime)
|
||||
}
|
||||
|
||||
|
||||
void Foam::Time::setDeltaT
|
||||
(
|
||||
const dimensionedScalar& deltaT,
|
||||
const bool bAdjustDeltaT
|
||||
)
|
||||
void Foam::Time::setDeltaT(const dimensionedScalar& deltaT)
|
||||
{
|
||||
setDeltaT(deltaT.value(), bAdjustDeltaT);
|
||||
setDeltaT(deltaT.value());
|
||||
}
|
||||
|
||||
|
||||
void Foam::Time::setDeltaT(const scalar deltaT, const bool bAdjustDeltaT)
|
||||
void Foam::Time::setDeltaT(const scalar deltaT)
|
||||
{
|
||||
deltaT_ = deltaT;
|
||||
deltaTchanged_ = true;
|
||||
setDeltaTNoAdjust(deltaT);
|
||||
|
||||
if (bAdjustDeltaT)
|
||||
functionObjects_.setTimeStep();
|
||||
|
||||
if (writeControl_ == wcAdjustableRunTime)
|
||||
{
|
||||
adjustDeltaT();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::Time::setDeltaTNoAdjust(const scalar deltaT)
|
||||
{
|
||||
deltaT_ = deltaT;
|
||||
deltaTchanged_ = true;
|
||||
}
|
||||
|
||||
|
||||
Foam::TimeState Foam::Time::subCycle(const label nSubCycles)
|
||||
{
|
||||
subCycling_ = true;
|
||||
|
||||
@ -516,18 +516,14 @@ public:
|
||||
virtual void setEndTime(const scalar);
|
||||
|
||||
//- Reset time step
|
||||
virtual void setDeltaT
|
||||
(
|
||||
const dimensionedScalar&,
|
||||
const bool adjustDeltaT = true
|
||||
);
|
||||
virtual void setDeltaT(const dimensionedScalar&);
|
||||
|
||||
//- Reset time step
|
||||
virtual void setDeltaT
|
||||
(
|
||||
const scalar,
|
||||
const bool adjustDeltaT = true
|
||||
);
|
||||
virtual void setDeltaT(const scalar);
|
||||
|
||||
//- Reset time step without additional adjustment or modification
|
||||
// by function objects
|
||||
virtual void setDeltaTNoAdjust(const scalar);
|
||||
|
||||
//- Set time to sub-cycle for the given number of steps
|
||||
virtual TimeState subCycle(const label nSubCycles);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -140,12 +140,18 @@ bool Foam::functionObject::end()
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObject::adjustTimeStep()
|
||||
bool Foam::functionObject::setTimeStep()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::functionObject::timeToNextWrite()
|
||||
{
|
||||
return vGreat;
|
||||
}
|
||||
|
||||
|
||||
void Foam::functionObject::updateMesh(const mapPolyMesh&)
|
||||
{}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -230,8 +230,14 @@ public:
|
||||
// By default it simply calls execute().
|
||||
virtual bool end();
|
||||
|
||||
//- Called at the end of Time::adjustDeltaT() if adjustTime is true
|
||||
virtual bool adjustTimeStep();
|
||||
//- Called by Time::setDeltaT(). Allows the function object to override
|
||||
// the time-step value. Returns whether or not the value was overriden.
|
||||
virtual bool setTimeStep();
|
||||
|
||||
//- Called by Time::adjustTimeStep(). Allows the function object to
|
||||
// insert a write time earlier than that already in use by the run
|
||||
// time. Returns the write time, or vGreat.
|
||||
virtual scalar timeToNextWrite();
|
||||
|
||||
//- Update for changes of mesh
|
||||
virtual void updateMesh(const mapPolyMesh& mpm);
|
||||
|
||||
@ -565,9 +565,46 @@ bool Foam::functionObjectList::end()
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjectList::adjustTimeStep()
|
||||
bool Foam::functionObjectList::setTimeStep()
|
||||
{
|
||||
bool ok = true;
|
||||
bool set = true;
|
||||
|
||||
if (execution_)
|
||||
{
|
||||
if (!updated_)
|
||||
{
|
||||
read();
|
||||
}
|
||||
|
||||
wordList names;
|
||||
|
||||
forAll(*this, objectI)
|
||||
{
|
||||
if (operator[](objectI).setTimeStep())
|
||||
{
|
||||
names.append(operator[](objectI).name());
|
||||
set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (names.size() > 1)
|
||||
{
|
||||
WarningInFunction << "Multiple function objects (" << names[0];
|
||||
for (label i = 1; i < names.size(); ++ i)
|
||||
{
|
||||
WarningInFunction << ", " << names[i];
|
||||
}
|
||||
WarningInFunction << ") are setting the time step." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::functionObjectList::timeToNextWrite()
|
||||
{
|
||||
scalar result = vGreat;
|
||||
|
||||
if (execution_)
|
||||
{
|
||||
@ -578,11 +615,11 @@ bool Foam::functionObjectList::adjustTimeStep()
|
||||
|
||||
forAll(*this, objectI)
|
||||
{
|
||||
ok = operator[](objectI).adjustTimeStep() && ok;
|
||||
result = min(result, operator[](objectI).timeToNextWrite());
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -274,8 +274,11 @@ public:
|
||||
//- Called when Time::run() determines that the time-loop exits
|
||||
bool end();
|
||||
|
||||
//- Called at the end of Time::adjustDeltaT() if adjustTime is true
|
||||
bool adjustTimeStep();
|
||||
//- Override the time-step value
|
||||
bool setTimeStep();
|
||||
|
||||
//- Return the time to the next write
|
||||
scalar timeToNextWrite();
|
||||
|
||||
//- Update for changes of mesh
|
||||
void updateMesh(const mapPolyMesh& mpm);
|
||||
|
||||
@ -119,48 +119,27 @@ bool Foam::functionObjects::timeControl::end()
|
||||
|
||||
|
||||
|
||||
bool Foam::functionObjects::timeControl::adjustTimeStep()
|
||||
Foam::scalar Foam::functionObjects::timeControl::timeToNextWrite()
|
||||
{
|
||||
if
|
||||
(
|
||||
active()
|
||||
&& writeControl_.control()
|
||||
== Foam::timeControl::ocAdjustableRunTime
|
||||
&& writeControl_.control() == Foam::timeControl::ocAdjustableRunTime
|
||||
)
|
||||
{
|
||||
const label writeTimeIndex = writeControl_.executionIndex();
|
||||
const scalar writeInterval = writeControl_.interval();
|
||||
|
||||
scalar timeToNextWrite = max
|
||||
return
|
||||
max
|
||||
(
|
||||
0.0,
|
||||
(writeTimeIndex + 1)*writeInterval
|
||||
- (time_.value() - time_.startTime().value())
|
||||
);
|
||||
|
||||
scalar deltaT = time_.deltaTValue();
|
||||
|
||||
scalar nSteps = timeToNextWrite/deltaT - small;
|
||||
|
||||
// functionObjects modify deltaT within nStepsToStartTimeChange
|
||||
// NOTE: Potential problems arise if two function objects dump within
|
||||
// the same interval
|
||||
if (nSteps < nStepsToStartTimeChange_)
|
||||
{
|
||||
label nStepsToNextWrite = label(nSteps) + 1;
|
||||
|
||||
scalar newDeltaT = timeToNextWrite/nStepsToNextWrite;
|
||||
|
||||
// Adjust time step
|
||||
if (newDeltaT < deltaT)
|
||||
{
|
||||
deltaT = max(newDeltaT, 0.2*deltaT);
|
||||
const_cast<Time&>(time_).setDeltaT(deltaT, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return vGreat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -158,8 +158,8 @@ public:
|
||||
//- Called when Time::run() determines that the time-loop exits
|
||||
virtual bool end();
|
||||
|
||||
//- Called at the end of Time::adjustDeltaT() if adjustTime is true
|
||||
virtual bool adjustTimeStep();
|
||||
//- Return the time to the next write
|
||||
virtual scalar timeToNextWrite();
|
||||
|
||||
//- Read and set the function object if its data have changed
|
||||
virtual bool read(const dictionary&);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2013-2018 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -75,12 +75,11 @@ Foam::functionObjects::setTimeStepFunctionObject::time() const
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjects::setTimeStepFunctionObject::adjustTimeStep()
|
||||
bool Foam::functionObjects::setTimeStepFunctionObject::setTimeStep()
|
||||
{
|
||||
const_cast<Time&>(time()).setDeltaT
|
||||
const_cast<Time&>(time()).setDeltaTNoAdjust
|
||||
(
|
||||
timeStepPtr_().value(time_.timeOutputValue()),
|
||||
false
|
||||
timeStepPtr_().value(time_.timeOutputValue())
|
||||
);
|
||||
|
||||
return true;
|
||||
@ -94,27 +93,20 @@ bool Foam::functionObjects::setTimeStepFunctionObject::read
|
||||
{
|
||||
timeStepPtr_ = Function1<scalar>::New("deltaT", dict);
|
||||
|
||||
// Check that adjustTimeStep is active
|
||||
const dictionary& controlDict = time_.controlDict();
|
||||
|
||||
Switch adjust;
|
||||
if
|
||||
(
|
||||
!controlDict.readIfPresent<Switch>("adjustTimeStep", adjust)
|
||||
|| !adjust
|
||||
)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Need to set 'adjustTimeStep' true to allow timestep control"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjects::setTimeStepFunctionObject::execute()
|
||||
{
|
||||
bool adjustTimeStep =
|
||||
time().controlDict().lookupOrDefault("adjustTimeStep", false);
|
||||
|
||||
if (!adjustTimeStep)
|
||||
{
|
||||
return setTimeStep();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013-2017 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2013-2018 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -104,8 +104,8 @@ public:
|
||||
//- Return time database
|
||||
const Time& time() const;
|
||||
|
||||
//- Called at the end of Time::adjustDeltaT() if adjustTime is true
|
||||
virtual bool adjustTimeStep();
|
||||
//- Override the time-step value
|
||||
virtual bool setTimeStep();
|
||||
|
||||
//- Read and set the function object if its data have changed
|
||||
virtual bool read(const dictionary&);
|
||||
|
||||
Reference in New Issue
Block a user