1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 4.0
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
27 #include "objectRegistry.H"
29 // These are for old syntax compatibility:
32 #include "IStringStream.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 Foam::debug::debugSwitch
43 // List of sub-dictionaries to rewrite
45 static const Foam::List<Foam::word> subDictNames
47 Foam::IStringStream("(preconditioner smoother)")()
49 //! @endcond localScope
52 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
54 void Foam::solution::read(const dictionary& dict)
56 if (dict.found("cache"))
58 cache_ = dict.subDict("cache");
59 caching_ = cache_.lookupOrDefault("active", true);
62 if (dict.found("relaxationFactors"))
64 const dictionary& relaxDict(dict.subDict("relaxationFactors"));
65 if (relaxDict.found("fields") || relaxDict.found("equations"))
67 if (relaxDict.found("fields"))
69 fieldRelaxDict_ = relaxDict.subDict("fields");
72 if (relaxDict.found("equations"))
74 eqnRelaxDict_ = relaxDict.subDict("equations");
79 // backwards compatibility
80 fieldRelaxDict_.clear();
82 const wordList entryNames(relaxDict.toc());
85 const word& e = entryNames[i];
86 scalar value = readScalar(relaxDict.lookup(e));
90 fieldRelaxDict_.add(e, value);
92 else if (e.length() >= 3)
96 fieldRelaxDict_.add(e, value);
102 eqnRelaxDict_ = relaxDict;
106 fieldRelaxDict_.lookupOrDefault<scalar>("default", 0.0);
109 eqnRelaxDict_.lookupOrDefault<scalar>("default", 0.0);
113 Info<< "relaxation factors:" << nl
114 << "fields: " << fieldRelaxDict_ << nl
115 << "equations: " << eqnRelaxDict_ << endl;
120 if (dict.found("solvers"))
122 solvers_ = dict.subDict("solvers");
123 upgradeSolverDict(solvers_);
126 if (dict.found("solverPerformance"))
128 solverPerformance_ = dict.subDict("solverPerformance");
133 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
135 Foam::solution::solution(const objectRegistry& obr, const fileName& dictName)
144 IOobject::READ_IF_PRESENT, // Allow default dictionary creation
148 cache_(dictionary::null),
150 fieldRelaxDict_(dictionary::null),
151 eqnRelaxDict_(dictionary::null),
152 fieldRelaxDefault_(0),
154 solvers_(dictionary::null),
155 solverPerformance_(dictionary::null),
164 "Foam::solution::solution(const objectRegistry& obr, "
165 "const fileName& dictName)"
166 ) << "Solution dictionary not found. Adding default entries"
171 read(solutionDict());
173 set("solverPerformance", dictionary());
177 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
179 Foam::label Foam::solution::upgradeSolverDict
187 // backward compatibility:
188 // recast primitive entries into dictionary entries
189 forAllIter(dictionary, dict, iter)
191 if (!iter().isDict())
193 Istream& is = iter().stream();
199 // special treatment for very old syntax
200 subdict = BICCG::solverDict(is);
202 else if (name == "ICCG")
204 // special treatment for very old syntax
205 subdict = ICCG::solverDict(is);
209 subdict.add("solver", name);
210 subdict <<= dictionary(is);
212 // preconditioner and smoother entries can be
213 // 1) primitiveEntry w/o settings,
214 // 2) or a dictionaryEntry.
215 // transform primitiveEntry with settings -> dictionaryEntry
216 forAll(subDictNames, dictI)
218 const word& dictName = subDictNames[dictI];
219 entry* ePtr = subdict.lookupEntryPtr(dictName,false,false);
221 if (ePtr && !ePtr->isDict())
223 Istream& is = ePtr->stream();
229 newDict.add(dictName, name);
230 newDict <<= dictionary(is);
232 subdict.set(dictName, newDict);
239 // write out information to help people adjust to the new syntax
240 if (verbose && Pstream::master())
242 Info<< "// using new solver syntax:\n"
243 << iter().keyword() << subdict << endl;
246 // overwrite with dictionary entry
247 dict.set(iter().keyword(), subdict);
257 bool Foam::solution::cache(const word& name) const
263 Info<< "Cache: find entry for " << name
264 << ": " << Switch(cache_.found(name)) << endl;
267 return cache_.found(name);
276 bool Foam::solution::relaxField(const word& name) const
280 Info<< "Field relaxation factor for " << name
281 << " is " << (fieldRelaxDict_.found(name) ? "set" : "unset")
285 return fieldRelaxDict_.found(name) || fieldRelaxDict_.found("default");
289 bool Foam::solution::relaxEquation(const word& name) const
293 Info<< "Find equation relaxation factor for " << name << endl;
296 return eqnRelaxDict_.found(name) || eqnRelaxDict_.found("default");
300 Foam::scalar Foam::solution::fieldRelaxationFactor(const word& name) const
304 Info<< "Lookup variable relaxation factor for " << name << endl;
307 if (fieldRelaxDict_.found(name))
309 return readScalar(fieldRelaxDict_.lookup(name));
311 else if (fieldRelaxDefault_ > SMALL)
313 return fieldRelaxDefault_;
319 "Foam::solution::fieldRelaxationFactor(const word&)",
321 ) << "Cannot find variable relaxation factor for '" << name
322 << "' or a suitable default value."
323 << exit(FatalIOError);
330 Foam::scalar Foam::solution::equationRelaxationFactor(const word& name) const
334 Info<< "Lookup equation relaxation factor for " << name << endl;
337 if (eqnRelaxDict_.found(name))
339 return readScalar(eqnRelaxDict_.lookup(name));
341 else if (eqnRelaxDefault_ > SMALL)
343 return eqnRelaxDefault_;
349 "Foam::solution::eqnRelaxationFactor(const word&)",
351 ) << "Cannot find equation relaxation factor for '" << name
352 << "' or a suitable default value."
353 << exit(FatalIOError);
360 const Foam::dictionary& Foam::solution::solutionDict() const
364 return subDict(word(lookup("select")));
373 const Foam::dictionary& Foam::solution::solverDict(const word& name) const
377 InfoIn("solution::solverDict(const word&)")
378 << "Lookup solver for " << name << endl;
381 return solvers_.subDict(name);
385 const Foam::dictionary& Foam::solution::solver(const word& name) const
389 InfoIn("solution::solver(const word&)")
390 << "Lookup solver for " << name << endl;
393 return solvers_.subDict(name);
397 bool Foam::solution::read()
399 if (regIOobject::read())
401 read(solutionDict());
411 bool Foam::solution::writeData(Ostream& os) const
413 // Write direct entries of the solution dictionary
415 dictionary::write(os, false);
420 Foam::dictionary& Foam::solution::solverPerformanceDict() const
422 return solverPerformance_;
426 void Foam::solution::setSolverPerformance
429 const lduSolverPerformance& sp
432 List<lduSolverPerformance> perfs;
434 if (prevTimeIndex_ != this->time().timeIndex())
436 // Reset solver performance between iterations
437 prevTimeIndex_ = this->time().timeIndex();
438 solverPerformance_.clear();
442 solverPerformance_.readIfPresent(name, perfs);
445 // Only the first iteration and the current iteration residuals are
446 // required, so the current iteration residual replaces the previous one and
447 // only the first iteration is always present, VS 2017-11-27
448 if (perfs.size() < 2)
451 perfs.setSize(perfs.size() + 1, sp);
458 solverPerformance_.set(name, perfs);
462 void Foam::solution::setSolverPerformance
464 const lduSolverPerformance& sp
467 setSolverPerformance(sp.fieldName(), sp);
470 // ************************************************************************* //