argList.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-2022 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 "argList.H"
30#include "OSspecific.H"
31#include "Switch.H"
32#include "clock.H"
33#include "dictionary.H"
34#include "IOobject.H"
35#include "JobInfo.H"
36#include "labelList.H"
37#include "IOobject.H"
38#include "dynamicCode.H"
40#include "sigFpe.H"
41#include "sigInt.H"
42#include "sigQuit.H"
43#include "sigSegv.H"
44#include "foamVersion.H"
45#include "stringOps.H"
46#include "CStringList.H"
47#include "stringListOps.H"
48#include "fileOperation.H"
50
51#include <cctype>
52
53// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
54
55bool Foam::argList::argsMandatory_ = true;
56bool Foam::argList::checkProcessorDirectories_ = true;
57
69
70std::string::size_type Foam::argList::usageMin = 20;
71std::string::size_type Foam::argList::usageMax = 80;
72
73Foam::argList::initValidTables::initValidTables()
74{
75 argList::addOption
76 (
77 "case",
78 "dir",
79 "Specify case directory to use (instead of cwd)"
80 );
81 argList::addOption
82 (
83 "lib",
84 "name",
85 "Additional library or library list to load"
86 " (can be used multiple times)",
87 true // advanced option
88 );
89
90 argList::addOption
91 (
92 "debug-switch",
93 "name=val",
94 "Specify the value of a registered debug switch."
95 " Default is 1 if the value is omitted."
96 " (Can be used multiple times)",
97 true // advanced option
98 );
99
100 argList::addOption
101 (
102 "info-switch",
103 "name=val",
104 "Specify the value of a registered info switch."
105 " Default is 1 if the value is omitted."
106 " (Can be used multiple times)",
107 true // advanced option
108 );
109
110 argList::addOption
111 (
112 "opt-switch",
113 "name=val",
114 "Specify the value of a registered optimisation switch."
115 " Default is 1 if the value is omitted."
116 " (Can be used multiple times)",
117 true // advanced option
118 );
119
120 argList::addBoolOption("parallel", "Run in parallel");
121 validParOptions.set("parallel", "");
122 argList::addOption
123 (
124 "roots",
125 "(dir1 .. dirN)",
126 "Subprocess root directories for distributed running",
127 true // advanced option
128 );
129 validParOptions.set
130 (
131 "roots",
132 "(dir1 .. dirN)"
133 );
134
135 argList::addOption
136 (
137 "decomposeParDict",
138 "file",
139 "Use specified file for decomposePar dictionary"
140 );
141 argList::addOption
142 (
143 "hostRoots",
144 "((host1 dir1) .. (hostN dirN))",
145 "Per-subprocess root directories for distributed running."
146 " The host specification can be a regex.",
147 true // advanced option
148 );
149 validParOptions.set
150 (
151 "hostRoots",
152 "((host1 dir1) .. (hostN dirN))"
153 );
154
155 argList::addBoolOption
156 (
157 "noFunctionObjects",
158 "Do not execute function objects",
159 true // advanced option
160 );
161
162 argList::addOption
163 (
164 "fileHandler",
165 "handler",
166 "Override the file handler type",
167 true // advanced option
168 );
169
170 argList::addOption
171 (
172 "world",
173 "name",
174 "Name of the local world for parallel communication",
175 true // advanced option
176 );
177 validParOptions.set
178 (
179 "world",
180 "name"
181 );
182
183
184 // Some standard option aliases (with or without version warnings)
185// argList::addOptionCompat
186// (
187// "noFunctionObjects", {"no-function-objects", 0}
188// );
189
190 Pstream::addValidParOptions(validParOptions);
191}
192
193Foam::argList::initValidTables dummyInitValidTables;
194
195
196// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
197
198namespace Foam
199{
200
201// Counted per machine name
202// Does not include any sorting since we wish to know the ordering according to
203// mpi rank.
204//
205// Always include the master too.
206// This provides a better overview of the subscription
207static void printHostsSubscription(const UList<string>& hostProcs)
208{
209 Info<< "Hosts :\n(" << nl;
210
211 std::string prev = Foam::hostName();
212 int count = 1;
213
214 for (const auto& str : hostProcs)
215 {
216 std::string curr(str.substr(0, str.rfind('.')));
217
218 if (prev != curr)
219 {
220 if (count)
221 {
222 // Finish previous
223 Info<< " (" << prev.c_str() << ' ' << count << ')' << nl;
224 count = 0;
225 }
226
227 prev = std::move(curr);
228 }
229 ++count;
230 }
231
232 if (count)
233 {
234 // Finished last one
235 Info<< " (" << prev.c_str() << ' ' << count << ')' << nl;
236 }
237
238 Info<< ')' << nl;
239}
240
241} // End namespace Foam
242
243
244// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
245
246void Foam::argList::checkITstream(const ITstream& is, const label index)
247{
248 const label remaining = is.nRemainingTokens();
249
250 if (remaining)
251 {
252 std::cerr
253 << nl
254 << "--> FOAM WARNING:" << nl
255 << "Argument " << index << " has "
256 << remaining << " excess tokens" << nl << nl;
257 }
258 else if (!is.size())
259 {
260 std::cerr
261 << nl
262 << "--> FOAM WARNING:" << nl
263 << "Argument " << index << " had no tokens" << nl << nl;
264 }
265}
266
267
268void Foam::argList::checkITstream(const ITstream& is, const word& optName)
269{
270 const label remaining = is.nRemainingTokens();
271
272 if (remaining)
273 {
274 std::cerr
275 << nl
276 << "--> FOAM WARNING:" << nl
277 << "Option -" << optName << " has "
278 << remaining << " excess tokens" << nl << nl;
279 }
280 else if (!is.size())
281 {
282 std::cerr
283 << nl
284 << "--> FOAM WARNING:" << nl
285 << "Option -" << optName << " had no tokens" << nl << nl;
286 }
287}
288
289
290void Foam::argList::raiseBadInput(const word& optName) const
291{
292 // Can use FatalError
293 // predicate checks are not used at the earliest stages
294 FatalErrorIn(executable())
295 << "Option -" << optName << " with invalid input" << nl
296 << exit(FatalError);
297}
298
299
301(
302 const string& argName,
303 const string& usage
304)
305{
306 validArgs.append(argName);
307
308 // The first program argument starts at 1 - obtain index after the append
309
310 const label index = validArgs.size();
311
312 if (usage.empty())
313 {
314 argUsage.erase(index);
315 }
316 else
317 {
318 argUsage.set(index, usage);
319 }
320}
321
322
324(
325 const word& optName,
326 const string& usage,
327 bool advanced
328)
329{
330 argList::addOption(optName, "", usage, advanced);
331}
332
333
335(
336 const word& optName,
337 const string& param,
338 const string& usage,
339 bool advanced
340)
341{
342 validOptions.set(optName, param);
343 if (!usage.empty())
344 {
345 optionUsage.set(optName, usage);
346 }
347 if (advanced)
348 {
349 advancedOptions.set(optName);
350 }
351}
352
353
354void Foam::argList::setAdvanced(const word& optName, bool advanced)
355{
356 if (advanced && validOptions.found(optName))
357 {
358 advancedOptions.set(optName);
359 }
360 else
361 {
362 advancedOptions.erase(optName);
363 }
364}
365
366
368(
369 const word& optName,
370 std::pair<const char*,int> compat
371)
372{
373 validOptionsCompat.insert
374 (
375 compat.first,
376 std::pair<word,int>(optName, compat.second)
377 );
378}
379
380
382(
383 std::pair<const char*,int> compat,
384 bool expectArg
385)
386{
387 ignoreOptionsCompat.insert
388 (
389 compat.first,
390 std::pair<bool,int>(expectArg, compat.second)
391 );
392}
393
394
396(
397 const word& optName,
398 const string& usage
399)
400{
401 if (usage.empty())
402 {
403 optionUsage.erase(optName);
404 }
405 else
406 {
407 optionUsage.set(optName, usage);
408 }
409}
410
411
412void Foam::argList::addNote(const string& note)
413{
414 if (!note.empty())
415 {
416 notes.append(note);
417 }
418}
419
420
422{
423 validOptions.erase(optName);
424 optionUsage.erase(optName);
425 advancedOptions.erase(optName);
426}
427
428
430{
431 argsMandatory_ = false;
432}
433
434
436{
437 return argsMandatory_;
438}
439
440
442{
444}
445
446
448{
449 return (::Foam::infoDetailLevel > 0);
450}
451
452
454(
455 const string& usage,
456 bool advanced
457)
458{
459 argList::addBoolOption("dry-run", usage, advanced);
460}
461
462
464(
465 const string& usage,
466 bool advanced
467)
468{
469 argList::addBoolOption("verbose", usage, advanced);
470}
471
472
473void Foam::argList::noFunctionObjects(bool addWithOption)
474{
475 removeOption("noFunctionObjects");
476
477 // Ignore this bool option without warning
478 // - cannot tie to any particular version anyhow
479 ignoreOptionCompat({"noFunctionObjects", 0}, false);
480
481 if (addWithOption)
482 {
484 (
485 "withFunctionObjects",
486 "Execute functionObjects",
487 true // advanced option
488 );
489 }
490}
491
492
494{
496}
497
498
500{
502 (
503 "no-libs",
504 "Disable use of the controlDict libs entry",
505 true // advanced option
506 );
507}
508
509
511{
512 removeOption("parallel");
513 removeOption("roots");
514 removeOption("decomposeParDict");
515 removeOption("hostRoots");
516 removeOption("world");
517 validParOptions.clear();
518}
519
520
522{
523 checkProcessorDirectories_ = false;
524}
525
526
527bool Foam::argList::postProcess(int argc, char *argv[])
528{
529 for (int i=1; i<argc; ++i)
530 {
531 if (argv[i] == '-' + postProcessOptionName)
532 {
533 return true;
534 }
535 }
536
537 return false;
538}
539
540
541// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
542
544{
545 return Foam::getEnv("FOAM_EXECUTABLE");
546}
547
548
550{
551 return Foam::getEnv("FOAM_CASE");
552}
553
554
556(
557 const fileName& input,
558 const bool caseTag
559)
560{
561 if (input.isAbsolute())
562 {
563 return input.relative(envGlobalPath(), caseTag);
564 }
565
566 return input;
567}
568
569
570// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
571
572Foam::word Foam::argList::optionCompat(const word& optName)
573{
574 // NB: optName includes the leading '-' so that the return value
575 // can be used directly
576
577 if (!validOptionsCompat.empty())
578 {
579 const auto fnd = validOptionsCompat.cfind(optName.substr(1));
580
581 if (fnd.found())
582 {
583 const auto& alt = fnd.val();
584
585 // No error::master() guard - only called on master anyhow
586 if (error::warnAboutAge(alt.second))
587 {
588 std::cerr
589 << "--> FOAM IOWarning :" << nl
590 << " Found [v" << alt.second << "] '"
591 << optName << "' instead of '-"
592 << alt.first << "' option"
593 << nl
594 << std::endl;
595
596 error::warnAboutAge("option", alt.second);
597 }
598
599 return "-" + alt.first;
600 }
601 }
602
603 // Nothing found - pass through the original input
604 return optName;
605}
606
607
608int Foam::argList::optionIgnore(const word& optName)
609{
610 // NB: optName is without the leading '-'
611
612 if (!ignoreOptionsCompat.empty())
613 {
614 const auto fnd = ignoreOptionsCompat.cfind(optName);
615
616 if (fnd.found())
617 {
618 const auto& alt = fnd.val();
619
620 // Number to skip (including the option itself)
621 // '-option ARG' or '-option'
622 const int nskip = (alt.first ? 2 : 1);
623
624 // No error::master() guard - only called on master anyhow
625 if (error::warnAboutAge(alt.second))
626 {
627 std::cerr
628 << "--> FOAM IOWarning :" << nl
629 << " Ignoring [v" << alt.second << "] '-"
630 << optName << (nskip > 1 ? " ARG" : "")
631 << "' option"
632 << nl
633 << std::endl;
634
635 error::warnAboutAge("option", alt.second);
636 }
637
638 return nskip;
639 }
640 }
641
642 return 0; // Do not skip
643}
644
645
646bool Foam::argList::regroupArgv(int& argc, char**& argv)
647{
648 int nArgs = 1;
649 int ignore = 0;
650 unsigned depth = 0;
651 string group; // For grouping ( ... ) arguments
652
653 // Note: we rewrite directly into args_
654 // and use a second pass to sort out args/options
655
656 args_[0] = fileName(argv[0]);
657 for (int argi = 1; argi < argc; ++argi)
658 {
659 if (strcmp(argv[argi], "(") == 0)
660 {
661 ++depth;
662 group += '(';
663 }
664 else if (strcmp(argv[argi], ")") == 0)
665 {
666 if (depth)
667 {
668 --depth;
669 group += ')';
670 if (!depth)
671 {
672 args_[nArgs++] = group;
673 group.clear();
674 }
675 }
676 else
677 {
678 args_[nArgs++] = argv[argi];
679 }
680 }
681 else if (depth)
682 {
683 // Quote each string element
684 group += '"';
685 group += argv[argi];
686 group += '"';
687 }
688 else if (argv[argi][0] == '-')
689 {
690 // Appears to be an option
691 const char *optName = &argv[argi][1];
692
693 if (validOptions.found(optName))
694 {
695 // Known option name
696 args_[nArgs++] = argv[argi];
697 }
698 else if ((ignore = optionIgnore(optName)) > 0)
699 {
700 // Option to be ignored (with/without an argument)
701 if (ignore > 1)
702 {
703 ++argi;
704 }
705 }
706 else
707 {
708 // Try alias for the option name
709 args_[nArgs++] = optionCompat(argv[argi]);
710 }
711 }
712 else
713 {
714 args_[nArgs++] = argv[argi];
715 }
716 }
717
718 if (group.size())
719 {
720 // Group(s) not closed, but flush anything still pending
721 args_[nArgs++] = group;
722 }
723
724 args_.resize(nArgs);
725
726 std::string::size_type len = (nArgs-1); // Spaces between args
727 for (const auto& s : args_)
728 {
729 len += s.length();
730 }
731
732 // Length needed for regrouped command-line
733 commandLine_.reserve(len);
734
735 return nArgs < argc;
736}
737
738
739void Foam::argList::setCasePaths()
740{
741 fileName caseDir;
742
743 const auto optIter = options_.cfind("case"); // [-case dir] specified?
744
745 if (optIter.found())
746 {
747 caseDir = fileName::validate(optIter.val()); // includes 'clean'
748
749 if (caseDir.empty() || caseDir == ".")
750 {
751 // Treat "", "." and "./" as if -case was not specified
752 caseDir = cwd();
753 options_.erase("case");
754 }
755 else
756 {
757 caseDir.expand();
758 caseDir.toAbsolute();
759 }
760 }
761 else
762 {
763 // Nothing specified, use the current dir
764 caseDir = cwd();
765 }
766
767 // The caseDir is a cleaned, absolute path
768
769 rootPath_ = caseDir.path();
770 globalCase_ = caseDir.name();
771 case_ = globalCase_; // The (processor) local case name
772
773 // OPENFOAM API
774 setEnv("FOAM_API", std::to_string(foamVersion::api), true);
775
776 // Global case (directory) and case-name as environment variables
777 setEnv("FOAM_CASE", caseDir, true);
778 setEnv("FOAM_CASENAME", globalCase_, true);
779
780 // Executable name, unless already present in the environment
781 setEnv("FOAM_EXECUTABLE", executable_, false);
782}
783
784
785// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
786
788(
789 int& argc,
790 char**& argv,
791 bool checkArgs,
792 bool checkOpts,
793 bool initialise
794)
795:
796 args_(argc),
797 options_(argc),
798 libs_()
799{
800 // Check for -fileHandler, which requires an argument.
801 word handlerType;
802 for (int argi = argc-2; argi > 0; --argi)
803 {
804 if (argv[argi][0] == '-')
805 {
806 const char *optName = &argv[argi][1];
807
808 if (strcmp(optName, "fileHandler") == 0)
809 {
810 handlerType = argv[argi+1];
811 break;
812 }
813 }
814 }
815 if (handlerType.empty())
816 {
817 handlerType = Foam::getEnv("FOAM_FILEHANDLER");
818 if (handlerType.empty())
819 {
821 }
822 }
823
824 // Detect any parallel options
825 const bool needsThread = fileOperations::fileOperationInitialise::New
826 (
827 handlerType,
828 argc,
829 argv
830 )().needsThreading();
831
832
833 // Check if this run is a parallel run by searching for any parallel option
834 // If found call runPar which might filter argv
835 for (int argi = 1; argi < argc; ++argi)
836 {
837 if (argv[argi][0] == '-')
838 {
839 const char *optName = &argv[argi][1];
840
841 if (validParOptions.found(optName))
842 {
843 runControl_.runPar(argc, argv, needsThread);
844 break;
845 }
846 }
847 }
848
849 // Convert argv -> args_ and capture ( ... ) lists
850 regroupArgv(argc, argv);
851 commandLine_ += args_[0];
852
853 // Set executable name immediately - useful when emitting errors.
854 executable_ = fileName(args_[0]).name();
855
856 // Count -dry-run and -verbose switches
857 int numDryRun = 0, numVerbose = 0;
858
859 // Check arguments and options, argv[0] was already handled
860 int nArgs = 1;
861 for (int argi = 1; argi < args_.size(); ++argi)
862 {
863 commandLine_ += ' ';
864 commandLine_ += args_[argi];
865
866 if (args_[argi][0] == '-')
867 {
868 const char *optName = &args_[argi][1];
869
870 if (!*optName)
871 {
872 Warning
873 << "Ignoring lone '-' on the command-line" << endl;
874 continue;
875 }
876
877 // Option known and expects an argument?
878 // - use Switch for a tri-state
879 // True : known option, expects a parameter
880 // False : known option, no parameter
881 // bad() : unknown option
882
883 Switch wantArg(Switch::INVALID);
884 auto optIter = validOptions.cfind(optName);
885 if
886 (
887 optIter.found()
888 || (optIter = validParOptions.cfind(optName)).found()
889 )
890 {
891 wantArg = !optIter.val().empty();
892 }
893
894
895 if (wantArg)
896 {
897 // Known option and expects a parameter
898 // - get it or emit a FatalError.
899
900 ++argi;
901 if (argi >= args_.size())
902 {
904
905 Info<< nl
906 <<"Error: option '-" << optName
907 << "' requires an argument" << nl << nl
908 << "See '" << executable_ << " -help' for usage"
909 << nl << nl;
910
911 Pstream::exit(1); // works for serial and parallel
912 }
913
914 commandLine_ += ' ';
915 commandLine_ += args_[argi];
916
917 //
918 // Special handling of these options
919 //
920
921 if (strcmp(optName, "lib") == 0)
922 {
923 // The '-lib' option:
924 // Append name(s) to libs for later opening
925 libs().append(this->getList<fileName>(argi));
926 }
927 else if (strcmp(optName, "debug-switch") == 0)
928 {
929 // The '-debug-switch' option:
930 // change registered debug switch
931 DetailInfo << "debug-switch ";
933 .setNamedValue(args_[argi], 1, true);
934 }
935 else if (strcmp(optName, "info-switch") == 0)
936 {
937 // The '-info-switch' option:
938 // change registered info switch
939 DetailInfo << "info-switch ";
941 .setNamedValue(args_[argi], 1, true);
942 }
943 else if (strcmp(optName, "opt-switch") == 0)
944 {
945 // The '-opt-switch' option:
946 // change registered optimisation switch
947 DetailInfo << "opt-switch ";
949 .setNamedValue(args_[argi], 1, true);
950 }
951 else
952 {
953 // Regular option (with a parameter):
954 // Duplicates handled by using the last -option specified
955 options_.set(optName, args_[argi]);
956 }
957 }
958 else
959 {
960 // All other options (including unknown ones) are simply
961 // registered as existing.
962
963 options_.insert(optName, "");
964
965 // Special increment handling for some known flags
966 if (wantArg.good())
967 {
968 if (strcmp(optName, "dry-run") == 0)
969 {
970 ++numDryRun;
971 }
972 else if (strcmp(optName, "verbose") == 0)
973 {
974 ++numVerbose;
975 }
976 }
977 }
978 }
979 else
980 {
981 if (nArgs != argi)
982 {
983 args_[nArgs] = args_[argi];
984 }
985 ++nArgs;
986 }
987 }
988
989 // Commit number of -dry-run and -verbose flag occurrences
990 runControl_.dryRun(numDryRun);
991 runControl_.verbose(numVerbose);
992
993 args_.resize(nArgs);
994
995 parse(checkArgs, checkOpts, initialise);
996}
997
998
1000(
1001 const argList& args,
1002 const HashTable<string>& options,
1003 bool checkArgs,
1004 bool checkOpts,
1005 bool initialise
1006)
1007:
1008 runControl_(args.runControl_),
1009 args_(args.args_),
1010 options_(options),
1011 libs_(),
1012 executable_(args.executable_),
1013 rootPath_(args.rootPath_),
1014 globalCase_(args.globalCase_),
1015 case_(args.case_),
1016 commandLine_(args.commandLine_)
1017{
1018 parse(checkArgs, checkOpts, initialise);
1019}
1020
1021
1023(
1024 bool checkArgs,
1025 bool checkOpts,
1026 bool initialise
1027)
1028{
1029 // Help/documentation options:
1030 // -doc Display documentation in browser
1031 // -doc-source Display source code in browser
1032 // -help Display short help and exit
1033 // -help-compat Display compatibility options
1034 // -help-full Display full help and exit
1035 {
1036 bool quickExit = false;
1037
1038 // Display either application or source documentation, not both
1039 if (options_.found("doc"))
1040 {
1041 displayDoc(false);
1042 quickExit = true;
1043 }
1044 else if (options_.found("doc-source"))
1045 {
1046 displayDoc(true);
1047 quickExit = true;
1048 }
1049
1050 // Display either short or full help, not both
1051 if (options_.found("help-full"))
1052 {
1053 printUsage(true);
1054 quickExit = true;
1055 }
1056 else if (options_.found("help-notes"))
1057 {
1058 printNotes();
1059 Info<< nl;
1060 quickExit = true;
1061 }
1062 else if (options_.found("help"))
1063 {
1064 printUsage(false);
1065 quickExit = true;
1066 }
1067 else if (options_.found("help-man"))
1068 {
1069 printMan();
1070 quickExit = true;
1071 }
1072
1073 // Allow independent display of compatibility information
1074 if (options_.found("help-compat"))
1075 {
1076 printCompat();
1077 quickExit = true;
1078 }
1079
1080 if (quickExit)
1081 {
1082 std::exit(0);
1083 }
1084 }
1085
1086 // Print the collected error messages and exit if check fails
1087 if (!check(checkArgs, checkOpts))
1088 {
1090 FatalError.write(Info, false);
1091
1092 Pstream::exit(1); // works for serial and parallel
1093 }
1094
1095 if (initialise)
1096 {
1097 const string dateString = clock::date();
1098 const string timeString = clock::clockTime();
1099
1100 // Print the banner once only for parallel runs
1101 if (Pstream::master() && bannerEnabled())
1102 {
1104 << "Build : ";
1105
1106 if (foamVersion::build.size())
1107 {
1108 Info<< foamVersion::build.c_str() << ' ';
1109 }
1110
1111 Info<< "OPENFOAM=" << foamVersion::api;
1112
1114 {
1115 // Patch-level, when defined
1116 Info<< " patch=" << foamVersion::patch.c_str();
1117 }
1118
1119 Info<< " version=" << foamVersion::version.c_str();
1120
1121 Info<< nl
1122 << "Arch : " << foamVersion::buildArch << nl
1123 << "Exec : " << commandLine_.c_str() << nl
1124 << "Date : " << dateString.c_str() << nl
1125 << "Time : " << timeString.c_str() << nl
1126 << "Host : " << Foam::hostName().c_str() << nl
1127 << "PID : " << pid() << nl;
1128 }
1129
1130 jobInfo.add("startDate", dateString);
1131 jobInfo.add("startTime", timeString);
1132 jobInfo.add("userName", userName());
1133
1134 jobInfo.add("foamApi", foamVersion::api);
1135 jobInfo.add("foamVersion", word(foamVersion::version));
1136
1137 // Add build information - only use the first word
1138 {
1139 std::string build(foamVersion::build);
1140 const auto space = build.find(' ');
1141 if (space != std::string::npos)
1142 {
1143 build.resize(space);
1144 }
1145 jobInfo.add("foamBuild", build);
1146 }
1147
1148 jobInfo.add("code", executable_);
1149 jobInfo.add("argList", commandLine_);
1150 jobInfo.add("currentDir", cwd());
1151 jobInfo.add("PPID", ppid());
1152 jobInfo.add("PGID", pgid());
1153
1154 // Load additional libraries (verbosity according to banner setting)
1155 libs().open(bannerEnabled());
1156 }
1157
1158
1159 // Set fileHandler. In increasing order of priority:
1160 // 1. default = uncollated
1161 // 2. env variable "FOAM_FILEHANDLER"
1162 // 3. etc/controlDict optimisationSwitches 'fileHandler'
1163 // 4. system/controlDict 'fileHandler' (not handled here; done in TimeIO.C)
1164 // 5. '-fileHandler' commmand-line option
1165
1166 {
1167 word handlerType
1168 (
1169 options_.lookup("fileHandler", Foam::getEnv("FOAM_FILEHANDLER"))
1170 );
1171
1172 if (handlerType.empty())
1173 {
1175 }
1176
1177 Foam::fileHandler(fileOperation::New(handlerType, bannerEnabled()));
1178 }
1179
1180
1181 stringList hostMachine;
1182 stringList hostProcs;
1183 const int writeHostsSwitch = Foam::debug::infoSwitch("writeHosts", 1);
1184
1185 // Collect machine/pid, and check that the build is identical
1186 if (runControl_.parRun())
1187 {
1188 if (Pstream::master())
1189 {
1190 hostMachine.resize(Pstream::nProcs()-1);
1191 hostProcs.resize(Pstream::nProcs()-1);
1192 string procBuild;
1193 label procPid;
1194 int proci = 0;
1195 for (const int subproci : Pstream::subProcs())
1196 {
1197 IPstream fromSubproc(Pstream::commsTypes::scheduled, subproci);
1198
1199 fromSubproc >> procBuild >> hostMachine[proci] >> procPid;
1200
1201 hostProcs[proci] = hostMachine[proci] + "." + name(procPid);
1202 ++proci;
1203
1204 // Verify that all processors are running the same build
1205 if (procBuild != foamVersion::build)
1206 {
1207 FatalErrorIn(executable())
1208 << "Running build version " << foamVersion::build
1209 << " but proc " << subproci << " is running "
1210 << procBuild << nl
1211 << exit(FatalError);
1212 }
1213 }
1214 }
1215 else
1216 {
1217 OPstream toMaster
1218 (
1221 );
1222 toMaster << foamVersion::build << Foam::hostName() << Foam::pid();
1223 }
1224 }
1225
1226
1227 // Case is a single processor run unless it is running parallel
1228 int nProcs = 1;
1229
1230 // Roots if running distributed
1231 fileNameList roots;
1232
1233 // If this actually is a parallel run
1234 if (runControl_.parRun())
1235 {
1236 // For the master
1237 if (Pstream::master())
1238 {
1239 // Establish rootPath_/globalCase_/case_ for master
1240 setCasePaths();
1241
1242 // The system/decomposeParDict (or equivalent)
1243 fileName source;
1244
1245 if (this->readIfPresent("decomposeParDict", source))
1246 {
1247 bool adjustOpt = false;
1248
1249 if (isDir(source))
1250 {
1251 source /= "decomposeParDict";
1252 adjustOpt = true;
1253 }
1254
1255 // Case-relative if not absolute and not "./" etc
1256 if (!source.isAbsolute() && !source.starts_with('.'))
1257 {
1258 source = rootPath_/globalCase_/source;
1259 adjustOpt = true;
1260 }
1261
1262 // Could also check for absolute path, but shouldn't be needed
1263 if (adjustOpt)
1264 {
1265 source.clean(); // Remove unneeded ".."
1266 options_.set("decomposeParDict", source);
1267 }
1268 }
1269
1270 // If running distributed (different roots for different procs)
1271 label dictNProcs = -1;
1272 if (this->readListIfPresent("roots", roots))
1273 {
1274 source = "-roots";
1275 runControl_.distributed(true);
1276
1277 if (roots.empty())
1278 {
1280 << "The -roots option must contain values"
1281 << exit(FatalError);
1282 }
1283 if (roots.size() > 1)
1284 {
1285 dictNProcs = roots.size()+1;
1286 }
1287 }
1288 else if (options_.found("hostRoots"))
1289 {
1290 source = "-hostRoots";
1291 runControl_.distributed(true);
1292
1293 ITstream is(this->lookup("hostRoots"));
1294
1295 List<Tuple2<wordRe, fileName>> hostRoots(is);
1296 checkITstream(is, "hostRoots");
1297
1298 if (hostRoots.empty())
1299 {
1301 << "The -hostRoots option must contain values"
1302 << exit(FatalError);
1303 }
1304
1305 // Match machine names to roots
1307 for (const auto& hostRoot : hostRoots)
1308 {
1309 labelList matched
1310 (
1311 findMatchingStrings(hostRoot.first(), hostMachine)
1312 );
1313 for (const label matchi : matched)
1314 {
1315 if (!roots[matchi].empty())
1316 {
1318 << "Multiple matching roots for "
1319 << hostMachine[matchi] << " in "
1320 << hostRoots << nl
1321 << exit(FatalError);
1322 }
1323
1324 roots[matchi] = hostRoot.second();
1325 }
1326 }
1327
1328 // Check
1329 forAll(roots, hosti)
1330 {
1331 if (roots[hosti].empty())
1332 {
1334 << "No matching roots for "
1335 << hostMachine[hosti] << " in "
1336 << hostRoots << nl
1337 << exit(FatalError);
1338 }
1339 }
1340
1341 if (roots.size() > 1)
1342 {
1343 dictNProcs = roots.size()+1;
1344 }
1345 }
1346 else if (checkProcessorDirectories_ && Pstream::nProcs() > 1)
1347 {
1348 // Check values from decomposeParDict
1349
1350 const bool useDefault = source.empty();
1351 if (useDefault)
1352 {
1353 source = rootPath_/globalCase_/"system"/"decomposeParDict";
1354 }
1355
1356 // Disable any parallel comms happening inside the fileHandler
1357 // since we are on master. This can happen e.g. inside
1358 // the masterUncollated/collated handler. Note that we
1359 // also have to protect the actual dictionary parsing since
1360 // it might trigger file access (e.g. #include, #codeStream)
1361 const bool oldParRun = Pstream::parRun(false);
1362
1363 autoPtr<ISstream> dictStream
1364 (
1365 fileHandler().NewIFstream(source)
1366 );
1367
1368 if (dictStream && dictStream->good())
1369 {
1370 dictionary decompDict(*dictStream);
1371 bool nDomainsMandatory = false;
1372
1373 if (decompDict.getOrDefault("distributed", false))
1374 {
1375 nDomainsMandatory = true;
1376 runControl_.distributed(true);
1377 decompDict.readEntry("roots", roots);
1378
1379 if (roots.empty())
1380 {
1382 << "WARNING: running distributed"
1383 << " but did not specify roots!" << nl;
1384 }
1385 }
1386
1387 // Get numberOfSubdomains if it exists.
1388 // - mandatory when running with distributed roots
1389 decompDict.readEntry
1390 (
1391 "numberOfSubdomains",
1392 dictNProcs,
1394 nDomainsMandatory
1395 );
1396 }
1397 else
1398 {
1399 if (useDefault)
1400 {
1401 // Optional if using default location
1403 << "WARNING: running without decomposeParDict "
1404 << this->relativePath(source) << nl;
1405 }
1406 else
1407 {
1408 // Mandatory if specified as -decomposeParDict
1410 << "Cannot read decomposeParDict: "
1411 << this->relativePath(source) << nl
1412 << exit(FatalError);
1413 }
1414 }
1415
1416 Pstream::parRun(oldParRun); // Restore parallel state
1417
1418 if (Pstream::nProcs() == 1)
1419 {
1420 Warning
1421 << "Running parallel on single processor. This only"
1422 << " makes sense for multi-world simulation" << endl;
1423 dictNProcs = 1;
1424 }
1425 }
1426
1427 // Convenience:
1428 // when a single root is specified, use it for all processes
1429 if (roots.size() == 1)
1430 {
1431 const fileName rootName(roots[0]);
1432 roots.resize(Pstream::nProcs()-1, rootName);
1433
1434 // Adjust dictNProcs for command-line '-roots' option
1435 if (dictNProcs <= 0)
1436 {
1437 dictNProcs = roots.size()+1;
1438 }
1439 }
1440
1441
1442 // Check number of processors.
1443 // nProcs => number of actual procs
1444 // dictNProcs => number of procs specified in decompositionDict
1445 // nProcDirs => number of processor directories
1446 // (n/a when running distributed)
1447 //
1448 // - normal running : nProcs = dictNProcs = nProcDirs
1449 // - decomposition to more processors : nProcs = dictNProcs
1450 // - decomposition to fewer processors : nProcs = nProcDirs
1451 if
1452 (
1453 checkProcessorDirectories_
1454 && Pstream::nProcs() > 1
1455 && dictNProcs > Pstream::nProcs()
1456 )
1457 {
1459 << this->relativePath(source)
1460 << " specifies " << dictNProcs
1461 << " processors but job was started with "
1462 << Pstream::nProcs() << " processors."
1463 << exit(FatalError);
1464 }
1465
1466 // Distributed data
1467 if (roots.size())
1468 {
1469 if (roots.size() != Pstream::nProcs()-1)
1470 {
1472 << "number of entries in roots "
1473 << roots.size()
1474 << " is not equal to the number of sub-processes "
1475 << Pstream::nProcs()-1
1476 << exit(FatalError);
1477 }
1478
1479 for (fileName& dir : roots)
1480 {
1481 dir.expand();
1482 }
1483
1484 // Distribute the master's argument list (with new root)
1485 const bool hadCaseOpt = options_.found("case");
1486 for (const int subproci : Pstream::subProcs())
1487 {
1488 options_.set("case", roots[subproci-1]/globalCase_);
1489
1490 OPstream toProc(Pstream::commsTypes::scheduled, subproci);
1491
1492 toProc
1493 << args_ << options_
1494 << runControl_.distributed()
1495 << label(runControl_.dryRun())
1496 << label(runControl_.verbose());
1497 }
1498 options_.erase("case");
1499
1500 // Restore [-case dir]
1501 if (hadCaseOpt)
1502 {
1503 options_.set("case", rootPath_/globalCase_);
1504 }
1505 }
1506 else
1507 {
1508 // Possibly going to fewer processors.
1509 // Check if all procDirs are there.
1510 if
1511 (
1512 checkProcessorDirectories_
1513 && Pstream::nProcs() > 1
1514 && dictNProcs >= 1
1515 && dictNProcs < Pstream::nProcs()
1516 )
1517 {
1518 label nProcDirs = 0;
1519 while
1520 (
1521 isDir
1522 (
1523 rootPath_/globalCase_
1524 / ("processor" + Foam::name(++nProcDirs))
1525 )
1526 )
1527 {}
1528
1529 if (nProcDirs != Pstream::nProcs())
1530 {
1532 << "number of processor directories = "
1533 << nProcDirs
1534 << " is not equal to the number of processors = "
1535 << Pstream::nProcs()
1536 << exit(FatalError);
1537 }
1538 }
1539
1540 // Distribute the master's argument list (unaltered)
1541 for (const int subproci : Pstream::subProcs())
1542 {
1543 OPstream toProc(Pstream::commsTypes::scheduled, subproci);
1544
1545 toProc
1546 << args_ << options_
1547 << runControl_.distributed()
1548 << label(runControl_.dryRun())
1549 << label(runControl_.verbose());
1550 }
1551 }
1552 }
1553 else
1554 {
1555 // Collect the master's argument list
1556 bool isDistributed;
1557 label numDryRun, numVerbose;
1558
1559 IPstream fromMaster
1560 (
1563 );
1564
1565 fromMaster
1566 >> args_ >> options_
1567 >> isDistributed
1568 >> numDryRun >> numVerbose;
1569
1570 runControl_.distributed(isDistributed);
1571 runControl_.dryRun(numDryRun);
1572 runControl_.verbose(numVerbose);
1573
1574 // Establish rootPath_/globalCase_/case_ for sub-process
1575 setCasePaths();
1576 }
1577
1578 nProcs = Pstream::nProcs();
1579 if (Pstream::nProcs() > 1)
1580 {
1581 case_ = globalCase_/("processor" + Foam::name(Pstream::myProcNo()));
1582 }
1583 else
1584 {
1585 case_ = globalCase_;
1586 }
1587 }
1588 else
1589 {
1590 // Establish rootPath_/globalCase_/case_
1591 setCasePaths();
1592 case_ = globalCase_; // Redundant, but extra safety?
1593 }
1594
1595 // If needed, adjust fileHandler for distributed roots
1596 if (runControl_.distributed())
1597 {
1599 {
1600 fileOperation::fileHandlerPtr_->distributed(true);
1601 }
1602 }
1603
1604 // Keep/discard sub-process host/root information for reporting:
1605 if (Pstream::master() && runControl_.parRun())
1606 {
1607 if (!writeHostsSwitch)
1608 {
1609 // Clear here to ensures it doesn't show in the jobInfo
1610 hostProcs.clear();
1611 }
1612 if (!debug::infoSwitch("writeRoots", 1))
1613 {
1614 roots.clear();
1615 }
1616 }
1617
1618 if (Pstream::master() && bannerEnabled())
1619 {
1620 Info<< "Case : " << (rootPath_/globalCase_).c_str() << nl
1621 << "nProcs : " << nProcs << nl;
1622
1623 if (runControl_.parRun())
1624 {
1625 if (hostProcs.size())
1626 {
1627 if (writeHostsSwitch == 1)
1628 {
1629 // Compact output (see etc/controlDict)
1630 printHostsSubscription(hostProcs);
1631 }
1632 else if (writeHostsSwitch)
1633 {
1634 // Full output of "host.pid"
1635 Info<< "Hosts :\n(" << nl;
1636
1637 // Include master in the list
1638 Info<< " " << Foam::hostName().c_str() << '.'
1639 << Foam::pid() << nl;
1640
1641 // Sub-processes
1642 for (const auto& str : hostProcs)
1643 {
1644 Info<< " " << str.c_str() << nl;
1645 }
1646 Info<< ')' << nl;
1647 }
1648 }
1649 if (roots.size())
1650 {
1651 Info<< "Roots : " << roots << nl;
1652 }
1653 Info<< "Pstream initialized with:" << nl
1654 << " floatTransfer : " << Pstream::floatTransfer << nl
1655 << " nProcsSimpleSum : " << Pstream::nProcsSimpleSum << nl
1656 << " commsType : "
1658 << " polling iterations : " << Pstream::nPollProcInterfaces
1659 << nl;
1660 if (UPstream::allWorlds().size() > 1)
1661 {
1662 Info<< " worlds : "
1664 << " world : " << UPstream::myWorld()
1665 << nl;
1666 }
1667 }
1668 }
1669
1670 if (initialise)
1671 {
1672 jobInfo.add("root", rootPath_);
1673 jobInfo.add("case", globalCase_);
1674 jobInfo.add("nProcs", nProcs);
1675 if (hostProcs.size())
1676 {
1677 jobInfo.add("hosts", hostProcs);
1678 }
1679 if (roots.size())
1680 {
1681 jobInfo.add("roots", roots);
1682 }
1683 jobInfo.write();
1684
1685 // Switch on signal trapping. We have to wait until after Pstream::init
1686 // since this sets up its own ones.
1687 sigFpe::set(bannerEnabled());
1688 sigInt::set(bannerEnabled());
1689 sigQuit::set(bannerEnabled());
1690 sigSegv::set(bannerEnabled());
1691
1692 if (Pstream::master() && bannerEnabled())
1693 {
1694 Info<< "fileModificationChecking : "
1695 << "Monitoring run-time modified files using "
1697 [
1699 ];
1700 if
1701 (
1704 )
1705 {
1707 {
1708 Info<< " (fileModificationSkew "
1710 << ")";
1711 }
1713 {
1714 Info<< " (fileModificationSkew "
1716 << ", maxFileModificationPolls "
1718 << ")";
1719 }
1720 else
1721 {
1723 << "Invalid setting for maxFileModificationPolls "
1725 << exit(FatalError);
1726 }
1727 }
1728 Info<< nl;
1729
1730 Info<< "allowSystemOperations : ";
1732 {
1733 Info<< "Allowing";
1734 }
1735 else
1736 {
1737 Info<< "Disallowing";
1738 }
1739 Info<< " user-supplied system call operations" << nl
1740 << nl;
1742 }
1743 }
1744}
1745
1746
1747// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
1748
1750{
1751 jobInfo.stop(); // Normal job termination
1752
1753 // Delete file handler to flush any remaining IO
1754 Foam::fileHandler(nullptr);
1755}
1756
1757
1758// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1759
1760Foam::label Foam::argList::count(const UList<word>& optionNames) const
1761{
1762 label n = 0;
1763 for (const word& optName : optionNames)
1764 {
1765 if (options_.found(optName))
1766 {
1767 ++n;
1768 }
1769 }
1770 return n;
1771}
1772
1773
1775(
1776 std::initializer_list<word> optionNames
1777) const
1778{
1779 label n = 0;
1780 for (const word& optName : optionNames)
1781 {
1782 if (options_.found(optName))
1783 {
1784 ++n;
1785 }
1786 }
1787 return n;
1788}
1789
1790
1791bool Foam::argList::setOption(const word& optName, const string& param)
1792{
1793 // Some options are always protected
1794 if
1795 (
1796 optName == "case"
1797 || optName == "parallel"
1798 || optName == "roots"
1799 )
1800 {
1802 <<"Option: '" << optName << "' is protected" << nl
1803 << exit(FatalError);
1804 return false;
1805 }
1806
1807 if (options_.found(optName) ? (options_[optName] != param) : true)
1808 {
1809 options_.set(optName, param);
1810 return true;
1811 }
1812
1813 return false;
1814}
1815
1816
1818{
1819 // Some options are always protected
1820 if
1821 (
1822 optName == "case"
1823 || optName == "parallel"
1824 || optName == "roots"
1825 || optName == "hostRoots"
1826 )
1827 {
1829 <<"Option: '" << optName << "' is protected" << nl
1830 << exit(FatalError);
1831 return false;
1832 }
1833
1834 // Remove the option, return true if state changed
1835 return options_.erase(optName);
1836}
1837
1838
1839void Foam::argList::displayDoc(bool source) const
1840{
1841 const dictionary& docDict = debug::controlDict().subDict("Documentation");
1842 fileNameList docDirs(docDict.get<fileNameList>("doxyDocDirs"));
1843 fileName docExt(docDict.get<fileName>("doxySourceFileExt"));
1844
1845 // For source code: change xxx_8C.html to xxx_8C_source.html
1846 if (source)
1847 {
1848 docExt.replace(".", "_source.");
1849 }
1850
1851 fileName url;
1852
1853 for (const fileName& dir : docDirs)
1854 {
1855 // The http protocols are last in the list
1856 if (dir.starts_with("http:") || dir.starts_with("https:"))
1857 {
1858 url = dir/executable_ + docExt;
1859 break;
1860 }
1861
1862 fileName docFile = stringOps::expand(dir/executable_ + docExt);
1863
1864 if
1865 (
1866 docFile.starts_with("file://")
1867 ? isFile(docFile.substr(7)) // check part after "file://"
1868 : isFile(docFile)
1869 )
1870 {
1871 url = std::move(docFile);
1872 break;
1873 }
1874 }
1875
1876 if (url.empty())
1877 {
1878 Info<< nl
1879 << "No documentation found for " << executable_
1880 << ", but you can use -help to display the usage\n" << endl;
1881
1882 return;
1883 }
1884
1885 string docBrowser = getEnv("FOAM_DOC_BROWSER");
1886 if (docBrowser.empty())
1887 {
1888 docDict.readEntry("docBrowser", docBrowser);
1889 }
1890
1891 // Can use FOAM_DOC_BROWSER='application file://%f' if required
1892 if (docBrowser.find("%f") != std::string::npos)
1893 {
1894 docBrowser.replace("%f", url);
1895 }
1896 else
1897 {
1898 docBrowser += " " + url;
1899 }
1900
1901 // Split on whitespace to use safer version of Foam::system()
1902
1903 CStringList command(stringOps::splitSpace(docBrowser));
1904
1905 Info
1906 << "OpenFOAM " << foamVersion::api << " documentation:" << nl
1907 << " " << command << nl << endl;
1908
1909 Foam::system(command, true);
1910}
1911
1912
1913bool Foam::argList::check(bool checkArgs, bool checkOpts) const
1914{
1915 bool ok = true;
1916
1917 if (Pstream::master())
1918 {
1919 const label nargs = args_.size()-1;
1920 if (checkArgs && nargs != validArgs.size())
1921 {
1923 << "Expected " << validArgs.size()
1924 << " arguments but found " << nargs << endl;
1925 ok = false;
1926 }
1927
1928 if (checkOpts)
1929 {
1930 forAllConstIters(options_, iter)
1931 {
1932 const word& optName = iter.key();
1933 if
1934 (
1935 !validOptions.found(optName)
1936 && !validParOptions.found(optName)
1937 )
1938 {
1940 << "Invalid option: -" << optName << endl;
1941 ok = false;
1942 }
1943 }
1944 }
1945
1946 if (!ok)
1947 {
1949 << nl
1950 << "See '" << executable_ << " -help' for usage"
1951 << nl << nl;
1952 }
1953 }
1954
1955 return ok;
1956}
1957
1958
1960{
1961 if (!fileHandler().isDir(rootPath()))
1962 {
1964 << executable_
1965 << ": cannot open root directory " << rootPath()
1966 << endl;
1967
1968 return false;
1969 }
1970
1971 const fileName pathDir(fileHandler().filePath(path()));
1972
1973 if (checkProcessorDirectories_ && pathDir.empty() && Pstream::master())
1974 {
1975 // Allow non-existent processor directories on sub-processes,
1976 // to be created later (e.g. redistributePar)
1978 << executable_
1979 << ": cannot open case directory " << path()
1980 << endl;
1981
1982 return false;
1983 }
1984
1985 return true;
1986}
1987
1988
1989// ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
label n
Foam::argList::initValidTables dummyInitValidTables
Definition: argList.C:193
An adapter for copying a list of C++ strings into a list of C-style strings for passing to C code tha...
Definition: CStringList.H:70
A HashTable with keys but without contents that is similar to std::unordered_set.
Definition: HashSet.H:96
A HashTable similar to std::unordered_map.
Definition: HashTable.H:123
static Ostream & writeDivider(Ostream &os)
Write the standard file section divider.
static Ostream & writeBanner(Ostream &os, const bool noSyntaxHint=false)
Write the standard OpenFOAM file/dictionary banner.
static float fileModificationSkew
Time skew (seconds) for file modification checks.
Definition: IOobject.H:306
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:303
static const Enum< fileCheckTypes > fileCheckTypesNames
Names for the fileCheckTypes.
Definition: IOobject.H:208
static int maxFileModificationPolls
Max number of times to poll for file modification changes.
Definition: IOobject.H:309
Input inter-processor communications stream.
Definition: IPstream.H:57
An input stream of tokens.
Definition: ITstream.H:56
static void disable() noexcept
Disallow JobInfo by forcing writeJobInfo (InfoSwitch) off.
Definition: JobInfo.C:92
void exit()
Job end with "exit" termination.
Definition: JobInfo.C:234
void write() const
Write job info to its file in the "running" jobs directory.
Definition: JobInfo.C:214
void stop()
Job end with "normal" termination.
Definition: JobInfo.C:232
Template class for non-intrusive linked lists.
Definition: LList.H:79
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
Output inter-processor communications stream.
Definition: OPstream.H:57
int dryRun() const noexcept
Non-zero if set as 'dry-run'.
Definition: parRun.H:119
int verbose() const noexcept
Non-zero if set as 'verbose'.
Definition: parRun.H:133
void runPar(int &argc, char **&argv, bool needsThread)
Initialize Pstream for a parallel run.
Definition: parRun.H:86
label nProcs() const noexcept
Number of ranks associated with PstreamBuffers.
UPstream::rangeType subProcs() const noexcept
Range of sub-processes indices associated with PstreamBuffers.
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
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
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 const Enum< commsTypes > commsTypeNames
Names of the communication types.
Definition: UPstream.H:74
static bool floatTransfer
Definition: UPstream.H:275
static constexpr int masterNo() noexcept
Process index of the master (always 0)
Definition: UPstream.H:451
static int nProcsSimpleSum
Number of processors to change from linear to tree communication.
Definition: UPstream.H:278
static int nPollProcInterfaces
Number of polling cycles in processor updates.
Definition: UPstream.H:284
static const wordList & allWorlds() noexcept
All worlds.
Definition: UPstream.H:483
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:281
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
static const word & myWorld()
My world.
Definition: UPstream.H:501
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:124
void parse(bool checkArgs, bool checkOpts, bool initialise)
Definition: argList.C:1023
static word postProcessOptionName
Standard name for the post-processing option.
Definition: argList.H:241
static HashTable< string, label, Hash< label > > argUsage
Short description for program arguments.
Definition: argList.H:226
static void noBanner()
Disable emitting the banner information.
Definition: argList.C:441
static std::string::size_type usageMin
Min indentation when displaying usage (default: 20)
Definition: argList.H:235
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition: argList.C:473
static HashTable< std::pair< word, int > > validOptionsCompat
A list of aliases for options.
Definition: argList.H:219
static HashTable< string > validParOptions
A list of valid parallel options.
Definition: argList.H:215
static void removeOption(const word &optName)
Remove option from validOptions and from optionUsage.
Definition: argList.C:421
static std::string::size_type usageMax
Max screen width when displaying usage (default: 80)
Definition: argList.H:238
bool unsetOption(const word &optName)
Unset option directly (use with caution)
Definition: argList.C:1817
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:301
static bool bannerEnabled()
Banner status (enabled/disabled).
Definition: argList.C:447
static fileName envGlobalPath()
Global case (directory) from environment variable.
Definition: argList.C:549
static void noLibs()
Add the '-no-libs' command line option.
Definition: argList.C:499
static void noJobInfo()
Suppress JobInfo, overriding controlDict setting.
Definition: argList.C:493
static void addVerboseOption(const string &usage, bool advanced=false)
Enable a 'verbose' bool option, with usage information.
Definition: argList.C:464
static void setAdvanced(const word &optName, bool advanced=true)
Set an existing option as being 'advanced' or normal.
Definition: argList.C:354
bool check(bool checkArgs=argList::argsMandatory(), bool checkOpts=true) const
Definition: argList.C:1913
virtual ~argList()
Destructor.
Definition: argList.C:1749
static HashTable< string > optionUsage
Short description for validOptions.
Definition: argList.H:229
static fileName envRelativePath(const fileName &input, const bool caseTag=false)
Definition: argList.C:556
static bool argsMandatory()
Command arguments type (optional/mandatory).
Definition: argList.C:435
static HashSet< string > advancedOptions
The "advanced" options are shown with -help-full (not with –help)
Definition: argList.H:209
bool setOption(const word &optName, const string &param="")
Set option directly (use with caution)
Definition: argList.C:1791
static void addOptionCompat(const word &optName, std::pair< const char *, int > compat)
Specify an alias for the option name.
Definition: argList.C:368
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a 'dry-run' bool option, with usage information.
Definition: argList.C:454
static void noCheckProcessorDirectories()
Remove checking of processor directories.
Definition: argList.C:521
static SLList< string > notes
General usage notes.
Definition: argList.H:232
bool checkRootCase() const
Check root path and case path.
Definition: argList.C:1959
void displayDoc(bool source=false) const
Display documentation in browser.
Definition: argList.C:1839
static void noMandatoryArgs()
Flag command arguments as being optional (non-mandatory)
Definition: argList.C:429
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:324
static void noParallel()
Remove the parallel options.
Definition: argList.C:510
static void addUsage(const word &optName, const string &usage)
Add option usage information to optionUsage.
Definition: argList.C:396
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:335
static HashTable< string > validOptions
A list of valid options.
Definition: argList.H:212
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:206
static word envExecutable()
Name of the executable from environment variable.
Definition: argList.C:543
static HashTable< std::pair< bool, int > > ignoreOptionsCompat
A list of options to ignore.
Definition: argList.H:223
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:412
static void ignoreOptionCompat(std::pair< const char *, int > compat, bool expectArg)
Specify an option to be ignored.
Definition: argList.C:382
dlLibraryTable & libs() const noexcept
Mutable access to the loaded dynamic libraries.
Definition: argListI.H:140
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
bool good() const noexcept
True if the managed pointer is non-null.
Definition: autoPtr.H:145
static std::string date()
Definition: clock.C:80
static std::string clockTime()
Definition: clock.C:95
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
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:640
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
bool append(const fileName &libName)
Add to the list of names, but do not yet open.
static int allowSystemOperations
Flag if system operations are allowed.
Definition: dynamicCode.H:166
virtual void write(Ostream &os, const bool withTitle=true) const
Print error message.
Definition: error.C:343
static bool warnAboutAge(const int version) noexcept
Test if an age warning should be emitted.
Definition: error.C:55
A class for handling file names.
Definition: fileName.H:76
static bool clean(std::string &str)
Definition: fileName.C:199
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:199
static bool isAbsolute(const std::string &str)
Definition: fileNameI.H:136
static word defaultFileHandler
Name of the default fileHandler.
static autoPtr< fileOperation > fileHandlerPtr_
Static fileOperation.
static bool postProcess
Global post-processing mode switch.
virtual void validate()
Validate the turbulence fields after construction.
Definition: kkLOmega.C:597
@ LITERAL
String literal.
Definition: keyType.H:81
std::ostream & stdStream()
Return std::ostream for output operations.
int myProcNo() const noexcept
Return processor number.
Lookup type of boundary radiation properties.
Definition: lookup.H:66
label count() const
void setNamedValue(std::string name, int val, bool report=false)
Set named value, but also handle embedded 'name=value' syntax.
splitCell * master() const
Definition: splitCell.H:113
bool starts_with(const std::string &s) const
True if string starts with the given prefix (cf. C++20)
Definition: string.H:297
string & replace(const std::string &s1, const std::string &s2, size_type pos=0)
Definition: string.C:108
bool set() const
Are all the vector set.
Definition: triadI.H:76
A class for handling words, derived from Foam::string.
Definition: word.H:68
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:448
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
#define DetailInfo
Definition: evalEntry.C:37
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
constexpr const char *const group
Group name for atomic constants.
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:231
simpleObjectRegistry & infoObjects()
Access to registered InfoSwitch objects.
Definition: debug.C:302
dictionary & controlDict()
Definition: debug.C:143
simpleObjectRegistry & optimisationObjects()
Access to registered OptimisationSwitch objects.
Definition: debug.C:313
simpleObjectRegistry & debugObjects()
Access to registered DebugSwitch objects.
Definition: debug.C:291
const std::string patch
OpenFOAM patch number as a std::string.
const std::string build
OpenFOAM build information as a std::string.
const std::string buildArch
void printBuildInfo(std::ostream &os, const bool full=true)
Print information about version, build, arch to output stream.
const std::string version
OpenFOAM version (name or stringified number) as a std::string.
Foam::SubStrings< StringType > splitSpace(const StringType &str)
Split string into sub-strings at whitespace (TAB, NL, VT, FF, CR, SPC)
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.
fileName cwd()
The physical or logical current working directory path name.
Definition: MSwindows.C:476
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: MSwindows.C:371
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable, return true on success.
Definition: MSwindows.C:395
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
Definition: MSwindows.C:1158
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:55
messageStream Info
Information stream (stdout output on master, null elsewhere)
static void check(const int retVal, const char *what)
labelList findMatchingStrings(const UnaryMatchPredicate &matcher, const UList< StringType > &input, const bool invert=false)
Extract list indices for all matches.
string userName()
Return the user's login name.
Definition: MSwindows.C:437
pid_t pgid()
Return the group PID of this process.
Definition: MSwindows.C:350
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
string hostName()
Return the system's host name, as per hostname(1)
Definition: MSwindows.C:410
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
pid_t ppid()
Return the parent PID of this process.
Definition: MSwindows.C:337
static void printHostsSubscription(const UList< string > &hostProcs)
Definition: argList.C:207
pid_t pid()
Return the PID of this process.
Definition: MSwindows.C:330
int infoDetailLevel
Global for selective suppression of Info output.
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
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
JobInfo jobInfo
Definition: JobInfo.C:49
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:651
messageStream Warning
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Definition: stdFoam.H:278
Operations on lists of strings.
propsDict readIfPresent("fields", acceptFields)