solution.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) 2011-2022 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 
26 #include "solution.H"
27 #include "Time.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  defineTypeNameAndDebug(solution, 0);
34 }
35 
36 // List of sub-dictionaries to rewrite
38 (
39  Foam::IStringStream("(preconditioner smoother)")()
40 );
41 
42 
43 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
44 
45 void Foam::solution::read(const dictionary& dict)
46 {
47  if (dict.found("cache"))
48  {
49  cache_ = dict.subDict("cache");
50  caching_ = cache_.lookupOrDefault("active", true);
51  }
52 
53  if (dict.found("relaxationFactors"))
54  {
55  const dictionary& relaxDict(dict.subDict("relaxationFactors"));
56  if (relaxDict.found("fields") || relaxDict.found("equations"))
57  {
58  if (relaxDict.found("fields"))
59  {
60  fieldRelaxDict_ = relaxDict.subDict("fields");
61  }
62 
63  if (relaxDict.found("equations"))
64  {
65  eqnRelaxDict_ = relaxDict.subDict("equations");
66  }
67  }
68  else
69  {
70  // backwards compatibility
71  fieldRelaxDict_.clear();
72 
73  const wordList entryNames(relaxDict.toc());
74  forAll(entryNames, i)
75  {
76  const word& e = entryNames[i];
77  scalar value = relaxDict.lookup<scalar>(e);
78 
79  if (e(0, 1) == "p")
80  {
81  fieldRelaxDict_.add(e, value);
82  }
83  else if (e.length() >= 3)
84  {
85  if (e(0, 3) == "rho")
86  {
87  fieldRelaxDict_.add(e, value);
88  }
89  }
90 
91  }
92 
93  eqnRelaxDict_ = relaxDict;
94  }
95 
96  fieldRelaxDefault_ =
97  fieldRelaxDict_.lookupOrDefault<scalar>("default", 0.0);
98 
99  eqnRelaxDefault_ =
100  eqnRelaxDict_.lookupOrDefault<scalar>("default", 0.0);
101 
102  if (debug)
103  {
104  Info<< "Relaxation factors:" << nl
105  << "fields: " << fieldRelaxDict_ << nl
106  << "equations: " << eqnRelaxDict_ << endl;
107  }
108  }
109 
110 
111  if (dict.found("solvers"))
112  {
113  solvers_ = dict.subDict("solvers");
114  upgradeSolverDict(solvers_);
115  }
116 }
117 
118 
119 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
120 
122 (
123  const objectRegistry& obr,
124  const fileName& dictName
125 )
126 :
128  (
129  IOobject
130  (
131  dictName,
132  obr.time().system(),
133  obr,
136  )
137  ),
138  cache_(dictionary::null),
139  caching_(false),
140  fieldRelaxDict_(dictionary::null),
141  eqnRelaxDict_(dictionary::null),
142  fieldRelaxDefault_(0),
143  eqnRelaxDefault_(0),
144  solvers_(dictionary::null)
145 {
146  read(dict());
147 }
148 
149 
150 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
151 
153 (
154  dictionary& dict,
155  const bool verbose
156 )
157 {
158  label nChanged = 0;
159 
160  // backward compatibility:
161  // recast primitive entries into dictionary entries
162  forAllIter(dictionary, dict, iter)
163  {
164  if (!iter().isDict())
165  {
166  Istream& is = iter().stream();
167  word name(is);
168  dictionary subdict;
169 
170  subdict.add("solver", name);
171  subdict <<= dictionary(is);
172 
173  // preconditioner and smoother entries can be
174  // 1) primitiveEntry w/o settings,
175  // 2) or a dictionaryEntry.
176  // transform primitiveEntry with settings -> dictionaryEntry
177  forAll(subDictNames, dictI)
178  {
179  const word& dictName = subDictNames[dictI];
180  entry* ePtr = subdict.lookupEntryPtr(dictName,false,false);
181 
182  if (ePtr && !ePtr->isDict())
183  {
184  Istream& is = ePtr->stream();
185  is >> name;
186 
187  if (!is.eof())
188  {
189  dictionary newDict;
190  newDict.add(dictName, name);
191  newDict <<= dictionary(is);
192 
193  subdict.set(dictName, newDict);
194  }
195  }
196  }
197 
198  // write out information to help people adjust to the new syntax
199  if (verbose && Pstream::master())
200  {
201  Info<< "// using new solver syntax:\n"
202  << iter().keyword() << subdict << endl;
203  }
204 
205  // overwrite with dictionary entry
206  dict.set(iter().keyword(), subdict);
207 
208  nChanged++;
209  }
210  }
211 
212  return nChanged;
213 }
214 
215 
216 bool Foam::solution::cache(const word& name) const
217 {
218  if (caching_)
219  {
220  if (debug)
221  {
222  Info<< "Cache: find entry for " << name << endl;
223  }
224 
225  return cache_.found(name);
226  }
227  else
228  {
229  return false;
230  }
231 }
232 
233 
235 {
236  if (debug)
237  {
238  Info<< "Field relaxation factor for " << name
239  << " is " << (fieldRelaxDict_.found(name) ? "set" : "unset")
240  << endl;
241  }
242 
243  return fieldRelaxDict_.found(name) || fieldRelaxDict_.found("default");
244 }
245 
246 
248 {
249  if (debug)
250  {
251  Info<< "Find equation relaxation factor for " << name << endl;
252  }
253 
254  return eqnRelaxDict_.found(name) || eqnRelaxDict_.found("default");
255 }
256 
257 
259 {
260  if (debug)
261  {
262  Info<< "Lookup variable relaxation factor for " << name << endl;
263  }
264 
265  if (fieldRelaxDict_.found(name))
266  {
267  return fieldRelaxDict_.lookup<scalar>(name);
268  }
269  else if (fieldRelaxDefault_ > small)
270  {
271  return fieldRelaxDefault_;
272  }
273  else
274  {
276  (
277  fieldRelaxDict_
278  ) << "Cannot find variable relaxation factor for '" << name
279  << "' or a suitable default value."
280  << exit(FatalIOError);
281 
282  return 0;
283  }
284 }
285 
286 
288 {
289  if (debug)
290  {
291  Info<< "Lookup equation relaxation factor for " << name << endl;
292  }
293 
294  if (eqnRelaxDict_.found(name))
295  {
296  return eqnRelaxDict_.lookup<scalar>(name);
297  }
298  else if (eqnRelaxDefault_ > small)
299  {
300  return eqnRelaxDefault_;
301  }
302  else
303  {
305  (
306  eqnRelaxDict_
307  ) << "Cannot find equation relaxation factor for '" << name
308  << "' or a suitable default value."
309  << exit(FatalIOError);
310 
311  return 0;
312  }
313 }
314 
315 
317 {
318  if (found("select"))
319  {
320  return subDict(word(lookup("select")));
321  }
322  else
323  {
324  return *this;
325  }
326 }
327 
328 
330 {
331  return solvers_;
332 }
333 
334 
336 {
337  if (debug)
338  {
339  Info<< "Lookup solver for " << name << endl;
340  }
341 
342  return solvers_.subDict(name);
343 }
344 
345 
347 {
348  if (regIOobject::read())
349  {
350  read(dict());
351 
352  return true;
353  }
354  else
355  {
356  return false;
357  }
358 }
359 
360 
361 // ************************************************************************* //
scalar equationRelaxationFactor(const word &name) const
Return the relaxation factor for the given eqation.
Definition: solution.C:287
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
A class for handling file names.
Definition: fileName.H:79
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:702
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
virtual bool read()
Read object.
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:156
bool read()
Read the solution dictionary.
Definition: solution.C:346
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:459
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
bool relaxField(const word &name) const
Return true if the relaxation factor is given for the field.
Definition: solution.C:234
const dictionary & solverDict(const word &name) const
Return the solver controls dictionary for the given field.
Definition: solution.C:335
bool relaxEquation(const word &name) const
Return true if the relaxation factor is given for the equation.
Definition: solution.C:247
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:1153
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:53
bool read(const char *, int32_t &)
Definition: int32IO.C:85
stressControl lookup("compactNormalStress") >> compactNormalStress
static const Foam::List< Foam::word > subDictNames(Foam::IStringStream("(preconditioner smoother)")())
A class for handling words, derived from string.
Definition: word.H:59
bool cache(const word &name) const
Return true if the given field should be cached.
Definition: solution.C:216
static const dictionary null
Null dictionary.
Definition: dictionary.H:242
bool eof() const
Return true if end of input seen.
Definition: IOstream.H:336
const word & system() const
Return system name.
Definition: TimePaths.H:113
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:156
solution(const objectRegistry &obr, const fileName &dictName)
Construct for given objectRegistry and dictionary.
Definition: solution.C:122
static const char nl
Definition: Ostream.H:260
const Time & time() const
Return time.
defineTypeNameAndDebug(combustionModel, 0)
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
const dictionary & solversDict() const
Return the solver controls dictionary.
Definition: solution.C:329
List< word > wordList
A List of words.
Definition: fileName.H:54
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:318
Input from memory buffer stream.
Definition: IStringStream.H:49
scalar fieldRelaxationFactor(const word &name) const
Return the relaxation factor for the given field.
Definition: solution.C:258
void set(entry *)
Assign a new entry, overwrite any existing entry.
Definition: dictionary.C:1291
messageStream Info
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:105
Registry of regIOobjects.
virtual ITstream & stream() const =0
Return token stream if this entry is a primitive entry.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:98
bool found
static label upgradeSolverDict(dictionary &dict, const bool verbose=true)
Update from older solver controls syntax.
Definition: solution.C:153
const dictionary & dict() const
Return the selected sub-dictionary of solvers if the "select".
Definition: solution.C:316
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:65
IOerror FatalIOError