mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
BUG: solutionControl solver objects can return false positives in residualControl
Reported by Mark Olesen
This commit is contained in:
@ -59,36 +59,37 @@ bool Foam::pimpleControl::criteriaSatisfied()
|
|||||||
bool firstIter = corr_ == 1;
|
bool firstIter = corr_ == 1;
|
||||||
|
|
||||||
bool achieved = true;
|
bool achieved = true;
|
||||||
const dictionary& solverDict = mesh_.solverPerformanceDict();
|
bool checked = false; // safety that some checks were indeed performed
|
||||||
|
|
||||||
|
const dictionary& solverDict = mesh_.solverPerformanceDict();
|
||||||
forAllConstIter(dictionary, solverDict, iter)
|
forAllConstIter(dictionary, solverDict, iter)
|
||||||
{
|
{
|
||||||
const word& variableName = iter().keyword();
|
const word& variableName = iter().keyword();
|
||||||
label fieldI = applyToField(variableName);
|
const label fieldI = applyToField(variableName);
|
||||||
if (fieldI != -1)
|
if (fieldI != -1)
|
||||||
{
|
{
|
||||||
const List<lduMatrix::solverPerformance> sp(iter().stream());
|
const List<lduMatrix::solverPerformance> sp(iter().stream());
|
||||||
const scalar residual = sp.last().initialResidual();
|
const scalar residual = sp.last().initialResidual();
|
||||||
|
|
||||||
|
checked = true;
|
||||||
|
|
||||||
if (firstIter)
|
if (firstIter)
|
||||||
{
|
{
|
||||||
residualControl_[fieldI].initialResidual =
|
residualControl_[fieldI].initialResidual =
|
||||||
sp.first().initialResidual();
|
sp.first().initialResidual();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool absCheck = residual < residualControl_[fieldI].absTol;
|
const bool absCheck = residual < residualControl_[fieldI].absTol;
|
||||||
|
|
||||||
bool relCheck = false;
|
bool relCheck = false;
|
||||||
|
|
||||||
scalar relative = 0.0;
|
scalar relative = 0.0;
|
||||||
if (!firstIter)
|
if (!firstIter)
|
||||||
{
|
{
|
||||||
scalar iniRes =
|
const scalar iniRes =
|
||||||
residualControl_[fieldI].initialResidual
|
residualControl_[fieldI].initialResidual
|
||||||
+ ROOTVSMALL;
|
+ ROOTVSMALL;
|
||||||
|
|
||||||
relative = residual/iniRes;
|
relative = residual/iniRes;
|
||||||
|
|
||||||
relCheck = relative < residualControl_[fieldI].relTol;
|
relCheck = relative < residualControl_[fieldI].relTol;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ bool Foam::pimpleControl::criteriaSatisfied()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return achieved;
|
return checked && achieved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -129,7 +130,13 @@ Foam::pimpleControl::pimpleControl(fvMesh& mesh)
|
|||||||
if (nOuterCorr_ > 1)
|
if (nOuterCorr_ > 1)
|
||||||
{
|
{
|
||||||
Info<< nl;
|
Info<< nl;
|
||||||
if (!residualControl_.empty())
|
if (residualControl_.empty())
|
||||||
|
{
|
||||||
|
Info<< algorithmName_ << ": no residual control data found. "
|
||||||
|
<< "Calculations will employ " << nOuterCorr_
|
||||||
|
<< " corrector loops" << nl << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Info<< algorithmName_ << ": max iterations = " << nOuterCorr_
|
Info<< algorithmName_ << ": max iterations = " << nOuterCorr_
|
||||||
<< endl;
|
<< endl;
|
||||||
@ -142,12 +149,6 @@ Foam::pimpleControl::pimpleControl(fvMesh& mesh)
|
|||||||
}
|
}
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Info<< algorithmName_ << ": no residual control data found. " << nl
|
|
||||||
<< "Calculations will employ " << nOuterCorr_
|
|
||||||
<< " corrector loops" << nl << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -69,10 +69,10 @@ protected:
|
|||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
//- Read constrols from fvSolution dictionary
|
//- Read controls from fvSolution dictionary
|
||||||
virtual void read();
|
virtual void read();
|
||||||
|
|
||||||
//- Return true if all convergence checks are satified
|
//- Return true if all convergence checks are satisfied
|
||||||
virtual bool criteriaSatisfied();
|
virtual bool criteriaSatisfied();
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
|
|||||||
@ -50,17 +50,20 @@ bool Foam::simpleControl::criteriaSatisfied()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool achieved = true;
|
bool achieved = true;
|
||||||
const dictionary& solverDict = mesh_.solverPerformanceDict();
|
bool checked = false; // safety that some checks were indeed performed
|
||||||
|
|
||||||
|
const dictionary& solverDict = mesh_.solverPerformanceDict();
|
||||||
forAllConstIter(dictionary, solverDict, iter)
|
forAllConstIter(dictionary, solverDict, iter)
|
||||||
{
|
{
|
||||||
const word& variableName = iter().keyword();
|
const word& variableName = iter().keyword();
|
||||||
label fieldI = applyToField(variableName);
|
const label fieldI = applyToField(variableName);
|
||||||
if (fieldI != -1)
|
if (fieldI != -1)
|
||||||
{
|
{
|
||||||
const List<lduMatrix::solverPerformance> sp(iter().stream());
|
const List<lduMatrix::solverPerformance> sp(iter().stream());
|
||||||
const scalar residual = sp.first().initialResidual();
|
const scalar residual = sp.first().initialResidual();
|
||||||
|
|
||||||
|
checked = true;
|
||||||
|
|
||||||
bool absCheck = residual < residualControl_[fieldI].absTol;
|
bool absCheck = residual < residualControl_[fieldI].absTol;
|
||||||
achieved = achieved && absCheck;
|
achieved = achieved && absCheck;
|
||||||
|
|
||||||
@ -75,7 +78,7 @@ bool Foam::simpleControl::criteriaSatisfied()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return achieved;
|
return checked && achieved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,7 +93,13 @@ Foam::simpleControl::simpleControl(fvMesh& mesh)
|
|||||||
|
|
||||||
Info<< nl;
|
Info<< nl;
|
||||||
|
|
||||||
if (residualControl_.size() > 0)
|
if (residualControl_.empty())
|
||||||
|
{
|
||||||
|
Info<< algorithmName_ << ": no convergence criteria found. "
|
||||||
|
<< "Calculations will run for " << mesh_.time().endTime().value()
|
||||||
|
<< " steps." << nl << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Info<< algorithmName_ << ": convergence criteria" << nl;
|
Info<< algorithmName_ << ": convergence criteria" << nl;
|
||||||
forAll(residualControl_, i)
|
forAll(residualControl_, i)
|
||||||
@ -101,12 +110,6 @@ Foam::simpleControl::simpleControl(fvMesh& mesh)
|
|||||||
}
|
}
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Info<< algorithmName_ << ": no convergence criteria found. "
|
|
||||||
<< "Calculations will run for " << mesh_.time().endTime().value()
|
|
||||||
<< " steps." << nl << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -59,10 +59,10 @@ protected:
|
|||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
//- Read constrols from fvSolution dictionary
|
//- Read controls from fvSolution dictionary
|
||||||
void read();
|
void read();
|
||||||
|
|
||||||
//- Return true if all convergence checks are satified
|
//- Return true if all convergence checks are satisfied
|
||||||
bool criteriaSatisfied();
|
bool criteriaSatisfied();
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
|
|||||||
@ -40,7 +40,7 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class solutionControl Declaration
|
Class solutionControl Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class solutionControl
|
class solutionControl
|
||||||
@ -78,19 +78,19 @@ protected:
|
|||||||
//- Flag to indicate to solve for momentum
|
//- Flag to indicate to solve for momentum
|
||||||
bool momentumPredictor_;
|
bool momentumPredictor_;
|
||||||
|
|
||||||
//- Flag to indictae to solve using transonic algorithm
|
//- Flag to indicate to solve using transonic algorithm
|
||||||
bool transonic_;
|
bool transonic_;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
//- Read constrols from fvSolution dictionary
|
//- Read controls from fvSolution dictionary
|
||||||
virtual void read(const bool absTolOnly);
|
virtual void read(const bool absTolOnly);
|
||||||
|
|
||||||
//- Return index of field in residualControl_ if present
|
//- Return index of field in residualControl_ if present
|
||||||
virtual label applyToField(const word& fieldName) const;
|
virtual label applyToField(const word& fieldName) const;
|
||||||
|
|
||||||
//- Return true if all convergence checks are satified
|
//- Return true if all convergence checks are satisfied
|
||||||
virtual bool criteriaSatisfied() = 0;
|
virtual bool criteriaSatisfied() = 0;
|
||||||
|
|
||||||
//- Store previous iteration fields
|
//- Store previous iteration fields
|
||||||
@ -142,7 +142,7 @@ public:
|
|||||||
//- Flag to indicate to solve for momentum
|
//- Flag to indicate to solve for momentum
|
||||||
inline bool momentumPredictor() const;
|
inline bool momentumPredictor() const;
|
||||||
|
|
||||||
//- Flag to indictae to solve using transonic algorithm
|
//- Flag to indicate to solve using transonic algorithm
|
||||||
inline bool transonic() const;
|
inline bool transonic() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user