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-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 "volFields.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
34 }
35 
36 
37 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
38 
40 {
41  const dictionary residualDict
42  (
43  control_.dict().subOrEmptyDict("residualControl")
44  );
45 
47 
48  forAllConstIter(dictionary, residualDict, iter)
49  {
50  const word& fName = iter().keyword();
51 
52  if (iter().isDict())
53  {
55  << "Solution convergence criteria specified in "
56  << control_.algorithmName() << '.' << residualDict.dictName()
57  << " must be given as single values. Corrector loop "
58  << "convergence criteria, if appropriate, are specified as "
59  << "dictionaries in " << control_.algorithmName()
60  << ".<loopName>ResidualControl." << exit(FatalError);
61  }
62 
63  const label fieldi =
65  if (fieldi == -1)
66  {
67  residualData rd;
68  rd.name = fName.c_str();
69  rd.absTol = residualDict.lookup<scalar>(fName);
70  data.append(rd);
71  }
72  else
73  {
74  residualData& rd = data[fieldi];
75  rd.absTol = residualDict.lookup<scalar>(fName);
76  }
77  }
78 
80 
81  if (control_.debug > 1)
82  {
84  {
85  const residualData& rd = residualControl_[i];
86  Info<< residualDict.dictName() << '[' << i << "]:" << nl
87  << " name : " << rd.name << nl
88  << " absTol : " << rd.absTol << endl;
89  }
90  }
91 
92  return true;
93 }
94 
95 
96 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
97 
99 (
100  const singleRegionSolutionControl& control
101 )
102 :
103  convergenceControl(control),
104  mesh_(control.mesh()),
105  residualControl_()
106 {
107  read();
108 }
109 
110 
111 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
112 
114 {}
115 
116 
117 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
118 
120 {
121  Info<< nl;
122 
123  Info<< control_.algorithmName() << ": "
124  << (residualControl_.empty() ? "No c" : "C")
125  << "onvergence criteria found" << nl;
126 
127  forAll(residualControl_, i)
128  {
129  Info<< control_.algorithmSpace() << " " << residualControl_[i].name
130  << ": tolerance " << residualControl_[i].absTol << nl;
131  }
132 
133  Info << endl;
134 }
135 
136 
138 {
139  return !residualControl_.empty();
140 }
141 
142 
145 {
146  if (!hasResidualControls())
147  {
148  return {false, false};
149  }
150 
151  convergenceData cs{false, true};
152 
153  if (control_.debug)
154  {
155  Info<< control_.algorithmName() << ": Residuals" << endl;
156  }
157 
158  DynamicList<word> fieldNames(getFieldNames(mesh_));
159 
160  forAll(fieldNames, i)
161  {
162  const word& fieldName = fieldNames[i];
163  const label fieldi = residualControlIndex(fieldName, residualControl_);
164  if (fieldi != -1)
165  {
166  scalar residual;
167  getInitialResiduals
168  (
169  mesh_,
170  fieldName,
171  0,
172  residual,
173  residual
174  );
175 
176  cs.checked = true;
177 
178  const bool absCheck = residual < residualControl_[fieldi].absTol;
179 
180  cs.satisfied = cs.satisfied && absCheck;
181 
182  if (control_.debug)
183  {
184  Info<< control_.algorithmSpace() << " " << fieldName
185  << ": tolerance " << residual << " ("
186  << residualControl_[fieldi].absTol << ")"
187  << (absCheck ? " CONVERGED" : "") << endl;
188  }
189  }
190  }
191 
192  return cs;
193 }
194 
195 
196 // ************************************************************************* //
#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
Convergence control class. Provides methods to check the convergence of the time loop against an abso...
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.
const solutionControl & control_
Reference to the solution control.
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 convergence control class.
singleRegionConvergenceControl(const singleRegionSolutionControl &control)
Construct from a solution control.
void printResidualControls() const
Print the residual controls.
virtual convergenceData criteriaSatisfied() const
Return true if all convergence checks are satisfied.
virtual bool hasResidualControls() const
Return true if residual controls are present.
List< residualData > residualControl_
List of residual data per field.
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
defineTypeNameAndDebug(combustionModel, 0)
error FatalError
static const char nl
Definition: Ostream.H:266