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-2023 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 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
39 
41 {
42  const dictionary residualDict
43  (
44  control_.dict().subOrEmptyDict(loopName_ + "ResidualControl")
45  );
46 
48 
49  forAllConstIter(dictionary, residualDict, iter)
50  {
51  const word& fName = iter().keyword();
52  if (!iter().isDict())
53  {
55  << "Corrector loop convergence criteria specified in "
56  << control_.algorithmName() << '.' << residualDict.dictName()
57  << " must be given as dictionaries containing \"tolerance\" "
58  << "and \"relTol\" entries. Solution convergence criteria are "
59  << "specified as single numbers in " << control_.algorithmName()
60  << ".residualControl." << exit(FatalError);
61  }
62 
63  const label fieldi =
65  (
66  fName,
68  false
69  );
70  if (fieldi == -1)
71  {
73  const dictionary& fieldDict(iter().dict());
74  rd.name = fName.c_str();
75  rd.absTol = fieldDict.lookup<scalar>("tolerance");
76  rd.relTol = fieldDict.lookup<scalar>("relTol");
77  data.append(rd);
78  }
79  else
80  {
81  corrResidualData& rd = data[fieldi];
82  const dictionary& fieldDict(iter().dict());
83  rd.absTol = fieldDict.lookup<scalar>("tolerance");
84  rd.relTol = fieldDict.lookup<scalar>("relTol");
85  }
86  }
87 
89 
90  if (control_.debug > 1)
91  {
93  {
95  Info<< residualDict.dictName() << '[' << i << "]:" << nl
96  << " name : " << rd.name << nl
97  << " absTol : " << rd.absTol << nl
98  << " relTol : " << rd.relTol << endl;
99  }
100  }
101 
102  return true;
103 }
104 
105 
106 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
107 
110 (
111  const singleRegionSolutionControl& control,
112  const word& loopName
113 )
114 :
115  correctorConvergenceControl(control, loopName),
116  mesh_(control.mesh()),
117  corrResidualControl_()
118 {
119  read();
120 }
121 
122 
123 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
124 
127 {}
128 
129 
130 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
131 
133 (
134  const label n
135 ) const
136 {
137  Info<< nl;
138 
139  Info<< control_.algorithmName() << ": "
140  << (corrResidualControl_.empty() ? "No c" : "C")
141  << "orrector convergence criteria found" << nl;
142 
143  forAll(corrResidualControl_, i)
144  {
145  Info<< control_.algorithmSpace() << " "
146  << corrResidualControl_[i].name << ": tolerance "
147  << corrResidualControl_[i].absTol << ", relTol "
148  << corrResidualControl_[i].relTol << nl;
149  }
150 
151  Info<< control_.algorithmSpace() << " Calculations will do " << n
152  << " corrections" << (corrResidualControl_.empty() ? "" :
153  " if the convergence criteria are not met") << nl << endl;
154 }
155 
156 
159 {
160  return !corrResidualControl_.empty();
161 }
162 
163 
165 corrCriteriaSatisfied() const
166 {
167  if (!hasCorrResidualControls())
168  {
169  return false;
170  }
171 
172  bool achieved = true;
173  bool checked = false; // ensure that some checks were actually performed
174 
175  if (control_.debug)
176  {
177  Info<< control_.algorithmName() << ": Correction residuals" << endl;
178  }
179 
181 
182  forAll(fieldNames, i)
183  {
184  const word& fieldName = fieldNames[i];
185  const label fieldi =
187  (
188  fieldName,
189  corrResidualControl_
190  );
191  if (fieldi != -1)
192  {
193  scalar firstResidual, residual;
195  (
196  mesh_,
197  fieldName,
198  solveIndex_.found(fieldName) ? solveIndex_[fieldName] : 0,
199  firstResidual,
200  residual
201  );
202  const scalar relativeResidual =
203  residual/(firstResidual + ROOTVSMALL);
204 
205  const bool absCheck =
206  residual < corrResidualControl_[fieldi].absTol;
207  const bool relCheck =
208  relativeResidual < corrResidualControl_[fieldi].relTol;
209 
210  checked = true;
211  achieved = achieved && (absCheck || relCheck);
212 
213  if (control_.debug)
214  {
215  Info<< control_.algorithmSpace() << " " << fieldName
216  << ": tolerance " << residual << " ("
217  << corrResidualControl_[fieldi].absTol << ")"
218  << ", relTol " << relativeResidual << " ("
219  << corrResidualControl_[fieldi].relTol << ")"
220  << (absCheck || relCheck ? " CONVERGED" : "") << endl;
221  }
222  }
223  }
224 
225  return checked && achieved;
226 }
227 
228 
230 {
231  solveIndex_.clear();
232 }
233 
234 
236 {
238 
239  forAll(fieldNames, i)
240  {
241  const word& fieldName = fieldNames[i];
242 
243  getNSolves
244  (
245  mesh_,
246  fieldName,
247  solveIndex_(fieldName)
248  );
249  }
250 }
251 
252 
253 // ************************************************************************* //
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
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
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 ...
const solutionControl & control_
Reference to the solution control.
const word loopName_
Name of the corrector loop.
const word dictName() const
Return the local dictionary name (final part of scoped name)
Definition: dictionary.H:123
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:162
dictionary subOrEmptyDict(const word &, const bool mustRead=false) const
Find and return a sub-dictionary as a copy, or.
Definition: dictionary.C:894
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:710
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.
List< corrResidualData > corrResidualControl_
List of residual data per field.
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.
const word & algorithmName() const
Return the name of the algorithm.
virtual const dictionary & dict() const =0
Return the dictionary.
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
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:257
messageStream Info
static const scalar ROOTVSMALL
Definition: scalar.H:118
defineTypeNameAndDebug(combustionModel, 0)
error FatalError
static const char nl
Definition: Ostream.H:266
dictionary dict