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 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_.lookupOrDefault("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_.lookupOrDefault<scalar>("default", 0.0);
96 
97  eqnRelaxDefault_ =
98  eqnRelaxDict_.lookupOrDefault<scalar>("default", 0.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 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
159 
161 (
162  dictionary& dict,
163  const bool verbose
164 )
165 {
166  label nChanged = 0;
167 
168  // backward compatibility:
169  // recast primitive entries into dictionary entries
170  for (const entry& dEntry : dict)
171  {
172  if (!dEntry.isDict())
173  {
174  Istream& is = dEntry.stream();
175  word name(is);
176  dictionary subdict;
177 
178  subdict.add("solver", name);
179  subdict <<= dictionary(is);
180 
181  // preconditioner and smoother entries can be
182  // 1) primitiveEntry w/o settings,
183  // 2) or a dictionaryEntry.
184  // transform primitiveEntry with settings -> dictionaryEntry
185  for (const word& dictName : subDictNames)
186  {
187  entry* eptr = subdict.findEntry(dictName, keyType::LITERAL);
188 
189  if (eptr && !eptr->isDict())
190  {
191  Istream& is = eptr->stream();
192  is >> name;
193 
194  if (!is.eof())
195  {
196  dictionary newDict;
197  newDict.add(dictName, name);
198  newDict <<= dictionary(is);
199 
200  subdict.set(dictName, newDict);
201  }
202  }
203  }
204 
205  // write out information to help people adjust to the new syntax
206  if (verbose && Pstream::master())
207  {
208  Info<< "// using new solver syntax:\n"
209  << dEntry.keyword() << subdict << endl;
210  }
211 
212  // overwrite with dictionary entry
213  dict.set(dEntry.keyword(), subdict);
214 
215  ++nChanged;
216  }
217  }
218 
219  return nChanged;
220 }
221 
222 
223 bool Foam::solution::cache(const word& name) const
224 {
225  if (caching_)
226  {
227  DebugInfo
228  << "Cache: find entry for " << name << endl;
229 
230  return cache_.found(name);
231  }
232 
233  return false;
234 }
235 
236 
238 {
239  DebugInfo
240  << "Field relaxation factor for " << name
241  << " is " << (fieldRelaxDict_.found(name) ? "set" : "unset") << endl;
242 
243  return fieldRelaxDict_.found(name) || fieldRelaxDict_.found("default");
244 }
245 
246 
248 {
249  DebugInfo
250  << "Find equation relaxation factor for " << name << endl;
251 
252  return eqnRelaxDict_.found(name) || eqnRelaxDict_.found("default");
253 }
254 
255 
257 {
258  DebugInfo
259  << "Lookup variable relaxation factor for " << name << endl;
260 
261  if (fieldRelaxDict_.found(name))
262  {
263  return fieldRelaxDict_.get<scalar>(name);
264  }
265  else if (fieldRelaxDefault_ > SMALL)
266  {
267  return fieldRelaxDefault_;
268  }
269 
270  FatalIOErrorInFunction(fieldRelaxDict_)
271  << "Cannot find variable relaxation factor for '" << name
272  << "' or a suitable default value." << nl
273  << exit(FatalIOError);
274 
275  return 0;
276 }
277 
278 
280 {
281  DebugInfo
282  << "Lookup equation relaxation factor for " << name << endl;
283 
284  if (eqnRelaxDict_.found(name))
285  {
286  return eqnRelaxDict_.get<scalar>(name);
287  }
288  else if (eqnRelaxDefault_ > SMALL)
289  {
290  return eqnRelaxDefault_;
291  }
292 
293  FatalIOErrorInFunction(eqnRelaxDict_)
294  << "Cannot find equation relaxation factor for '" << name
295  << "' or a suitable default value."
296  << exit(FatalIOError);
297 
298  return 0;
299 }
300 
301 
303 {
304  if (found("select"))
305  {
306  return subDict(get<word>("select"));
307  }
308 
309  return *this;
310 }
311 
312 
314 {
315  DebugInfo
316  << "Lookup solver for " << name << endl;
317 
318  return solvers_.subDict(name);
319 }
320 
321 
323 {
324  DebugInfo
325  << "Lookup solver for " << name << endl;
326 
327  return solvers_.subDict(name);
328 }
329 
330 
332 {
333  if (regIOobject::read())
334  {
335  read(solutionDict());
336 
337  return true;
338  }
339 
340  return false;
341 }
342 
343 
344 // ************************************************************************* //
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:313
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:223
solutionDict
fvSolution solutionDict(runTime)
Foam::IOstream::eof
bool eof() const
Return true if end of input seen.
Definition: IOstream.H:222
Foam::dictionary::dictionary
dictionary()
Construct top-level dictionary null.
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
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:161
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::dictionary::set
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:842
Foam::dictionary::lookupOrDefault
T lookupOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.H:1241
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:256
Foam::label
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:62
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:523
Foam::IOobject::READ_IF_PRESENT
Definition: IOobject.H:122
Foam::solution::read
bool read()
Read the solution dictionary.
Definition: solution.C:331
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:247
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:279
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:438
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:302
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:350
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::List< Foam::word >
Foam::IOobject::readOpt
readOption readOpt() const
The read option.
Definition: IOobjectI.H:141
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:369
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:703
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:375
Foam::solution::solver
const dictionary & solver(const word &name) const
Return the solver controls dictionary for the given field.
Definition: solution.C:322
Foam::keyType::LITERAL
String literal.
Definition: keyType.H:73
Foam::dictionary::clear
void clear()
Clear the dictionary.
Definition: dictionary.C:919
Foam::solution::relaxField
bool relaxField(const word &name) const
Return true if the relaxation factor is given for the field.
Definition: solution.C:237
Foam::IOobject::MUST_READ
Definition: IOobject.H:120