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

functionObjectList.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 "functionObjectList.H"
00027 #include <OpenFOAM/Time.H>
00028 
00029 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
00030 
00031 Foam::functionObject*
00032 Foam::functionObjectList::remove(const word& key, label& oldIndex)
00033 {
00034     functionObject* ptr = 0;
00035 
00036     // Find index of existing functionObject
00037     HashTable<label>::iterator fnd = indices_.find(key);
00038 
00039     if (fnd != indices_.end())
00040     {
00041         oldIndex = fnd();
00042 
00043         // retrieve the pointer and remove it from the old list
00044         ptr = this->set(oldIndex, 0).ptr();
00045         indices_.erase(fnd);
00046     }
00047     else
00048     {
00049         oldIndex = -1;
00050     }
00051 
00052     return ptr;
00053 }
00054 
00055 
00056 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00057 
00058 Foam::functionObjectList::functionObjectList
00059 (
00060     const Time& t,
00061     const bool execution
00062 )
00063 :
00064     PtrList<functionObject>(),
00065     digests_(),
00066     indices_(),
00067     time_(t),
00068     parentDict_(t.controlDict()),
00069     execution_(execution),
00070     updated_(false)
00071 {}
00072 
00073 
00074 Foam::functionObjectList::functionObjectList
00075 (
00076     const Time& t,
00077     const dictionary& parentDict,
00078     const bool execution
00079 )
00080 :
00081     PtrList<functionObject>(),
00082     digests_(),
00083     indices_(),
00084     time_(t),
00085     parentDict_(parentDict),
00086     execution_(execution),
00087     updated_(false)
00088 {}
00089 
00090 
00091 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00092 
00093 Foam::functionObjectList::~functionObjectList()
00094 {}
00095 
00096 
00097 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00098 
00099 void Foam::functionObjectList::clear()
00100 {
00101     PtrList<functionObject>::clear();
00102     digests_.clear();
00103     indices_.clear();
00104     updated_ = false;
00105 }
00106 
00107 
00108 void Foam::functionObjectList::on()
00109 {
00110     execution_ = true;
00111 }
00112 
00113 
00114 void Foam::functionObjectList::off()
00115 {
00116     // for safety, also force a read() when execution is turned back on
00117     updated_ = execution_ = false;
00118 }
00119 
00120 
00121 bool Foam::functionObjectList::status() const
00122 {
00123     return execution_;
00124 }
00125 
00126 
00127 bool Foam::functionObjectList::start()
00128 {
00129     return read();
00130 }
00131 
00132 
00133 bool Foam::functionObjectList::execute()
00134 {
00135     bool ok = true;
00136 
00137     if (execution_)
00138     {
00139         if (!updated_)
00140         {
00141             read();
00142         }
00143 
00144         forAllIter
00145         (
00146             PtrList<functionObject>,
00147             static_cast<PtrList<functionObject>&>(*this),
00148             iter
00149         )
00150         {
00151             ok = iter().execute() && ok;
00152         }
00153     }
00154 
00155     return ok;
00156 }
00157 
00158 
00159 bool Foam::functionObjectList::end()
00160 {
00161     bool ok = true;
00162 
00163     if (execution_)
00164     {
00165         if (!updated_)
00166         {
00167             read();
00168         }
00169 
00170         forAllIter
00171         (
00172             PtrList<functionObject>,
00173             static_cast<PtrList<functionObject>&>(*this),
00174             iter
00175         )
00176         {
00177             ok = iter().end() && ok;
00178         }
00179     }
00180 
00181     return ok;
00182 }
00183 
00184 
00185 bool Foam::functionObjectList::read()
00186 {
00187     bool ok = true;
00188     updated_ = execution_;
00189 
00190     // avoid reading/initializing if execution is off
00191     if (!execution_)
00192     {
00193         return ok;
00194     }
00195 
00196     // Update existing and add new functionObjects
00197     const entry* entryPtr = parentDict_.lookupEntryPtr("functions",false,false);
00198     if (entryPtr)
00199     {
00200         PtrList<functionObject> newPtrs;
00201         List<SHA1Digest> newDigs;
00202         HashTable<label> newIndices;
00203 
00204         label nFunc = 0;
00205 
00206         if (entryPtr->isDict())
00207         {
00208             // a dictionary of functionObjects
00209             const dictionary& functionDicts = entryPtr->dict();
00210 
00211             newPtrs.setSize(functionDicts.size());
00212             newDigs.setSize(functionDicts.size());
00213 
00214             forAllConstIter(dictionary, functionDicts, iter)
00215             {
00216                 // safety:
00217                 if (!iter().isDict())
00218                 {
00219                     continue;
00220                 }
00221                 const word& key = iter().keyword();
00222                 const dictionary& dict = iter().dict();
00223 
00224                 newDigs[nFunc] = dict.digest();
00225 
00226                 label oldIndex;
00227                 functionObject* objPtr = remove(key, oldIndex);
00228                 if (objPtr)
00229                 {
00230                     // an existing functionObject, and dictionary changed
00231                     if (newDigs[nFunc] != digests_[oldIndex])
00232                     {
00233                         ok = objPtr->read(dict) && ok;
00234                     }
00235                 }
00236                 else
00237                 {
00238                     // new functionObject
00239                     objPtr = functionObject::New(key, time_, dict).ptr();
00240                     ok = objPtr->start() && ok;
00241                 }
00242 
00243                 newPtrs.set(nFunc, objPtr);
00244                 newIndices.insert(key, nFunc);
00245                 nFunc++;
00246             }
00247         }
00248         else
00249         {
00250             // a list of functionObjects
00251             PtrList<entry> functionDicts(entryPtr->stream());
00252 
00253             newPtrs.setSize(functionDicts.size());
00254             newDigs.setSize(functionDicts.size());
00255 
00256             forAllIter(PtrList<entry>, functionDicts, iter)
00257             {
00258                 // safety:
00259                 if (!iter().isDict())
00260                 {
00261                     continue;
00262                 }
00263                 const word& key = iter().keyword();
00264                 const dictionary& dict = iter().dict();
00265 
00266                 newDigs[nFunc] = dict.digest();
00267 
00268                 label oldIndex;
00269                 functionObject* objPtr = remove(key, oldIndex);
00270                 if (objPtr)
00271                 {
00272                     // an existing functionObject, and dictionary changed
00273                     if (newDigs[nFunc] != digests_[oldIndex])
00274                     {
00275                         ok = objPtr->read(dict) && ok;
00276                     }
00277                 }
00278                 else
00279                 {
00280                     // new functionObject
00281                     objPtr = functionObject::New(key, time_, dict).ptr();
00282                     ok = objPtr->start() && ok;
00283                 }
00284 
00285                 newPtrs.set(nFunc, objPtr);
00286                 newIndices.insert(key, nFunc);
00287                 nFunc++;
00288             }
00289         }
00290 
00291         // safety:
00292         newPtrs.setSize(nFunc);
00293         newDigs.setSize(nFunc);
00294 
00295         // updating the PtrList of functionObjects also deletes any existing,
00296         // but unused functionObjects
00297         PtrList<functionObject>::transfer(newPtrs);
00298         digests_.transfer(newDigs);
00299         indices_.transfer(newIndices);
00300     }
00301     else
00302     {
00303         PtrList<functionObject>::clear();
00304         digests_.clear();
00305         indices_.clear();
00306     }
00307 
00308     return ok;
00309 }
00310 
00311 
00312 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines