1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "pimpleControl.H"
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 defineTypeNameAndDebug(pimpleControl, 0);
37 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
39 void Foam::pimpleControl::read()
41 solutionControl::read(false);
43 // Read solution controls
44 const dictionary& pimpleDict = dict();
45 nOuterCorr_ = pimpleDict.lookupOrDefault<label>("nOuterCorrectors", 1);
46 nCorr_ = pimpleDict.lookupOrDefault<label>("nCorrectors", 1);
47 turbOnFinalIterOnly_ =
48 pimpleDict.lookupOrDefault<Switch>("turbOnFinalIterOnly", true);
52 bool Foam::pimpleControl::criteriaSatisfied()
54 if ((corr_ == 0) || residualControl_.empty() || finalIter())
59 bool firstIter = corr_ == 1;
62 const dictionary& solverDict = mesh_.solverPerformanceDict();
64 forAllConstIter(dictionary, solverDict, iter)
66 const word& variableName = iter().keyword();
67 label fieldI = applyToField(variableName);
70 const List<lduMatrix::solverPerformance> sp(iter().stream());
71 const scalar residual = sp.last().initialResidual();
75 residualControl_[fieldI].initialResidual =
76 sp.first().initialResidual();
79 bool absCheck = residual < residualControl_[fieldI].absTol;
81 bool relCheck = false;
83 scalar relative = 0.0;
87 residualControl_[fieldI].initialResidual
90 relative = residual/iniRes;
92 relCheck = relative < residualControl_[fieldI].relTol;
95 achieved = achieved && (absCheck || relCheck);
99 Info<< algorithmName_ << "loop statistics:" << endl;
101 Info<< " " << variableName << " iter " << corr_
103 << residualControl_[fieldI].initialResidual
104 << ", abs tol = " << residual
105 << " (" << residualControl_[fieldI].absTol << ")"
106 << ", rel tol = " << relative
107 << " (" << residualControl_[fieldI].relTol << ")"
117 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
119 Foam::pimpleControl::pimpleControl(fvMesh& mesh)
121 solutionControl(mesh, "PIMPLE"),
125 turbOnFinalIterOnly_(true)
132 if (!residualControl_.empty())
134 Info<< algorithmName_ << ": max iterations = " << nOuterCorr_
136 forAll(residualControl_, i)
138 Info<< " field " << residualControl_[i].name << token::TAB
139 << ": relTol " << residualControl_[i].relTol
140 << ", tolerance " << residualControl_[i].absTol
147 Info<< algorithmName_ << ": no residual control data found. " << nl
148 << "Calculations will employ " << nOuterCorr_
149 << " corrector loops" << nl << endl;
154 Info<< nl << algorithmName_ << ": Operating solver in PISO mode" << nl
160 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
162 Foam::pimpleControl::~pimpleControl()
166 // ************************************************************************* //