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-------------------------------------------------------------------------------
11License
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)
47static constexpr const uint32_t maxWarnings = 10u;
48
50(
51 "caseDicts/postProcessing"
52);
53
54
55const Foam::Enum
56<
57 Foam::functionObjectList::errorHandlingType
58>
59Foam::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
70namespace 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;
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
101void 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
123void 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
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
169void 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;
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
351Foam::functionObjectList::errorHandlingType
352Foam::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
393(
394 const Time& runTime,
395 const bool execution
396)
397:
399{}
400
401
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 (
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,
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,
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
581Foam::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
792bool 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
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
1112 (
1113 fo,
1114 "functionObject::" + key + "::new"
1115 );
1116 if (needsTimeControl)
1117 {
1118 objPtr.reset
1119 (
1120 new functionObjects::timeControl(key, time_, dict)
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// ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: Enum.H:61
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:191
A HashTable similar to std::unordered_map.
Definition: HashTable.H:123
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:137
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:180
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:180
The IOstreamOption is a simple container for options an IOstream can normally have.
static unsigned int precision_
Default precision.
Definition: IOstream.H:98
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:58
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
Definition: StringStream.H:112
void exit()
Job end with "exit" termination.
Definition: JobInfo.C:234
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
unsigned int remove()
Remove and return the last element.
Definition: PackedListI.H:709
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: PtrList.H:73
const T * set(const label i) const
Definition: PtrList.H:138
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
Definition: PtrListI.H:97
void resize(const label newLen)
Adjust size of PtrList.
Definition: PtrList.C:103
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:78
bool good() const noexcept
True if the Switch represents a valid enumeration.
Definition: Switch.C:300
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: Tuple2.H:58
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:124
label size() const noexcept
The number of arguments.
Definition: argListI.H:146
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:178
List< T > getList(const label index) const
Get a List of values from the argument at index.
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
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:117
A keyword and a list of tokens is a 'dictionaryEntry'.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find and return a sub-dictionary pointer if present.
Definition: dictionaryI.H:127
bool merge(const dictionary &dict)
Merge entries from the given dictionary.
Definition: dictionary.C:812
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
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
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
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:640
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:780
SHA1Digest digest() const
Return the SHA1 digest of the dictionary contents.
Definition: dictionary.C:227
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:70
virtual bool isDict() const noexcept
Return true if this entry is a dictionary.
Definition: entry.H:233
virtual const dictionary & dict() const =0
Return dictionary, if entry is a dictionary.
T get() const
Definition: entry.H:269
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:77
static void printStack(Ostream &os)
Helper function to print a stack.
virtual void write(Ostream &os, const bool withTitle=true) const
Print error message.
Definition: error.C:343
static bool useAbort()
True if FOAM_ABORT is on.
Definition: error.C:98
bool throwing() const noexcept
Return the current exception throwing state (on or off)
Definition: error.H:169
A class for handling file names.
Definition: fileName.H:76
@ DIRECTORY
A directory.
Definition: fileName.H:84
static const fileName null
An empty fileName.
Definition: fileName.H:102
List of function objects with start(), execute() and end() functions that is called for each object.
static fileName findDict(const word &funcName)
void off()
Switch the function objects off.
objectRegistry & storedObjects()
bool filesModified() const
Did any file get changed during execution?
label findObjectID(const word &objName) const
Find the ID of a given function object by name, -1 if not found.
bool adjustTimeStep()
Called at the end of Time::adjustDeltaT() if adjustTime is true.
bool start()
Called at the start of the time-loop.
void clear()
Clear the list of function objects.
void resetPropertiesDict()
Reset/read properties dictionary for current time.
functionObjects::properties & propsDict()
bool status() const
Return the execution status (on/off) of the function objects.
label triggerIndex() const
Return the current trigger index (read from the propsDict)
bool execute()
Called at each ++ or += of the time-loop.
static bool readFunctionObject(const string &funcNameArgs0, dictionary &functionsDict, HashSet< wordRe > &requiredFields, const word &region=word::null)
static fileName functionObjectDictPath
bool end()
Called when Time::run() determines that the time-loop exits.
void on()
Switch the function objects on.
bool read()
Read and set the function objects if their data have changed.
Abstract base-class for Time/database function objects.
static bool defaultUseNamePrefix
Global default for useNamePrefix.
Storage for function object properties, derived from IOdictionary. Provides functionality to read/wri...
Wrapper around functionObjects to add time control.
static bool entriesPresent(const dictionary &dict)
Helper function to identify if a timeControl object is present.
virtual void validate()
Validate the turbulence fields after construction.
Definition: kkLOmega.C:597
@ LITERAL
String literal.
Definition: keyType.H:81
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:162
void movePoints()
Update for new mesh geometry.
void updateMesh()
Update for new mesh topology.
Registry of regIOobjects.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:83
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:54
A class for handling words, derived from Foam::string.
Definition: word.H:68
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
runTime controlDict().readEntry("adjustTimeStep"
dynamicFvMesh & mesh
engineTime & runTime
Foam::word regionName(Foam::polyMesh::defaultRegion)
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Functions to search 'etc' directories for configuration files etc.
static constexpr const uint32_t maxWarnings
Max number of warnings (per functionObject)
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
bool match(const UList< wordRe > &patterns, const std::string &text)
Return true if text matches one of the regular expressions.
Definition: stringOps.H:76
label splitFunctionArgs(const std::string &str, wordRes &args, List< Tuple2< word, string > > &namedArgs)
Split out arguments (named or unnamed) from an input string.
string expand(const std::string &s, const HashTable< string > &mapping, const char sigil='$')
Definition: stringOps.C:718
Namespace for OpenFOAM.
const fileOperation & fileHandler()
Get current file handler.
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
static void exitNow(const error &err)
Mimic exit handling of the error class.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
IOerror FatalIOError
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:715
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:666
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
Definition: HashSet.H:82
error FatalError
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
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
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
messageStream Warning
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:624
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define addProfiling(name, descr)
Define profiling trigger with specified name and description string.
labelList f(nPoints)
dictionary dict
Foam::argList args(argc, argv)
IOdictionary propsDict(dictIO)