pimpleControl.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "pimpleControl.H"
27 #include "Switch.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  defineTypeNameAndDebug(pimpleControl, 0);
34 }
35 
36 
37 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
38 
40 {
41  solutionControl::read(false);
42 
43  const dictionary& pimpleDict = dict();
44 
45  solveFlow_ = pimpleDict.lookupOrDefault<Switch>("solveFlow", true);
46  nCorrPIMPLE_ = pimpleDict.lookupOrDefault<label>("nOuterCorrectors", 1);
47  nCorrPISO_ = pimpleDict.lookupOrDefault<label>("nCorrectors", 1);
48  SIMPLErho_ = pimpleDict.lookupOrDefault<Switch>("SIMPLErho", false);
49  turbOnFinalIterOnly_ =
50  pimpleDict.lookupOrDefault<Switch>("turbOnFinalIterOnly", true);
51 }
52 
53 
55 {
56  // no checks on first iteration - nothing has been calculated yet
57  if ((corr_ == 1) || residualControl_.empty() || finalIter())
58  {
59  return false;
60  }
61 
62 
63  bool storeIni = this->storeInitialResiduals();
64 
65  bool achieved = true;
66  bool checked = false; // safety that some checks were indeed performed
67 
68  const dictionary& solverDict = mesh_.solverPerformanceDict();
69  forAllConstIter(dictionary, solverDict, iter)
70  {
71  const word& variableName = iter().keyword();
72  const label fieldi = applyToField(variableName);
73  if (fieldi != -1)
74  {
75  scalar residual = 0;
76  const scalar firstResidual =
77  maxResidual(variableName, iter().stream(), residual);
78 
79  checked = true;
80 
81  if (storeIni)
82  {
83  residualControl_[fieldi].initialResidual = firstResidual;
84  }
85 
86  const bool absCheck = residual < residualControl_[fieldi].absTol;
87  bool relCheck = false;
88 
89  scalar relative = 0.0;
90  if (!storeIni)
91  {
92  const scalar iniRes =
93  residualControl_[fieldi].initialResidual
94  + ROOTVSMALL;
95 
96  relative = residual/iniRes;
97  relCheck = relative < residualControl_[fieldi].relTol;
98  }
99 
100  achieved = achieved && (absCheck || relCheck);
101 
102  if (debug)
103  {
104  Info<< algorithmName_ << " loop:" << endl;
105 
106  Info<< " " << variableName
107  << " PIMPLE iter " << corr_
108  << ": ini res = "
109  << residualControl_[fieldi].initialResidual
110  << ", abs tol = " << residual
111  << " (" << residualControl_[fieldi].absTol << ")"
112  << ", rel tol = " << relative
113  << " (" << residualControl_[fieldi].relTol << ")"
114  << endl;
115  }
116  }
117  }
118 
119  return checked && achieved;
120 }
121 
122 
123 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
124 
125 Foam::pimpleControl::pimpleControl(fvMesh& mesh, const word& dictName)
126 :
127  solutionControl(mesh, dictName),
128  solveFlow_(true),
129  nCorrPIMPLE_(0),
130  nCorrPISO_(0),
131  corrPISO_(0),
132  SIMPLErho_(false),
133  turbOnFinalIterOnly_(true),
134  converged_(false)
135 {
136  read();
137 
138  if (nCorrPIMPLE_ > 1)
139  {
140  Info<< nl;
141  if (residualControl_.empty())
142  {
143  Info<< algorithmName_ << ": no residual control data found. "
144  << "Calculations will employ " << nCorrPIMPLE_
145  << " corrector loops" << nl << endl;
146  }
147  else
148  {
149  Info<< algorithmName_ << ": max iterations = " << nCorrPIMPLE_
150  << endl;
152  {
153  Info<< " field " << residualControl_[i].name << token::TAB
154  << ": relTol " << residualControl_[i].relTol
155  << ", tolerance " << residualControl_[i].absTol
156  << nl;
157  }
158  Info<< endl;
159  }
160  }
161  else
162  {
163  Info<< nl << algorithmName_ << ": Operating solver in PISO mode" << nl
164  << endl;
165  }
166 }
167 
168 
169 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
170 
172 {}
173 
174 
175 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
176 
178 {
179  read();
180 
181  corr_++;
182 
183  if (debug)
184  {
185  Info<< algorithmName_ << " loop: corr = " << corr_ << endl;
186  }
187 
188  if (corr_ == nCorrPIMPLE_ + 1)
189  {
190  if ((!residualControl_.empty()) && (nCorrPIMPLE_ != 1))
191  {
192  Info<< algorithmName_ << ": not converged within "
193  << nCorrPIMPLE_ << " iterations" << endl;
194  }
195 
196  corr_ = 0;
197  mesh_.data::remove("finalIteration");
198  return false;
199  }
200 
201  bool completed = false;
202  if (converged_ || criteriaSatisfied())
203  {
204  if (converged_)
205  {
206  Info<< algorithmName_ << ": converged in " << corr_ - 1
207  << " iterations" << endl;
208 
209  mesh_.data::remove("finalIteration");
210  corr_ = 0;
211  converged_ = false;
212 
213  completed = true;
214  }
215  else
216  {
217  Info<< algorithmName_ << ": iteration " << corr_ << endl;
219 
220  mesh_.data::add("finalIteration", true);
221  converged_ = true;
222  }
223  }
224  else
225  {
226  if (finalIter())
227  {
228  mesh_.data::add("finalIteration", true);
229  }
230 
231  if (corr_ <= nCorrPIMPLE_)
232  {
233  Info<< algorithmName_ << ": iteration " << corr_ << endl;
235  completed = false;
236  }
237  }
238 
239  return !completed;
240 }
241 
242 
243 // ************************************************************************* //
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
fvMesh & mesh_
Reference to the mesh database.
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
List< fieldData > residualControl_
List of residual data per field.
Base class for solution control classes.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, y/n, t/f, or none.
Definition: Switch.H:60
dynamicFvMesh & mesh
virtual void read()
Read controls from fvSolution dictionary.
Definition: pimpleControl.C:39
A class for handling words, derived from string.
Definition: word.H:59
virtual bool loop()
PIMPLE loop.
const word algorithmName_
The dictionary name, e.g. SIMPLE, PIMPLE.
const word dictName("particleTrackDict")
label nCorrPIMPLE_
Maximum number of PIMPLE correctors.
Definition: pimpleControl.H:75
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
virtual void read()
Read controls from fvSolution dictionary.
static const char nl
Definition: Ostream.H:262
defineTypeNameAndDebug(combustionModel, 0)
label corr_
Current corrector loop index.
virtual void storePrevIterFields() const
Store previous iteration fields.
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
const dictionary & pimpleDict
Definition: setRDeltaT.H:29
messageStream Info
virtual bool criteriaSatisfied()
Return true if all convergence checks are satisfied.
Definition: pimpleControl.C:54
virtual ~pimpleControl()
Destructor.
bool finalIter() const
Return true fore final PIMPLE (outer) iteration.
Namespace for OpenFOAM.
bool converged_
Converged flag.
Definition: pimpleControl.H:91
tmp< surfaceScalarField > relative(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given absolute flux in relative form.
Definition: fvcMeshPhi.C:153