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 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  rd.solveIndex = 0;
100  data.append(rd);
101  }
102  else
103  {
104  corrResidualData& rd = data[fieldi];
105  const dictionary& fieldDict(iter().dict());
106  rd.absTol = readScalar(fieldDict.lookup("tolerance"));
107  rd.relTol = readScalar(fieldDict.lookup("relTol"));
108  }
109  }
110 
111  corrResidualControl_.transfer(data);
112 
113  if (control_.debug > 1)
114  {
115  forAll(corrResidualControl_, i)
116  {
117  const corrResidualData& rd = corrResidualControl_[i];
118  Info<< residualDict.dictName() << '[' << i << "]:" << nl
119  << " name : " << rd.name << nl
120  << " absTol : " << rd.absTol << nl
121  << " relTol : " << rd.relTol << endl;
122  }
123  }
124 
125  return true;
126 }
127 
128 
130 (
131  const label n
132 ) const
133 {
134  Info<< nl;
135 
136  Info<< control_.algorithmName() << ": "
137  << (corrResidualControl_.empty() ? "No c" : "C")
138  << "orrector convergence criteria found" << nl;
139 
140  forAll(corrResidualControl_, i)
141  {
142  Info<< control_.algorithmSpace() << " "
143  << corrResidualControl_[i].name << ": tolerance "
144  << corrResidualControl_[i].absTol << ", relTol "
145  << corrResidualControl_[i].relTol << nl;
146  }
147 
148  Info<< control_.algorithmSpace() << " Calclations will do " << n
149  << " corrections" << (corrResidualControl_.empty() ? "" :
150  " if the convergence criteria are not met") << nl << endl;
151 }
152 
153 
156 {
157  return !corrResidualControl_.empty();
158 }
159 
160 
163 {
164  if (!hasCorrResidualControls())
165  {
166  return false;
167  }
168 
169  bool achieved = true;
170  bool checked = false; // ensure that some checks were actually performed
171 
172  if (control_.debug)
173  {
174  Info<< control_.algorithmName() << ": Correction residuals" << endl;
175  }
176 
177  const dictionary& solverDict = mesh_.solverPerformanceDict();
178  forAllConstIter(dictionary, solverDict, iter)
179  {
180  const word& variableName = iter().keyword();
181  const label fieldi =
183  (
184  variableName,
185  corrResidualControl_
186  );
187  if (fieldi != -1)
188  {
189  scalar firstResidual, residual;
191  (
192  mesh_,
193  variableName,
194  corrResidualControl_[fieldi].solveIndex,
195  iter().stream(),
196  firstResidual,
197  residual
198  );
199  const scalar relativeResidual =
200  residual/(firstResidual + ROOTVSMALL);
201 
202  const bool absCheck =
203  residual < corrResidualControl_[fieldi].absTol;
204  const bool relCheck =
205  relativeResidual < corrResidualControl_[fieldi].relTol;
206 
207  checked = true;
208  achieved = achieved && (absCheck || relCheck);
209 
210  if (control_.debug)
211  {
212  Info<< control_.algorithmSpace() << " " << variableName
213  << ": tolerance " << residual << " ("
214  << corrResidualControl_[fieldi].absTol << ")"
215  << ", relTol " << relativeResidual << " ("
216  << corrResidualControl_[fieldi].relTol << ")"
217  << (absCheck || relCheck ? " CONVERGED" : "") << endl;
218  }
219  }
220  }
221 
222  return checked && achieved;
223 }
224 
225 
227 {
228  forAll(corrResidualControl_, i)
229  {
230  corrResidualControl_[i].solveIndex = 0;
231  }
232 }
233 
234 
236 {
237  const dictionary& solverDict = mesh_.solverPerformanceDict();
238  forAllConstIter(dictionary, solverDict, iter)
239  {
240  const word& variableName = iter().keyword();
241  const label fieldi =
243  (
244  variableName,
245  corrResidualControl_
246  );
247  if (fieldi != -1)
248  {
249  getNSolves
250  (
251  mesh_,
252  variableName,
253  iter().stream(),
254  corrResidualControl_[fieldi].solveIndex
255  );
256  }
257  }
258 }
259 
260 
261 // ************************************************************************* //
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:428
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:137
#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
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, ITstream &data, scalar &r0, scalar &r)
Get the initial residuals for the first and the i-th solves in this.
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 data, solver performance and other reduced data.
Definition: data.H:52
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:576
singleRegionCorrectorConvergenceControl(const singleRegionSolutionControl &control, const word &loopName)
Construct from a solution control and the loop name.