singleRegionConvergenceControl.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 "volFields.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  defineTypeNameAndDebug(singleRegionConvergenceControl, 0);
34 }
35 
36 
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 
40 (
41  const singleRegionSolutionControl& control
42 )
43 :
44  convergenceControl(control),
45  mesh_(control.mesh()),
46  residualControl_()
47 {}
48 
49 
50 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
51 
53 {}
54 
55 
56 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
57 
59 {
60  const dictionary residualDict
61  (
62  control_.dict().subOrEmptyDict("residualControl")
63  );
64 
65  DynamicList<residualData> data(residualControl_);
66 
67  forAllConstIter(dictionary, residualDict, iter)
68  {
69  const word& fName = iter().keyword();
70 
71  if (iter().isDict())
72  {
74  << "Solution convergence criteria specified in "
75  << control_.algorithmName() << '.' << residualDict.dictName()
76  << " must be given as single values. Corrector loop "
77  << "convergence criteria, if appropriate, are specified as "
78  << "dictionaries in " << control_.algorithmName()
79  << ".<loopName>ResidualControl." << exit(FatalError);
80  }
81 
82  const label fieldi =
83  residualControlIndex(fName, residualControl_, false);
84  if (fieldi == -1)
85  {
86  residualData rd;
87  rd.name = fName.c_str();
88  rd.absTol = readScalar(residualDict.lookup(fName));
89  data.append(rd);
90  }
91  else
92  {
93  residualData& rd = data[fieldi];
94  rd.absTol = readScalar(residualDict.lookup(fName));
95  }
96  }
97 
98  residualControl_.transfer(data);
99 
100  if (control_.debug > 1)
101  {
102  forAll(residualControl_, i)
103  {
104  const residualData& rd = residualControl_[i];
105  Info<< residualDict.dictName() << '[' << i << "]:" << nl
106  << " name : " << rd.name << nl
107  << " absTol : " << rd.absTol << endl;
108  }
109  }
110 
111  return true;
112 }
113 
114 
116 {
117  Info<< nl;
118 
119  Info<< control_.algorithmName() << ": "
120  << (residualControl_.empty() ? "No c" : "C")
121  << "onvergence criteria found" << nl;
122 
123  forAll(residualControl_, i)
124  {
125  Info<< control_.algorithmSpace() << " " << residualControl_[i].name
126  << ": tolerance " << residualControl_[i].absTol << nl;
127  }
128 
129  Info << endl;
130 }
131 
132 
134 {
135  return !residualControl_.empty();
136 }
137 
138 
140 {
141  if (!hasResidualControls())
142  {
143  return false;
144  }
145 
146  bool achieved = true;
147  bool checked = false; // ensure that some checks were actually performed
148 
149  if (control_.debug)
150  {
151  Info<< control_.algorithmName() << ": Residuals" << endl;
152  }
153 
154  const dictionary& solverDict = mesh_.solverPerformanceDict();
155  forAllConstIter(dictionary, solverDict, iter)
156  {
157  const word& variableName = iter().keyword();
158  const label fieldi =
159  residualControlIndex(variableName, residualControl_);
160  if (fieldi != -1)
161  {
162  scalar residual;
163  getInitialResiduals
164  (
165  mesh_,
166  variableName,
167  0,
168  iter().stream(),
169  residual,
170  residual
171  );
172 
173  checked = true;
174 
175  bool absCheck = residual < residualControl_[fieldi].absTol;
176 
177  achieved = achieved && absCheck;
178 
179  if (control_.debug)
180  {
181  Info<< control_.algorithmSpace() << " " << variableName
182  << ": tolerance " << residual << " ("
183  << residualControl_[fieldi].absTol << ")"
184  << (absCheck ? " CONVERGED" : "") << endl;
185  }
186  }
187  }
188 
189  return checked && achieved;
190 }
191 
192 
193 // ************************************************************************* //
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
bool readResidualControls()
Read residual controls.
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
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
A class for handling words, derived from string.
Definition: word.H:59
Convergence control class. Provides methods to check the convergence of the time loop against an abso...
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.
virtual bool hasResidualControls() const
Return true if residual controls are present.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
static const char nl
Definition: Ostream.H:265
singleRegionConvergenceControl(const singleRegionSolutionControl &control)
Construct from a solution control.
defineTypeNameAndDebug(combustionModel, 0)
Database for solution data, solver performance and other reduced data.
Definition: data.H:52
virtual bool criteriaSatisfied() const
Return true if all convergence checks are satisfied.
messageStream Info
void printResidualControls() const
Print the residual controls.
Namespace for OpenFOAM.