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