Transferred copyright to the OpenFOAM Foundation
[OpenFOAM-2.0.x.git] / src / finiteVolume / cfdTools / general / solutionControl / pimpleControl / pimpleControl.C
blob8707d021ade2e0ea7b9ead32bcd52ddd2b0a4642
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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"
27 #include "Switch.H"
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 namespace Foam
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())
55     {
56         return false;
57     }
59     bool firstIter = corr_ == 1;
61     bool achieved = true;
62     const dictionary& solverDict = mesh_.solverPerformanceDict();
64     forAllConstIter(dictionary, solverDict, iter)
65     {
66         const word& variableName = iter().keyword();
67         label fieldI = applyToField(variableName);
68         if (fieldI != -1)
69         {
70             const List<lduMatrix::solverPerformance> sp(iter().stream());
71             const scalar residual = sp.last().initialResidual();
73             if (firstIter)
74             {
75                 residualControl_[fieldI].initialResidual =
76                     sp.first().initialResidual();
77             }
79             bool absCheck = residual < residualControl_[fieldI].absTol;
81             bool relCheck = false;
83             scalar relative = 0.0;
84             if (!firstIter)
85             {
86                 scalar iniRes =
87                     residualControl_[fieldI].initialResidual
88                   + ROOTVSMALL;
90                 relative = residual/iniRes;
92                 relCheck = relative < residualControl_[fieldI].relTol;
93             }
95             achieved = achieved && (absCheck || relCheck);
97             if (debug)
98             {
99                 Info<< algorithmName_ << "loop statistics:" << endl;
101                 Info<< "    " << variableName << " iter " << corr_
102                     << ": ini res = "
103                     << residualControl_[fieldI].initialResidual
104                     << ", abs tol = " << residual
105                     << " (" << residualControl_[fieldI].absTol << ")"
106                     << ", rel tol = " << relative
107                     << " (" << residualControl_[fieldI].relTol << ")"
108                     << endl;
109             }
110         }
111     }
113     return achieved;
117 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
119 Foam::pimpleControl::pimpleControl(fvMesh& mesh)
121     solutionControl(mesh, "PIMPLE"),
122     nOuterCorr_(0),
123     nCorr_(0),
124     corr_(0),
125     turbOnFinalIterOnly_(true)
127     read();
129     if (nOuterCorr_ > 1)
130     {
131         Info<< nl;
132         if (!residualControl_.empty())
133         {
134             Info<< algorithmName_ << ": max iterations = " << nOuterCorr_
135                 << endl;
136             forAll(residualControl_, i)
137             {
138                 Info<< "    field " << residualControl_[i].name << token::TAB
139                     << ": relTol " << residualControl_[i].relTol
140                     << ", tolerance " << residualControl_[i].absTol
141                     << nl;
142             }
143             Info<< endl;
144         }
145         else
146         {
147             Info<< algorithmName_ << ": no residual control data found. " << nl
148                 << "Calculations will employ " << nOuterCorr_
149                 << " corrector loops" << nl << endl;
150         }
151     }
152     else
153     {
154         Info<< nl << algorithmName_ << ": Operating solver in PISO mode" << nl
155             << endl;
156     }
160 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
162 Foam::pimpleControl::~pimpleControl()
166 // ************************************************************************* //