singleRegionCorrectorConvergenceControl.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2018-2019 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 
27 #include "convergenceControl.H"
28 #include "volFields.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34  defineTypeNameAndDebug(singleRegionCorrectorConvergenceControl, 0);
35 }
36 
37 
38 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
39 
42 (
43  const singleRegionSolutionControl& control,
44  const word& loopName
45 )
46 :
47  correctorConvergenceControl(control, loopName),
48  mesh_(control.mesh()),
49  corrResidualControl_()
50 {}
51 
52 
53 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
54 
57 {}
58 
59 
60 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
61 
63 {
64  const dictionary residualDict
65  (
66  control_.dict().subOrEmptyDict(loopName_ + "ResidualControl")
67  );
68 
69  DynamicList<corrResidualData> data(corrResidualControl_);
70 
71  forAllConstIter(dictionary, residualDict, iter)
72  {
73  const word& fName = iter().keyword();
74  if (!iter().isDict())
75  {
77  << "Corrector loop convergence criteria specified in "
78  << control_.algorithmName() << '.' << residualDict.dictName()
79  << " must be given as dictionaries containing \"tolerance\" "
80  << "and \"relTol\" entries. Solution convergence criteria are "
81  << "specified as single numbers in " << control_.algorithmName()
82  << ".residualControl." << exit(FatalError);
83  }
84 
85  const label fieldi =
87  (
88  fName,
89  corrResidualControl_,
90  false
91  );
92  if (fieldi == -1)
93  {
95  const dictionary& fieldDict(iter().dict());
96  rd.name = fName.c_str();
97  rd.absTol = readScalar(fieldDict.lookup("tolerance"));
98  rd.relTol = readScalar(fieldDict.lookup("relTol"));
99  data.append(rd);
100  }
101  else
102  {
103  corrResidualData& rd = data[fieldi];
104  const dictionary& fieldDict(iter().dict());
105  rd.absTol = readScalar(fieldDict.lookup("tolerance"));
106  rd.relTol = readScalar(fieldDict.lookup("relTol"));
107  }
108  }
109 
110  corrResidualControl_.transfer(data);
111 
112  if (control_.debug > 1)
113  {
114  forAll(corrResidualControl_, i)
115  {
116  const corrResidualData& rd = corrResidualControl_[i];
117  Info<< residualDict.dictName() << '[' << i << "]:" << nl
118  << " name : " << rd.name << nl
119  << " absTol : " << rd.absTol << nl
120  << " relTol : " << rd.relTol << endl;
121  }
122  }
123 
124  return true;
125 }
126 
127 
129 (
130  const label n
131 ) const
132 {
133  Info<< nl;
134 
135  Info<< control_.algorithmName() << ": "
136  << (corrResidualControl_.empty() ? "No c" : "C")
137  << "orrector convergence criteria found" << nl;
138 
139  forAll(corrResidualControl_, i)
140  {
141  Info<< control_.algorithmSpace() << " "
142  << corrResidualControl_[i].name << ": tolerance "
143  << corrResidualControl_[i].absTol << ", relTol "
144  << corrResidualControl_[i].relTol << nl;
145  }
146 
147  Info<< control_.algorithmSpace() << " Calculations will do " << n
148  << " corrections" << (corrResidualControl_.empty() ? "" :
149  " if the convergence criteria are not met") << nl << endl;
150 }
151 
152 
155 {
156  return !corrResidualControl_.empty();
157 }
158 
159 
162 {
163  if (!hasCorrResidualControls())
164  {
165  return false;
166  }
167 
168  bool achieved = true;
169  bool checked = false; // ensure that some checks were actually performed
170 
171  if (control_.debug)
172  {
173  Info<< control_.algorithmName() << ": Correction residuals" << endl;
174  }
175 
177 
178  forAll(fieldNames, i)
179  {
180  const word& fieldName = fieldNames[i];
181  const label fieldi =
183  (
184  fieldName,
185  corrResidualControl_
186  );
187  if (fieldi != -1)
188  {
189  scalar firstResidual, residual;
191  (
192  mesh_,
193  fieldName,
194  solveIndex_.found(fieldName) ? solveIndex_[fieldName] : 0,
195  firstResidual,
196  residual
197  );
198  const scalar relativeResidual =
199  residual/(firstResidual + ROOTVSMALL);
200 
201  const bool absCheck =
202  residual < corrResidualControl_[fieldi].absTol;
203  const bool relCheck =
204  relativeResidual < corrResidualControl_[fieldi].relTol;
205 
206  checked = true;
207  achieved = achieved && (absCheck || relCheck);
208 
209  if (control_.debug)
210  {
211  Info<< control_.algorithmSpace() << " " << fieldName
212  << ": tolerance " << residual << " ("
213  << corrResidualControl_[fieldi].absTol << ")"
214  << ", relTol " << relativeResidual << " ("
215  << corrResidualControl_[fieldi].relTol << ")"
216  << (absCheck || relCheck ? " CONVERGED" : "") << endl;
217  }
218  }
219  }
220 
221  return checked && achieved;
222 }
223 
224 
226 {
227  solveIndex_.clear();
228 }
229 
230 
232 {
234 
235  forAll(fieldNames, i)
236  {
237  const word& fieldName = fieldNames[i];
238 
239  getNSolves
240  (
241  mesh_,
242  fieldName,
243  solveIndex_(fieldName)
244  );
245  }
246 }
247 
248 
249 // ************************************************************************* //
virtual void resetCorrSolveIndex()
Reset the solve index in the correction residual control data.
dictionary dict
void printCorrResidualControls(const label n) const
Print the residual controls.
Single-region-specific derivation of the solution control class.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:158
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
static DynamicList< word > getFieldNames(const fvMesh &mesh)
Get the list of names of the fields.
Corrector convergence control class. Provides methods to check the convergence of an inner iteration ...
static const scalar ROOTVSMALL
Definition: scalar.H:115
static void getInitialResiduals(const fvMesh &mesh, const word &fieldName, const label solvei, scalar &r0, scalar &r)
Get the initial residuals for the first and the i-th solves in this.
static List< word > fieldNames
Definition: globalFoam.H:46
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
virtual void updateCorrSolveIndex()
Update the solve index in the correction residual control data.
A class for handling words, derived from string.
Definition: word.H:59
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if successful.
Definition: doubleScalar.H:68
const fvMesh & mesh() const
Return the mesh.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
virtual bool hasCorrResidualControls() const
Return true if corrector residual controls are present.
static const char nl
Definition: Ostream.H:265
defineTypeNameAndDebug(combustionModel, 0)
Database for solution and other reduced data.
Definition: data.H:51
static label residualControlIndex(const word &fieldName, const List< ResidualData > &residualControl, const bool useRegEx=true)
Return the index of the named field in residual control data, or -1.
virtual bool corrCriteriaSatisfied() const
Return true if all correction convergence checks are satisfied.
messageStream Info
Namespace for OpenFOAM.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:583
singleRegionCorrectorConvergenceControl(const singleRegionSolutionControl &control, const word &loopName)
Construct from a solution control and the loop name.