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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2017-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "pimpleControl.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35  defineTypeNameAndDebug(pimpleControl, 0);
36 }
37 
38 
39 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
40 
42 {
43  solutionControl::read(false);
44 
45  const dictionary pimpleDict(dict());
46 
47  solveFlow_ = pimpleDict.getOrDefault("solveFlow", true);
48  nCorrPIMPLE_ = pimpleDict.getOrDefault<label>("nOuterCorrectors", 1);
49  nCorrPISO_ = pimpleDict.getOrDefault<label>("nCorrectors", 1);
50  SIMPLErho_ = pimpleDict.getOrDefault("SIMPLErho", false);
52  pimpleDict.getOrDefault("turbOnFinalIterOnly", true);
54  pimpleDict.getOrDefault("finalOnLastPimpleIterOnly", false);
55  ddtCorr_ = pimpleDict.getOrDefault("ddtCorr", true);
56 
57  return true;
58 }
59 
60 
62 {
63  // no checks on first iteration - nothing has been calculated yet
64  if ((corr_ == 1) || residualControl_.empty() || finalIter())
65  {
66  return false;
67  }
68 
69 
70  const bool storeIni = this->storeInitialResiduals();
71 
72  bool achieved = true;
73  bool checked = false; // safety that some checks were indeed performed
74 
75  const dictionary& solverDict = mesh_.solverPerformanceDict();
76  forAllConstIters(solverDict, iter)
77  {
78  const entry& solverPerfDictEntry = *iter;
79 
80  const word& fieldName = solverPerfDictEntry.keyword();
81  const label fieldi = applyToField(fieldName);
82 
83  if (fieldi != -1)
84  {
85  Pair<scalar> residuals = maxResidual(solverPerfDictEntry);
86 
87  checked = true;
88 
89  scalar relative = 0.0;
90  bool relCheck = false;
91 
92  const bool absCheck =
93  (residuals.last() < residualControl_[fieldi].absTol);
94 
95  if (storeIni)
96  {
97  residualControl_[fieldi].initialResidual = residuals.first();
98  }
99  else
100  {
101  const scalar iniRes =
102  (residualControl_[fieldi].initialResidual + ROOTVSMALL);
103 
104  relative = residuals.last() / iniRes;
105  relCheck = (relative < residualControl_[fieldi].relTol);
106  }
107 
108  achieved = achieved && (absCheck || relCheck);
109 
110  if (debug)
111  {
112  Info<< algorithmName_ << " loop:" << endl;
113 
114  Info<< " " << fieldName
115  << " PIMPLE iter " << corr_
116  << ": ini res = "
117  << residualControl_[fieldi].initialResidual
118  << ", abs tol = " << residuals.last()
119  << " (" << residualControl_[fieldi].absTol << ")"
120  << ", rel tol = " << relative
121  << " (" << residualControl_[fieldi].relTol << ")"
122  << endl;
123  }
124  }
125  }
126 
127  return checked && achieved;
128 }
129 
130 
131 void Foam::pimpleControl::setFirstIterFlag(const bool check, const bool force)
132 {
133  DebugInfo
134  << "corr:" << corr_
135  << " corrPISO:" << corrPISO_
136  << " corrNonOrtho:" << corrNonOrtho_
137  << endl;
138 
139  solutionControl::setFirstIterFlag(check && corrPISO_ <= 1, force);
140 }
141 
142 
143 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
144 
145 Foam::pimpleControl::pimpleControl
146 (
147  fvMesh& mesh,
148  const word& dictName,
149  const bool verbose
150 )
151 :
153  solveFlow_(true),
154  nCorrPIMPLE_(0),
155  nCorrPISO_(0),
156  corrPISO_(0),
157  SIMPLErho_(false),
158  turbOnFinalIterOnly_(true),
159  finalOnLastPimpleIterOnly_(false),
160  ddtCorr_(true),
161  converged_(false)
162 {
163  read();
164 
165  if (verbose)
166  {
167  Info<< nl << algorithmName_;
168 
169  if (nCorrPIMPLE_ > 1)
170  {
171  if (residualControl_.empty())
172  {
173  Info<< ": no residual control data found. "
174  << "Calculations will employ " << nCorrPIMPLE_
175  << " corrector loops" << nl;
176  }
177  else
178  {
179  Info<< ": max iterations = " << nCorrPIMPLE_ << nl;
180 
181  for (const fieldData& ctrl : residualControl_)
182  {
183  Info<< " field " << ctrl.name << token::TAB
184  << ": relTol " << ctrl.relTol
185  << ", tolerance " << ctrl.absTol
186  << nl;
187  }
188  }
189  }
190  else
191  {
192  Info<< ": Operating solver in PISO mode" << nl;
193  }
194 
195  Info<< endl;
196  }
197 }
198 
199 
200 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
201 
203 {
204  read();
205 
206  ++corr_;
207 
208  if (debug)
209  {
210  Info<< algorithmName_ << " loop: corr = " << corr_ << endl;
211  }
212 
213  setFirstIterFlag();
214 
215  if (corr_ == nCorrPIMPLE_ + 1)
216  {
217  if (!residualControl_.empty() && (nCorrPIMPLE_ != 1))
218  {
219  Info<< algorithmName_ << ": not converged within "
220  << nCorrPIMPLE_ << " iterations" << endl;
221  }
222 
223  corr_ = 0;
224  mesh_.data::remove("finalIteration");
225  return false;
226  }
227 
228  bool completed = false;
229  if (converged_ || criteriaSatisfied())
230  {
231  if (converged_)
232  {
233  Info<< algorithmName_ << ": converged in " << corr_ - 1
234  << " iterations" << endl;
235 
236  mesh_.data::remove("finalIteration");
237  corr_ = 0;
238  converged_ = false;
239 
240  completed = true;
241  }
242  else
243  {
244  Info<< algorithmName_ << ": iteration " << corr_ << endl;
245  storePrevIterFields();
246 
247  mesh_.data::add("finalIteration", true);
248  converged_ = true;
249  }
250  }
251  else
252  {
253  if (finalIter())
254  {
255  mesh_.data::add("finalIteration", true);
256  }
257 
258  if (corr_ <= nCorrPIMPLE_)
259  {
260  Info<< algorithmName_ << ": iteration " << corr_ << endl;
261  storePrevIterFields();
262  completed = false;
263  }
264  }
265 
266  return !completed;
267 }
268 
269 
270 // ************************************************************************* //
Foam::solutionControl::dict
virtual const dictionary dict() const
Return the solution dictionary.
Definition: solutionControl.C:300
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::pimpleControl::read
virtual bool read()
Read controls from fvSolution dictionary.
Definition: pimpleControl.C:41
Foam::pimpleControl::setFirstIterFlag
virtual void setFirstIterFlag(const bool check=true, const bool force=false)
Set the firstIteration flag on the mesh data dictionary.
Definition: pimpleControl.C:131
Foam::pimpleControl::nCorrPIMPLE_
label nCorrPIMPLE_
Maximum number of PIMPLE correctors.
Definition: pimpleControl.H:78
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::entry::keyword
const keyType & keyword() const
Return keyword.
Definition: entry.H:187
Foam::solutionControl
Base class for solution control classes.
Definition: solutionControl.H:49
Foam::pimpleControl::turbOnFinalIterOnly_
bool turbOnFinalIterOnly_
Flag to indicate whether to only solve turbulence on final iter.
Definition: pimpleControl.H:91
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
dictName
const word dictName("blockMeshDict")
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::pimpleControl::finalOnLastPimpleIterOnly_
bool finalOnLastPimpleIterOnly_
Definition: pimpleControl.H:95
pimpleControl.H
Foam::solutionControl::setFirstIterFlag
virtual void setFirstIterFlag(const bool check=true, const bool force=false)
Set the firstIteration flag on the mesh data dictionary.
Definition: solutionControl.C:181
Foam::pimpleControl::criteriaSatisfied
virtual bool criteriaSatisfied()
Return true if all convergence checks are satisfied.
Definition: pimpleControl.C:61
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::pimpleControl::solveFlow_
bool solveFlow_
Flag to indicate whether to solve for the flow.
Definition: pimpleControl.H:75
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::pimpleControl::loop
virtual bool loop()
PIMPLE loop.
Definition: pimpleControl.C:202
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:83
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::pimpleControl::ddtCorr_
bool ddtCorr_
Flag to indicate that ddtCorr should be applied; default = yes.
Definition: pimpleControl.H:98
Foam::solutionControl::read
virtual bool read()
Read controls from fvSolution dictionary.
Definition: solutionControl.C:136
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:359
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::Pair< scalar >
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
pimpleDict
const dictionary & pimpleDict
Definition: createRegionControls.H:3
Foam::solutionControl::fieldData
Simple convenient storage of field residuals.
Definition: solutionControl.H:56
Foam::pimpleControl::SIMPLErho_
bool SIMPLErho_
Definition: pimpleControl.H:88
Foam::token::TAB
Tab [isspace].
Definition: token.H:118
Foam::fvc::relative
tmp< surfaceScalarField > relative(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given absolute flux in relative form.
Definition: fvcMeshPhi.C:155
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::pimpleControl::nCorrPISO_
label nCorrPISO_
Maximum number of PISO correctors.
Definition: pimpleControl.H:81