Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OpenFOAM / matrices / solution / solution.C
blob8bb2a8fcde51871b481c31c3b81b7e588aff9ff7
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2011 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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.
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.
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "solution.H"
27 #include "Time.H"
29 // These are for old syntax compatibility:
30 #include "BICCG.H"
31 #include "ICCG.H"
32 #include "IStringStream.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 int Foam::solution::debug(::Foam::debug::debugSwitch("solution", 0));
38 // List of sub-dictionaries to rewrite
39 //! \cond localScope
40 static const Foam::List<Foam::word> subDictNames
42     Foam::IStringStream("(preconditioner smoother)")()
44 //! \endcond
47 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
49 void Foam::solution::read(const dictionary& dict)
51     if (dict.found("cache"))
52     {
53         cache_ = dict.subDict("cache");
54         caching_ = cache_.lookupOrDefault("active", true);
55     }
57     if (dict.found("relaxationFactors"))
58     {
59         relaxationFactors_ = dict.subDict("relaxationFactors");
60     }
62     relaxationFactors_.readIfPresent("default", defaultRelaxationFactor_);
64     if (dict.found("solvers"))
65     {
66         solvers_ = dict.subDict("solvers");
67         upgradeSolverDict(solvers_);
68     }
72 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
74 Foam::solution::solution
76     const objectRegistry& obr,
77     const fileName& dictName
80     IOdictionary
81     (
82         IOobject
83         (
84             dictName,
85             obr.time().system(),
86             obr,
87             (
88                 obr.readOpt() == IOobject::MUST_READ
89               ? IOobject::MUST_READ_IF_MODIFIED
90               : obr.readOpt()
91             ),
92             IOobject::NO_WRITE
93         )
94     ),
95     cache_(ITstream("cache", tokenList())()),
96     caching_(false),
97     relaxationFactors_(ITstream("relaxationFactors", tokenList())()),
98     defaultRelaxationFactor_(0),
99     solvers_(ITstream("solvers", tokenList())())
101     if
102     (
103         readOpt() == IOobject::MUST_READ
104      || readOpt() == IOobject::MUST_READ_IF_MODIFIED
105     )
106     {
107         read(solutionDict());
108     }
112 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
114 Foam::label Foam::solution::upgradeSolverDict
116     dictionary& dict,
117     const bool verbose
120     label nChanged = 0;
122     // backward compatibility:
123     // recast primitive entries into dictionary entries
124     forAllIter(dictionary, dict, iter)
125     {
126         if (!iter().isDict())
127         {
128             Istream& is = iter().stream();
129             word name(is);
130             dictionary subdict;
132             if (name == "BICCG")
133             {
134                 // special treatment for very old syntax
135                 subdict = BICCG::solverDict(is);
136             }
137             else if (name == "ICCG")
138             {
139                 // special treatment for very old syntax
140                 subdict = ICCG::solverDict(is);
141             }
142             else
143             {
144                 subdict.add("solver", name);
145                 subdict <<= dictionary(is);
147                 // preconditioner and smoother entries can be
148                 // 1) primitiveEntry w/o settings,
149                 // 2) or a dictionaryEntry.
150                 // transform primitiveEntry with settings -> dictionaryEntry
151                 forAll(subDictNames, dictI)
152                 {
153                     const word& dictName = subDictNames[dictI];
154                     entry* ePtr = subdict.lookupEntryPtr(dictName,false,false);
156                     if (ePtr && !ePtr->isDict())
157                     {
158                         Istream& is = ePtr->stream();
159                         is >> name;
161                         if (!is.eof())
162                         {
163                             dictionary newDict;
164                             newDict.add(dictName, name);
165                             newDict <<= dictionary(is);
167                             subdict.set(dictName, newDict);
168                         }
169                     }
170                 }
171             }
174             // write out information to help people adjust to the new syntax
175             if (verbose && Pstream::master())
176             {
177                 Info<< "// using new solver syntax:\n"
178                     << iter().keyword() << subdict << endl;
179             }
181             // overwrite with dictionary entry
182             dict.set(iter().keyword(), subdict);
184             nChanged++;
185         }
186     }
188     return nChanged;
192 bool Foam::solution::cache(const word& name) const
194     if (caching_)
195     {
196         if (debug)
197         {
198             Info<< "Cache: find entry for " << name << endl;
199         }
201         return cache_.found(name);
202     }
203     else
204     {
205         return false;
206     }
210 bool Foam::solution::relax(const word& name) const
212     if (debug)
213     {
214         Info<< "Find relax for " << name << endl;
215     }
217     return
218         relaxationFactors_.found(name)
219      || relaxationFactors_.found("default");
223 Foam::scalar Foam::solution::relaxationFactor(const word& name) const
225     if (debug)
226     {
227         Info<< "Lookup relaxationFactor for " << name << endl;
228     }
230     if (relaxationFactors_.found(name))
231     {
232         return readScalar(relaxationFactors_.lookup(name));
233     }
234     else if (defaultRelaxationFactor_ > SMALL)
235     {
236         return defaultRelaxationFactor_;
237     }
238     else
239     {
240         FatalIOErrorIn
241         (
242             "Foam::solution::relaxationFactor(const word&)",
243             relaxationFactors_
244         )   << "Cannot find relaxationFactor for '" << name
245             << "' or a suitable default value."
246             << exit(FatalIOError);
248         return 0;
249     }
253 const Foam::dictionary& Foam::solution::solutionDict() const
255     if (found("select"))
256     {
257         return subDict(word(lookup("select")));
258     }
259     else
260     {
261         return *this;
262     }
266 const Foam::dictionary& Foam::solution::solverDict(const word& name) const
268     if (debug)
269     {
270         InfoIn("solution::solverDict(const word&)")
271             << "Lookup solver for " << name << endl;
272     }
274     return solvers_.subDict(name);
278 const Foam::dictionary& Foam::solution::solver(const word& name) const
280     if (debug)
281     {
282         InfoIn("solution::solver(const word&)")
283             << "Lookup solver for " << name << endl;
284     }
286     return solvers_.subDict(name);
290 bool Foam::solution::read()
292     if (regIOobject::read())
293     {
294         read(solutionDict());
296         return true;
297     }
298     else
299     {
300         return false;
301     }
305 // ************************************************************************* //