From 402e6053912eb7a5769ed5d7dc92ac43c3e666b0 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Tue, 28 Nov 2017 11:46:48 +0100 Subject: [PATCH] ENH: expose solutionControl::maxResiduals as a static with simpler parameters - use a Pair<scalar> with first() / last() residuals --- src/OpenFOAM/meshes/data/data.H | 43 +++++----- .../pimpleControl/pimpleControl.C | 86 +++++++++---------- .../pimpleControl/pimpleControl.H | 10 +-- .../pimpleControl/pimpleControlI.H | 10 +-- .../simpleControl/simpleControl.C | 75 +++++++--------- .../simpleControl/simpleControl.H | 14 +-- .../solutionControl/solutionControl.C | 82 +++++++++++------- .../solutionControl/solutionControl.H | 52 +++++++---- .../solutionControl/solutionControlI.H | 10 +-- 9 files changed, 199 insertions(+), 183 deletions(-) diff --git a/src/OpenFOAM/meshes/data/data.H b/src/OpenFOAM/meshes/data/data.H index 61583483644..9671fe30202 100644 --- a/src/OpenFOAM/meshes/data/data.H +++ b/src/OpenFOAM/meshes/data/data.H @@ -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; - - //- 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; + //- 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, using its fieldName + template<class Type> + void setSolverPerformance + ( + const SolverPerformance<Type>& sp + ) const; }; diff --git a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C index 6d031f05b6d..754b7112307 100644 --- a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C +++ b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C @@ -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; + scalar relative = 0.0; + bool relCheck = false; + + const bool absCheck = + (residuals.last() < residualControl_[fieldi].absTol); + if (storeIni) { - residualControl_[fieldi].initialResidual = firstResidual; + residualControl_[fieldi].initialResidual = residuals.first(); } - - const bool absCheck = residual < residualControl_[fieldi].absTol; - bool relCheck = false; - - scalar relative = 0.0; - if (!storeIni) + 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,41 +135,37 @@ 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; } -} - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::pimpleControl::~pimpleControl() -{} + Info<< endl; +} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // @@ -178,7 +174,7 @@ 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; diff --git a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.H b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.H index 5e87b20ea33..73134cdaabb 100644 --- a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.H +++ b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.H @@ -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 diff --git a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControlI.H b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControlI.H index 268655c3d92..f283eb2512b 100644 --- a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControlI.H +++ b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControlI.H @@ -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; } diff --git a/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.C b/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.C index 3724e38ea42..f0b3d68a5b4 100644 --- a/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.C +++ b/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.C @@ -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(); } diff --git a/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.H b/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.H index 8a44079a5c7..36849c75976 100644 --- a/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.H +++ b/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.H @@ -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(); }; diff --git a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.C b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.C index c5a47ca61ed..1d3596fb181 100644 --- a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.C +++ b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.C @@ -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 +{ + return maxResidual(mesh_, solverPerfDictEntry); +} + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +template<class Type> +bool Foam::solutionControl::maxTypeResidual +( + const fvMesh& fvmesh, + const entry& solverPerfDictEntry, + Pair<scalar>& residuals +) { typedef GeometricField<Type, fvPatchField, volMesh> fieldType; - if (mesh_.foundObject<fieldType>(fieldName)) + const word& fieldName = solverPerfDictEntry.keyword(); + + if (fvmesh.foundObject<fieldType>(fieldName)) { - const List<SolverPerformance<Type>> sp(data); - firstRes = cmptMax(sp.first().initialResidual()); - lastRes = cmptMax(sp.last().initialResidual()); + const List<SolverPerformance<Type>> sp(solverPerfDictEntry.stream()); + + residuals.first() = cmptMax(sp.first().initialResidual()); + residuals.last() = cmptMax(sp.last().initialResidual()); + + return true; } + + return false; } -Foam::scalar Foam::solutionControl::maxResidual +Foam::Pair<Foam::scalar> Foam::solutionControl::maxResidual ( - const word& fieldName, - ITstream& data, - scalar& lastRes -) const + const fvMesh& fvmesh, + const entry& solverPerfDictEntry +) { - scalar firstRes = 0; + Pair<scalar> residuals(0,0); - 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); + // 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) + ); - return firstRes; + 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() -{} - - // ************************************************************************* // diff --git a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.H b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.H index 19b45f724bd..921fbcd2580 100644 --- a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.H +++ b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.H @@ -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 diff --git a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControlI.H b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControlI.H index d2316407c07..8fb196669b7 100644 --- a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControlI.H +++ b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControlI.H @@ -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; } -- GitLab