solution.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "solution.H"
30 #include "Time.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineDebugSwitchWithName(solution, "solution", 0);
37 }
38 
39 // List of sub-dictionaries to rewrite
41 ({
42  "preconditioner", "smoother"
43 });
44 
45 
46 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
47 
48 void Foam::solution::read(const dictionary& dict)
49 {
50  if (dict.found("cache"))
51  {
52  cache_ = dict.subDict("cache");
53  caching_ = cache_.getOrDefault("active", true);
54  }
55 
56  if (dict.found("relaxationFactors"))
57  {
58  const dictionary& relaxDict(dict.subDict("relaxationFactors"));
59  if (relaxDict.found("fields") || relaxDict.found("equations"))
60  {
61  if (relaxDict.found("fields"))
62  {
63  fieldRelaxDict_ = relaxDict.subDict("fields");
64  }
65 
66  if (relaxDict.found("equations"))
67  {
68  eqnRelaxDict_ = relaxDict.subDict("equations");
69  }
70  }
71  else
72  {
73  // backwards compatibility
74  fieldRelaxDict_.clear();
75 
76  for (const word& e : relaxDict.toc())
77  {
78  scalar value = relaxDict.get<scalar>(e);
79 
80  if (e.starts_with('p'))
81  {
82  fieldRelaxDict_.add(e, value);
83  }
84  else if (e.starts_with("rho"))
85  {
86  fieldRelaxDict_.add(e, value);
87  }
88 
89  }
90 
91  eqnRelaxDict_ = relaxDict;
92  }
93 
94  fieldRelaxDefault_ =
95  fieldRelaxDict_.getOrDefault<scalar>("default", 0);
96 
97  eqnRelaxDefault_ =
98  eqnRelaxDict_.getOrDefault<scalar>("default", 0);
99 
100  DebugInfo
101  << "Relaxation factors:" << nl
102  << "fields: " << fieldRelaxDict_ << nl
103  << "equations: " << eqnRelaxDict_ << endl;
104  }
105 
106  if (dict.found("solvers"))
107  {
108  solvers_ = dict.subDict("solvers");
109  upgradeSolverDict(solvers_);
110  }
111 }
112 
113 
114 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
115 
116 Foam::solution::solution
117 (
118  const objectRegistry& obr,
119  const fileName& dictName
120 )
121 :
123  (
124  IOobject
125  (
126  dictName,
127  obr.time().system(),
128  obr,
129  (
133  : obr.readOpt()
134  ),
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  if
147  (
148  readOpt() == IOobject::MUST_READ
149  || readOpt() == IOobject::MUST_READ_IF_MODIFIED
150  || (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
151  )
152  {
153  read(solutionDict());
154  }
155 }
156 
157 
158 Foam::solution::solution
159 (
160  const objectRegistry& obr,
161  const fileName& dictName,
162  const dictionary& dict
163 )
164 :
166  (
167  IOobject
168  (
169  dictName,
170  obr.time().system(),
171  obr,
172  (
176  : obr.readOpt()
177  ),
179  ),
180  dict
181  ),
182  cache_(dictionary::null),
183  caching_(false),
184  fieldRelaxDict_(dictionary::null),
185  eqnRelaxDict_(dictionary::null),
186  fieldRelaxDefault_(0),
187  eqnRelaxDefault_(0),
188  solvers_(dictionary::null)
189 {
190  if
191  (
192  readOpt() == IOobject::MUST_READ
193  || readOpt() == IOobject::MUST_READ_IF_MODIFIED
194  || (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
195  )
196  {
197  read(solutionDict());
198  }
199 }
200 
201 
202 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
203 
205 (
206  dictionary& dict,
207  const bool verbose
208 )
209 {
210  label nChanged = 0;
211 
212  // backward compatibility:
213  // recast primitive entries into dictionary entries
214  for (const entry& dEntry : dict)
215  {
216  if (!dEntry.isDict())
217  {
218  Istream& is = dEntry.stream();
219  word name(is);
220  dictionary subdict;
221 
222  subdict.add("solver", name);
223  subdict <<= dictionary(is);
224 
225  // preconditioner and smoother entries can be
226  // 1) primitiveEntry w/o settings,
227  // 2) or a dictionaryEntry.
228  // transform primitiveEntry with settings -> dictionaryEntry
229  for (const word& dictName : subDictNames)
230  {
231  entry* eptr = subdict.findEntry(dictName, keyType::LITERAL);
232 
233  if (eptr && !eptr->isDict())
234  {
235  Istream& is = eptr->stream();
236  is >> name;
237 
238  if (!is.eof())
239  {
240  dictionary newDict;
241  newDict.add(dictName, name);
242  newDict <<= dictionary(is);
243 
244  subdict.set(dictName, newDict);
245  }
246  }
247  }
248 
249  // write out information to help people adjust to the new syntax
250  if (verbose && Pstream::master())
251  {
252  Info<< "// using new solver syntax:\n"
253  << dEntry.keyword() << subdict << endl;
254  }
255 
256  // overwrite with dictionary entry
257  dict.set(dEntry.keyword(), subdict);
258 
259  ++nChanged;
260  }
261  }
262 
263  return nChanged;
264 }
265 
266 
267 bool Foam::solution::cache(const word& name) const
268 {
269  if (caching_)
270  {
271  DebugInfo
272  << "Cache: find entry for " << name << endl;
273 
274  return cache_.found(name);
275  }
276 
277  return false;
278 }
279 
280 
282 {
283  DebugInfo
284  << "Field relaxation factor for " << name
285  << " is " << (fieldRelaxDict_.found(name) ? "set" : "unset") << endl;
286 
287  return fieldRelaxDict_.found(name) || fieldRelaxDict_.found("default");
288 }
289 
290 
292 {
293  DebugInfo
294  << "Find equation relaxation factor for " << name << endl;
295 
296  return eqnRelaxDict_.found(name) || eqnRelaxDict_.found("default");
297 }
298 
299 
301 {
302  DebugInfo
303  << "Lookup variable relaxation factor for " << name << endl;
304 
305  if (fieldRelaxDict_.found(name))
306  {
307  return fieldRelaxDict_.get<scalar>(name);
308  }
309  else if (fieldRelaxDefault_ > SMALL)
310  {
311  return fieldRelaxDefault_;
312  }
313 
314  FatalIOErrorInFunction(fieldRelaxDict_)
315  << "Cannot find variable relaxation factor for '" << name
316  << "' or a suitable default value." << nl
317  << exit(FatalIOError);
318 
319  return 0;
320 }
321 
322 
324 {
325  DebugInfo
326  << "Lookup equation relaxation factor for " << name << endl;
327 
328  if (eqnRelaxDict_.found(name))
329  {
330  return eqnRelaxDict_.get<scalar>(name);
331  }
332  else if (eqnRelaxDefault_ > SMALL)
333  {
334  return eqnRelaxDefault_;
335  }
336 
337  FatalIOErrorInFunction(eqnRelaxDict_)
338  << "Cannot find equation relaxation factor for '" << name
339  << "' or a suitable default value."
340  << exit(FatalIOError);
341 
342  return 0;
343 }
344 
345 
347 {
348  if (found("select"))
349  {
350  return subDict(get<word>("select"));
351  }
352 
353  return *this;
354 }
355 
356 
358 {
359  DebugInfo
360  << "Lookup solver for " << name << endl;
361 
362  return solvers_.subDict(name);
363 }
364 
365 
367 {
368  DebugInfo
369  << "Lookup solver for " << name << endl;
370 
371  return solvers_.subDict(name);
372 }
373 
374 
376 {
377  if (regIOobject::read())
378  {
379  read(solutionDict());
380 
381  return true;
382  }
383 
384  return false;
385 }
386 
387 
388 // ************************************************************************* //
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
Foam::solution::solverDict
const dictionary & solverDict(const word &name) const
Return the solver controls dictionary for the given field.
Definition: solution.C:357
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::entry::stream
virtual ITstream & stream() const =0
Return token stream, if entry is a primitive entry.
Foam::defineDebugSwitchWithName
defineDebugSwitchWithName(pointMVCWeight, "pointMVCWeight", 0)
Foam::solution::cache
bool cache(const word &name) const
Return true if the given field should be cached.
Definition: solution.C:267
Foam::IOstream::eof
bool eof() const
Return true if end of input seen.
Definition: IOstream.H:230
Foam::dictionary::dictionary
dictionary()
Default construct, a top-level empty dictionary.
Definition: dictionary.C:81
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::objectRegistry::time
const Time & time() const
Return time.
Definition: objectRegistry.H:186
Foam::regIOobject::read
virtual bool read()
Read object.
Definition: regIOobjectRead.C:202
solutionDict
fvSolution solutionDict(runTime)
dictName
const word dictName("blockMeshDict")
Foam::solution::upgradeSolverDict
static label upgradeSolverDict(dictionary &dict, const bool verbose=true)
Update from older solver controls syntax.
Definition: solution.C:205
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:458
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::dictionary::set
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:847
subDictNames
static const Foam::List< Foam::word > subDictNames({ "preconditioner", "smoother" })
Foam::dictionary::null
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
Definition: dictionary.H:385
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::solution::fieldRelaxationFactor
scalar fieldRelaxationFactor(const word &name) const
Return the relaxation factor for the given field.
Definition: solution.C:300
Foam::entry::isDict
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:222
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:528
Foam::IOobject::READ_IF_PRESENT
Definition: IOobject.H:122
Foam::solution::read
bool read()
Read the solution dictionary.
Definition: solution.C:375
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::solution::relaxEquation
bool relaxEquation(const word &name) const
Return true if the relaxation factor is given for the equation.
Definition: solution.C:291
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
solution.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::solution::equationRelaxationFactor
scalar equationRelaxationFactor(const word &name) const
Return the relaxation factor for the given equation.
Definition: solution.C:323
found
bool found
Definition: TABSMDCalcMethod2.H:32
Time.H
Foam::TimePaths::system
const word & system() const
Return system name.
Definition: TimePathsI.H:94
Foam::solution::solutionDict
const dictionary & solutionDict() const
Return the selected sub-dictionary of solvers if the "select".
Definition: solution.C:346
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:359
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::List< Foam::word >
Foam::IOobject::readOpt
readOption readOpt() const
The read option.
Definition: IOobjectI.H:165
Foam::dictionary::findEntry
entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find for an entry (non-const access) with the given keyword.
Definition: dictionary.C:374
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::IOobject::MUST_READ_IF_MODIFIED
Definition: IOobject.H:121
Foam::dictionary::add
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:708
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::solution::solver
const dictionary & solver(const word &name) const
Return the solver controls dictionary for the given field.
Definition: solution.C:366
Foam::keyType::LITERAL
String literal.
Definition: keyType.H:73
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:122
Foam::dictionary::clear
void clear()
Clear the dictionary.
Definition: dictionary.C:924
Foam::solution::relaxField
bool relaxField(const word &name) const
Return true if the relaxation factor is given for the field.
Definition: solution.C:281
Foam::IOobject::MUST_READ
Definition: IOobject.H:120