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