ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / OpenFOAM / db / functionObjects / functionObjectList / functionObjectList.C
blob22d6d4609708abebd77a26d0e135cee386b180ce
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
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 "functionObjectList.H"
27 #include "Time.H"
29 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
31 Foam::functionObject*
32 Foam::functionObjectList::remove(const word& key, label& oldIndex)
34     functionObject* ptr = 0;
36     // Find index of existing functionObject
37     HashTable<label>::iterator fnd = indices_.find(key);
39     if (fnd != indices_.end())
40     {
41         oldIndex = fnd();
43         // retrieve the pointer and remove it from the old list
44         ptr = this->set(oldIndex, 0).ptr();
45         indices_.erase(fnd);
46     }
47     else
48     {
49         oldIndex = -1;
50     }
52     return ptr;
56 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
58 Foam::functionObjectList::functionObjectList
60     const Time& t,
61     const bool execution
64     PtrList<functionObject>(),
65     digests_(),
66     indices_(),
67     time_(t),
68     parentDict_(t.controlDict()),
69     execution_(execution),
70     updated_(false)
74 Foam::functionObjectList::functionObjectList
76     const Time& t,
77     const dictionary& parentDict,
78     const bool execution
81     PtrList<functionObject>(),
82     digests_(),
83     indices_(),
84     time_(t),
85     parentDict_(parentDict),
86     execution_(execution),
87     updated_(false)
91 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
93 Foam::functionObjectList::~functionObjectList()
97 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
99 void Foam::functionObjectList::clear()
101     PtrList<functionObject>::clear();
102     digests_.clear();
103     indices_.clear();
104     updated_ = false;
108 Foam::label Foam::functionObjectList::findObjectID(const word& name) const
110     forAll(*this, objectI)
111     {
112         if (operator[](objectI).name() == name)
113         {
114             return objectI;
115         }
116     }
118     return -1;
122 void Foam::functionObjectList::on()
124     execution_ = true;
128 void Foam::functionObjectList::off()
130     // for safety, also force a read() when execution is turned back on
131     updated_ = execution_ = false;
135 bool Foam::functionObjectList::status() const
137     return execution_;
141 bool Foam::functionObjectList::start()
143     return read();
147 bool Foam::functionObjectList::execute(const bool forceWrite)
149     bool ok = true;
151     if (execution_)
152     {
153         if (!updated_)
154         {
155             read();
156         }
158         forAll(*this, objectI)
159         {
160             ok = operator[](objectI).execute(forceWrite) && ok;
161         }
162     }
164     return ok;
168 bool Foam::functionObjectList::end()
170     bool ok = true;
172     if (execution_)
173     {
174         if (!updated_)
175         {
176             read();
177         }
179         forAll(*this, objectI)
180         {
181             ok = operator[](objectI).end() && ok;
182         }
183     }
185     return ok;
189 bool Foam::functionObjectList::read()
191     bool ok = true;
192     updated_ = execution_;
194     // avoid reading/initializing if execution is off
195     if (!execution_)
196     {
197         return ok;
198     }
200     // Update existing and add new functionObjects
201     const entry* entryPtr = parentDict_.lookupEntryPtr
202     (
203         "functions",
204         false,
205         false
206     );
208     if (entryPtr)
209     {
210         PtrList<functionObject> newPtrs;
211         List<SHA1Digest> newDigs;
212         HashTable<label> newIndices;
214         label nFunc = 0;
216         if (entryPtr->isDict())
217         {
218             // a dictionary of functionObjects
219             const dictionary& functionDicts = entryPtr->dict();
221             newPtrs.setSize(functionDicts.size());
222             newDigs.setSize(functionDicts.size());
224             forAllConstIter(dictionary, functionDicts, iter)
225             {
226                 // safety:
227                 if (!iter().isDict())
228                 {
229                     continue;
230                 }
231                 const word& key = iter().keyword();
232                 const dictionary& dict = iter().dict();
234                 newDigs[nFunc] = dict.digest();
236                 label oldIndex;
237                 functionObject* objPtr = remove(key, oldIndex);
238                 if (objPtr)
239                 {
240                     // an existing functionObject, and dictionary changed
241                     if (newDigs[nFunc] != digests_[oldIndex])
242                     {
243                         ok = objPtr->read(dict) && ok;
244                     }
245                 }
246                 else
247                 {
248                     // new functionObject
249                     objPtr = functionObject::New(key, time_, dict).ptr();
250                     ok = objPtr->start() && ok;
251                 }
253                 newPtrs.set(nFunc, objPtr);
254                 newIndices.insert(key, nFunc);
255                 nFunc++;
256             }
257         }
258         else
259         {
260             // a list of functionObjects
261             PtrList<entry> functionDicts(entryPtr->stream());
263             newPtrs.setSize(functionDicts.size());
264             newDigs.setSize(functionDicts.size());
266             forAllIter(PtrList<entry>, functionDicts, iter)
267             {
268                 // safety:
269                 if (!iter().isDict())
270                 {
271                     continue;
272                 }
273                 const word& key = iter().keyword();
274                 const dictionary& dict = iter().dict();
276                 newDigs[nFunc] = dict.digest();
278                 label oldIndex;
279                 functionObject* objPtr = remove(key, oldIndex);
280                 if (objPtr)
281                 {
282                     // an existing functionObject, and dictionary changed
283                     if (newDigs[nFunc] != digests_[oldIndex])
284                     {
285                         ok = objPtr->read(dict) && ok;
286                     }
287                 }
288                 else
289                 {
290                     // new functionObject
291                     objPtr = functionObject::New(key, time_, dict).ptr();
292                     ok = objPtr->start() && ok;
293                 }
295                 newPtrs.set(nFunc, objPtr);
296                 newIndices.insert(key, nFunc);
297                 nFunc++;
298             }
299         }
301         // safety:
302         newPtrs.setSize(nFunc);
303         newDigs.setSize(nFunc);
305         // updating the PtrList of functionObjects also deletes any existing,
306         // but unused functionObjects
307         PtrList<functionObject>::transfer(newPtrs);
308         digests_.transfer(newDigs);
309         indices_.transfer(newIndices);
310     }
311     else
312     {
313         PtrList<functionObject>::clear();
314         digests_.clear();
315         indices_.clear();
316     }
318     return ok;
322 // ************************************************************************* //