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-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 "volFields.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
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 = residualDict.lookup<scalar>(fName);
89  data.append(rd);
90  }
91  else
92  {
93  residualData& rd = data[fieldi];
94  rd.absTol = residualDict.lookup<scalar>(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  DynamicList<word> fieldNames(getFieldNames(mesh_));
155 
156  forAll(fieldNames, i)
157  {
158  const word& fieldName = fieldNames[i];
159  const label fieldi =
160  residualControlIndex(fieldName, residualControl_);
161  if (fieldi != -1)
162  {
163  scalar residual;
164  getInitialResiduals
165  (
166  mesh_,
167  fieldName,
168  0,
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() << " " << fieldName
182  << ": tolerance " << residual << " ("
183  << residualControl_[fieldi].absTol << ")"
184  << (absCheck ? " CONVERGED" : "") << endl;
185  }
186  }
187  }
188 
189  return checked && achieved;
190 }
191 
192 
193 // ************************************************************************* //
#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
Convergence control class. Provides methods to check the convergence of the time loop against an abso...
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 convergence control class.
singleRegionConvergenceControl(const singleRegionSolutionControl &control)
Construct from a solution control.
virtual bool criteriaSatisfied() const
Return true if all convergence checks are satisfied.
void printResidualControls() const
Print the residual controls.
virtual bool hasResidualControls() const
Return true if residual controls are present.
bool readResidualControls()
Read residual controls.
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
defineTypeNameAndDebug(combustionModel, 0)
error FatalError
static const char nl
Definition: Ostream.H:260