ENH: timeControl: adds some more #423.

This commit is contained in:
mattijs
2017-06-26 11:51:14 +01:00
parent a22d9fe760
commit 2dc8038092

View File

@ -51,9 +51,20 @@ void Foam::functionObjects::timeControl::readControls()
{ {
timeEnd_ = time_.userTimeToTime(timeEnd_); timeEnd_ = time_.userTimeToTime(timeEnd_);
} }
deltaTCoeff_ = dict_.lookupOrDefault("deltaTCoeff", GREAT); deltaTCoeff_ = GREAT;
if (dict_.readIfPresent("deltaTCoeff", deltaTCoeff_))
dict_.readIfPresent("nStepsToStartTimeChange", nStepsToStartTimeChange_); {
nStepsToStartTimeChange_ = labelMax;
}
else
{
nStepsToStartTimeChange_ = 3;
dict_.readIfPresent
(
"nStepsToStartTimeChange",
nStepsToStartTimeChange_
);
}
} }
@ -73,7 +84,6 @@ Foam::scalar Foam::functionObjects::timeControl::calcExpansion
) )
{ {
scalar ratio = startRatio; scalar ratio = startRatio;
// This function is used to calculate the 'expansion ratio' or // This function is used to calculate the 'expansion ratio' or
// 'time step growth factor'. Inputs: // 'time step growth factor'. Inputs:
// - ratio: wanted ratio // - ratio: wanted ratio
@ -156,7 +166,7 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
/(requiredDeltaTCoeff - 1); /(requiredDeltaTCoeff - 1);
} }
// Nearest time which is multiple of wantedDT, after // Nearest time which is multiple of wantedDT, after
// requiredTimeInterval // requiredTimeInterval
scalar timeToNextMultiple = -presentTime; scalar timeToNextMultiple = -presentTime;
@ -185,7 +195,7 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
if (timeToNextWrite <= timeToNextMultiple) if (timeToNextWrite <= timeToNextMultiple)
{ {
// As the ramping can't be achieved, use current, unadapted deltaT // As the ramping can't be achieved, use current, unadapted deltaT
// (from e.g. maxCo calculation in solver) and adjust when // (from e.g. maxCo calculation in solver) and adjust when
// writeInterval is closer than this deltaT // writeInterval is closer than this deltaT
newDeltaT = deltaT0_; newDeltaT = deltaT0_;
if (timeToNextWrite < newDeltaT) if (timeToNextWrite < newDeltaT)
@ -220,13 +230,12 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
} }
else else
{ {
// Find the minimum number of time steps (with constant deltaT // Find the minimum number of time steps (with constant deltaT
// variation) to get us to the writeInterval and multiples of wantedDT. // variation) to get us to the writeInterval and multiples of wantedDT.
// Increases the number of nSteps to do the adjustment in until it // Increases the number of nSteps to do the adjustment in until it
// has reached one that is possible. Returns the new expansionratio. // has reached one that is possible. Returns the new expansionratio.
scalar y = timeToNextMultiple/wantedDT; scalar y = timeToNextMultiple/wantedDT;
label requiredSteps = nSteps; label requiredSteps = nSteps;
scalar ratioEstimate = deltaTCoeff_; scalar ratioEstimate = deltaTCoeff_;
@ -240,6 +249,7 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
if (!rampDirectionUp) if (!rampDirectionUp)
{ {
ratioEstimate = 1/ratioEstimate; ratioEstimate = 1/ratioEstimate;
ratioMax = 1/ratioMax;
requiredSteps *= -1; requiredSteps *= -1;
} }
// Provision for fall-back value if we can't satisfy requirements // Provision for fall-back value if we can't satisfy requirements
@ -253,16 +263,18 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
y, y,
requiredSteps requiredSteps
); );
const scalar deltaTLoop = wantedDT/pow(newRatio, requiredSteps-1); const scalar deltaTLoop =
wantedDT
/ pow(newRatio, mag(requiredSteps)-1);
scalar firstDeltaRatio = deltaTLoop/deltaT0_; scalar firstDeltaRatio = deltaTLoop/deltaT0_;
// Avoid division by zero for ratio = 1.0
scalar Sn =
deltaTLoop
*(pow(newRatio, mag(requiredSteps))-1)
/(newRatio-1+SMALL);
if (debug) if (debug)
{ {
// Avoid division by zero for ratio = 1.0
scalar Sn =
deltaTLoop
*(pow(newRatio, requiredSteps)-1)
/(newRatio-1+SMALL);
Info<< " nSteps " << requiredSteps Info<< " nSteps " << requiredSteps
<< " ratioEstimate " << ratioEstimate << " ratioEstimate " << ratioEstimate
<< " a0 " << deltaTLoop << " a0 " << deltaTLoop
@ -281,7 +293,7 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
) )
{ {
y += 1; y += 1;
requiredSteps = nSteps; requiredSteps = mag(nSteps);
if (debug) if (debug)
{ {
Info<< "firstDeltaRatio " << firstDeltaRatio << " rampDir" Info<< "firstDeltaRatio " << firstDeltaRatio << " rampDir"
@ -291,7 +303,7 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
continue; continue;
} }
if (firstDeltaRatio > ratioMax) if (firstDeltaRatio > ratioMax && rampDirectionUp)
{ {
requiredSteps++; requiredSteps++;
if (debug) if (debug)
@ -302,7 +314,22 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
<< endl; << endl;
} }
} }
else if (newRatio > ratioMax) else if (firstDeltaRatio < ratioMax && !rampDirectionUp)
{
requiredSteps--;
if (debug)
{
Info<< "First ratio " << firstDeltaRatio
<< " exceeds threshold " << ratioMax << nl
<< "Decreasing required steps " << requiredSteps
<< endl;
}
}
else if
(
(newRatio > ratioMax && rampDirectionUp)
|| (newRatio < ratioMax && !rampDirectionUp)
)
{ {
y += 1; y += 1;
requiredSteps = nSteps; requiredSteps = nSteps;
@ -319,8 +346,19 @@ void Foam::functionObjects::timeControl::calcDeltaTCoeff
// Reset future series expansion at last step // Reset future series expansion at last step
if (requiredSteps == 1) if (requiredSteps == 1)
{ {
Sn = deltaT0_*firstDeltaRatio;
seriesDTCoeff_ = GREAT; seriesDTCoeff_ = GREAT;
} }
// Situations where we achieve wantedDT but fail to achieve
// multiple of writeInterval
scalar jumpError =
remainder(Sn + presentTime, wantedDT) / wantedDT;
if (mag(jumpError) > ROOTSMALL)
{
requiredSteps = label(timeToNextWrite/wantedDT);
firstDeltaRatio = timeToNextWrite/requiredSteps/deltaT0_;
}
if (debug) if (debug)
{ {
Info<< "All conditions satisfied deltaT0_:" << deltaT0_ Info<< "All conditions satisfied deltaT0_:" << deltaT0_
@ -365,10 +403,7 @@ Foam::functionObjects::timeControl::timeControl
dict_(dict), dict_(dict),
timeStart_(-VGREAT), timeStart_(-VGREAT),
timeEnd_(VGREAT), timeEnd_(VGREAT),
nStepsToStartTimeChange_ nStepsToStartTimeChange_(labelMax),
(
dict.lookupOrDefault("nStepsToStartTimeChange", 3)
),
executeControl_(t, dict, "execute"), executeControl_(t, dict, "execute"),
writeControl_(t, dict, "write"), writeControl_(t, dict, "write"),
foPtr_(functionObject::New(name, t, dict_)), foPtr_(functionObject::New(name, t, dict_)),
@ -484,7 +519,7 @@ bool Foam::functionObjects::timeControl::adjustTimeStep()
// too strict. // too strict.
scalar intervalError = scalar intervalError =
remainder(writeInterval, wantedDT)/writeInterval; remainder(writeInterval, wantedDT)/writeInterval;
if if
( (
mag(intervalError) > ROOTSMALL mag(intervalError) > ROOTSMALL
|| deltaTCoeff_ == GREAT || deltaTCoeff_ == GREAT
@ -494,7 +529,14 @@ bool Foam::functionObjects::timeControl::adjustTimeStep()
scalar nSteps = timeToNextWrite/deltaT; scalar nSteps = timeToNextWrite/deltaT;
// For tiny deltaT the label can overflow! // For tiny deltaT the label can overflow!
if (nSteps < labelMax) if
(
nSteps < labelMax
&& (
deltaTCoeff_ != GREAT
|| nSteps < nStepsToStartTimeChange_
)
)
{ {
// nSteps can be < 1 so make sure at least 1 // nSteps can be < 1 so make sure at least 1
@ -517,6 +559,7 @@ bool Foam::functionObjects::timeControl::adjustTimeStep()
clipThreshold = 1/clipThreshold; clipThreshold = 1/clipThreshold;
deltaT = max(newDeltaT, clipThreshold*deltaT); deltaT = max(newDeltaT, clipThreshold*deltaT);
} }
const_cast<Time&>(time_).setDeltaT(deltaT, false); const_cast<Time&>(time_).setDeltaT(deltaT, false);
} }
} }
@ -569,12 +612,12 @@ bool Foam::functionObjects::timeControl::adjustTimeStep()
) )
); );
} }
// Negative steps -> ramp down needed, // Negative steps -> ramp down needed,
// zero steps -> we are at writeInterval-multiple time! // zero steps -> we are at writeInterval-multiple time!
if (nSteps < 1) if (nSteps < 1)
{ {
// Not enough steps to do gradual time step adjustment // Not enough steps to do gradual time step adjustment
// if earlier deltaT larger than wantedDT // if earlier deltaT larger than wantedDT
if (wantedDT < deltaT0_) if (wantedDT < deltaT0_)
{ {
requiredDeltaTCoeff = 1/requiredDeltaTCoeff; requiredDeltaTCoeff = 1/requiredDeltaTCoeff;
@ -582,7 +625,7 @@ bool Foam::functionObjects::timeControl::adjustTimeStep()
( (
requiredDeltaTCoeff, requiredDeltaTCoeff,
wantedDT, wantedDT,
nSteps, nSteps,
presentTime, presentTime,
timeToNextWrite, timeToNextWrite,
false false
@ -614,7 +657,7 @@ bool Foam::functionObjects::timeControl::adjustTimeStep()
( (
requiredDeltaTCoeff, requiredDeltaTCoeff,
wantedDT, wantedDT,
nSteps, nSteps,
presentTime, presentTime,
timeToNextWrite, timeToNextWrite,
true true
@ -635,7 +678,7 @@ bool Foam::functionObjects::timeControl::adjustTimeStep()
} }
} }
} }
else else
{ {
foPtr_->adjustTimeStep(); foPtr_->adjustTimeStep();
const scalar wantedDT = time_.deltaTValue(); const scalar wantedDT = time_.deltaTValue();