FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

solution.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "solution.H"
00027 #include <OpenFOAM/Time.H>
00028 
00029 // These are for old syntax compatibility:
00030 #include <OpenFOAM/BICCG.H>
00031 #include <OpenFOAM/ICCG.H>
00032 #include <OpenFOAM/IStringStream.H>
00033 
00034 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00035 
00036 int Foam::solution::debug(::Foam::debug::debugSwitch("solution", 0));
00037 
00038 // List of sub-dictionaries to rewrite
00040 static const Foam::List<Foam::word> subDictNames
00041 (
00042     Foam::IStringStream("(preconditioner smoother)")()
00043 );
00045 
00046 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00047 
00048 Foam::solution::solution(const objectRegistry& obr, const fileName& dictName)
00049 :
00050     IOdictionary
00051     (
00052         IOobject
00053         (
00054             dictName,
00055             obr.time().system(),
00056             obr,
00057             IOobject::MUST_READ,
00058             IOobject::NO_WRITE
00059         )
00060     ),
00061     relaxationFactors_
00062     (
00063         ITstream("relaxationFactors",
00064         tokenList())()
00065     ),
00066     defaultRelaxationFactor_(0),
00067     solvers_(ITstream("solvers", tokenList())())
00068 {
00069     read();
00070 }
00071 
00072 
00073 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00074 
00075 Foam::label Foam::solution::upgradeSolverDict
00076 (
00077     dictionary& dict,
00078     const bool verbose
00079 )
00080 {
00081     label nChanged = 0;
00082 
00083     // backward compatibility:
00084     // recast primitive entries into dictionary entries
00085     forAllIter(dictionary, dict, iter)
00086     {
00087         if (!iter().isDict())
00088         {
00089             Istream& is = iter().stream();
00090             word name(is);
00091             dictionary subdict;
00092 
00093             if (name == "BICCG")
00094             {
00095                 // special treatment for very old syntax
00096                 subdict = BICCG::solverDict(is);
00097             }
00098             else if (name == "ICCG")
00099             {
00100                 // special treatment for very old syntax
00101                 subdict = ICCG::solverDict(is);
00102             }
00103             else
00104             {
00105                 subdict.add("solver", name);
00106                 subdict <<= dictionary(is);
00107 
00108                 // preconditioner and smoother entries can be
00109                 // 1) primitiveEntry w/o settings,
00110                 // 2) or a dictionaryEntry.
00111                 // transform primitiveEntry with settings -> dictionaryEntry
00112                 forAll(subDictNames, dictI)
00113                 {
00114                     const word& dictName = subDictNames[dictI];
00115                     entry* ePtr = subdict.lookupEntryPtr(dictName,false,false);
00116 
00117                     if (ePtr && !ePtr->isDict())
00118                     {
00119                         Istream& is = ePtr->stream();
00120                         is >> name;
00121 
00122                         if (!is.eof())
00123                         {
00124                             dictionary newDict;
00125                             newDict.add(dictName, name);
00126                             newDict <<= dictionary(is);
00127 
00128                             subdict.set(dictName, newDict);
00129                         }
00130                     }
00131                 }
00132             }
00133 
00134 
00135             // write out information to help people adjust to the new syntax
00136             if (verbose && Pstream::master())
00137             {
00138                 Info<< "// using new solver syntax:\n"
00139                     << iter().keyword() << subdict << endl;
00140             }
00141 
00142             // overwrite with dictionary entry
00143             dict.set(iter().keyword(), subdict);
00144 
00145             nChanged++;
00146         }
00147     }
00148 
00149     return nChanged;
00150 }
00151 
00152 
00153 bool Foam::solution::read()
00154 {
00155     if (regIOobject::read())
00156     {
00157         const dictionary& dict = solutionDict();
00158 
00159         if (dict.found("relaxationFactors"))
00160         {
00161             relaxationFactors_ = dict.subDict("relaxationFactors");
00162         }
00163 
00164         relaxationFactors_.readIfPresent("default", defaultRelaxationFactor_);
00165 
00166         if (dict.found("solvers"))
00167         {
00168             solvers_ = dict.subDict("solvers");
00169             upgradeSolverDict(solvers_);
00170         }
00171 
00172         return true;
00173     }
00174     else
00175     {
00176         return false;
00177     }
00178 }
00179 
00180 
00181 const Foam::dictionary& Foam::solution::solutionDict() const
00182 {
00183     if (found("select"))
00184     {
00185         return subDict(word(lookup("select")));
00186     }
00187     else
00188     {
00189         return *this;
00190     }
00191 }
00192 
00193 
00194 bool Foam::solution::relax(const word& name) const
00195 {
00196     if (debug)
00197     {
00198         Info<< "Find relax for " << name << endl;
00199     }
00200 
00201     return
00202         relaxationFactors_.found(name)
00203      || relaxationFactors_.found("default");
00204 }
00205 
00206 
00207 Foam::scalar Foam::solution::relaxationFactor(const word& name) const
00208 {
00209     if (debug)
00210     {
00211         Info<< "Lookup relaxationFactor for " << name << endl;
00212     }
00213 
00214     if (relaxationFactors_.found(name))
00215     {
00216         return readScalar(relaxationFactors_.lookup(name));
00217     }
00218     else if (defaultRelaxationFactor_ > SMALL)
00219     {
00220         return defaultRelaxationFactor_;
00221     }
00222     else
00223     {
00224         FatalIOErrorIn
00225         (
00226             "Foam::solution::relaxationFactor(const word&)",
00227             relaxationFactors_
00228         )   << "Cannot find relaxationFactor for '" << name
00229             << "' or a suitable default value."
00230             << exit(FatalIOError);
00231 
00232         return 0;
00233     }
00234 }
00235 
00236 
00237 const Foam::dictionary& Foam::solution::solverDict(const word& name) const
00238 {
00239     if (debug)
00240     {
00241         InfoIn("solution::solverDict(const word&)")
00242             << "Lookup solver for " << name << endl;
00243     }
00244 
00245     return solvers_.subDict(name);
00246 }
00247 
00248 
00249 const Foam::dictionary& Foam::solution::solver(const word& name) const
00250 {
00251     if (debug)
00252     {
00253         InfoIn("solution::solver(const word&)")
00254             << "Lookup solver for " << name << endl;
00255     }
00256 
00257     return solvers_.subDict(name);
00258 }
00259 
00260 
00261 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines