FreeFOAM The Cross-Platform CFD Toolkit
functionObjectList.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "functionObjectList.H"
27 #include <OpenFOAM/Time.H>
28 
29 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
30 
32 Foam::functionObjectList::remove(const word& key, label& oldIndex)
33 {
34  functionObject* ptr = 0;
35 
36  // Find index of existing functionObject
37  HashTable<label>::iterator fnd = indices_.find(key);
38 
39  if (fnd != indices_.end())
40  {
41  oldIndex = fnd();
42 
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  }
51 
52  return ptr;
53 }
54 
55 
56 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
57 
58 Foam::functionObjectList::functionObjectList
59 (
60  const Time& t,
61  const bool execution
62 )
63 :
65  digests_(),
66  indices_(),
67  time_(t),
68  parentDict_(t.controlDict()),
69  execution_(execution),
70  updated_(false)
71 {}
72 
73 
74 Foam::functionObjectList::functionObjectList
75 (
76  const Time& t,
77  const dictionary& parentDict,
78  const bool execution
79 )
80 :
82  digests_(),
83  indices_(),
84  time_(t),
85  parentDict_(parentDict),
86  execution_(execution),
87  updated_(false)
88 {}
89 
90 
91 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
92 
94 {}
95 
96 
97 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
98 
100 {
102  digests_.clear();
103  indices_.clear();
104  updated_ = false;
105 }
106 
107 
109 {
110  execution_ = true;
111 }
112 
113 
115 {
116  // for safety, also force a read() when execution is turned back on
117  updated_ = execution_ = false;
118 }
119 
120 
122 {
123  return execution_;
124 }
125 
126 
128 {
129  return read();
130 }
131 
132 
134 {
135  bool ok = true;
136 
137  if (execution_)
138  {
139  if (!updated_)
140  {
141  read();
142  }
143 
144  forAllIter
145  (
147  static_cast<PtrList<functionObject>&>(*this),
148  iter
149  )
150  {
151  ok = iter().execute() && ok;
152  }
153  }
154 
155  return ok;
156 }
157 
158 
160 {
161  bool ok = true;
162 
163  if (execution_)
164  {
165  if (!updated_)
166  {
167  read();
168  }
169 
170  forAllIter
171  (
173  static_cast<PtrList<functionObject>&>(*this),
174  iter
175  )
176  {
177  ok = iter().end() && ok;
178  }
179  }
180 
181  return ok;
182 }
183 
184 
186 {
187  bool ok = true;
188  updated_ = execution_;
189 
190  // avoid reading/initializing if execution is off
191  if (!execution_)
192  {
193  return ok;
194  }
195 
196  // Update existing and add new functionObjects
197  const entry* entryPtr = parentDict_.lookupEntryPtr("functions",false,false);
198  if (entryPtr)
199  {
200  PtrList<functionObject> newPtrs;
201  List<SHA1Digest> newDigs;
202  HashTable<label> newIndices;
203 
204  label nFunc = 0;
205 
206  if (entryPtr->isDict())
207  {
208  // a dictionary of functionObjects
209  const dictionary& functionDicts = entryPtr->dict();
210 
211  newPtrs.setSize(functionDicts.size());
212  newDigs.setSize(functionDicts.size());
213 
214  forAllConstIter(dictionary, functionDicts, iter)
215  {
216  // safety:
217  if (!iter().isDict())
218  {
219  continue;
220  }
221  const word& key = iter().keyword();
222  const dictionary& dict = iter().dict();
223 
224  newDigs[nFunc] = dict.digest();
225 
226  label oldIndex;
227  functionObject* objPtr = remove(key, oldIndex);
228  if (objPtr)
229  {
230  // an existing functionObject, and dictionary changed
231  if (newDigs[nFunc] != digests_[oldIndex])
232  {
233  ok = objPtr->read(dict) && ok;
234  }
235  }
236  else
237  {
238  // new functionObject
239  objPtr = functionObject::New(key, time_, dict).ptr();
240  ok = objPtr->start() && ok;
241  }
242 
243  newPtrs.set(nFunc, objPtr);
244  newIndices.insert(key, nFunc);
245  nFunc++;
246  }
247  }
248  else
249  {
250  // a list of functionObjects
251  PtrList<entry> functionDicts(entryPtr->stream());
252 
253  newPtrs.setSize(functionDicts.size());
254  newDigs.setSize(functionDicts.size());
255 
256  forAllIter(PtrList<entry>, functionDicts, iter)
257  {
258  // safety:
259  if (!iter().isDict())
260  {
261  continue;
262  }
263  const word& key = iter().keyword();
264  const dictionary& dict = iter().dict();
265 
266  newDigs[nFunc] = dict.digest();
267 
268  label oldIndex;
269  functionObject* objPtr = remove(key, oldIndex);
270  if (objPtr)
271  {
272  // an existing functionObject, and dictionary changed
273  if (newDigs[nFunc] != digests_[oldIndex])
274  {
275  ok = objPtr->read(dict) && ok;
276  }
277  }
278  else
279  {
280  // new functionObject
281  objPtr = functionObject::New(key, time_, dict).ptr();
282  ok = objPtr->start() && ok;
283  }
284 
285  newPtrs.set(nFunc, objPtr);
286  newIndices.insert(key, nFunc);
287  nFunc++;
288  }
289  }
290 
291  // safety:
292  newPtrs.setSize(nFunc);
293  newDigs.setSize(nFunc);
294 
295  // updating the PtrList of functionObjects also deletes any existing,
296  // but unused functionObjects
298  digests_.transfer(newDigs);
299  indices_.transfer(newIndices);
300  }
301  else
302  {
304  digests_.clear();
305  indices_.clear();
306  }
307 
308  return ok;
309 }
310 
311 
312 // ************************ vim: set sw=4 sts=4 et: ************************ //