functionObjectList.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
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 "argList.H"
29 #include "dictionaryEntry.H"
30 
31 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
32 
33 Foam::functionObject* Foam::functionObjectList::remove
34 (
35  const word& key,
36  label& oldIndex
37 )
38 {
39  functionObject* ptr = 0;
40 
41  // Find index of existing functionObject
42  HashTable<label>::iterator fnd = indices_.find(key);
43 
44  if (fnd != indices_.end())
45  {
46  oldIndex = fnd();
47 
48  // Retrieve the pointer and remove it from the old list
49  ptr = this->set(oldIndex, 0).ptr();
50  indices_.erase(fnd);
51  }
52  else
53  {
54  oldIndex = -1;
55  }
56 
57  return ptr;
58 }
59 
60 
61 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
62 
64 (
65  const Time& t,
66  const bool execution
67 )
68 :
70  digests_(),
71  indices_(),
72  time_(t),
73  parentDict_(t.controlDict()),
74  execution_(execution),
75  updated_(false)
76 {}
77 
78 
80 (
81  const Time& t,
82  const dictionary& parentDict,
83  const bool execution
84 )
85 :
87  digests_(),
88  indices_(),
89  time_(t),
90  parentDict_(parentDict),
91  execution_(execution),
92  updated_(false)
93 {}
94 
95 
97 (
98  const argList& args,
99  const Time& runTime,
101 )
102 {
103  autoPtr<functionObjectList> functionsPtr;
104 
105  controlDict.add
106  (
108  );
109 
110  dictionary& functionsDict = controlDict.subDict("functions");
111 
112  word region = word::null;
113 
114  // Set the region name if specified
115  if (args.optionFound("region"))
116  {
117  region = args["region"];
118  }
119 
120  if
121  (
122  args.optionFound("dict")
123  || args.optionFound("func")
124  || args.optionFound("funcs")
125  )
126  {
127  if (args.optionFound("dict"))
128  {
129  controlDict.merge
130  (
132  (
133  IOobject
134  (
135  args["dict"],
136  runTime,
138  )
139  )
140  );
141  }
142 
143  if (args.optionFound("func"))
144  {
146  (
147  "function",
148  args["func"],
149  functionsDict,
151  {"command", args.commandLine()},
152  region
153  );
154  }
155 
156  if (args.optionFound("funcs"))
157  {
158  wordList funcs(args.optionLookup("funcs")());
159 
160  forAll(funcs, i)
161  {
163  (
164  "function",
165  funcs[i],
166  functionsDict,
168  {"command", args.commandLine()},
169  region
170  );
171  }
172  }
173 
174  functionsPtr.reset(new functionObjectList(runTime, controlDict));
175  }
176  else
177  {
178  functionsPtr.reset(new functionObjectList(runTime));
179  }
180 
181  functionsPtr->read();
182 
183  return functionsPtr;
184 }
185 
186 
187 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
188 
190 {}
191 
192 
193 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
194 
196 {
198  digests_.clear();
199  indices_.clear();
200  updated_ = false;
201 }
202 
203 
205 {
206  forAll(*this, oi)
207  {
208  if (operator[](oi).name() == name)
209  {
210  return oi;
211  }
212  }
213 
214  return -1;
215 }
216 
217 
219 {
220  bool ok = read();
221 
222  if (execution_)
223  {
224  forAll(*this, oi)
225  {
226  if (operator[](oi).executeAtStart())
227  {
228  ok = operator[](oi).execute() && ok;
229  ok = operator[](oi).write() && ok;
230  }
231  }
232  }
233 
234  return ok;
235 }
236 
237 
239 {
240  bool ok = true;
241 
242  if (execution_)
243  {
244  if (!updated_)
245  {
246  read();
247  }
248 
249  forAll(*this, oi)
250  {
251  ok = operator[](oi).execute() && ok;
252  ok = operator[](oi).write() && ok;
253  }
254  }
255 
256  return ok;
257 }
258 
259 
261 {
262  bool ok = true;
263 
264  if (execution_)
265  {
266  if (!updated_)
267  {
268  read();
269  }
270 
271  forAll(*this, oi)
272  {
273  ok = operator[](oi).end() && ok;
274  }
275  }
276 
277  return ok;
278 }
279 
280 
282 {
283  scalar result = vGreat;
284 
285  if (execution_)
286  {
287  if (!updated_)
288  {
289  read();
290  }
291 
292  forAll(*this, oi)
293  {
294  result = min(result, operator[](oi).timeToNextAction());
295  }
296  }
297 
298  return result;
299 }
300 
301 
303 {
304  bool ok = true;
305  updated_ = execution_;
306 
307  // Avoid reading/initialising if execution is off
308  if (!execution_)
309  {
310  return true;
311  }
312 
313  // Update existing and add new functionObjects
314  const entry* entryPtr = parentDict_.lookupEntryPtr
315  (
316  "functions",
317  false,
318  false
319  );
320 
321  if (entryPtr)
322  {
323  PtrList<functionObject> newPtrs;
324  List<SHA1Digest> newDigs;
325  HashTable<label> newIndices;
326 
327  label nFunc = 0;
328 
329  if (!entryPtr->isDict())
330  {
331  FatalIOErrorInFunction(parentDict_)
332  << "'functions' entry is not a dictionary"
333  << exit(FatalIOError);
334  }
335 
336  const dictionary& functionsDict = entryPtr->dict();
337 
338  libs.open
339  (
340  functionsDict,
341  "libs",
342  functionObject::dictionaryConstructorTablePtr_
343  );
344 
345  newPtrs.setSize(functionsDict.size());
346  newDigs.setSize(functionsDict.size());
347 
348  forAllConstIter(dictionary, functionsDict, iter)
349  {
350  const word& key = iter().keyword();
351 
352  if (!iter().isDict())
353  {
354  if (key != "libs")
355  {
356  IOWarningInFunction(parentDict_)
357  << "Entry " << key << " is not a dictionary" << endl;
358  }
359 
360  continue;
361  }
362 
363  const dictionary& dict = iter().dict();
364  const bool enabled = dict.lookupOrDefault("enabled", true);
365 
366  newDigs[nFunc] = dict.digest();
367 
368  label oldIndex;
369  functionObject* objPtr = remove(key, oldIndex);
370 
371  if (objPtr)
372  {
373  if (enabled)
374  {
375  // Dictionary changed for an existing functionObject
376  if (newDigs[nFunc] != digests_[oldIndex])
377  {
378  ok = objPtr->read(dict) && ok;
379  }
380  }
381  else
382  {
383  // Delete the disabled functionObject
384  delete objPtr;
385  objPtr = nullptr;
386  continue;
387  }
388  }
389  else if (enabled)
390  {
392 
393  if
394  (
395  dict.found("executeControl")
396  || dict.found("writeControl")
397  || dict.found("outputControl")
398  )
399  {
400  foPtr.set
401  (
402  new functionObjects::timeControl(key, time_, dict)
403  );
404  }
405  else
406  {
407  foPtr = functionObject::New(key, time_, dict);
408  }
409 
410  if (foPtr.valid())
411  {
412  objPtr = foPtr.ptr();
413  }
414  else
415  {
416  ok = false;
417  }
418  }
419 
420  // Insert active functionObjects into the list
421  if (objPtr)
422  {
423  newPtrs.set(nFunc, objPtr);
424  newIndices.insert(key, nFunc);
425  nFunc++;
426  }
427  }
428 
429  newPtrs.setSize(nFunc);
430  newDigs.setSize(nFunc);
431 
432  // Updating the PtrList of functionObjects deletes any
433  // existing unused functionObjects
435  digests_.transfer(newDigs);
436  indices_.transfer(newIndices);
437  }
438  else
439  {
441  digests_.clear();
442  indices_.clear();
443  }
444 
445  return ok;
446 }
447 
448 
450 {
451  if (execution_)
452  {
453  forAll(*this, oi)
454  {
455  operator[](oi).movePoints(mesh);
456  }
457  }
458 }
459 
460 
462 {
463  if (execution_)
464  {
465  forAll(*this, oi)
466  {
467  operator[](oi).topoChange(map);
468  }
469  }
470 }
471 
472 
474 {
475  if (execution_)
476  {
477  forAll(*this, oi)
478  {
479  operator[](oi).mapMesh(map);
480  }
481  }
482 }
483 
484 
486 {
487  if (execution_)
488  {
489  forAll(*this, oi)
490  {
491  operator[](oi).distribute(map);
492  }
493  }
494 }
495 
496 
497 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
bool erase(const iterator &)
Erase a hashedEntry specified by given iterator.
Definition: HashTable.C:371
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
friend class iterator
Declare friendship with the iterator.
Definition: HashTable.H:194
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:142
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:119
void setSize(const label)
Reset size of List.
Definition: List.C:281
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
bool set(const label) const
Is element set.
Definition: PtrListI.H:65
void clear()
Clear the PtrList, i.e. set size to zero deleting all the.
Definition: PtrList.C:174
void transfer(PtrList< T > &)
Transfer the contents of the argument PtrList into this PtrList.
Definition: PtrList.C:189
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:131
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:103
const string & commandLine() const
Return the command line string.
Definition: argListI.H:30
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:114
IStringStream optionLookup(const word &opt) const
Return an IStringStream from the named option.
Definition: argListI.H:120
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set)
Definition: autoPtrI.H:83
T * ptr()
Return object pointer for reuse.
Definition: autoPtrI.H:90
void reset(T *=nullptr)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
void set(T *)
Set pointer to that given.
Definition: autoPtrI.H:99
A keyword and a list of tokens is a 'dictionaryEntry'.
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:659
static const dictionary null
Null dictionary.
Definition: dictionary.H:242
SHA1Digest digest() const
Return the SHA1 digest of the dictionary contents.
Definition: dictionary.C:625
bool open(const fileName &libName, const bool verbose=true)
Open the named library, optionally with warnings if problems occur.
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:68
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:156
virtual const dictionary & dict() const =0
Return dictionary if this entry is a dictionary.
static fileName functionObjectDictPath
Default relative path to the directory structure.
List of function objects with start(), execute() and end() functions that is called for each object.
static autoPtr< functionObjectList > New(const argList &args, const Time &runTime, dictionary &controlDict)
Construct and return a functionObjectList for an application.
virtual ~functionObjectList()
Destructor.
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
virtual void movePoints(const polyMesh &mesh)
Update topology using the given map.
label findObjectID(const word &name) const
Find the ID of a given function object by name.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
bool start()
Called at the start of the time-loop.
functionObjectList(const Time &runTime, const bool execution=true)
Construct from Time and the execution setting.
void clear()
Clear the list of function objects.
scalar timeToNextAction()
Return the time to the next write.
bool execute()
Called at each ++ or += of the time-loop.
virtual void topoChange(const polyTopoChangeMap &map)
Update topology using the given map.
bool end()
Called when Time::run() determines that the time-loop exits.
bool read()
Read and set the function objects if their data have changed.
Abstract base-class for Time/database functionObjects.
static autoPtr< functionObject > New(const word &name, const Time &, const dictionary &)
Select from dictionary, based on its "type" entry.
virtual bool read(const dictionary &)
Read and set the functionObject if its data have changed.
General time control for functionObjects.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:318
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dlLibraryTable libs
Table of loaded dynamic libraries.
bool read(const char *, int32_t &)
Definition: int32IO.C:85
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
bool readConfigFile(const word &configType, const string &argString, dictionary &parentDict, const fileName &configFilesPath, const Pair< string > &contextTypeAndValue, const word &region=word::null)
Read the specified configuration file.
Definition: dictionaryIO.C:424
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
IOerror FatalIOError
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
runTime controlDict().lookup("adjustTimeStep") >> adjustTimeStep
dictionary dict
Foam::argList args(argc, argv)
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112