initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / db / functionObjects / functionObjectList / functionObjectList.C
blob0e52db7fc71ae2cff6e5307884af84000cd8a5d3
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "functionObjectList.H"
28 #include "Time.H"
30 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
32 Foam::functionObject*
33 Foam::functionObjectList::remove(const word& key, label& oldIndex)
35     functionObject* ptr = 0;
37     // Find index of existing functionObject
38     HashTable<label>::iterator fnd = indices_.find(key);
40     if (fnd != indices_.end())
41     {
42         oldIndex = fnd();
44         // retrieve the pointer and remove it from the old list
45         ptr = this->set(oldIndex, 0).ptr();
46         indices_.erase(fnd);
47     }
48     else
49     {
50         oldIndex = -1;
51     }
53     return ptr;
57 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
59 Foam::functionObjectList::functionObjectList
61     const Time& t,
62     const bool execution
65     PtrList<functionObject>(),
66     digests_(),
67     indices_(),
68     time_(t),
69     parentDict_(t.controlDict()),
70     execution_(execution),
71     updated_(false)
75 Foam::functionObjectList::functionObjectList
77     const Time& t,
78     const dictionary& parentDict,
79     const bool execution
82     PtrList<functionObject>(),
83     digests_(),
84     indices_(),
85     time_(t),
86     parentDict_(parentDict),
87     execution_(execution),
88     updated_(false)
92 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
94 Foam::functionObjectList::~functionObjectList()
98 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
100 void Foam::functionObjectList::clear()
102     PtrList<functionObject>::clear();
103     digests_.clear();
104     indices_.clear();
105     updated_ = false;
109 void Foam::functionObjectList::on()
111     execution_ = true;
115 void Foam::functionObjectList::off()
117     // for safety, also force a read() when execution is turned back on
118     updated_ = execution_ = false;
122 bool Foam::functionObjectList::status() const
124     return execution_;
128 bool Foam::functionObjectList::start()
130     return read();
134 bool Foam::functionObjectList::execute()
136     bool ok = true;
138     if (execution_)
139     {
140         if (!updated_)
141         {
142             read();
143         }
145         forAllIter
146         (
147             PtrList<functionObject>,
148             static_cast<PtrList<functionObject>&>(*this),
149             iter
150         )
151         {
152             ok = iter().execute() && ok;
153         }
154     }
156     return ok;
160 bool Foam::functionObjectList::end()
162     bool ok = true;
164     if (execution_)
165     {
166         if (!updated_)
167         {
168             read();
169         }
171         forAllIter
172         (
173             PtrList<functionObject>,
174             static_cast<PtrList<functionObject>&>(*this),
175             iter
176         )
177         {
178             ok = iter().end() && ok;
179         }
180     }
182     return ok;
186 bool Foam::functionObjectList::read()
188     bool ok = true;
189     updated_ = execution_;
191     // avoid reading/initializing if execution is off
192     if (!execution_)
193     {
194         return ok;
195     }
197     // Update existing and add new functionObjects
198     const entry* entryPtr = parentDict_.lookupEntryPtr("functions",false,false);
199     if (entryPtr)
200     {
201         PtrList<functionObject> newPtrs;
202         List<SHA1Digest> newDigs;
203         HashTable<label> newIndices;
205         label nFunc = 0;
207         if (entryPtr->isDict())
208         {
209             // a dictionary of functionObjects
210             const dictionary& functionDicts = entryPtr->dict();
212             newPtrs.setSize(functionDicts.size());
213             newDigs.setSize(functionDicts.size());
215             forAllConstIter(dictionary, functionDicts, iter)
216             {
217                 // safety:
218                 if (!iter().isDict())
219                 {
220                     continue;
221                 }
222                 const word& key = iter().keyword();
223                 const dictionary& dict = iter().dict();
225                 newDigs[nFunc] = dict.digest();
227                 label oldIndex;
228                 functionObject* objPtr = remove(key, oldIndex);
229                 if (objPtr)
230                 {
231                     // an existing functionObject, and dictionary changed
232                     if (newDigs[nFunc] != digests_[oldIndex])
233                     {
234                         ok = objPtr->read(dict) && ok;
235                     }
236                 }
237                 else
238                 {
239                     // new functionObject
240                     objPtr = functionObject::New(key, time_, dict).ptr();
241                     ok = objPtr->start() && ok;
242                 }
244                 newPtrs.set(nFunc, objPtr);
245                 newIndices.insert(key, nFunc);
246                 nFunc++;
247             }
248         }
249         else
250         {
251             // a list of functionObjects
252             PtrList<entry> functionDicts(entryPtr->stream());
254             newPtrs.setSize(functionDicts.size());
255             newDigs.setSize(functionDicts.size());
257             forAllIter(PtrList<entry>, functionDicts, iter)
258             {
259                 // safety:
260                 if (!iter().isDict())
261                 {
262                     continue;
263                 }
264                 const word& key = iter().keyword();
265                 const dictionary& dict = iter().dict();
267                 newDigs[nFunc] = dict.digest();
269                 label oldIndex;
270                 functionObject* objPtr = remove(key, oldIndex);
271                 if (objPtr)
272                 {
273                     // an existing functionObject, and dictionary changed
274                     if (newDigs[nFunc] != digests_[oldIndex])
275                     {
276                         ok = objPtr->read(dict) && ok;
277                     }
278                 }
279                 else
280                 {
281                     // new functionObject
282                     objPtr = functionObject::New(key, time_, dict).ptr();
283                     ok = objPtr->start() && ok;
284                 }
286                 newPtrs.set(nFunc, objPtr);
287                 newIndices.insert(key, nFunc);
288                 nFunc++;
289             }
290         }
292         // safety:
293         newPtrs.setSize(nFunc);
294         newDigs.setSize(nFunc);
296         // updating the PtrList of functionObjects also deletes any existing,
297         // but unused functionObjects
298         PtrList<functionObject>::transfer(newPtrs);
299         digests_.transfer(newDigs);
300         indices_.transfer(newIndices);
301     }
302     else
303     {
304         PtrList<functionObject>::clear();
305         digests_.clear();
306         indices_.clear();
307     }
309     return ok;
313 // ************************************************************************* //