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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "functionObjectList.H"
30 #include "Time.H"
31 #include "mapPolyMesh.H"
32 #include "profiling.H"
33 #include "argList.H"
35 #include "dictionaryEntry.H"
36 #include "stringOps.H"
37 #include "Tuple2.H"
38 #include "etcFiles.H"
39 #include "IOdictionary.H"
40 #include "Pstream.H"
41 #include "OSspecific.H"
42 
43 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
44 
45 //- Max number of warnings (per functionObject)
46 static constexpr const uint32_t maxWarnings = 10u;
47 
49 (
50  "caseDicts/postProcessing"
51 );
52 
53 
54 const Foam::Enum
55 <
56  Foam::functionObjectList::errorHandlingType
57 >
58 Foam::functionObjectList::errorHandlingNames_
59 ({
60  { errorHandlingType::DEFAULT, "default" },
61  { errorHandlingType::WARN, "warn" },
62  { errorHandlingType::IGNORE, "ignore" },
63  { errorHandlingType::STRICT, "strict" },
64 });
65 
66 
67 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
68 
69 namespace Foam
70 {
71  //- Mimic exit handling of the error class
72  static void exitNow(const error& err)
73  {
74  if (error::useAbort())
75  {
76  Perr<< nl << err << nl
77  << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
79  std::abort();
80  }
81  else if (Pstream::parRun())
82  {
83  Perr<< nl << err << nl
84  << "\nFOAM parallel run exiting\n" << endl;
85  Pstream::exit(1);
86  }
87  else
88  {
89  Perr<< nl << err << nl
90  << "\nFOAM exiting\n" << endl;
91  std::exit(1);
92  }
93  }
94 
95 } // End namespace Foam
96 
97 
98 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
99 
100 void Foam::functionObjectList::createStateDict() const
101 {
102  // Cannot set the state dictionary on construction since Time has not
103  // been fully initialised
104  stateDictPtr_.reset
105  (
106  new IOdictionary
107  (
108  IOobject
109  (
110  "functionObjectProperties",
111  time_.timeName(),
112  "uniform"/word("functionObjects"),
113  time_,
116  )
117  )
118  );
119 }
120 
121 
122 void Foam::functionObjectList::createOutputRegistry() const
123 {
124  objectsRegistryPtr_.reset
125  (
126  new objectRegistry
127  (
128  IOobject
129  (
130  "functionObjectObjects",
131  time_.timeName(),
132  time_,
135  )
136  )
137  );
138 }
139 
140 
141 Foam::autoPtr<Foam::functionObject> Foam::functionObjectList::remove
142 (
143  const word& key,
144  label& oldIndex
145 )
146 {
147  autoPtr<functionObject> oldptr;
148 
149  auto iter = indices_.find(key); // Index of existing functionObject
150 
151  if (iter.found())
152  {
153  oldIndex = *iter;
154 
155  // Remove pointer from the old list
156  oldptr = this->release(oldIndex);
157  indices_.erase(iter);
158  }
159  else
160  {
161  oldIndex = -1;
162  }
163 
164  return oldptr;
165 }
166 
167 
168 void Foam::functionObjectList::listDir
169 (
170  const fileName& dir,
171  wordHashSet& available
172 )
173 {
174  // Search specified directory for functionObject configuration files
175  for (const fileName& f : fileHandler().readDir(dir))
176  {
177  if (f.ext().empty())
178  {
179  available.insert(f);
180  }
181  }
182 
183  // Recurse into sub-directories
184  for (const fileName& d : fileHandler().readDir(dir, fileName::DIRECTORY))
185  {
186  listDir(dir/d, available);
187  }
188 }
189 
190 
192 {
193  wordHashSet available;
194 
195  for (const fileName& d : findEtcDirs(functionObjectDictPath))
196  {
197  listDir(d, available);
198  }
199 
200  Info<< nl
201  << "Available configured functionObjects:"
202  << available.sortedToc()
203  << nl;
204 }
205 
206 
208 {
209  // First check for functionObject dictionary file in globalCase system/
210 
211  fileName dictFile = stringOps::expand("<system>")/funcName;
212 
213  if (isFile(dictFile))
214  {
215  return dictFile;
216  }
217 
218  for (const fileName& d : findEtcDirs(functionObjectDictPath))
219  {
220  dictFile = search(funcName, d);
221  if (!dictFile.empty())
222  {
223  return dictFile;
224  }
225  }
226 
227  return fileName::null;
228 }
229 
230 
232 (
233  const string& funcNameArgs,
234  dictionary& functionsDict,
235  HashSet<wordRe>& requiredFields,
236  const word& region
237 )
238 {
239  // Parse the optional functionObject arguments:
240  // 'Q(U)' -> funcName = Q; args = (U); field = U
241  //
242  // Supports named arguments:
243  // 'patchAverage(patch=inlet, p)' -> funcName = patchAverage;
244  // args = (patch=inlet, p); field = p
245 
246  word funcName(funcNameArgs);
247 
248  int argLevel = 0;
249  wordRes args;
250 
251  List<Tuple2<word, string>> namedArgs;
252  bool hasNamedArg = false;
253  word argName;
254 
255  word::size_type start = 0;
256  word::size_type i = 0;
257 
258  for
259  (
260  word::const_iterator iter = funcNameArgs.begin();
261  iter != funcNameArgs.end();
262  ++iter
263  )
264  {
265  char c = *iter;
266 
267  if (c == '(')
268  {
269  if (argLevel == 0)
270  {
271  funcName = funcNameArgs.substr(start, i - start);
272  start = i+1;
273  }
274  ++argLevel;
275  }
276  else if (c == ',' || c == ')')
277  {
278  if (argLevel == 1)
279  {
280  if (hasNamedArg)
281  {
282  namedArgs.append
283  (
285  (
286  argName,
287  funcNameArgs.substr(start, i - start)
288  )
289  );
290  hasNamedArg = false;
291  }
292  else
293  {
294  args.append
295  (
296  wordRe
297  (
299  (
300  funcNameArgs.substr(start, i - start)
301  )
302  )
303  );
304  }
305  start = i+1;
306  }
307 
308  if (c == ')')
309  {
310  if (argLevel == 1)
311  {
312  break;
313  }
314  --argLevel;
315  }
316  }
317  else if (c == '=')
318  {
319  argName = word::validate
320  (
321  funcNameArgs.substr(start, i - start)
322  );
323 
324  start = i+1;
325  hasNamedArg = true;
326  }
327 
328  ++i;
329  }
330 
331  // Search for the functionObject dictionary
333 
334  if (path.empty())
335  {
337  << "Cannot find functionObject file " << funcName << endl;
338  return false;
339  }
340 
341  // Read the functionObject dictionary
342  autoPtr<ISstream> fileStreamPtr(fileHandler().NewIFstream(path));
343  ISstream& fileStream = *fileStreamPtr;
344 
345  dictionary funcsDict(fileStream);
346  dictionary* funcDictPtr = funcsDict.findDict(funcName);
347  dictionary& funcDict = (funcDictPtr ? *funcDictPtr : funcsDict);
348 
349 
350  // Insert the 'field' and/or 'fields' entry corresponding to the optional
351  // arguments or read the 'field' or 'fields' entry and add the required
352  // fields to requiredFields
353  if (args.size() == 1)
354  {
355  funcDict.set("field", args[0]);
356  funcDict.set("fields", args);
357  requiredFields.insert(args[0]);
358  }
359  else if (args.size() > 1)
360  {
361  funcDict.set("fields", args);
362  requiredFields.insert(args);
363  }
364  else if (funcDict.found("field"))
365  {
366  requiredFields.insert(funcDict.get<wordRe>("field"));
367  }
368  else if (funcDict.found("fields"))
369  {
370  requiredFields.insert(funcDict.get<wordRes>("fields"));
371  }
372 
373  // Insert named arguments
374  for (const Tuple2<word, string>& namedArg : namedArgs)
375  {
376  IStringStream entryStream
377  (
378  namedArg.first() + ' ' + namedArg.second() + ';'
379  );
380 
381  funcDict.set(entry::New(entryStream).ptr());
382  }
383 
384  // Insert the region name if specified
385  if (!region.empty())
386  {
387  funcDict.set("region", region);
388  }
389 
390  // Merge this functionObject dictionary into functionsDict
391  dictionary funcArgsDict;
392  funcArgsDict.add(word::validate(funcNameArgs), funcDict);
393  functionsDict.merge(funcArgsDict);
394 
395  return true;
396 }
397 
398 
399 Foam::functionObjectList::errorHandlingType
400 Foam::functionObjectList::getOrDefaultErrorHandling
401 (
402  const word& key,
403  const dictionary& dict,
404  const errorHandlingType deflt
405 ) const
406 {
407  const entry* eptr = dict.findEntry(key, keyType::LITERAL);
408 
409  if (eptr)
410  {
411  if (eptr->isDict())
412  {
413  Warning
414  << "The sub-dictionary '" << key
415  << "' masks error handling for functions" << endl;
416  }
417  else
418  {
419  const word enumName(eptr->get<word>());
420 
421  if (!errorHandlingNames_.found(enumName))
422  {
423  // Failed the name lookup
425  << enumName << " is not in enumeration: "
426  << errorHandlingNames_ << nl
427  << exit(FatalIOError);
428  }
429 
430  return errorHandlingNames_.get(enumName);
431  }
432  }
433 
434  return deflt;
435 }
436 
437 
438 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
439 
440 Foam::functionObjectList::functionObjectList
441 (
442  const Time& runTime,
443  const bool execution
444 )
445 :
447 {}
448 
449 
450 Foam::functionObjectList::functionObjectList
451 (
452  const Time& runTime,
453  const dictionary& parentDict,
454  const bool execution
455 )
456 :
458  errorHandling_(),
459  digests_(),
460  indices_(),
461  warnings_(),
462  time_(runTime),
463  parentDict_(parentDict),
464  stateDictPtr_(nullptr),
465  objectsRegistryPtr_(nullptr),
466  execution_(execution),
467  updated_(false)
468 {}
469 
470 
472 (
473  const argList& args,
474  const Time& runTime,
476  HashSet<wordRe>& requiredFields
477 )
478 {
479  // Merge any functions from the provided controlDict
480  controlDict.add
481  (
483  true
484  );
485 
486  dictionary& functionsDict = controlDict.subDict("functions");
487 
488  const word regionName = args.getOrDefault<word>("region", "");
489 
490  bool modifiedControlDict = false;
491 
492  if (args.found("dict"))
493  {
494  modifiedControlDict = true;
495 
496  controlDict.merge
497  (
499  (
500  IOobject
501  (
502  args["dict"],
503  runTime,
505  )
506  )
507  );
508  }
509 
510  if (args.found("func"))
511  {
512  modifiedControlDict = true;
513 
514  readFunctionObject
515  (
516  args["func"],
517  functionsDict,
518  requiredFields,
519  regionName
520  );
521  }
522 
523  if (args.found("funcs"))
524  {
525  modifiedControlDict = true;
526 
527  for (const word& funcName : args.getList<word>("funcs"))
528  {
529  readFunctionObject
530  (
531  funcName,
532  functionsDict,
533  requiredFields,
534  regionName
535  );
536  }
537  }
538 
539 
540  autoPtr<functionObjectList> functionsPtr;
541 
542  if (modifiedControlDict)
543  {
544  functionsPtr.reset(new functionObjectList(runTime, controlDict));
545  }
546  else
547  {
548  functionsPtr.reset(new functionObjectList(runTime));
549  }
550 
551  functionsPtr->start();
552 
553  return functionsPtr;
554 }
555 
556 
557 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
558 
560 {
561  return stateDict().getOrDefault<label>("triggerIndex", labelMin);
562 }
563 
564 
566 {
567  // Reset (re-read) the state dictionary
568  stateDictPtr_.reset(nullptr);
569  createStateDict();
570 }
571 
572 
574 {
575  if (!stateDictPtr_)
576  {
577  createStateDict();
578  }
579 
580  return *stateDictPtr_;
581 }
582 
583 
585 {
586  if (!stateDictPtr_)
587  {
588  createStateDict();
589  }
590 
591  return *stateDictPtr_;
592 }
593 
594 
596 {
597  if (!objectsRegistryPtr_)
598  {
599  createOutputRegistry();
600  }
601 
602  return *objectsRegistryPtr_;
603 }
604 
605 
607 {
608  if (!objectsRegistryPtr_)
609  {
610  createOutputRegistry();
611  }
612 
613  return *objectsRegistryPtr_;
614 }
615 
616 
618 {
620  errorHandling_.clear();
621  digests_.clear();
622  indices_.clear();
623  warnings_.clear();
624  updated_ = false;
625 }
626 
627 
628 Foam::label Foam::functionObjectList::findObjectID(const word& objName) const
629 {
630  label id = 0;
631 
632  for (const functionObject& funcObj : functions())
633  {
634  if (funcObj.name() == objName)
635  {
636  return id;
637  }
638 
639  ++id;
640  }
641 
642  return -1;
643 }
644 
645 
647 {
648  execution_ = true;
649 }
650 
651 
653 {
654  // For safety, also force a read() when execution is resumed
655  updated_ = execution_ = false;
656 }
657 
658 
660 {
661  return execution_;
662 }
663 
664 
666 {
667  return read();
668 }
669 
670 
672 {
673  bool ok = true;
674 
675  if (execution_)
676  {
677  if (!updated_)
678  {
679  read();
680  }
681 
682  auto errIter = errorHandling_.cbegin();
683 
684  for (functionObject& funcObj : functions())
685  {
686  const errorHandlingType errorHandling = *errIter;
687  ++errIter;
688 
689  const word& objName = funcObj.name();
690 
691  if
692  (
693  errorHandling == errorHandlingType::WARN
694  || errorHandling == errorHandlingType::IGNORE
695  )
696  {
697  // Throw FatalError, FatalIOError as exceptions
698 
699  const bool throwingError = FatalError.throwExceptions();
700  const bool throwingIOerr = FatalIOError.throwExceptions();
701 
702  bool hadError = false;
703 
704  // execute()
705  try
706  {
708  (
709  fo,
710  "functionObject::" + objName + "::execute"
711  );
712 
713  ok = funcObj.execute() && ok;
714  }
715  catch (const Foam::error& err)
716  {
717  // Treat IOerror and error identically
718  uint32_t nWarnings;
719  hadError = true;
720 
721  if
722  (
723  errorHandling != errorHandlingType::IGNORE
724  && (nWarnings = ++warnings_(objName)) <= maxWarnings
725  )
726  {
727  // Trickery to get original message
728  err.write(Warning, false);
729  Info<< nl
730  << "--> execute() function object '"
731  << objName << "'";
732 
733  if (nWarnings == maxWarnings)
734  {
735  Info<< nl << "... silencing further warnings";
736  }
737 
738  Info<< nl << endl;
739  }
740  }
741 
742  if (hadError)
743  {
744  // Restore previous state
745  FatalError.throwExceptions(throwingError);
746  FatalIOError.throwExceptions(throwingIOerr);
747  continue;
748  }
749 
750  // write()
751  try
752  {
754  (
755  fo,
756  "functionObject::" + objName + ":write"
757  );
758 
759  ok = funcObj.write() && ok;
760  }
761  catch (const Foam::error& err)
762  {
763  // Treat IOerror and error identically
764  uint32_t nWarnings;
765 
766  if
767  (
768  errorHandling != errorHandlingType::IGNORE
769  && (nWarnings = ++warnings_(objName)) <= maxWarnings
770  )
771  {
772  // Trickery to get original message
773  err.write(Warning, false);
774  Info<< nl
775  << "--> write() function object '"
776  << objName << "'";
777 
778  if (nWarnings == maxWarnings)
779  {
780  Info<< nl << "... silencing further warnings";
781  }
782 
783  Info<< nl << endl;
784  }
785  }
786 
787  // Restore previous state
788  FatalError.throwExceptions(throwingError);
789  FatalIOError.throwExceptions(throwingIOerr);
790  }
791  else
792  {
793  // No special trapping of errors
794 
795  // execute()
796  {
798  (
799  fo,
800  "functionObject::" + objName + "::execute"
801  );
802 
803  ok = funcObj.execute() && ok;
804  }
805 
806  // write()
807  {
809  (
810  fo,
811  "functionObject::" + objName + ":write"
812  );
813 
814  ok = funcObj.write() && ok;
815  }
816  }
817  }
818  }
819 
820  // Force writing of state dictionary after function object execution
821  if (time_.writeTime())
822  {
823  const auto oldPrecision = IOstream::precision_;
825 
826  stateDictPtr_->writeObject
827  (
828  IOstreamOption(IOstream::ASCII, time_.writeCompression()),
829  true
830  );
831 
832  IOstream::precision_ = oldPrecision;
833  }
834 
835  return ok;
836 }
837 
838 
839 bool Foam::functionObjectList::execute(const label subIndex)
840 {
841  bool ok = execution_;
842 
843  if (ok)
844  {
845  for (functionObject& funcObj : functions())
846  {
847  // Probably do not need try/catch...
848 
849  ok = funcObj.execute(subIndex) && ok;
850  }
851  }
852 
853  return ok;
854 }
855 
856 
858 (
859  const UList<wordRe>& functionNames,
860  const label subIndex
861 )
862 {
863  bool ok = execution_;
864 
865  if (ok && functionNames.size())
866  {
867  for (functionObject& funcObj : functions())
868  {
869  if (stringOps::match(functionNames, funcObj.name()))
870  {
871  // Probably do not need try/catch...
872 
873  ok = funcObj.execute(subIndex) && ok;
874  }
875  }
876  }
877 
878  return ok;
879 }
880 
881 
883 {
884  bool ok = true;
885 
886  if (execution_)
887  {
888  if (!updated_)
889  {
890  read();
891  }
892 
893  auto errIter = errorHandling_.cbegin();
894 
895  for (functionObject& funcObj : functions())
896  {
897  const errorHandlingType errorHandling = *errIter;
898  ++errIter;
899 
900  const word& objName = funcObj.name();
901 
902  // Ignore failure on end() - not much we can do anyhow
903 
904  // Throw FatalError, FatalIOError as exceptions
905  const bool throwingError = FatalError.throwExceptions();
906  const bool throwingIOerr = FatalIOError.throwExceptions();
907 
908  try
909  {
910  addProfiling(fo, "functionObject::" + objName + "::end");
911  ok = funcObj.end() && ok;
912  }
913  catch (const Foam::error& err)
914  {
915  // Treat IOerror and error identically
916  uint32_t nWarnings;
917 
918  if
919  (
920  errorHandling != errorHandlingType::IGNORE
921  && (nWarnings = ++warnings_(objName)) <= maxWarnings
922  )
923  {
924  // Trickery to get original message
925  err.write(Warning, false);
926  Info<< nl
927  << "--> end() function object '"
928  << objName << "'";
929 
930  if (nWarnings == maxWarnings)
931  {
932  Info<< nl << "... silencing further warnings";
933  }
934 
935  Info<< nl << endl;
936  }
937  }
938 
939  // Restore previous state
940  FatalError.throwExceptions(throwingError);
941  FatalIOError.throwExceptions(throwingIOerr);
942  }
943  }
944 
945  return ok;
946 }
947 
948 
950 {
951  bool ok = true;
952 
953  if (execution_)
954  {
955  if (!updated_)
956  {
957  read();
958  }
959 
960  for (functionObject& funcObj : functions())
961  {
962  const word& objName = funcObj.name();
963 
964  // Probably do not need try/catch...
965 
967  (
968  fo,
969  "functionObject::" + objName + "::adjustTimeStep"
970  );
971 
972  ok = funcObj.adjustTimeStep() && ok;
973  }
974  }
975 
976  return ok;
977 }
978 
979 
981 {
982  if (!stateDictPtr_)
983  {
984  createStateDict();
985  }
986 
987  updated_ = execution_;
988 
989  // Avoid reading/initializing if execution is off
990  if (!execution_)
991  {
992  return true;
993  }
994 
995  // Update existing and add new functionObjects
996  const entry* entryPtr =
997  parentDict_.findEntry("functions", keyType::LITERAL);
998 
999  bool ok = true;
1000 
1001  if (!entryPtr)
1002  {
1003  // No functions
1005  errorHandling_.clear();
1006  digests_.clear();
1007  indices_.clear();
1008  warnings_.clear();
1009  }
1010  else if (!entryPtr->isDict())
1011  {
1012  // Bad entry type
1013  ok = false;
1014  FatalIOErrorInFunction(parentDict_)
1015  << "'functions' entry is not a dictionary"
1016  << exit(FatalIOError);
1017  }
1018  else
1019  {
1020  const dictionary& functionsDict = entryPtr->dict();
1021 
1022  PtrList<functionObject> newPtrs(functionsDict.size());
1023  List<SHA1Digest> newDigs(functionsDict.size());
1024 
1025  errorHandling_.resize
1026  (
1027  functionsDict.size(),
1028  errorHandlingType::DEFAULT
1029  );
1030 
1031  HashTable<label> newIndices;
1032 
1033  addProfiling(fo, "functionObjects::read");
1034 
1035  // Top-level "libs" specification (optional)
1036  time_.libs().open
1037  (
1038  functionsDict,
1039  "libs",
1040  functionObject::dictionaryConstructorTablePtr_
1041  );
1042 
1043  // Top-level "errors" specification (optional)
1044  const errorHandlingType errorHandlingFallback =
1045  getOrDefaultErrorHandling
1046  (
1047  "errors",
1048  functionsDict,
1049  errorHandlingType::DEFAULT
1050  );
1051 
1052  label nFunc = 0;
1053 
1054  for (const entry& dEntry : functionsDict)
1055  {
1056  const word& key = dEntry.keyword();
1057 
1058  if (!dEntry.isDict())
1059  {
1060  if (key != "errors" && key != "libs")
1061  {
1062  IOWarningInFunction(parentDict_)
1063  << "Entry " << key << " is not a dictionary" << endl;
1064  }
1065 
1066  continue;
1067  }
1068 
1069  const dictionary& dict = dEntry.dict();
1070 
1071  bool enabled = dict.getOrDefault("enabled", true);
1072 
1073  // Per-function "errors" specification
1074  const errorHandlingType errorHandling =
1075  getOrDefaultErrorHandling
1076  (
1077  "errors",
1078  dict,
1079  errorHandlingFallback
1080  );
1081 
1082  errorHandling_[nFunc] = errorHandling;
1083 
1084  newDigs[nFunc] = dict.digest();
1085 
1086  label oldIndex = -1;
1087  autoPtr<functionObject> objPtr = remove(key, oldIndex);
1088 
1089  const bool needsTimeControl =
1091 
1092  if (objPtr)
1093  {
1094  // Existing functionObject:
1095  // Re-read if dictionary content changed and did not
1096  // change timeControl <-> regular
1097 
1098  if (enabled && newDigs[nFunc] != digests_[oldIndex])
1099  {
1100  const bool wasTimeControl =
1101  isA<functionObjects::timeControl>(*objPtr);
1102 
1103  if (needsTimeControl != wasTimeControl)
1104  {
1105  // Changed from timeControl <-> regular
1106 
1107  // Fallthrough to 'new'
1108  objPtr.reset(nullptr);
1109  }
1110  else
1111  {
1112  // Normal read. Assume no errors to trap
1113 
1114  addProfiling
1115  (
1116  fo,
1117  "functionObject::" + objPtr->name() + "::read"
1118  );
1119 
1120  enabled = objPtr->read(dict);
1121  }
1122  }
1123 
1124  if (!enabled)
1125  {
1126  // Delete disabled or an invalid(read) functionObject
1127  objPtr.reset(nullptr);
1128  continue;
1129  }
1130  }
1131 
1132  if (enabled && !objPtr)
1133  {
1134  // Throw FatalError, FatalIOError as exceptions
1135  const bool throwingError = FatalError.throwExceptions();
1136  const bool throwingIOerr = FatalIOError.throwExceptions();
1137 
1138  try
1139  {
1140  // New functionObject
1141  addProfiling
1142  (
1143  fo,
1144  "functionObject::" + key + "::new"
1145  );
1146  if (needsTimeControl)
1147  {
1148  objPtr.reset
1149  (
1150  new functionObjects::timeControl(key, time_, dict)
1151  );
1152  }
1153  else
1154  {
1155  objPtr = functionObject::New(key, time_, dict);
1156  }
1157  }
1158  catch (const Foam::error& err)
1159  {
1160  objPtr.reset(nullptr); // extra safety
1161 
1162  switch (errorHandling)
1163  {
1164  case errorHandlingType::IGNORE:
1165  break;
1166 
1167  case errorHandlingType::STRICT:
1168  {
1169  exitNow(err);
1170  break;
1171  }
1172 
1173  case errorHandlingType::DEFAULT:
1174  {
1175  if (isA<Foam::IOerror>(err))
1176  {
1177  // Fatal for Foam::IOerror
1178  exitNow(err);
1179  break;
1180  }
1181 
1182  // Emit warning otherwise
1183  [[fallthrough]];
1184  }
1185 
1186  case errorHandlingType::WARN:
1187  {
1188  // Trickery to get original message
1189  err.write(Warning, false);
1190  Info<< nl
1191  << "--> loading function object '"
1192  << key << "'"
1193  << nl << endl;
1194  break;
1195  }
1196  }
1197  }
1198 
1199  // Restore previous state
1200  FatalError.throwExceptions(throwingError);
1201  FatalIOError.throwExceptions(throwingIOerr);
1202 
1203  // Require valid functionObject on all processors
1204  if (!returnReduce(bool(objPtr), andOp<bool>()))
1205  {
1206  objPtr.reset(nullptr);
1207  ok = false;
1208  }
1209  }
1210 
1211  // Insert active functionObject into the list
1212  if (objPtr)
1213  {
1214  newPtrs.set(nFunc, objPtr);
1215  newIndices.insert(key, nFunc);
1216  ++nFunc;
1217  }
1218  }
1219 
1220  newPtrs.resize(nFunc);
1221  newDigs.resize(nFunc);
1222  errorHandling_.resize(nFunc);
1223 
1224  // Updating PtrList of functionObjects deletes any
1225  // existing unused functionObjects
1227  digests_.transfer(newDigs);
1228  indices_.transfer(newIndices);
1229  warnings_.clear();
1230  }
1231 
1232  return ok;
1233 }
1234 
1235 
1237 {
1238  bool ok = false;
1239  if (execution_)
1240  {
1241  for (const functionObject& funcObj : functions())
1242  {
1243  bool changed = funcObj.filesModified();
1244  ok = ok || changed;
1245  }
1246  }
1247  return ok;
1248 }
1249 
1250 
1252 {
1253  if (execution_)
1254  {
1255  for (functionObject& funcObj : functions())
1256  {
1257  funcObj.updateMesh(mpm);
1258  }
1259  }
1260 }
1261 
1262 
1264 {
1265  if (execution_)
1266  {
1267  for (functionObject& funcObj : functions())
1268  {
1269  funcObj.movePoints(mesh);
1270  }
1271  }
1272 }
1273 
1274 
1275 // ************************************************************************* //
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::dictionary::findDict
dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary pointer if present.
Definition: dictionary.C:508
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
profiling.H
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::autoPtr::reset
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:109
Foam::functionObjectList::movePoints
void movePoints(const polyMesh &mesh)
Update for changes of mesh.
Definition: functionObjectList.C:1263
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
Foam::dictionaryEntry
A keyword and a list of tokens is a 'dictionaryEntry'.
Definition: dictionaryEntry.H:65
Foam::functionObjectList::list
static void list()
Definition: functionObjectList.C:191
Foam::entry::New
static bool New(dictionary &parentDict, Istream &is, const inputMode inpMode=inputMode::GLOBAL, const int endChar=0)
Construct from an Istream and insert into the dictionary.
Definition: entryIO.C:104
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::error::printStack
static void printStack(Ostream &os)
Helper function to print a stack.
Definition: dummyPrintStack.C:36
Foam::functionObjectList::status
bool status() const
Return the execution status (on/off) of the function objects.
Definition: functionObjectList.C:659
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::functionObjectList::adjustTimeStep
bool adjustTimeStep()
Called at the end of Time::adjustDeltaT() if adjustTime is true.
Definition: functionObjectList.C:949
Foam::functionObjectList::findDict
static fileName findDict(const word &funcName)
Definition: functionObjectList.C:207
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::functionObject::New
static autoPtr< functionObject > New(const word &name, const Time &runTime, const dictionary &dict)
Select from dictionary, based on its "type" entry.
Definition: functionObject.C:67
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:280
Tuple2.H
Foam::functionObjectList::on
void on()
Switch the function objects on.
Definition: functionObjectList.C:646
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionary.C:364
Foam::exitNow
static void exitNow(const error &err)
Mimic exit handling of the error class.
Definition: functionObjectList.C:72
mapPolyMesh.H
Foam::Warning
messageStream Warning
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::findEtcDirs
fileNameList findEtcDirs(const fileName &name, unsigned short location=0777, const bool findFirst=false)
Search for directories from user/group/other etc locations.
Definition: etcFiles.C:381
Foam::functionObjectList::stateDict
IOdictionary & stateDict()
Definition: functionObjectList.C:573
Foam::UPstream::parRun
static bool & parRun()
Test if this a parallel run, or allow modify access.
Definition: UPstream.H:434
functionObjectList.H
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::functionObjects::timeControl
Wrapper around functionObjects to add time control.
Definition: timeControlFunctionObject.H:76
Foam::ISstream
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:55
Foam::functionObjectList::updateMesh
void updateMesh(const mapPolyMesh &mpm)
Update for changes of mesh.
Definition: functionObjectList.C:1251
Foam::HashTable::insert
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:180
Foam::word::validate
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition: word.C:45
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:123
Foam::isFile
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Definition: MSwindows.C:658
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1354
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:182
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::IOstream::precision_
static unsigned int precision_
Default precision.
Definition: IOstream.H:94
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:81
Foam::dictionary::set
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:847
Foam::functionObjectList::execute
bool execute()
Called at each ++ or += of the time-loop.
Definition: functionObjectList.C:671
Foam::HashSet< word >
Foam::functionObjectList
List of function objects with start(), execute() and end() functions that is called for each object.
Definition: functionObjectList.H:122
Foam::wordRe
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:72
Foam::functionObjectList::start
bool start()
Called at the start of the time-loop.
Definition: functionObjectList.C:665
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::functionObject
Abstract base-class for Time/database function objects.
Definition: functionObject.H:321
Foam::functionObjectList::clear
void clear()
Clear the list of function objects.
Definition: functionObjectList.C:617
Foam::dictionary::null
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
Definition: dictionary.H:385
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::stringOps::expand
string expand(const std::string &s, const HashTable< string, word, string::hash > &mapping, const char sigil='$')
Definition: stringOps.C:720
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::dictionary::merge
bool merge(const dictionary &dict)
Merge entries from the given dictionary.
Definition: dictionary.C:879
Foam::entry::isDict
virtual bool isDict() const
Return true if this entry is a dictionary.
Definition: entry.H:222
Foam::functionObjectList::off
void off()
Switch the function objects off.
Definition: functionObjectList.C:652
Foam::functionObjectList::triggerIndex
label triggerIndex() const
Return the current trigger index (read from the stateDict)
Definition: functionObjectList.C:559
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
argList.H
controlDict
runTime controlDict().readEntry("adjustTimeStep"
Definition: debug.C:143
Foam::IOobject::READ_IF_PRESENT
Definition: IOobject.H:122
Foam::functionObjectList::findObjectID
label findObjectID(const word &objName) const
Find the ID of a given function object by name, -1 if not found.
Definition: functionObjectList.C:628
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::functionObjectList::functionObjectDictPath
static fileName functionObjectDictPath
Definition: functionObjectList.H:226
Foam::andOp
Definition: ops.H:233
Foam::PtrList< functionObject >
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:76
Foam::functionObject::read
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
Definition: functionObject.C:137
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
dict
dictionary dict
Definition: searchingEngine.H:14
addProfiling
#define addProfiling(name, descr)
Define profiling trigger with specified name and description string.
Definition: profilingTrigger.H:113
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::Time::controlDict
const dictionary & controlDict() const
Return read access to the controlDict dictionary.
Definition: Time.H:364
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Pstream.H
Foam::functionObjectList::New
static autoPtr< functionObjectList > New(const argList &args, const Time &runTime, dictionary &controlDict, HashSet< wordRe > &requiredFields)
Construct and return a functionObjectList for an application.
Definition: functionObjectList.C:472
Foam::PtrList::clear
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
Definition: PtrListI.H:97
Foam::IStringStream
Input from string buffer, using a ISstream.
Definition: StringStream.H:111
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::error::useAbort
static bool useAbort()
True if FOAM_ABORT is on.
Definition: error.C:74
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::entry::dict
virtual const dictionary & dict() const =0
Return dictionary, if entry is a dictionary.
Foam::HashTable::sortedToc
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:136
dictionaryEntry.H
Foam::fileName::null
static const fileName null
An empty fileName.
Definition: fileName.H:97
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::HashTable< label >
Foam::Perr
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
etcFiles.H
Functions to search 'etc' directories for configuration files etc.
IOdictionary.H
Time.H
Foam::autoPtr< Foam::functionObject >
Foam::argList::size
label size() const noexcept
The number of arguments.
Definition: argListI.H:121
Foam::stringOps::match
bool match(const UList< wordRe > &patterns, const std::string &text)
Return true if text matches one of the regular expressions.
Definition: stringOps.H:75
maxWarnings
static constexpr const uint32_t maxWarnings
Max number of warnings (per functionObject)
Definition: functionObjectList.C:46
Foam::functionObjectList::readFunctionObject
static bool readFunctionObject(const string &funcNameArgs0, dictionary &functionsDict, HashSet< wordRe > &requiredFields, const word &region=word::null)
Definition: functionObjectList.C:232
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::functionObject::name
const word & name() const
Return the name of this functionObject.
Definition: functionObject.C:131
f
labelList f(nPoints)
Foam::entry::get
T get() const
Definition: entry.H:258
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::dictionary::findEntry
entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find for an entry (non-const access) with the given keyword.
Definition: dictionary.C:374
timeControlFunctionObject.H
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:181
Foam::fileName::DIRECTORY
A directory.
Definition: fileName.H:80
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Foam::search
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:576
Foam::IOobject::MUST_READ_IF_MODIFIED
Definition: IOobject.H:121
Foam::argList::getList
List< T > getList(const label index) const
Get a List of values from the argument at index.
Foam::labelMin
constexpr label labelMin
Definition: label.H:60
Foam::mapPolyMesh
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:161
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::wordHashSet
HashSet< word > wordHashSet
A HashSet with word keys.
Definition: HashSet.H:406
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
Foam::dictionary::add
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:708
Foam::functionObjects::timeControl::entriesPresent
static bool entriesPresent(const dictionary &dict)
Helper function to identify if a timeControl object is present.
Definition: timeControlFunctionObject.C:473
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::error::write
void write(Ostream &os, const bool includeTitle=true) const
Print error message.
Definition: error.C:301
Foam::keyType::LITERAL
String literal.
Definition: keyType.H:73
Foam::dictionary::digest
SHA1Digest digest() const
Return the SHA1 digest of the dictionary contents.
Definition: dictionary.C:227
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:315
Foam::Tuple2
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: Tuple2.H:57
Foam::functionObjectList::read
bool read()
Read and set the function objects if their data have changed.
Definition: functionObjectList.C:980
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:122
Foam::functionObjectList::resetState
void resetState()
Reset/read state dictionary for current time.
Definition: functionObjectList.C:565
Foam::IOobject::NO_READ
Definition: IOobject.H:123
args
Foam::argList args(argc, argv)
stringOps.H
Foam::readDir
fileNameList readDir(const fileName &directory, const fileName::Type type=fileName::FILE, const bool filtergz=true, const bool followLink=true)
Read a directory and return the entries as a fileName List.
Definition: MSwindows.C:707
Foam::error::throwExceptions
bool throwExceptions(bool doThrow)
Activate/deactivate exception throwing.
Definition: error.H:151
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303
Foam::error
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:70
Foam::functionObjectList::end
bool end()
Called when Time::run() determines that the time-loop exits.
Definition: functionObjectList.C:882
Foam::functionObjectList::storedObjects
objectRegistry & storedObjects()
Definition: functionObjectList.C:595
Foam::PtrList::transfer
void transfer(PtrList< T > &list)
Transfer into this list and annul the argument list.
Definition: PtrListI.H:252
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:151
Foam::functionObjectList::filesModified
bool filesModified() const
Did any file get changed during execution?
Definition: functionObjectList.C:1236
Foam::UPstream::exit
static void exit(int errNo=1)
Shutdown (finalize) MPI as required and exit program with errNo.
Definition: UPstream.C:63