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 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.lookupOrDefault("solveFlow", true);
48  nCorrPIMPLE_ = pimpleDict.lookupOrDefault<label>("nOuterCorrectors", 1);
49  nCorrPISO_ = pimpleDict.lookupOrDefault<label>("nCorrectors", 1);
50  SIMPLErho_ = pimpleDict.lookupOrDefault("SIMPLErho", false);
52  pimpleDict.lookupOrDefault("turbOnFinalIterOnly", true);
53 
54  return true;
55 }
56 
57 
59 {
60  // no checks on first iteration - nothing has been calculated yet
61  if ((corr_ == 1) || residualControl_.empty() || finalIter())
62  {
63  return false;
64  }
65 
66 
67  const bool storeIni = this->storeInitialResiduals();
68 
69  bool achieved = true;
70  bool checked = false; // safety that some checks were indeed performed
71 
72  const dictionary& solverDict = mesh_.solverPerformanceDict();
73  forAllConstIters(solverDict, iter)
74  {
75  const entry& solverPerfDictEntry = *iter;
76 
77  const word& fieldName = solverPerfDictEntry.keyword();
78  const label fieldi = applyToField(fieldName);
79 
80  if (fieldi != -1)
81  {
82  Pair<scalar> residuals = maxResidual(solverPerfDictEntry);
83 
84  checked = true;
85 
86  scalar relative = 0.0;
87  bool relCheck = false;
88 
89  const bool absCheck =
90  (residuals.last() < residualControl_[fieldi].absTol);
91 
92  if (storeIni)
93  {
94  residualControl_[fieldi].initialResidual = residuals.first();
95  }
96  else
97  {
98  const scalar iniRes =
99  (residualControl_[fieldi].initialResidual + ROOTVSMALL);
100 
101  relative = residuals.last() / iniRes;
102  relCheck = (relative < residualControl_[fieldi].relTol);
103  }
104 
105  achieved = achieved && (absCheck || relCheck);
106 
107  if (debug)
108  {
109  Info<< algorithmName_ << " loop:" << endl;
110 
111  Info<< " " << fieldName
112  << " PIMPLE iter " << corr_
113  << ": ini res = "
114  << residualControl_[fieldi].initialResidual
115  << ", abs tol = " << residuals.last()
116  << " (" << residualControl_[fieldi].absTol << ")"
117  << ", rel tol = " << relative
118  << " (" << residualControl_[fieldi].relTol << ")"
119  << endl;
120  }
121  }
122  }
123 
124  return checked && achieved;
125 }
126 
127 
128 void Foam::pimpleControl::setFirstIterFlag(const bool check, const bool force)
129 {
130  DebugInfo
131  << "corr:" << corr_
132  << " corrPISO:" << corrPISO_
133  << " corrNonOrtho:" << corrNonOrtho_
134  << endl;
135 
136  solutionControl::setFirstIterFlag(check && corrPISO_ <= 1, force);
137 }
138 
139 
140 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
141 
142 Foam::pimpleControl::pimpleControl
143 (
144  fvMesh& mesh,
145  const word& dictName,
146  const bool verbose
147 )
148 :
150  solveFlow_(true),
151  nCorrPIMPLE_(0),
152  nCorrPISO_(0),
153  corrPISO_(0),
154  SIMPLErho_(false),
155  turbOnFinalIterOnly_(true),
156  converged_(false)
157 {
158  read();
159 
160  if (verbose)
161  {
162  Info<< nl << algorithmName_;
163 
164  if (nCorrPIMPLE_ > 1)
165  {
166  if (residualControl_.empty())
167  {
168  Info<< ": no residual control data found. "
169  << "Calculations will employ " << nCorrPIMPLE_
170  << " corrector loops" << nl;
171  }
172  else
173  {
174  Info<< ": max iterations = " << nCorrPIMPLE_ << nl;
175 
176  for (const fieldData& ctrl : residualControl_)
177  {
178  Info<< " field " << ctrl.name << token::TAB
179  << ": relTol " << ctrl.relTol
180  << ", tolerance " << ctrl.absTol
181  << nl;
182  }
183  }
184  }
185  else
186  {
187  Info<< ": Operating solver in PISO mode" << nl;
188  }
189 
190  Info<< endl;
191  }
192 }
193 
194 
195 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
196 
198 {
199  read();
200 
201  ++corr_;
202 
203  if (debug)
204  {
205  Info<< algorithmName_ << " loop: corr = " << corr_ << endl;
206  }
207 
208  setFirstIterFlag();
209 
210  if (corr_ == nCorrPIMPLE_ + 1)
211  {
212  if (!residualControl_.empty() && (nCorrPIMPLE_ != 1))
213  {
214  Info<< algorithmName_ << ": not converged within "
215  << nCorrPIMPLE_ << " iterations" << endl;
216  }
217 
218  corr_ = 0;
219  mesh_.data::remove("finalIteration");
220  return false;
221  }
222 
223  bool completed = false;
224  if (converged_ || criteriaSatisfied())
225  {
226  if (converged_)
227  {
228  Info<< algorithmName_ << ": converged in " << corr_ - 1
229  << " iterations" << endl;
230 
231  mesh_.data::remove("finalIteration");
232  corr_ = 0;
233  converged_ = false;
234 
235  completed = true;
236  }
237  else
238  {
239  Info<< algorithmName_ << ": iteration " << corr_ << endl;
240  storePrevIterFields();
241 
242  mesh_.data::add("finalIteration", true);
243  converged_ = true;
244  }
245  }
246  else
247  {
248  if (finalIter())
249  {
250  mesh_.data::add("finalIteration", true);
251  }
252 
253  if (corr_ <= nCorrPIMPLE_)
254  {
255  Info<< algorithmName_ << ": iteration " << corr_ << endl;
256  storePrevIterFields();
257  completed = false;
258  }
259  }
260 
261  return !completed;
262 }
263 
264 
265 // ************************************************************************* //
Foam::solutionControl::dict
virtual const dictionary dict() const
Return the solution dictionary.
Definition: solutionControl.C:299
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:128
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:337
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:180
pimpleDict
const dictionary & pimpleDict
Definition: setRDeltaT.H:31
Foam::pimpleControl::criteriaSatisfied
virtual bool criteriaSatisfied()
Return true if all convergence checks are satisfied.
Definition: pimpleControl.C:58
Foam::label
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:62
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:197
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::solutionControl::read
virtual bool read()
Read controls from fvSolution dictionary.
Definition: solutionControl.C:135
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:350
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::Pair< scalar >
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::solutionControl::fieldData
Simple convenient storage of field residuals.
Definition: solutionControl.H:56
Foam::pimpleControl::SIMPLErho_
bool SIMPLErho_
Flag to indicate whether to update density in SIMPLE.
Definition: pimpleControl.H:88
Foam::token::TAB
Tab [isspace].
Definition: token.H:113
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