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