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-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "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"
39 #include "simpleObjectRegistry.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 
55 bool Foam::argList::argsMandatory_ = true;
56 bool Foam::argList::checkProcessorDirectories_ = true;
57 
69 
72 
73 Foam::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 
193 Foam::argList::initValidTables dummyInitValidTables;
194 
195 
196 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
197 
198 namespace 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
207 static 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 
246 void 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 
268 void 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 
290 void 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 
354 void 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 
412 void Foam::argList::addNote(const string& note)
413 {
414  if (!note.empty())
415  {
416  notes.append(note);
417  }
418 }
419 
420 
421 void Foam::argList::removeOption(const word& optName)
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 
473 void 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 
527 bool 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 
572 Foam::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 
608 int 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 
646 bool 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 
739 void 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  {
820  handlerType = fileOperation::defaultFileHandler;
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 
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 
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 
1113  if (foamVersion::patched())
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  {
1174  handlerType = fileOperation::defaultFileHandler;
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  if (roots.empty())
1277  {
1279  << "The -roots option must contain values"
1280  << exit(FatalError);
1281  }
1282  if (roots.size() > 1)
1283  {
1284  dictNProcs = roots.size()+1;
1285  }
1286  }
1287  else if (options_.found("hostRoots"))
1288  {
1289  source = "-hostRoots";
1290  runControl_.distributed(true);
1291 
1292  ITstream is(this->lookup("hostRoots"));
1293 
1294  List<Tuple2<wordRe, fileName>> hostRoots(is);
1295  checkITstream(is, "hostRoots");
1296 
1297  if (hostRoots.empty())
1298  {
1300  << "The -hostRoots option must contain values"
1301  << exit(FatalError);
1302  }
1303 
1304  // Match machine names to roots
1306  for (const auto& hostRoot : hostRoots)
1307  {
1308  labelList matched
1309  (
1310  findMatchingStrings(hostRoot.first(), hostMachine)
1311  );
1312  for (const label matchi : matched)
1313  {
1314  if (!roots[matchi].empty())
1315  {
1317  << "Multiple matching roots for "
1318  << hostMachine[matchi] << " in "
1319  << hostRoots << nl
1320  << exit(FatalError);
1321  }
1322 
1323  roots[matchi] = hostRoot.second();
1324  }
1325  }
1326 
1327  // Check
1328  forAll(roots, hosti)
1329  {
1330  if (roots[hosti].empty())
1331  {
1333  << "No matching roots for "
1334  << hostMachine[hosti] << " in "
1335  << hostRoots << nl
1336  << exit(FatalError);
1337  }
1338  }
1339 
1340  if (roots.size() > 1)
1341  {
1342  dictNProcs = roots.size()+1;
1343  }
1344  }
1345  else if (checkProcessorDirectories_ && Pstream::nProcs() > 1)
1346  {
1347  // Check values from decomposeParDict
1348 
1349  const bool useDefault = source.empty();
1350  if (useDefault)
1351  {
1352  source = rootPath_/globalCase_/"system"/"decomposeParDict";
1353  }
1354 
1355  // Disable any parallel comms happening inside the fileHandler
1356  // since we are on master. This can happen e.g. inside
1357  // the masterUncollated/collated handler.
1358  const bool oldParRun = Pstream::parRun(false);
1359 
1360  autoPtr<ISstream> dictStream
1361  (
1362  fileHandler().NewIFstream(source)
1363  );
1364 
1365  Pstream::parRun(oldParRun); // Restore parallel state
1366 
1367  if (dictStream && dictStream->good())
1368  {
1369  dictionary decompDict(*dictStream);
1370  bool nDomainsMandatory = false;
1371 
1372  if (decompDict.getOrDefault("distributed", false))
1373  {
1374  nDomainsMandatory = true;
1375  runControl_.distributed(true);
1376  decompDict.readEntry("roots", roots);
1377 
1378  if (roots.empty())
1379  {
1380  DetailInfo
1381  << "WARNING: running distributed"
1382  << " but did not specify roots!" << nl;
1383  }
1384  }
1385 
1386  // Get numberOfSubdomains if it exists.
1387  // - mandatory when running with distributed roots
1388  decompDict.readEntry
1389  (
1390  "numberOfSubdomains",
1391  dictNProcs,
1393  nDomainsMandatory
1394  );
1395  }
1396  else
1397  {
1398  if (useDefault)
1399  {
1400  // Optional if using default location
1401  DetailInfo
1402  << "WARNING: running without decomposeParDict "
1403  << this->relativePath(source) << nl;
1404  }
1405  else
1406  {
1407  // Mandatory if specified as -decomposeParDict
1408  FatalError
1409  << "Cannot read decomposeParDict: "
1410  << this->relativePath(source) << nl
1411  << exit(FatalError);
1412  }
1413  }
1414 
1415  if (Pstream::nProcs() == 1)
1416  {
1417  Warning
1418  << "Running parallel on single processor. This only"
1419  << " makes sense for multi-world simulation" << endl;
1420  dictNProcs = 1;
1421  }
1422  }
1423 
1424  // Convenience:
1425  // when a single root is specified, use it for all processes
1426  if (roots.size() == 1)
1427  {
1428  const fileName rootName(roots[0]);
1429  roots.resize(Pstream::nProcs()-1, rootName);
1430 
1431  // Adjust dictNProcs for command-line '-roots' option
1432  if (dictNProcs <= 0)
1433  {
1434  dictNProcs = roots.size()+1;
1435  }
1436  }
1437 
1438 
1439  // Check number of processors.
1440  // nProcs => number of actual procs
1441  // dictNProcs => number of procs specified in decompositionDict
1442  // nProcDirs => number of processor directories
1443  // (n/a when running distributed)
1444  //
1445  // - normal running : nProcs = dictNProcs = nProcDirs
1446  // - decomposition to more processors : nProcs = dictNProcs
1447  // - decomposition to fewer processors : nProcs = nProcDirs
1448  if
1449  (
1450  checkProcessorDirectories_
1451  && Pstream::nProcs() > 1
1452  && dictNProcs > Pstream::nProcs()
1453  )
1454  {
1455  FatalError
1456  << this->relativePath(source)
1457  << " specifies " << dictNProcs
1458  << " processors but job was started with "
1459  << Pstream::nProcs() << " processors."
1460  << exit(FatalError);
1461  }
1462 
1463  // Distributed data
1464  if (roots.size())
1465  {
1466  if (roots.size() != Pstream::nProcs()-1)
1467  {
1468  FatalError
1469  << "number of entries in roots "
1470  << roots.size()
1471  << " is not equal to the number of sub-processes "
1472  << Pstream::nProcs()-1
1473  << exit(FatalError);
1474  }
1475 
1476  for (fileName& dir : roots)
1477  {
1478  dir.expand();
1479  }
1480 
1481  // Distribute the master's argument list (with new root)
1482  const bool hadCaseOpt = options_.found("case");
1483  for (const int subproci : Pstream::subProcs())
1484  {
1485  options_.set("case", roots[subproci-1]/globalCase_);
1486 
1487  OPstream toProc(Pstream::commsTypes::scheduled, subproci);
1488  toProc
1489  << args_ << options_
1490  << runControl_.distributed()
1491  << label(runControl_.dryRun())
1492  << label(runControl_.verbose());
1493 
1494  }
1495  options_.erase("case");
1496 
1497  // Restore [-case dir]
1498  if (hadCaseOpt)
1499  {
1500  options_.set("case", rootPath_/globalCase_);
1501  }
1502  }
1503  else
1504  {
1505  // Possibly going to fewer processors.
1506  // Check if all procDirs are there.
1507  if
1508  (
1509  checkProcessorDirectories_
1510  && Pstream::nProcs() > 1
1511  && dictNProcs >= 1
1512  && dictNProcs < Pstream::nProcs()
1513  )
1514  {
1515  label nProcDirs = 0;
1516  while
1517  (
1518  isDir
1519  (
1520  rootPath_/globalCase_
1521  / ("processor" + Foam::name(++nProcDirs))
1522  )
1523  )
1524  {}
1525 
1526  if (nProcDirs != Pstream::nProcs())
1527  {
1528  FatalError
1529  << "number of processor directories = "
1530  << nProcDirs
1531  << " is not equal to the number of processors = "
1532  << Pstream::nProcs()
1533  << exit(FatalError);
1534  }
1535  }
1536 
1537  // Distribute the master's argument list (unaltered)
1538  for (const int subproci : Pstream::subProcs())
1539  {
1540  OPstream toProc(Pstream::commsTypes::scheduled, subproci);
1541  toProc
1542  << args_ << options_
1543  << runControl_.distributed()
1544  << label(runControl_.dryRun())
1545  << label(runControl_.verbose());
1546  }
1547  }
1548  }
1549  else
1550  {
1551  // Collect the master's argument list
1552  bool isDistributed;
1553  label numDryRun, numVerbose;
1554 
1555  IPstream fromMaster
1556  (
1559  );
1560  fromMaster
1561  >> args_ >> options_
1562  >> isDistributed
1563  >> numDryRun >> numVerbose;
1564 
1565  runControl_.distributed(isDistributed);
1566  runControl_.dryRun(numDryRun);
1567  runControl_.verbose(numVerbose);
1568 
1569  // Establish rootPath_/globalCase_/case_ for sub-process
1570  setCasePaths();
1571  }
1572 
1573  nProcs = Pstream::nProcs();
1574  if (Pstream::nProcs() > 1)
1575  {
1576  case_ = globalCase_/("processor" + Foam::name(Pstream::myProcNo()));
1577  }
1578  else
1579  {
1580  case_ = globalCase_;
1581  }
1582  }
1583  else
1584  {
1585  // Establish rootPath_/globalCase_/case_
1586  setCasePaths();
1587  case_ = globalCase_; // Redundant, but extra safety?
1588  }
1589 
1590  // If needed, adjust fileHandler for distributed roots
1591  if (runControl_.distributed())
1592  {
1594  {
1595  fileOperation::fileHandlerPtr_->distributed(true);
1596  }
1597  }
1598 
1599  // Keep/discard sub-process host/root information for reporting:
1600  if (Pstream::master() && runControl_.parRun())
1601  {
1602  if (!writeHostsSwitch)
1603  {
1604  // Clear here to ensures it doesn't show in the jobInfo
1605  hostProcs.clear();
1606  }
1607  if (!debug::infoSwitch("writeRoots", 1))
1608  {
1609  roots.clear();
1610  }
1611  }
1612 
1613  if (Pstream::master() && bannerEnabled())
1614  {
1615  Info<< "Case : " << (rootPath_/globalCase_).c_str() << nl
1616  << "nProcs : " << nProcs << nl;
1617 
1618  if (runControl_.parRun())
1619  {
1620  if (hostProcs.size())
1621  {
1622  if (writeHostsSwitch == 1)
1623  {
1624  // Compact output (see etc/controlDict)
1625  printHostsSubscription(hostProcs);
1626  }
1627  else if (writeHostsSwitch)
1628  {
1629  // Full output of "host.pid"
1630  Info<< "Hosts :\n(" << nl;
1631 
1632  // Include master in the list
1633  Info<< " " << Foam::hostName().c_str() << '.'
1634  << Foam::pid() << nl;
1635 
1636  // Sub-processes
1637  for (const auto& str : hostProcs)
1638  {
1639  Info<< " " << str.c_str() << nl;
1640  }
1641  Info<< ')' << nl;
1642  }
1643  }
1644  if (roots.size())
1645  {
1646  Info<< "Roots : " << roots << nl;
1647  }
1648  Info<< "Pstream initialized with:" << nl
1649  << " floatTransfer : " << Pstream::floatTransfer << nl
1650  << " nProcsSimpleSum : " << Pstream::nProcsSimpleSum << nl
1651  << " commsType : "
1653  << " polling iterations : " << Pstream::nPollProcInterfaces
1654  << nl;
1655  if (UPstream::allWorlds().size() > 1)
1656  {
1657  Info<< " worlds : "
1659  << " world : " << UPstream::myWorld()
1660  << nl;
1661  }
1662  }
1663  }
1664 
1665  if (initialise)
1666  {
1667  jobInfo.add("root", rootPath_);
1668  jobInfo.add("case", globalCase_);
1669  jobInfo.add("nProcs", nProcs);
1670  if (hostProcs.size())
1671  {
1672  jobInfo.add("hosts", hostProcs);
1673  }
1674  if (roots.size())
1675  {
1676  jobInfo.add("roots", roots);
1677  }
1678  jobInfo.write();
1679 
1680  // Switch on signal trapping. We have to wait until after Pstream::init
1681  // since this sets up its own ones.
1682  sigFpe::set(bannerEnabled());
1683  sigInt::set(bannerEnabled());
1684  sigQuit::set(bannerEnabled());
1685  sigSegv::set(bannerEnabled());
1686 
1687  if (Pstream::master() && bannerEnabled())
1688  {
1689  Info<< "fileModificationChecking : "
1690  << "Monitoring run-time modified files using "
1692  [
1694  ];
1695  if
1696  (
1699  )
1700  {
1702  {
1703  Info<< " (fileModificationSkew "
1705  << ")";
1706  }
1708  {
1709  Info<< " (fileModificationSkew "
1711  << ", maxFileModificationPolls "
1713  << ")";
1714  }
1715  else
1716  {
1718  << "Invalid setting for maxFileModificationPolls "
1720  << exit(FatalError);
1721  }
1722  }
1723  Info<< nl;
1724 
1725  Info<< "allowSystemOperations : ";
1727  {
1728  Info<< "Allowing";
1729  }
1730  else
1731  {
1732  Info<< "Disallowing";
1733  }
1734  Info<< " user-supplied system call operations" << nl
1735  << nl;
1737  }
1738  }
1739 }
1740 
1741 
1742 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
1743 
1745 {
1746  jobInfo.stop(); // Normal job termination
1747 
1748  // Delete file handler to flush any remaining IO
1749  Foam::fileHandler(nullptr);
1750 }
1751 
1752 
1753 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1754 
1755 Foam::label Foam::argList::count(const UList<word>& optionNames) const
1756 {
1757  label n = 0;
1758  for (const word& optName : optionNames)
1759  {
1760  if (options_.found(optName))
1761  {
1762  ++n;
1763  }
1764  }
1765  return n;
1766 }
1767 
1768 
1769 Foam::label Foam::argList::count
1771  std::initializer_list<word> optionNames
1772 ) const
1773 {
1774  label n = 0;
1775  for (const word& optName : optionNames)
1776  {
1777  if (options_.found(optName))
1778  {
1779  ++n;
1780  }
1781  }
1782  return n;
1783 }
1784 
1785 
1786 bool Foam::argList::setOption(const word& optName, const string& param)
1787 {
1788  // Some options are always protected
1789  if
1790  (
1791  optName == "case"
1792  || optName == "parallel"
1793  || optName == "roots"
1794  )
1795  {
1797  <<"Option: '" << optName << "' is protected" << nl
1798  << exit(FatalError);
1799  return false;
1800  }
1801 
1802  if (options_.found(optName) ? (options_[optName] != param) : true)
1803  {
1804  options_.set(optName, param);
1805  return true;
1806  }
1807 
1808  return false;
1809 }
1810 
1811 
1812 bool Foam::argList::unsetOption(const word& optName)
1813 {
1814  // Some options are always protected
1815  if
1816  (
1817  optName == "case"
1818  || optName == "parallel"
1819  || optName == "roots"
1820  || optName == "hostRoots"
1821  )
1822  {
1824  <<"Option: '" << optName << "' is protected" << nl
1825  << exit(FatalError);
1826  return false;
1827  }
1828 
1829  // Remove the option, return true if state changed
1830  return options_.erase(optName);
1831 }
1832 
1833 
1834 void Foam::argList::displayDoc(bool source) const
1835 {
1836  const dictionary& docDict = debug::controlDict().subDict("Documentation");
1837  fileNameList docDirs(docDict.get<fileNameList>("doxyDocDirs"));
1838  fileName docExt(docDict.get<fileName>("doxySourceFileExt"));
1839 
1840  // For source code: change xxx_8C.html to xxx_8C_source.html
1841  if (source)
1842  {
1843  docExt.replace(".", "_source.");
1844  }
1845 
1846  fileName url;
1847 
1848  for (const fileName& dir : docDirs)
1849  {
1850  // The http protocols are last in the list
1851  if (dir.starts_with("http:") || dir.starts_with("https:"))
1852  {
1853  url = dir/executable_ + docExt;
1854  break;
1855  }
1856 
1857  fileName docFile = stringOps::expand(dir/executable_ + docExt);
1858 
1859  if
1860  (
1861  docFile.starts_with("file://")
1862  ? isFile(docFile.substr(7)) // check part after "file://"
1863  : isFile(docFile)
1864  )
1865  {
1866  url = std::move(docFile);
1867  break;
1868  }
1869  }
1870 
1871  if (url.empty())
1872  {
1873  Info<< nl
1874  << "No documentation found for " << executable_
1875  << ", but you can use -help to display the usage\n" << endl;
1876 
1877  return;
1878  }
1879 
1880  string docBrowser = getEnv("FOAM_DOC_BROWSER");
1881  if (docBrowser.empty())
1882  {
1883  docDict.readEntry("docBrowser", docBrowser);
1884  }
1885 
1886  // Can use FOAM_DOC_BROWSER='application file://%f' if required
1887  if (docBrowser.find("%f") != std::string::npos)
1888  {
1889  docBrowser.replace("%f", url);
1890  }
1891  else
1892  {
1893  docBrowser += " " + url;
1894  }
1895 
1896  // Split on whitespace to use safer version of Foam::system()
1897 
1898  CStringList command(stringOps::splitSpace(docBrowser));
1899 
1900  Info
1901  << "OpenFOAM " << foamVersion::api << " documentation:" << nl
1902  << " " << command << nl << endl;
1903 
1904  Foam::system(command, true);
1905 }
1906 
1907 
1908 bool Foam::argList::check(bool checkArgs, bool checkOpts) const
1909 {
1910  bool ok = true;
1911 
1912  if (Pstream::master())
1913  {
1914  const label nargs = args_.size()-1;
1915  if (checkArgs && nargs != validArgs.size())
1916  {
1917  FatalError
1918  << "Expected " << validArgs.size()
1919  << " arguments but found " << nargs << endl;
1920  ok = false;
1921  }
1922 
1923  if (checkOpts)
1924  {
1925  forAllConstIters(options_, iter)
1926  {
1927  const word& optName = iter.key();
1928  if
1929  (
1930  !validOptions.found(optName)
1931  && !validParOptions.found(optName)
1932  )
1933  {
1934  FatalError
1935  << "Invalid option: -" << optName << endl;
1936  ok = false;
1937  }
1938  }
1939  }
1940 
1941  if (!ok)
1942  {
1943  FatalError
1944  << nl
1945  << "See '" << executable_ << " -help' for usage"
1946  << nl << nl;
1947  }
1948  }
1949 
1950  return ok;
1951 }
1952 
1953 
1955 {
1956  if (!fileHandler().isDir(rootPath()))
1957  {
1958  FatalError
1959  << executable_
1960  << ": cannot open root directory " << rootPath()
1961  << endl;
1962 
1963  return false;
1964  }
1965 
1966  const fileName pathDir(fileHandler().filePath(path()));
1967 
1968  if (checkProcessorDirectories_ && pathDir.empty() && Pstream::master())
1969  {
1970  // Allow non-existent processor directories on sub-processes,
1971  // to be created later (e.g. redistributePar)
1972  FatalError
1973  << executable_
1974  << ": cannot open case directory " << path()
1975  << endl;
1976 
1977  return false;
1978  }
1979 
1980  return true;
1981 }
1982 
1983 
1984 // ************************************************************************* //
Foam::argList::validArgs
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:206
Foam::string::replace
string & replace(const std::string &s1, const std::string &s2, size_type pos=0)
Definition: string.C:108
Foam::argList::count
label count(const UList< word > &optionNames) const
Return how many of the specified options were used.
Definition: argList.C:1755
Foam::sigFpe::set
static void set(bool verbose=false)
Activate SIGFPE signal handler when FOAM_SIGFPE is set.
Definition: sigFpe.C:148
Foam::argList::noBanner
static void noBanner()
Disable emitting the banner information.
Definition: argList.C:441
Foam::argList::usageMin
static std::string::size_type usageMin
Min indentation when displaying usage (default: 20)
Definition: argList.H:235
Foam::foamVersion::build
const std::string build
OpenFOAM build information as a std::string.
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:77
Foam::UPstream::masterNo
static constexpr int masterNo() noexcept
Process index of the master (always 0)
Definition: UPstream.H:451
Foam::argList::addUsage
static void addUsage(const word &optName, const string &usage)
Add option usage information to optionUsage.
Definition: argList.C:396
Foam::IOobject::timeStamp
Definition: IOobject.H:201
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
dummyInitValidTables
Foam::argList::initValidTables dummyInitValidTables
Definition: argList.C:193
Foam::foamVersion::patched
bool patched()
Foam::IOobject::fileCheckTypesNames
static const Enum< fileCheckTypes > fileCheckTypesNames
Names for the fileCheckTypes.
Definition: IOobject.H:208
Foam::argList::usageMax
static std::string::size_type usageMax
Max screen width when displaying usage (default: 80)
Definition: argList.H:238
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::argList::validOptionsCompat
static HashTable< std::pair< word, int > > validOptionsCompat
A list of aliases for options.
Definition: argList.H:219
s
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))
Definition: gmvOutputSpray.H:25
fileOperationInitialise.H
Foam::constant::atomic::group
constexpr const char *const group
Group name for atomic constants.
Definition: atomicConstants.H:52
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::argList::envGlobalPath
static fileName envGlobalPath()
Global case (directory) from environment variable.
Definition: argList.C:549
Foam::fileOperation::fileHandlerPtr_
static autoPtr< fileOperation > fileHandlerPtr_
Static fileOperation.
Definition: fileOperation.H:181
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:53
Foam::string::starts_with
bool starts_with(const std::string &s) const
True if string starts with the given prefix (cf. C++20)
Definition: string.H:297
Foam::argList::optionUsage
static HashTable< string > optionUsage
Short description for validOptions.
Definition: argList.H:229
Foam::fileName::name
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:199
Foam::Warning
messageStream Warning
Foam::system
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
Definition: MSwindows.C:1150
Foam::IOobject::timeStampMaster
Definition: IOobject.H:202
Foam::IOobject::fileModificationChecking
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:303
simpleObjectRegistry.H
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:412
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::argList::addOptionCompat
static void addOptionCompat(const word &optName, std::pair< const char *, int > compat)
Specify an alias for the option name.
Definition: argList.C:368
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:123
Foam::isFile
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Definition: MSwindows.C:658
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1485
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::setEnv
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable, return true on success.
Definition: MSwindows.C:395
Foam::UPstream::defaultCommsType
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:281
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::Switch::good
bool good() const noexcept
True if the Switch represents a valid enumeration.
Definition: Switch.C:300
Foam::stringOps::splitSpace
Foam::SubStrings< StringType > splitSpace(const StringType &str)
Split string into sub-strings at whitespace (TAB, NL, VT, FF, CR, SPC)
Definition: stringOpsTemplates.C:246
Foam::HashSet< Foam::string >
Foam::JobInfo::write
void write() const
Write job info to its file in the "running" jobs directory.
Definition: JobInfo.C:214
Foam::IOobject::writeBanner
static Ostream & writeBanner(Ostream &os, const bool noSyntaxHint=false)
Write the standard OpenFOAM file/dictionary banner.
Definition: IOobjectWriteHeader.C:76
Foam::argList::noMandatoryArgs
static void noMandatoryArgs()
Flag command arguments as being optional (non-mandatory)
Definition: argList.C:429
Foam::getEnv
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: MSwindows.C:371
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::argList::argList
argList(int &argc, char **&argv, bool checkArgs=argList::argsMandatory(), bool checkOpts=true, bool initialise=true)
Definition: argList.C:788
Foam::pgid
pid_t pgid()
Return the group PID of this process.
Definition: MSwindows.C:350
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::dynamicCode::allowSystemOperations
static int allowSystemOperations
Flag if system operations are allowed.
Definition: dynamicCode.H:166
Foam::argList::ignoreOptionCompat
static void ignoreOptionCompat(std::pair< const char *, int > compat, bool expectArg)
Specify an option to be ignored.
Definition: argList.C:382
Foam::JobInfo::disable
static void disable() noexcept
Disallow JobInfo by forcing writeJobInfo (InfoSwitch) off.
Definition: JobInfo.C:92
Foam::UPstream::allWorlds
static const wordList & allWorlds() noexcept
All worlds.
Definition: UPstream.H:483
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:301
Foam::debug::infoSwitch
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:231
Foam::fileOperation::New
static autoPtr< fileOperation > New(const word &handlerType, bool verbose=false)
Select fileHandler-type.
Definition: fileOperation.C:706
Foam::LList
Template class for non-intrusive linked lists.
Definition: LList.H:54
Foam::argList::validParOptions
static HashTable< string > validParOptions
A list of valid parallel options.
Definition: argList.H:215
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::argList::parse
void parse(bool checkArgs, bool checkOpts, bool initialise)
Definition: argList.C:1023
Foam::argList::noLibs
static void noLibs()
Add the '-no-libs' command line option.
Definition: argList.C:499
Foam::argList::noFunctionObjects
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition: argList.C:473
Foam::userName
string userName()
Return the user's login name.
Definition: MSwindows.C:429
Foam::debug::optimisationObjects
simpleObjectRegistry & optimisationObjects()
Access to registered OptimisationSwitch objects.
Definition: debug.C:313
Foam::UPstream::subProcs
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:515
Foam::check
static void check(const int retVal, const char *what)
Definition: ptscotchDecomp.C:80
Foam::foamVersion::api
const int api
Foam::simpleObjectRegistry::setNamedValue
void setNamedValue(std::string name, int val, bool report=false)
Set named value, but also handle embedded 'name=value' syntax.
Definition: simpleObjectRegistry.C:92
labelList.H
Foam::Switch::INVALID
Definition: Switch.H:94
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:52
Foam::argList::setOption
bool setOption(const word &optName, const string &param="")
Set option directly (use with caution)
Definition: argList.C:1786
Foam::argList::noJobInfo
static void noJobInfo()
Suppress JobInfo, overriding controlDict setting.
Definition: argList.C:493
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::debug::debugObjects
simpleObjectRegistry & debugObjects()
Access to registered DebugSwitch objects.
Definition: debug.C:291
clock.H
Foam::UPstream::floatTransfer
static bool floatTransfer
Definition: UPstream.H:274
Foam::pid
pid_t pid()
Return the PID of this process.
Definition: MSwindows.C:330
argList.H
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
Foam::ppid
pid_t ppid()
Return the parent PID of this process.
Definition: MSwindows.C:337
Foam::argList::envRelativePath
static fileName envRelativePath(const fileName &input, const bool caseTag=false)
Definition: argList.C:556
Foam::argList::postProcessOptionName
static word postProcessOptionName
Standard name for the post-processing option.
Definition: argList.H:241
Switch.H
Foam::dictionary::readEntry
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
Definition: dictionaryTemplates.C:302
dynamicCode.H
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:76
Foam::argList::setAdvanced
static void setAdvanced(const word &optName, bool advanced=true)
Set an existing option as being 'advanced' or normal.
Definition: argList.C:354
DetailInfo
#define DetailInfo
Definition: evalEntry.C:37
Foam::radiation::lookup
Lookup type of boundary radiation properties.
Definition: lookup.H:63
Foam::UPstream::commsTypeNames
static const Enum< commsTypes > commsTypeNames
Names of the communication types.
Definition: UPstream.H:77
Foam::IOobject::fileModificationSkew
static float fileModificationSkew
Time skew (seconds) for file modification checks.
Definition: IOobject.H:306
Foam::UPstream::myWorld
static const word & myWorld()
My world.
Definition: UPstream.H:501
Foam::argList::noCheckProcessorDirectories
static void noCheckProcessorDirectories()
Remove checking of processor directories.
Definition: argList.C:521
IOobject.H
Foam::argList::validOptions
static HashTable< string > validOptions
A list of valid options.
Definition: argList.H:212
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::debug::infoObjects
simpleObjectRegistry & infoObjects()
Access to registered InfoSwitch objects.
Definition: debug.C:302
fileOperation.H
Foam::argList::postProcess
static bool postProcess(int argc, char *argv[])
Return true if the post-processing option is specified.
Definition: argList.C:527
Foam::fileName::validate
static fileName validate(const std::string &, const bool doClean=true)
Definition: fileName.C:206
Foam::clock::date
static std::string date()
Definition: clock.C:80
Foam::fileOperation::defaultFileHandler
static word defaultFileHandler
Name of the default fileHandler.
Definition: fileOperation.H:171
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::flatOutput
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:216
Foam::argList::addDryRunOption
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a 'dry-run' bool option, with usage information.
Definition: argList.C:454
Foam::infoDetailLevel
int infoDetailLevel
Global for selective suppression of Info output.
Foam::fileName::null
static const fileName null
An empty fileName.
Definition: fileName.H:101
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::foamVersion::version
const std::string version
OpenFOAM version (name or stringified number) as a std::string.
Foam::argList::unsetOption
bool unsetOption(const word &optName)
Unset option directly (use with caution)
Definition: argList.C:1812
Foam::UPstream::nProcsSimpleSum
static int nProcsSimpleSum
Definition: UPstream.H:278
Foam::HashTable< Foam::string >
Foam::jobInfo
JobInfo jobInfo
Definition: JobInfo.C:49
found
bool found
Definition: TABSMDCalcMethod2.H:32
Foam::argList::addBoolOption
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
Foam::argList::envExecutable
static word envExecutable()
Name of the executable from environment variable.
Definition: argList.C:543
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
CStringList.H
Foam::argList::advancedOptions
static HashSet< string > advancedOptions
The "advanced" options are shown with -help-full (not with –help)
Definition: argList.H:209
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::JobInfo::stop
void stop()
Job end with "normal" termination.
Definition: JobInfo.C:232
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:463
Foam::nl
constexpr char nl
Definition: Ostream.H:404
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::argList::argsMandatory
static bool argsMandatory()
Command arguments type (optional/mandatory).
Definition: argList.C:435
Foam::UPstream::commsTypes::scheduled
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::sigSegv::set
static void set(bool verbose=false)
Activate SIGSEGV signal handler.
Definition: sigSegv.C:73
Foam::IOobject::writeDivider
static Ostream & writeDivider(Ostream &os)
Write the standard file section divider.
Definition: IOobjectWriteHeader.C:132
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List< string >
Foam::foamVersion::buildArch
const std::string buildArch
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
dictionary.H
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Foam::hostName
string hostName(bool full=false)
Return the system's host name, as per hostname(1)
Definition: MSwindows.C:410
Foam::argList::notes
static SLList< string > notes
General usage notes.
Definition: argList.H:232
Foam::input
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:55
Foam::argList::checkRootCase
bool checkRootCase() const
Check root path and case path.
Definition: argList.C:1954
Foam::clock::clockTime
static std::string clockTime()
Definition: clock.C:95
JobInfo.H
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::fileName::clean
static bool clean(std::string &str)
Definition: fileName.C:199
Foam::error::warnAboutAge
static bool warnAboutAge(const int version) noexcept
Test if an age warning should be emitted.
Definition: error.C:55
Foam::cwd
fileName cwd()
The physical or logical current working directory path name.
Definition: MSwindows.C:468
stringListOps.H
Operations on lists of strings.
Foam::dictionary::add
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:640
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:53
FatalErrorIn
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:448
Foam::argList::ignoreOptionsCompat
static HashTable< std::pair< bool, int > > ignoreOptionsCompat
A list of options to ignore.
Definition: argList.H:223
Foam::debug::controlDict
dictionary & controlDict()
Definition: debug.C:143
Foam::keyType::LITERAL
String literal.
Definition: keyType.H:81
Foam::foamVersion::printBuildInfo
void printBuildInfo(std::ostream &os, const bool full=true)
Print information about version, build, arch to output stream.
Foam::argList::argUsage
static HashTable< string, label, Hash< label > > argUsage
Short description for program arguments.
Definition: argList.H:226
Foam::argList::check
bool check(bool checkArgs=argList::argsMandatory(), bool checkOpts=true) const
Definition: argList.C:1908
Foam::messageStream::stdStream
std::ostream & stdStream()
Return std::ostream for output operations.
Definition: messageStream.C:157
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:510
Foam::sigQuit::set
static void set(bool verbose=false)
Activate SIGQUIT signal handler.
Definition: sigQuit.C:76
Foam::stringOps::expand
string expand(const std::string &s, const HashTable< string > &mapping, const char sigil='$')
Definition: stringOps.C:718
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::argList::bannerEnabled
static bool bannerEnabled()
Banner status (enabled/disabled).
Definition: argList.C:447
Foam::argList::addOption
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
args
Foam::argList args(argc, argv)
Foam::error::write
virtual void write(Ostream &os, const bool withTitle=true) const
Print error message.
Definition: error.C:343
stringOps.H
Foam::findMatchingStrings
labelList findMatchingStrings(const UnaryMatchPredicate &matcher, const UList< StringType > &input, const bool invert=false)
Extract list indices for all matches.
Foam::printHostsSubscription
static void printHostsSubscription(const UList< string > &hostProcs)
Definition: argList.C:207
Foam::fileName::isAbsolute
static bool isAbsolute(const std::string &str)
Definition: fileNameI.H:136
Foam::argList::~argList
virtual ~argList()
Destructor.
Definition: argList.C:1744
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:445
Foam::argList::displayDoc
void displayDoc(bool source=false) const
Display documentation in browser.
Definition: argList.C:1834
Foam::argList::addVerboseOption
static void addVerboseOption(const string &usage, bool advanced=false)
Enable a 'verbose' bool option, with usage information.
Definition: argList.C:464
Foam::sigInt::set
static void set(bool verbose=false)
Activate SIGINT signal handler.
Definition: sigInt.C:73
Foam::argList::removeOption
static void removeOption(const word &optName)
Remove option from validOptions and from optionUsage.
Definition: argList.C:421
Foam::UPstream::nPollProcInterfaces
static int nPollProcInterfaces
Number of polling cycles in processor updates.
Definition: UPstream.H:284
Foam::isDir
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:643
Foam::IOobject::maxFileModificationPolls
static int maxFileModificationPolls
Max number of times to poll for file modification changes.
Definition: IOobject.H:309
Foam::UPstream::exit
static void exit(int errNo=1)
Shutdown (finalize) MPI as required and exit program with errNo.
Definition: UPstream.C:63
Foam::fileOperations::fileOperationInitialise::New
static autoPtr< fileOperationInitialise > New(const word &type, int &argc, char **&argv)
Select type.
Definition: fileOperationInitialise.C:80
foamVersion.H
Foam::CStringList
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:69