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 {
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,
134  IOobject::MUST_READ_IF_MODIFIED,
135  IOobject::NO_WRITE
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  caching_ = true;
237 
238  if (debug)
239  {
240  Info<< "Enable cache for " << name << endl;
241  }
242 
243  cache_.add(name, true);
244 }
245 
246 
248 {
249  if (debug)
250  {
251  Info<< "Field relaxation factor for " << name
252  << " is " << (fieldRelaxDict_.found(name) ? "set" : "unset")
253  << endl;
254  }
255 
256  return fieldRelaxDict_.found(name) || fieldRelaxDict_.found("default");
257 }
258 
259 
261 {
262  if (debug)
263  {
264  Info<< "Find equation relaxation factor for " << name << endl;
265  }
266 
267  return eqnRelaxDict_.found(name) || eqnRelaxDict_.found("default");
268 }
269 
270 
272 {
273  if (debug)
274  {
275  Info<< "Lookup variable relaxation factor for " << name << endl;
276  }
277 
278  if (fieldRelaxDict_.found(name))
279  {
280  return fieldRelaxDict_.lookup<scalar>(name);
281  }
282  else if (fieldRelaxDefault_ > small)
283  {
284  return fieldRelaxDefault_;
285  }
286  else
287  {
289  (
290  fieldRelaxDict_
291  ) << "Cannot find variable relaxation factor for '" << name
292  << "' or a suitable default value."
293  << exit(FatalIOError);
294 
295  return 0;
296  }
297 }
298 
299 
301 {
302  if (debug)
303  {
304  Info<< "Lookup equation relaxation factor for " << name << endl;
305  }
306 
307  if (eqnRelaxDict_.found(name))
308  {
309  return eqnRelaxDict_.lookup<scalar>(name);
310  }
311  else if (eqnRelaxDefault_ > small)
312  {
313  return eqnRelaxDefault_;
314  }
315  else
316  {
318  (
319  eqnRelaxDict_
320  ) << "Cannot find equation relaxation factor for '" << name
321  << "' or a suitable default value."
322  << exit(FatalIOError);
323 
324  return 0;
325  }
326 }
327 
328 
330 {
331  if (found("select"))
332  {
333  return subDict(word(lookup("select")));
334  }
335  else
336  {
337  return *this;
338  }
339 }
340 
341 
343 {
344  return solvers_;
345 }
346 
347 
349 {
350  if (debug)
351  {
352  Info<< "Lookup solver for " << name << endl;
353  }
354 
355  return solvers_.subDict(name);
356 }
357 
358 
360 {
361  if (regIOobject::read())
362  {
363  read(dict());
364 
365  return true;
366  }
367  else
368  {
369  return false;
370  }
371 }
372 
373 
374 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:459
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
bool eof() const
Return true if end of input seen.
Definition: IOstream.H:336
Input from memory buffer stream.
Definition: IStringStream.H:52
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
dictionary()
Construct top-level dictionary null.
Definition: dictionary.C:436
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:698
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
void set(entry *)
Assign a new entry, overwrite any existing entry.
Definition: dictionary.C:1307
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:998
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:1169
void clear()
Clear the dictionary.
Definition: dictionary.C:1499
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:659
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:68
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:156
virtual ITstream & stream() const =0
Return token stream if this entry is a primitive entry.
A class for handling file names.
Definition: fileName.H:82
Registry of regIOobjects.
virtual bool read()
Read object.
Selector class for relaxation factors, solver type and solution.
Definition: solution.H:51
void enableCache(const word &name) const
Enable caching of the given field.
Definition: solution.C:234
solution(const objectRegistry &obr, const fileName &dictName)
Construct for given objectRegistry and dictionary.
Definition: solution.C:122
bool cache(const word &name) const
Return true if the given field should be cached.
Definition: solution.C:216
const dictionary & solversDict() const
Return the solver controls dictionary.
Definition: solution.C:342
bool relaxField(const word &name) const
Return true if the relaxation factor is given for the field.
Definition: solution.C:247
scalar fieldRelaxationFactor(const word &name) const
Return the relaxation factor for the given field.
Definition: solution.C:271
const dictionary & solverDict(const word &name) const
Return the solver controls dictionary for the given field.
Definition: solution.C:348
static label upgradeSolverDict(dictionary &dict, const bool verbose=true)
Update from older solver controls syntax.
Definition: solution.C:153
scalar equationRelaxationFactor(const word &name) const
Return the relaxation factor for the given eqation.
Definition: solution.C:300
const dictionary & dict() const
Return the selected sub-dictionary of solvers if the "select".
Definition: solution.C:329
bool relaxEquation(const word &name) const
Return true if the relaxation factor is given for the equation.
Definition: solution.C:260
bool read()
Read the solution dictionary.
Definition: solution.C:359
A class for handling words, derived from string.
Definition: word.H:62
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:318
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1230
List< word > wordList
A List of words.
Definition: fileName.H:54
const doubleScalar e
Definition: doubleScalar.H:105
bool read(const char *, int32_t &)
Definition: int32IO.C:85
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)
IOerror FatalIOError
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
static const char nl
Definition: Ostream.H:260
dictionary dict
static const Foam::List< Foam::word > subDictNames(Foam::IStringStream("(preconditioner smoother)")())