pimpleControlDF.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v3
5 
6  This file is modified from OpenFOAM's source code
7  src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C
8 
9  OpenFOAM: The Open Source CFD Toolbox
10 
11  Copyright (C): 2011-2016 OpenFOAM Foundation
12 
13  OpenFOAM License:
14 
15  OpenFOAM is free software: you can redistribute it and/or modify it
16  under the terms of the GNU General Public License as published by
17  the Free Software Foundation, either version 3 of the License, or
18  (at your option) any later version.
19 
20  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  for more details.
24 
25  You should have received a copy of the GNU General Public License
26  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27 
28 \*---------------------------------------------------------------------------*/
29 
30 #include "pimpleControlDF.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 defineTypeNameAndDebug(pimpleControlDF, 0);
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 
56 {
57  // no checks on first iteration - nothing has been calculated yet
58  if ((corr_ == 1) || residualControl_.empty() || finalIter())
59  {
60  return false;
61  }
62 
63  const 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  forAllConstIters(solverDict, iter)
70  {
71  const entry& solverPerfDictEntry = *iter;
72 
73  const word& fieldName = solverPerfDictEntry.keyword();
74  const label fieldi = applyToField(fieldName);
75 
76  if (fieldi != -1)
77  {
78  Pair<scalar> residuals = maxResidual(solverPerfDictEntry);
79 
80  checked = true;
81 
82  scalar relative = 0.0;
83  bool relCheck = false;
84 
85  const bool absCheck =
86  (residuals.last() < residualControl_[fieldi].absTol);
87 
88  if (storeIni)
89  {
90  residualControl_[fieldi].initialResidual = residuals.first();
91  }
92  else
93  {
94  const scalar iniRes =
95  (residualControl_[fieldi].initialResidual + ROOTVSMALL);
96 
97  relative = residuals.last() / iniRes;
98  relCheck = (relative < residualControl_[fieldi].relTol);
99  }
100 
101  achieved = achieved && (absCheck || relCheck);
102 
103  if (debug)
104  {
105  Info << algorithmName_ << " loop:" << endl;
106 
107  Info << " " << fieldName
108  << " PIMPLE iter " << corr_
109  << ": ini res = "
110  << residualControl_[fieldi].initialResidual
111  << ", abs tol = " << residuals.last()
112  << " (" << residualControl_[fieldi].absTol << ")"
113  << ", rel tol = " << relative
114  << " (" << residualControl_[fieldi].relTol << ")"
115  << endl;
116  }
117  }
118  }
119 
120  return checked && achieved;
121 }
122 
123 void Foam::pimpleControlDF::setFirstIterFlag(const bool check, const bool force)
124 {
125  DebugInfo
126  << "corr:" << corr_
127  << " corrPISO:" << corrPISO_
128  << " corrNonOrtho:" << corrNonOrtho_
129  << endl;
130 
131  solutionControl::setFirstIterFlag(check && corrPISO_ <= 1, force);
132 }
133 
134 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
135 
136 Foam::pimpleControlDF::pimpleControlDF(fvMesh& mesh, const word& dictName)
137  : solutionControl(mesh, dictName),
138  solveFlow_(true),
139  nCorrPIMPLE_(0),
140  nCorrPISO_(0),
141  corrPISO_(0),
142  SIMPLErho_(false),
143  turbOnFinalIterOnly_(true),
144  converged_(false)
145 {
146  read();
147 
148  Info << nl
149  << algorithmName_;
150 
151  if (nCorrPIMPLE_ > 1)
152  {
153  if (residualControl_.empty())
154  {
155  Info << ": no residual control data found. "
156  << "Calculations will employ " << nCorrPIMPLE_
157  << " corrector loops" << nl;
158  }
159  else
160  {
161  Info << ": max iterations = " << nCorrPIMPLE_ << nl;
162 
163  for (const fieldData& ctrl : residualControl_)
164  {
165  Info << " field " << ctrl.name << token::TAB
166  << ": relTol " << ctrl.relTol
167  << ", tolerance " << ctrl.absTol
168  << nl;
169  }
170  }
171  }
172  else
173  {
174  Info << ": Operating solver in PISO mode" << nl;
175  }
176 
177  Info << endl;
178 }
179 
180 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
181 
183 {
184  read();
185 
186  ++corr_;
187 
188  if (debug)
189  {
190  Info << algorithmName_ << " loop: corr = " << corr_ << endl;
191  }
192 
193  setFirstIterFlag();
194 
195  if (corr_ == nCorrPIMPLE_ + 1)
196  {
197  if (!residualControl_.empty() && (nCorrPIMPLE_ != 1))
198  {
199  if (debug)
200  {
201  Info << algorithmName_ << ": not converged within "
202  << nCorrPIMPLE_ << " iterations" << endl;
203  }
204  }
205 
206  corr_ = 0;
207  mesh_.data::remove("finalIteration");
208  return false;
209  }
210 
211  bool completed = false;
212  if (converged_ || criteriaSatisfied())
213  {
214  if (converged_)
215  {
216  if (debug)
217  {
218  Info << algorithmName_ << ": converged in " << corr_ - 1
219  << " iterations" << endl;
220  }
221 
222  mesh_.data::remove("finalIteration");
223  corr_ = 0;
224  converged_ = false;
225 
226  completed = true;
227  }
228  else
229  {
230  if (debug)
231  {
232  Info << algorithmName_ << ": iteration " << corr_ << endl;
233  }
234  storePrevIterFields();
235 
236  mesh_.data::add("finalIteration", true);
237  converged_ = true;
238  }
239  }
240  else
241  {
242  if (finalIter())
243  {
244  mesh_.data::add("finalIteration", true);
245  }
246 
247  if (corr_ <= nCorrPIMPLE_)
248  {
249  if (debug)
250  {
251  Info << algorithmName_ << ": iteration " << corr_ << endl;
252  }
253  storePrevIterFields();
254  completed = false;
255  }
256  }
257 
258  return !completed;
259 }
260 
261 // ************************************************************************* //
Foam::pimpleControlDF::loop
virtual bool loop()
Definition: pimpleControlDF.C:182
Foam::pimpleControlDF::solveFlow_
bool solveFlow_
Definition: pimpleControlDF.H:68
Foam::pimpleControlDF::setFirstIterFlag
virtual void setFirstIterFlag(const bool check=true, const bool force=false)
Definition: pimpleControlDF.C:123
Foam::pimpleControlDF::nCorrPISO_
label nCorrPISO_
Definition: pimpleControlDF.H:74
Foam::pimpleControlDF::nCorrPIMPLE_
label nCorrPIMPLE_
Definition: pimpleControlDF.H:71
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
pimpleControlDF.H
Foam::pimpleControlDF::SIMPLErho_
bool SIMPLErho_
Definition: pimpleControlDF.H:81
Foam::pimpleControlDF::read
virtual void read()
Definition: pimpleControlDF.C:41
Foam
Definition: multiFreqScalarFvPatchField.C:144
Foam::pimpleControlDF::criteriaSatisfied
virtual bool criteriaSatisfied()
Definition: pimpleControlDF.C:55
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(DAFvSource, 0)
Foam::pimpleControlDF::turbOnFinalIterOnly_
bool turbOnFinalIterOnly_
Definition: pimpleControlDF.H:84