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 {
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 = fieldDict.lookup<scalar>("tolerance");
98  rd.relTol = fieldDict.lookup<scalar>("relTol");
99  data.append(rd);
100  }
101  else
102  {
103  corrResidualData& rd = data[fieldi];
104  const dictionary& fieldDict(iter().dict());
105  rd.absTol = fieldDict.lookup<scalar>("tolerance");
106  rd.relTol = fieldDict.lookup<scalar>("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 
161 corrCriteriaSatisfied() const
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 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:78
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
static DynamicList< word > getFieldNames(const fvMesh &mesh)
Get the list of names of the fields.
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 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.
Corrector convergence control class. Provides methods to check the convergence of an inner iteration ...
Database for solution and other reduced data.
Definition: data.H:54
const word dictName() const
Return the local dictionary name (final part of scoped name)
Definition: dictionary.H:121
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:860
Single-region-specific derivation of the corrector convergence control class.
void printCorrResidualControls(const label n) const
Print the residual controls.
virtual bool hasCorrResidualControls() const
Return true if corrector residual controls are present.
virtual void resetCorrSolveIndex()
Reset the solve index in the correction residual control data.
virtual void updateCorrSolveIndex()
Update the solve index in the correction residual control data.
virtual bool corrCriteriaSatisfied() const
Return true if all correction convergence checks are satisfied.
singleRegionCorrectorConvergenceControl(const singleRegionSolutionControl &control, const word &loopName)
Construct from a solution control and the loop name.
Single-region-specific derivation of the solution control class.
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
static List< word > fieldNames
Definition: globalFoam.H:46
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
messageStream Info
static const scalar ROOTVSMALL
Definition: scalar.H:118
defineTypeNameAndDebug(combustionModel, 0)
error FatalError
static const char nl
Definition: Ostream.H:260
dictionary dict