https://mooseframework.inl.gov
MooseApp.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #ifdef HAVE_GPERFTOOLS
11 #include "gperftools/profiler.h"
12 #include "gperftools/heap-profiler.h"
13 #endif
14 
15 // MOOSE includes
16 #include "MooseRevision.h"
17 #include "AppFactory.h"
18 #include "DisplacedProblem.h"
19 #include "NonlinearSystemBase.h"
20 #include "AuxiliarySystem.h"
21 #include "MooseSyntax.h"
22 #include "MooseInit.h"
23 #include "Executioner.h"
24 #include "Executor.h"
25 #include "PetscSupport.h"
26 #include "Conversion.h"
27 #include "CommandLine.h"
28 #include "InfixIterator.h"
29 #include "MultiApp.h"
30 #include "MooseUtils.h"
31 #include "MooseObjectAction.h"
33 #include "SystemInfo.h"
34 #include "MooseMesh.h"
35 #include "FileOutput.h"
36 #include "ConsoleUtils.h"
37 #include "JsonSyntaxTree.h"
38 #include "JsonInputFileFormatter.h"
39 #include "SONDefinitionFormatter.h"
40 #include "RelationshipManager.h"
42 #include "Registry.h"
43 #include "SerializerGuard.h"
44 #include "PerfGraphInterface.h" // For TIME_SECTION
46 #include "Attributes.h"
47 #include "MooseApp.h"
48 #include "CommonOutputAction.h"
49 #include "CastUniquePointer.h"
50 #include "NullExecutor.h"
51 #include "ExecFlagRegistry.h"
52 #include "SolutionInvalidity.h"
53 #include "MooseServer.h"
54 #include "RestartableDataWriter.h"
55 #include "StringInputStream.h"
56 #include "MooseMain.h"
57 #include "FEProblemBase.h"
58 #include "Parser.h"
59 #include "CSGBase.h"
60 
61 // Regular expression includes
62 #include "pcrecpp.h"
63 
64 #include "libmesh/exodusII_io.h"
65 #include "libmesh/mesh_refinement.h"
66 #include "libmesh/string_to_enum.h"
67 #include "libmesh/checkpoint_io.h"
68 #include "libmesh/mesh_base.h"
69 #include "libmesh/petsc_solver_exception.h"
70 
71 // System include for dynamic library methods
72 #ifdef LIBMESH_HAVE_DLOPEN
73 #include <dlfcn.h>
74 #include <sys/utsname.h> // utsname
75 #endif
76 
77 #ifdef MOOSE_LIBTORCH_ENABLED
78 #include <torch/version.h>
79 #endif
80 
81 // C++ includes
82 #include <numeric> // std::accumulate
83 #include <fstream>
84 #include <sys/types.h>
85 #include <unistd.h>
86 #include <cstdlib> // for system()
87 #include <chrono>
88 #include <thread>
89 #include <filesystem>
90 
91 using namespace libMesh;
92 
93 void
95 {
96  params.addCommandLineParam<std::string>(
97  "app_to_run", "--app <type>", "Specify the application type to run (case-sensitive)");
98 }
99 
100 void
102 {
103  params.addCommandLineParam<std::vector<std::string>>(
104  "input_file", "-i <input file(s)>", "Specify input file(s); multiple files are merged");
105 }
106 
109 {
111 
112  MooseApp::addAppParam(params);
113  MooseApp::addInputParam(params);
114 
115  params.addCommandLineParam<bool>("display_version", "-v --version", "Print application version");
116 
117  params.addOptionalValuedCommandLineParam<std::string>(
118  "mesh_only",
119  "--mesh-only <optional path>",
120  "",
121  "Build and output the mesh only (Default: \"<input_file_name>_in.e\")");
122  params.addOptionalValuedCommandLineParam<std::string>(
123  "csg_only",
124  "--csg-only <optional path>",
125  "",
126  "Setup and output the input mesh in CSG format only (Default: "
127  "\"<input_file_name>_out_csg.json\")");
128  params.addCommandLineParam<bool>(
129  "show_input", "--show-input", "Shows the parsed input file before running the simulation");
130  params.setGlobalCommandLineParam("show_input");
131  params.addCommandLineParam<bool>(
132  "show_outputs", "--show-outputs", "Shows the output execution time information");
133  params.setGlobalCommandLineParam("show_outputs");
134  params.addCommandLineParam<bool>(
135  "show_controls", "--show-controls", "Shows the Control logic available and executed");
136  params.setGlobalCommandLineParam("show_controls");
137 
138  params.addCommandLineParam<bool>(
139  "no_color", "--no-color", "Disable coloring of all Console outputs");
140  params.setGlobalCommandLineParam("no_color");
141 
142  MooseEnum colors("auto on off", "on");
144  "color", "--color <auto,on,off=on>", colors, "Whether to use color in console output");
145  params.setGlobalCommandLineParam("color");
146 
147  params.addCommandLineParam<bool>("help", "-h --help", "Displays CLI usage statement");
148  params.addCommandLineParam<bool>(
149  "minimal",
150  "--minimal",
151  "Ignore input file and build a minimal application with Transient executioner");
152 
153  params.addCommandLineParam<bool>(
154  "language_server",
155  "--language-server",
156  "Starts a process to communicate with development tools using the language server protocol");
157 
158  params.addCommandLineParam<bool>(
159  "definition", "--definition", "Shows a SON style input definition dump for input validation");
160  params.addCommandLineParam<bool>("dump", "--dump", "Shows a dump of available input file syntax");
161  params.addCommandLineParam<std::string>(
162  "dump_search",
163  "--dump-search <search>",
164  "Shows a dump of available input syntax matching a search");
165  params.addCommandLineParam<bool>("registry", "--registry", "Lists all known objects and actions");
166  params.addCommandLineParam<bool>(
167  "registry_hit", "--registry-hit", "Lists all known objects and actions in hit format");
168  params.addCommandLineParam<bool>(
169  "use_executor", "--executor", "Use the new Executor system instead of Executioners");
170 
171  params.addCommandLineParam<bool>(
172  "show_type", "--show-type", "Return the name of the application object");
173  params.addCommandLineParam<bool>("yaml", "--yaml", "Dumps all input file syntax in YAML format");
174  params.addCommandLineParam<std::string>(
175  "yaml_search", "--yaml-search", "Dumps input file syntax matching a search in YAML format");
176  params.addCommandLineParam<bool>("json", "--json", "Dumps all input file syntax in JSON format");
177  params.addCommandLineParam<std::string>(
178  "json_search", "--json-search", "Dumps input file syntax matching a search in JSON format");
179  params.addCommandLineParam<bool>(
180  "syntax", "--syntax", "Dumps the associated Action syntax paths ONLY");
181  params.addCommandLineParam<bool>(
182  "show_docs", "--docs", "Print url/path to the documentation website");
183  params.addCommandLineParam<bool>(
184  "show_capabilities", "--show-capabilities", "Dumps the capability registry in JSON format.");
185  params.addCommandLineParam<std::string>(
186  "required_capabilities",
187  "--required-capabilities",
188  "A list of conditions that is checked against the registered capabilities (see "
189  "--show-capabilities). The executable will terminate early if the conditions are not met.");
190  params.addCommandLineParam<std::string>(
191  "check_capabilities",
192  "--check-capabilities",
193  "A list of conditions that is checked against the registered capabilities. Will exit based "
194  "on whether or not the capaiblities are fulfilled. Does not check dynamically loaded apps.");
195  params.addCommandLineParam<bool>("check_input",
196  "--check-input",
197  "Check the input file (i.e. requires -i <filename>) and quit");
198  params.setGlobalCommandLineParam("check_input");
199  params.addCommandLineParam<bool>(
200  "show_inputs",
201  "--show-copyable-inputs",
202  "Shows the directories able to be copied into a user-writable location");
203 
204  params.addCommandLineParam<std::string>(
205  "copy_inputs",
206  "--copy-inputs <dir>",
207  "Copies installed inputs (e.g. tests, examples, etc.) to a directory <appname>_<dir>");
208  // TODO: Should this remain a bool? It can't be a regular argument because it contains
209  // values that have dashes in it, so it'll get treated as another arg
210  params.addOptionalValuedCommandLineParam<std::string>(
211  "run",
212  "--run <test harness args>",
213  "",
214  "Runs the inputs in the current directory copied to a "
215  "user-writable location by \"--copy-inputs\"");
216 
217  params.addCommandLineParam<bool>(
218  "list_constructed_objects",
219  "--list-constructed-objects",
220  "List all moose object type names constructed by the master app factory");
221 
222  params.addCommandLineParam<unsigned int>(
223  "n_threads", "--n-threads=<n>", "Runs the specified number of threads per process");
224  // This probably shouldn't be global, but the implications of removing this are currently
225  // unknown and we need to manage it with libmesh better
226  params.setGlobalCommandLineParam("n_threads");
227 
228  params.addCommandLineParam<bool>("allow_unused",
229  "-w --allow-unused",
230  "Warn about unused input file options instead of erroring");
231  params.setGlobalCommandLineParam("allow_unused");
232  params.addCommandLineParam<bool>(
233  "error_unused", "-e --error-unused", "Error when encountering unused input file options");
234  params.setGlobalCommandLineParam("error_unused");
235  params.addCommandLineParam<bool>(
236  "error_override",
237  "-o --error-override",
238  "Error when encountering overridden or parameters supplied multiple times");
239  params.setGlobalCommandLineParam("error_override");
240  params.addCommandLineParam<bool>(
241  "error_deprecated", "--error-deprecated", "Turn deprecated code messages into Errors");
242  params.setGlobalCommandLineParam("error_deprecated");
243 
244  params.addCommandLineParam<bool>("distributed_mesh",
245  "--distributed-mesh",
246  "Forces the use of a distributed finite element mesh");
247  // Would prefer that this parameter isn't global, but we rely on it too much
248  // in tests to be able to go back on that decision now
249  params.setGlobalCommandLineParam("distributed_mesh");
250 
251  params.addCommandLineParam<std::string>(
252  "split_mesh",
253  "--split-mesh <splits>",
254  "Comma-separated list of numbers of chunks to split the mesh into");
255 
256  // TODO: remove the logic now that this is global
257  params.addCommandLineParam<std::string>(
258  "split_file", "--split-file <filename>", "Name of split mesh file(s) to write/read");
259 
260  params.addCommandLineParam<bool>("use_split", "--use-split", "Use split distributed mesh files");
261 
262  params.addCommandLineParam<unsigned int>(
263  "refinements", "-r <num refinements>", "Specify additional initial uniform mesh refinements");
264 
265  params.addOptionalValuedCommandLineParam<std::string>(
266  "recover",
267  "--recover <optional file base>",
268  "",
269  "Continue the calculation. Without <file base>, the most recent recovery file will be used");
270  params.setGlobalCommandLineParam("recover");
271  params.addCommandLineParam<bool>(
272  "force_restart",
273  "--force-restart",
274  "Forcefully load checkpoints despite possible incompatibilities");
275  params.setGlobalCommandLineParam("force_restart");
276 
277  params.addCommandLineParam<bool>("suppress_header",
278  "--suppress-header",
279  false,
280  "Disables the output of the application header.");
281  params.setGlobalCommandLineParam("suppress_header");
282 
283  params.addCommandLineParam<bool>(
284  "test_checkpoint_half_transient",
285  "--test-checkpoint-half-transient",
286  "Run half of a transient with checkpoints enabled; used by the TestHarness");
287  params.setGlobalCommandLineParam("test_checkpoint_half_transient");
288 
289  params.addCommandLineParam<bool>("test_restep",
290  "--test-restep",
291  "Test re-running the middle timestep; used by the TestHarness");
292 
293  params.addCommandLineParam<bool>(
294  "trap_fpe",
295  "--trap-fpe",
296  "Enable floating point exception handling in critical sections of code"
297 #ifdef DEBUG
298  " (automatic due to debug build)"
299 #endif
300  );
301  params.setGlobalCommandLineParam("trap_fpe");
302 
303  params.addCommandLineParam<bool>(
304  "no_trap_fpe",
305  "--no-trap-fpe",
306  "Disable floating point exception handling in critical sections of code"
307 #ifndef DEBUG
308  " (unused due to non-debug build)"
309 #endif
310  );
311 
312  params.setGlobalCommandLineParam("no_trap_fpe");
313 
314  params.addCommandLineParam<bool>(
315  "no_gdb_backtrace", "--no-gdb-backtrace", "Disables gdb backtraces.");
316  params.setGlobalCommandLineParam("no_gdb_backtrace");
317 
318  params.addCommandLineParam<bool>("error", "--error", "Turn all warnings into errors");
319  params.setGlobalCommandLineParam("error");
320 
321  params.addCommandLineParam<bool>("timing",
322  "-t --timing",
323  "Enable all performance logging for timing; disables screen "
324  "output of performance logs for all Console objects");
325  params.setGlobalCommandLineParam("timing");
326  params.addCommandLineParam<bool>(
327  "no_timing", "--no-timing", "Disabled performance logging; overrides -t or --timing");
328  params.setGlobalCommandLineParam("no_timing");
329 
330  params.addCommandLineParam<bool>(
331  "allow_test_objects", "--allow-test-objects", "Register test objects and syntax");
332  params.setGlobalCommandLineParam("allow_test_objects");
333 
334  // Options ignored by MOOSE but picked up by libMesh, these are here so that they are displayed in
335  // the application help
336  params.addCommandLineParam<bool>(
337  "keep_cout",
338  "--keep-cout",
339  "Keep standard output from all processors when running in parallel");
340  params.setGlobalCommandLineParam("keep_cout");
341  params.addCommandLineParam<bool>(
342  "redirect_stdout",
343  "--redirect-stdout",
344  "Keep standard output from all processors when running in parallel");
345  params.setGlobalCommandLineParam("redirect_stdout");
346 
347  params.addCommandLineParam<std::string>(
348  "timpi_sync",
349  "--timpi-sync <type=nbx>",
350  "nbx",
351  "Changes the sync type used in spare parallel communitations within TIMPI");
352  params.setGlobalCommandLineParam("timpi_sync");
353 
354  // Options for debugging
355  params.addCommandLineParam<std::string>("start_in_debugger",
356  "--start-in-debugger <debugger>",
357  "Start the application and attach a debugger; this will "
358  "launch xterm windows using <debugger>");
359 
360  params.addCommandLineParam<unsigned int>(
361  "stop_for_debugger",
362  "--stop-for-debugger <seconds>",
363  "Pauses the application during startup for <seconds> to allow for connection of debuggers");
364 
365  params.addCommandLineParam<bool>(
366  "perf_graph_live_all", "--perf-graph-live-all", "Forces printing of ALL progress messages");
367  params.setGlobalCommandLineParam("perf_graph_live_all");
368 
369  params.addCommandLineParam<bool>(
370  "disable_perf_graph_live", "--disable-perf-graph-live", "Disables PerfGraph live printing");
371  params.setGlobalCommandLineParam("disable_perf_graph_live");
372 
373  params.addParam<bool>(
374  "automatic_automatic_scaling", false, "Whether to turn on automatic scaling by default");
375 
376  const MooseEnum compute_device_type("cpu cuda mps hip ceed-cpu ceed-cuda ceed-hip", "cpu");
378  "compute_device",
379  "--compute-device",
380  compute_device_type,
381  "The device type we want to run accelerated (libtorch, MFEM) computations on.");
382 
383 #ifdef HAVE_GPERFTOOLS
384  params.addCommandLineParam<std::string>(
385  "gperf_profiler_on",
386  "--gperf-profiler-on <ranks>",
387  "To generate profiling report only on comma-separated list of MPI ranks");
388 #endif
389 
390  params.addCommandLineParam<bool>(
391  "show_data_params",
392  "--show-data-params",
393  false,
394  "Show found paths for all DataFileName parameters in the header");
395  params.addCommandLineParam<bool>("show_data_paths",
396  "--show-data-paths",
397  false,
398  "Show registered data paths for searching in the header");
399 
400  params.addPrivateParam<std::shared_ptr<CommandLine>>("_command_line");
401  params.addPrivateParam<std::shared_ptr<Parallel::Communicator>>("_comm");
402  params.addPrivateParam<unsigned int>("_multiapp_level");
403  params.addPrivateParam<unsigned int>("_multiapp_number");
404  params.addPrivateParam<bool>("_use_master_mesh", false);
405  params.addPrivateParam<const MooseMesh *>("_master_mesh");
406  params.addPrivateParam<const MooseMesh *>("_master_displaced_mesh");
407  params.addPrivateParam<std::unique_ptr<Backup> *>("_initial_backup", nullptr);
408  params.addPrivateParam<std::shared_ptr<Parser>>("_parser");
409 #ifdef MOOSE_MFEM_ENABLED
410  params.addPrivateParam<std::shared_ptr<mfem::Device>>("_mfem_device");
411  params.addPrivateParam<std::set<std::string>>("_mfem_devices");
412 #endif
413 
414  params.addParam<bool>(
415  "use_legacy_material_output",
416  true,
417  "Set false to allow material properties to be output on INITIAL, not just TIMESTEP_END.");
418  params.addParam<bool>(
419  "use_legacy_initial_residual_evaluation_behavior",
420  true,
421  "The legacy behavior performs an often times redundant residual evaluation before the "
422  "solution modifying objects are executed prior to the initial (0th nonlinear iteration) "
423  "residual evaluation. The new behavior skips that redundant residual evaluation unless the "
424  "parameter Executioner/use_pre_SMO_residual is set to true.");
425 
426  params.addParam<bool>(
428  false,
429  "Set true to enable data-driven mesh generation, which is an experimental feature");
430 
431  params.addCommandLineParam<bool>(
432  "parse_neml2_only",
433  "--parse-neml2-only",
434  "Executes the [NEML2] block to parse the input file and terminate.");
435 
436  MooseApp::addAppParam(params);
437 
438  params.registerBase("Application");
439 
440  return params;
441 }
442 
444  : PerfGraphInterface(*this, "MooseApp"),
445  ParallelObject(*parameters.get<std::shared_ptr<Parallel::Communicator>>(
446  "_comm")), // Can't call getParam() before pars is set
447  // The use of AppFactory::getAppParams() is atrocious. However, a long time ago
448  // we decided to copy construct parameters in each derived application...
449  // which means that the "parameters" we get if someone derives from MooseApp are
450  // actually a copy of the ones built by the factory. Because we have unique
451  // application names, this allows us to reference (using _pars and MooseBase)
452  // the actual const parameters that the AppFactory made for this application
453  MooseBase(*this, AppFactory::instance().getAppParams(parameters)),
454  _comm(getParam<std::shared_ptr<Parallel::Communicator>>("_comm")),
455  _file_base_set_by_user(false),
456  _output_position_set(false),
457  _start_time_set(false),
458  _start_time(0.0),
459  _global_time_offset(0.0),
460  _input_parameter_warehouse(std::make_unique<InputParameterWarehouse>()),
461  _action_factory(*this),
462  _action_warehouse(*this, _syntax, _action_factory),
463  _output_warehouse(*this),
464  _parser(getCheckedPointerParam<std::shared_ptr<Parser>>("_parser")),
465  _command_line(getCheckedPointerParam<std::shared_ptr<CommandLine>>("_command_line")),
466  _builder(*this, _action_warehouse, *_parser),
467  _restartable_data(libMesh::n_threads()),
468  _perf_graph(createRecoverablePerfGraph()),
469  _solution_invalidity(createRecoverableSolutionInvalidity()),
470  _rank_map(*_comm, _perf_graph),
471  _use_executor(getParam<bool>("use_executor")),
472  _null_executor(NULL),
473  _use_nonlinear(true),
474  _use_eigen_value(false),
475  _enable_unused_check(ERROR_UNUSED),
476  _factory(*this),
477  _error_overridden(false),
478  _early_exit_param(""),
479  _ready_to_exit(false),
480  _exit_code(0),
481  _initial_from_file(false),
482  _distributed_mesh_on_command_line(false),
483  _recover(false),
484  _restart(false),
485  _split_mesh(false),
486  _use_split(getParam<bool>("use_split")),
487  _force_restart(getParam<bool>("force_restart")),
488 #ifdef DEBUG
489  _trap_fpe(true),
490 #else
491  _trap_fpe(false),
492 #endif
493  _test_checkpoint_half_transient(parameters.get<bool>("test_checkpoint_half_transient")),
494  _test_restep(parameters.get<bool>("test_restep")),
495  _check_input(getParam<bool>("check_input")),
496  _multiapp_level(isParamValid("_multiapp_level") ? getParam<unsigned int>("_multiapp_level")
497  : 0),
498  _multiapp_number(isParamValid("_multiapp_number") ? getParam<unsigned int>("_multiapp_number")
499  : 0),
500  _use_master_mesh(getParam<bool>("_use_master_mesh")),
501  _master_mesh(isParamValid("_master_mesh") ? getParam<const MooseMesh *>("_master_mesh")
502  : nullptr),
503  _master_displaced_mesh(isParamValid("_master_displaced_mesh")
504  ? getParam<const MooseMesh *>("_master_displaced_mesh")
505  : nullptr),
506  _mesh_generator_system(*this),
507  _chain_control_system(*this),
508  _rd_reader(*this, _restartable_data, forceRestart()),
509  _execute_flags(moose::internal::ExecFlagRegistry::getExecFlagRegistry().getFlags()),
510  _output_buffer_cache(nullptr),
511  _automatic_automatic_scaling(getParam<bool>("automatic_automatic_scaling")),
512  _initial_backup(getParam<std::unique_ptr<Backup> *>("_initial_backup"))
513 #ifdef MOOSE_LIBTORCH_ENABLED
514  ,
515  _libtorch_device(determineLibtorchDeviceType(getParam<MooseEnum>("compute_device")))
516 #endif
517 #ifdef MOOSE_MFEM_ENABLED
518  ,
519  _mfem_device(isParamValid("_mfem_device")
520  ? getParam<std::shared_ptr<mfem::Device>>("_mfem_device")
521  : nullptr),
522  _mfem_devices(isParamValid("_mfem_devices") ? getParam<std::set<std::string>>("_mfem_devices")
523  : std::set<std::string>{})
524 #endif
525 {
526  if (&parameters != &_pars)
527  {
528  const auto show_trace = Moose::show_trace;
529  Moose::show_trace = false;
530  const std::string bad_params = "(InputParameters parameters)";
531  const std::string good_params = "(const InputParameters & parameters)";
532  const std::string source_constructor = type() + "::" + type();
533  mooseDoOnce(mooseDeprecated(type(),
534  " copy-constructs its input parameters.\n\n",
535  "This is deprecated and will not be allowed in the future.\n\n",
536  "In ",
537  type(),
538  ".C, change:\n ",
539  source_constructor,
540  bad_params,
541  " -> ",
542  source_constructor,
543  good_params,
544  "\n\n",
545  "In ",
546  type(),
547  ".h, change:\n ",
548  type(),
549  bad_params,
550  "; -> ",
551  type(),
552  good_params,
553  ";"));
555  }
556 
557  mooseAssert(_command_line->hasParsed(), "Command line has not parsed");
558  mooseAssert(_parser->queryRoot() && _parser->queryCommandLineRoot(), "Parser has not parsed");
559 
560  // Set the TIMPI sync type via --timpi-sync
561  const auto & timpi_sync = getParam<std::string>("timpi_sync");
562  const_cast<Parallel::Communicator &>(comm()).sync_type(timpi_sync);
563 
564 #ifdef HAVE_GPERFTOOLS
565  if (isUltimateMaster())
566  {
567  bool has_cpu_profiling = false;
568  bool has_heap_profiling = false;
569  static std::string cpu_profile_file;
570  static std::string heap_profile_file;
571 
572  // For CPU profiling, users need to have environment 'MOOSE_PROFILE_BASE'
573  if (std::getenv("MOOSE_PROFILE_BASE"))
574  {
575  has_cpu_profiling = true;
576  cpu_profile_file =
577  std::getenv("MOOSE_PROFILE_BASE") + std::to_string(_comm->rank()) + ".prof";
578  // create directory if needed
579  auto name = MooseUtils::splitFileName(cpu_profile_file);
580  if (!name.first.empty())
581  {
582  if (processor_id() == 0)
583  MooseUtils::makedirs(name.first.c_str());
584  _comm->barrier();
585  }
586  }
587 
588  // For Heap profiling, users need to have 'MOOSE_HEAP_BASE'
589  if (std::getenv("MOOSE_HEAP_BASE"))
590  {
591  has_heap_profiling = true;
592  heap_profile_file = std::getenv("MOOSE_HEAP_BASE") + std::to_string(_comm->rank());
593  // create directory if needed
594  auto name = MooseUtils::splitFileName(heap_profile_file);
595  if (!name.first.empty())
596  {
597  if (processor_id() == 0)
598  MooseUtils::makedirs(name.first.c_str());
599  _comm->barrier();
600  }
601  }
602 
603  // turn on profiling only on selected ranks
604  if (isParamSetByUser("gperf_profiler_on"))
605  {
606  auto rankstr = getParam<std::string>("gperf_profiler_on");
607  std::vector<processor_id_type> ranks;
608  bool success = MooseUtils::tokenizeAndConvert(rankstr, ranks, ", ");
609  if (!success)
610  mooseError("Invalid argument for --gperf-profiler-on: '", rankstr, "'");
611  for (auto & rank : ranks)
612  {
613  if (rank >= _comm->size())
614  mooseError("Invalid argument for --gperf-profiler-on: ",
615  rank,
616  " is greater than or equal to ",
617  _comm->size());
618  if (rank == _comm->rank())
619  {
620  _cpu_profiling = has_cpu_profiling;
621  _heap_profiling = has_heap_profiling;
622  }
623  }
624  }
625  else
626  {
627  _cpu_profiling = has_cpu_profiling;
628  _heap_profiling = has_heap_profiling;
629  }
630 
631  if (_cpu_profiling)
632  if (!ProfilerStart(cpu_profile_file.c_str()))
633  mooseError("CPU profiler is not started properly");
634 
635  if (_heap_profiling)
636  {
637  HeapProfilerStart(heap_profile_file.c_str());
638  if (!IsHeapProfilerRunning())
639  mooseError("Heap profiler is not started properly");
640  }
641  }
642 #else
643  if (std::getenv("MOOSE_PROFILE_BASE") || std::getenv("MOOSE_HEAP_BASE"))
644  mooseError("gperftool is not available for CPU or heap profiling");
645 #endif
646 
647  // If this will be a language server then turn off output until that starts
648  if (isParamValid("language_server") && getParam<bool>("language_server"))
649  _output_buffer_cache = Moose::out.rdbuf(nullptr);
650 
652  Moose::registerAll(_factory, _action_factory, _syntax);
653 
654  _the_warehouse = std::make_unique<TheWarehouse>();
655  _the_warehouse->registerAttribute<AttribMatrixTags>("matrix_tags", 0);
656  _the_warehouse->registerAttribute<AttribVectorTags>("vector_tags", 0);
657  _the_warehouse->registerAttribute<AttribExecOns>("exec_ons", 0);
658  _the_warehouse->registerAttribute<AttribSubdomains>("subdomains", 0);
659  _the_warehouse->registerAttribute<AttribBoundaries>("boundaries", 0);
660  _the_warehouse->registerAttribute<AttribThread>("thread", 0);
661  _the_warehouse->registerAttribute<AttribExecutionOrderGroup>("execution_order_group", 0);
662  _the_warehouse->registerAttribute<AttribPreIC>("pre_ic", 0);
663  _the_warehouse->registerAttribute<AttribPreAux>("pre_aux");
664  _the_warehouse->registerAttribute<AttribPostAux>("post_aux");
665  _the_warehouse->registerAttribute<AttribName>("name", "dummy");
666  _the_warehouse->registerAttribute<AttribSystem>("system", "dummy");
667  _the_warehouse->registerAttribute<AttribVar>("variable", -1);
668  _the_warehouse->registerAttribute<AttribInterfaces>("interfaces", 0);
669  _the_warehouse->registerAttribute<AttribSysNum>("sys_num", libMesh::invalid_uint);
670  _the_warehouse->registerAttribute<AttribResidualObject>("residual_object");
671  _the_warehouse->registerAttribute<AttribSorted>("sorted");
672  _the_warehouse->registerAttribute<AttribDisplaced>("displaced", -1);
673 
674  _perf_graph.enableLivePrint();
675 
676  if (_check_input && isParamSetByUser("recover"))
677  mooseError("Cannot run --check-input with --recover. Recover files might not exist");
678 
679  if (isParamSetByUser("start_in_debugger") && isUltimateMaster())
680  {
681  auto command = getParam<std::string>("start_in_debugger");
682 
683  Moose::out << "Starting in debugger using: " << command << std::endl;
684 
686 
687  std::stringstream command_stream;
688 
689  // This will start XTerm and print out some info first... then run the debugger
690  command_stream << "xterm -e \"echo 'Rank: " << processor_id() << " Hostname: " << hostname
691  << " PID: " << getpid() << "'; echo ''; ";
692 
693  // Figure out how to run the debugger
694  if (command.find("lldb") != std::string::npos || command.find("gdb") != std::string::npos)
695  command_stream << command << " -p " << getpid();
696  else
697  mooseError("Unknown debugger: ",
698  command,
699  "\nIf this is truly what you meant then contact moose-users to have a discussion "
700  "about adding your debugger.");
701 
702  // Finish up the command
703  command_stream << "\""
704  << " & ";
705  std::string command_string = command_stream.str();
706  Moose::out << "Running: " << command_string << std::endl;
707 
708  int ret = std::system(command_string.c_str());
709  libmesh_ignore(ret);
710 
711  // Sleep to allow time for the debugger to attach
712  std::this_thread::sleep_for(std::chrono::seconds(10));
713  }
714 
715  if (isParamSetByUser("stop_for_debugger") && isUltimateMaster())
716  {
717  Moose::out << "\nStopping for " << getParam<unsigned int>("stop_for_debugger")
718  << " seconds to allow attachment from a debugger.\n";
719 
720  Moose::out << "\nAll of the processes you can connect to:\n";
721  Moose::out << "rank - hostname - pid\n";
722 
724 
725  {
726  // The 'false' turns off the serialization warning
727  SerializerGuard sg(_communicator, false); // Guarantees that the processors print in order
728  Moose::err << processor_id() << " - " << hostname << " - " << getpid() << "\n";
729  }
730 
731  Moose::out << "\nWaiting...\n" << std::endl;
732 
733  // Sleep to allow time for the debugger to attach
734  std::this_thread::sleep_for(std::chrono::seconds(getParam<unsigned int>("stop_for_debugger")));
735  }
736 
737  if (_master_mesh && isUltimateMaster())
738  mooseError("Mesh can be passed in only for sub-apps");
739 
740  if (_master_displaced_mesh && !_master_mesh)
741  mooseError("_master_mesh should have been set when _master_displaced_mesh is set");
742 
743 #ifdef MOOSE_MFEM_ENABLED
744  if (_mfem_device)
745  {
746  mooseAssert(!isUltimateMaster(),
747  "The MFEM device should only be auto-set for sub-applications");
748  mooseAssert(!_mfem_devices.empty(),
749  "If we are a sub-application and we have an MFEM device object, then we must know "
750  "its configuration string");
751  }
752 #endif
753 
754  // Data specifically associated with the mesh (meta-data) that will read from the restart
755  // file early during the simulation setup so that they are available to Actions and other objects
756  // that need them during the setup process. Most of the restartable data isn't made available
757  // until all objects have been created and all Actions have been executed (i.e. initialSetup).
758  registerRestartableDataMapName(MooseApp::MESH_META_DATA, MooseApp::MESH_META_DATA_SUFFIX);
759 
760  if (_pars.have_parameter<bool>("use_legacy_dirichlet_bc"))
761  mooseDeprecated("The parameter 'use_legacy_dirichlet_bc' is no longer valid.\n\n",
762  "All Dirichlet boundary conditions are preset by default.\n\n",
763  "Remove said parameter in ",
764  name(),
765  " to remove this deprecation warning.");
766 
767  if (_test_restep && _test_checkpoint_half_transient)
768  mooseError("Cannot use --test-restep and --test-checkpoint-half-transient together");
769 
770  registerCapabilities();
771 
772  Moose::out << std::flush;
773 
774 #ifdef MOOSE_KOKKOS_ENABLED
775 #ifdef MOOSE_ENABLE_KOKKOS_GPU
776  queryKokkosGPUs();
777 #endif
778 #endif
779 }
780 
781 std::optional<MooseEnum>
783 {
784  if (isParamSetByUser("compute_device"))
785  return getParam<MooseEnum>("compute_device");
786  return {};
787 }
788 
789 void
791 {
792  // helper lambdas
793  auto haveCapability = [](const std::string & capability, const std::string & doc)
794  { addCapability(capability, true, doc + " is available."); };
795 
796  auto missingCapability =
797  [](const std::string & capability, const std::string & doc, const std::string & help = "")
798  { addCapability(capability, false, doc + " is not available. " + help); };
799 
800  auto haveCapabilityVersion =
801  [](const std::string & capability, const std::string & doc, const std::string & version)
802  { addCapability(capability, version, doc + " version " + version + " is available."); };
803 
804  auto petscMissingCapability = [](const std::string & capability, const std::string & doc)
805  {
807  capability, false, doc + " is not available. Check your PETSc configure options.");
808  };
809 
810  auto libmeshMissingCapability =
811  [](const std::string & capability, const std::string & doc, const std::string & config_option)
812  {
813  addCapability(capability,
814  false,
815  doc + " is not available. It is controlled by the `" + config_option +
816  "` libMesh configure option.");
817  };
818 
819  // register capabilities
820  if (_trap_fpe)
821  addCapability("trap_fpe",
822  true,
823  "Trapping floating point exceptions is enabled (in debug mode this "
824  "can be disabled using the --no-trap-fpe option).");
825  else
826  addCapability("trap_fpe",
827  false,
828  "Trapping floating point exceptions is not enabled (enable them using "
829  "the --trap-fpe option or by running a debug mode executable).");
830 
831  {
832  const auto doc = "LibTorch machine learning and parallel tensor algebra library";
833 #ifdef MOOSE_LIBTORCH_ENABLED
834  addCapability("libtorch", TORCH_VERSION, doc);
835 #else
836  missingCapability("libtorch",
837  doc,
838  "Check "
839  "https://mooseframework.inl.gov/moose/getting_started/installation/"
840  "install_libtorch.html for "
841  "instructions on how to configure and build moose with libTorch.");
842 #endif
843  }
844 
845  {
846  const auto doc = "MFEM finite element library";
847 #ifdef MOOSE_MFEM_ENABLED
848  haveCapability("mfem", doc);
849 #else
850  missingCapability("mfem",
851  doc,
852  "Install mfem using the scripts/update_and_rebuild_mfem.sh script after "
853  "first running scripts/update_and_rebuild_conduit.sh. Finally, configure "
854  "moose with ./configure --with-mfem");
855 #endif
856  }
857 
858  {
859  const auto doc = "New Engineering Material model Library, version 2";
860 #ifdef NEML2_ENABLED
861  haveCapability("neml2", doc);
862 #else
863  missingCapability("neml2",
864  doc,
865  "Install neml2 using the scripts/update_and_rebuild_neml2.sh script, then "
866  "configure moose with ./configure --with-neml2 --with-libtorch");
867 #endif
868  }
869 
870  {
871  const auto doc = "gperftools code performance analysis and profiling library";
872 #ifdef HAVE_GPERFTOOLS
873  haveCapability("gperftools", doc);
874 #else
875  missingCapability("gperftools",
876  doc,
877  "Check https://mooseframework.inl.gov/application_development/profiling.html "
878  "for instructions on profiling MOOSE based applications.");
879 #endif
880  }
881 
882  {
883  const auto doc = "libPNG portable network graphics format library";
884 #ifdef MOOSE_HAVE_LIBPNG
885  haveCapability("libpng", doc);
886 #else
887  missingCapability("libpng",
888  doc,
889  "Install libpng through conda or your distribution and check that it gets "
890  "detected through pkg-config, then reconfigure and rebuild MOOSE.");
891 #endif
892  }
893 
894  {
895  const auto doc = "NVIDIA GPU parallel computing platform";
896 #ifdef PETSC_HAVE_CUDA
897  haveCapability("cuda", doc);
898 #else
899  missingCapability("cuda", doc, "Add the CUDA bin directory to your path and rebuild PETSc.");
900 #endif
901  }
902 
903  {
904  const auto doc = "Kokkos performance portability programming ecosystem";
905 #ifdef MOOSE_KOKKOS_ENABLED
906  haveCapability("kokkos", doc);
907 #else
908  missingCapability("kokkos",
909  doc,
910  "Rebuild PETSc with Kokkos support and libMesh. Then, reconfigure MOOSE with "
911  "--with-kokkos.");
912 #endif
913  }
914 
915  {
916  const auto doc = "Kokkos support for PETSc";
917 #ifdef PETSC_HAVE_KOKKOS
918  haveCapability("petsc_kokkos", doc);
919 #else
920  missingCapability(
921  "kokkos", doc, "Rebuild PETSc with Kokkos support, then rebuild libMesh and MOOSE.");
922 #endif
923  }
924 
926  "ad_size",
927  MOOSE_AD_MAX_DOFS_PER_ELEM,
928  "MOOSE was configured and built with a dual number backing store size of " +
929  Moose::stringify(MOOSE_AD_MAX_DOFS_PER_ELEM) +
930  ". Complex simulations with many variables or contact problems may require larger "
931  "values. Reconfigure MOOSE with the --with-derivative-size=<n> option in the root of the "
932  "repository.");
933  {
934  const std::string method = QUOTE(METHOD);
935  addCapability("method", method, "The executable was built with METHOD=\"" + method + "\"");
936  }
937 
938  {
939  const std::string version = QUOTE(LIBMESH_DETECTED_PETSC_VERSION_MAJOR) "." QUOTE(
940  LIBMESH_DETECTED_PETSC_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR);
941  addCapability("petsc", version, "Using PETSc version " + version + ".");
942  }
943 
944 #ifdef LIBMESH_PETSC_USE_DEBUG
945  addCapability("petsc_debug", true, "PETSc was built with debugging options.");
946 #else
947  addCapability("petsc_debug", false, "PETSc was built without debugging options.");
948 #endif
949 
950  {
951  const auto doc = "SuperLU direct solver";
952 #ifdef LIBMESH_PETSC_HAVE_SUPERLU_DIST
953  haveCapability("superlu", doc);
954 #else
955  petscMissingCapability("superlu", doc);
956 #endif
957  }
958 
959  {
960  const auto doc = "MUltifrontal Massively Parallel sparse direct Solver (MUMPS)";
961 #ifdef LIBMESH_PETSC_HAVE_MUMPS
962  haveCapability("mumps", doc);
963 #else
964  petscMissingCapability("mumps", doc);
965 #endif
966  }
967 
968  {
969  const auto doc = "STRUMPACK - STRUctured Matrix PACKage solver library";
970 #ifdef LIBMESH_PETSC_HAVE_STRUMPACK
971  haveCapability("strumpack", doc);
972 #else
973  petscMissingCapability("strumpack", doc);
974 #endif
975  }
976 
977  {
978  const auto doc = "Parmetis partitioning library";
979 #if defined(LIBMESH_PETSC_HAVE_PARMETIS) || defined(LIBMESH_HAVE_PARMETIS)
980  haveCapability("parmetis", doc);
981 #else
982  petscMissingCapability("parmetis", doc);
983 #endif
984  }
985 
986  {
987  const auto doc = "Chaco graph partitioning library";
988 #ifdef LIBMESH_PETSC_HAVE_CHACO
989  haveCapability("chaco", doc);
990 #else
991  petscMissingCapability("chaco", doc);
992 #endif
993  }
994 
995  {
996  const auto doc = "Party matrix or graph partitioning library";
997 #ifdef LIBMESH_PETSC_HAVE_PARTY
998  haveCapability("party", doc);
999 #else
1000  petscMissingCapability("party", doc);
1001 #endif
1002  }
1003 
1004  {
1005  const auto doc = "PT-Scotch graph partitioning library";
1006 #ifdef LIBMESH_PETSC_HAVE_PTSCOTCH
1007  haveCapability("ptscotch", doc);
1008 #else
1009  petscMissingCapability("ptscotch", doc);
1010 #endif
1011  }
1012 
1013  {
1014  const auto doc = "Scalable Library for Eigenvalue Problem Computations (SLEPc)";
1015 #ifdef LIBMESH_HAVE_SLEPC
1016  const auto version = QUOTE(LIBMESH_DETECTED_SLEPC_VERSION_MAJOR) "." QUOTE(
1017  LIBMESH_DETECTED_SLEPC_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_SLEPC_VERSION_SUBMINOR);
1018  haveCapabilityVersion("slepc", doc, version);
1019 #else
1020  petscMissingCapability("slepc", doc);
1021 #endif
1022  }
1023 
1024  {
1025  const auto doc = "Exodus mesh file format library";
1026 #ifdef LIBMESH_HAVE_EXODUS_API
1027  const std::string version = QUOTE(LIBMESH_DETECTED_EXODUS_VERSION_MAJOR) "." QUOTE(
1028  LIBMESH_DETECTED_EXODUS_VERSION_MINOR);
1029  haveCapabilityVersion("exodus", doc, version);
1030 #else
1031  libmeshMissingCapability("exodus", doc, "--enable-exodus");
1032 #endif
1033  }
1034 
1035  {
1036  const auto doc = "Netgen meshing library";
1037 #ifdef LIBMESH_HAVE_NETGEN
1038  haveCapability("netgen", doc);
1039 #else
1040  libmeshMissingCapability("netgen", doc, "--enable-netgen");
1041 #endif
1042  }
1043 
1044  {
1045  const auto doc = "Visualization Toolkit (VTK)";
1046 #ifdef LIBMESH_HAVE_VTK
1047  const std::string version = QUOTE(LIBMESH_DETECTED_VTK_VERSION_MAJOR) "." QUOTE(
1048  LIBMESH_DETECTED_VTK_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_VTK_VERSION_SUBMINOR);
1049  haveCapabilityVersion("vtk", doc, version);
1050 #else
1051  libmeshMissingCapability("vtk", doc, "--disable-vtk and --enable-vtk-required");
1052 #endif
1053  }
1054 
1055  {
1056  const auto doc = "libcurl - the multiprotocol file transfer library";
1057 #ifdef LIBMESH_HAVE_CURL
1058  haveCapability("curl", doc);
1059 #else
1060  libmeshMissingCapability("curl", doc, "--enable-curl");
1061 #endif
1062  }
1063 
1064  {
1065  const auto doc = "Tecplot post-processing tools API";
1066 #ifdef LIBMESH_HAVE_TECPLOT_API
1067  haveCapability("tecplot", doc);
1068 #else
1069  libmeshMissingCapability("tecplot", doc, "--enable-tecplot");
1070 #endif
1071  }
1072 
1073  {
1074  const auto doc = "Boost C++ library";
1075 #ifdef LIBMESH_HAVE_EXTERNAL_BOOST
1076  haveCapability("boost", doc);
1077 #else
1078  libmeshMissingCapability("boost", doc, "--with-boost");
1079 #endif
1080  }
1081 
1082  // libmesh stuff
1083  {
1084  const auto doc = "Adaptive mesh refinement";
1085 #ifdef LIBMESH_ENABLE_AMR
1086  haveCapability("amr", doc);
1087 #else
1088  libmeshMissingCapability("amr", doc, "--disable-amr");
1089 #endif
1090  }
1091 
1092  {
1093  const auto doc = "nanoflann library for Nearest Neighbor (NN) search with KD-trees";
1094 #ifdef LIBMESH_HAVE_NANOFLANN
1095  haveCapability("nanoflann", doc);
1096 #else
1097  libmeshMissingCapability("nanoflann", doc, "--disable-nanoflann");
1098 #endif
1099  }
1100 
1101  {
1102  const auto doc = "sfcurves library for space filling curves (required by geometric "
1103  "partitioners such as SFCurves, Hilbert and Morton - not LGPL compatible)";
1104 #ifdef LIBMESH_HAVE_SFCURVES
1105  haveCapability("sfcurves", doc);
1106 #else
1107  libmeshMissingCapability("sfcurves", doc, "--disable-sfc");
1108 #endif
1109  }
1110 
1111 #ifdef LIBMESH_HAVE_FPARSER
1112 #ifdef LIBMESH_HAVE_FPARSER_JIT
1113  addCapability("fparser", "jit", "FParser enabled with just in time compilation support.");
1114 #else
1115  addCapability("fparser", "byte_code", "FParser enabled.");
1116 #endif
1117 #else
1118  addCapability("fparser",
1119  false,
1120  "FParser is disabled, libMesh was likely configured with --disable-fparser.");
1121 #endif
1122 
1123 #ifdef LIBMESH_HAVE_DLOPEN
1124  addCapability(
1125  "dlopen", true, "The dlopen() system call is available to dynamically load libraries.");
1126 #else
1127  addCapability("dlopen",
1128  false,
1129  "The dlopen() system call is not available. Dynamic library loading is "
1130  "not supported on this system.");
1131 #endif
1132 
1133  {
1134  const auto doc = "LibMesh support for threaded execution";
1135 #ifdef LIBMESH_USING_THREADS
1136  haveCapability("threads", doc);
1137 #else
1138  libmeshMissingCapability("threads", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
1139 #endif
1140  }
1141 
1142  {
1143  const auto doc = "OpenMP multi-platform shared-memory parallel programming API";
1144 #ifdef LIBMESH_HAVE_OPENMP
1145  haveCapability("openmp", doc);
1146 #else
1147  libmeshMissingCapability("openmp", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
1148 #endif
1149  }
1150  {
1151  const auto doc = "oneAPI Threading Building Blocks (TBB) API";
1152 #ifdef LIBMESH_HAVE_TBB_API
1153  haveCapability("tbb", doc);
1154 #else
1155  libmeshMissingCapability("tbb", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
1156 #endif
1157  }
1158 
1159  {
1160  const auto doc = "libMesh unique ID support";
1161 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1162  haveCapability("unique_id", doc);
1163 #else
1164  libmeshMissingCapability("unique_id", doc, "--enable-unique-id");
1165 #endif
1166  }
1167 
1168  {
1169  const auto doc = "libMesh default mesh mode";
1170 #ifdef LIBMESH_ENABLE_PARMESH
1171  addCapability("mesh_mode", "distributed", doc);
1172 #else
1173  addCapability("mesh_mode", "replicated", doc);
1174 #endif
1175  }
1176 
1177  addCapability("dof_id_bytes",
1178  static_cast<int>(sizeof(dof_id_type)),
1179  "Degree of freedom (DOF) identifiers use " + Moose::stringify(sizeof(dof_id_type)) +
1180  " bytes for storage. This is controlled by the "
1181  "--with-dof-id-bytes=<1|2|4|8> libMesh configure option.");
1182 
1183  // compiler
1184  {
1185  const auto doc = "Compiler used to build the MOOSE framework.";
1186 #if defined(__INTEL_LLVM_COMPILER)
1187  addCapability("compiler", "intel", doc);
1188 #elif defined(__clang__)
1189  addCapability("compiler", "clang", doc);
1190 #elif defined(__GNUC__) || defined(__GNUG__)
1191  addCapability("compiler", "gcc", doc);
1192 #elif defined(_MSC_VER)
1193  addCapability("compiler", "msvc", doc);
1194 #else
1195  addCapability("compiler", false, "Unknown compiler");
1196 #endif
1197  }
1198 
1199  // OS related
1200  {
1201  const auto doc = "Operating system this executable is running on.";
1202 #ifdef __APPLE__
1203  addCapability("platform", "darwin", doc);
1204 #elif __WIN32__
1205  addCapability("platform", "win32", doc);
1206 #elif __linux__
1207  addCapability("platform", "linux", doc);
1208 #elif __unix__ // all unices not caught above
1209  addCapability("platform", "unix", doc);
1210 #endif
1211  }
1212 }
1213 
1215 {
1216 #ifdef HAVE_GPERFTOOLS
1217  // CPU profiling stop
1218  if (_cpu_profiling)
1219  ProfilerStop();
1220  // Heap profiling stop
1221  if (_heap_profiling)
1222  HeapProfilerStop();
1223 #endif
1225  _the_warehouse.reset();
1226  _executioner.reset();
1227 
1228  // Don't wait for implicit destruction of input parameter storage
1230 
1231  // This is dirty, but I don't know what else to do. Obviously, others
1232  // have had similar problems if you look above. In specific, the
1233  // dlclose below on macs is destructing some data that does not
1234  // belong to it in garbage collection. So... don't even give
1235  // dlclose an option
1236  _restartable_data.clear();
1237 
1238  // Remove this app's parameters from the AppFactory. This allows
1239  // for creating an app with this name again in the same execution,
1240  // which needs to be done when resetting applications in MultiApp
1242 
1243 #ifdef LIBMESH_HAVE_DLOPEN
1244  // Close any open dynamic libraries
1245  for (const auto & lib_pair : _lib_handles)
1246  dlclose(lib_pair.second.library_handle);
1247 #endif
1248 
1249 #ifdef MOOSE_KOKKOS_ENABLED
1251 #endif
1252 }
1253 
1254 std::string
1256 {
1257  return MOOSE_VERSION;
1258 }
1259 
1260 std::string
1262 {
1263  return MOOSE_VERSION;
1264 }
1265 
1266 std::string
1268 {
1269  return getPrintableName() + " Version: " + getVersion();
1270 }
1271 
1272 void
1274 {
1275  TIME_SECTION("setupOptions", 5, "Setting Up Options");
1276 
1277  // Print the header, this is as early as possible
1278  if (header().length() && !getParam<bool>("suppress_header"))
1279  _console << header() << std::endl;
1280 
1281  if (getParam<bool>("error_unused"))
1282  setCheckUnusedFlag(true);
1283  else if (getParam<bool>("allow_unused"))
1284  setCheckUnusedFlag(false);
1285 
1286  if (getParam<bool>("error_override"))
1288 
1289  _distributed_mesh_on_command_line = getParam<bool>("distributed_mesh");
1290 
1291  if (getParam<bool>("trap_fpe"))
1292  {
1293  _trap_fpe = true;
1294  _perf_graph.setActive(false);
1295  if (getParam<bool>("no_trap_fpe"))
1296  mooseError("Cannot use both \"--trap-fpe\" and \"--no-trap-fpe\" flags.");
1297  }
1298  else if (getParam<bool>("no_trap_fpe"))
1299  _trap_fpe = false;
1300 
1301  // Turn all warnings in MOOSE to errors (almost see next logic block)
1302  Moose::_warnings_are_errors = getParam<bool>("error");
1303 
1304  // Deprecated messages can be toggled to errors independently from everything else.
1305  Moose::_deprecated_is_error = getParam<bool>("error_deprecated");
1306 
1307  if (isUltimateMaster()) // makes sure coloring isn't reset incorrectly in multi-app settings
1308  {
1309  // Set from command line
1310  auto color = getParam<MooseEnum>("color");
1311  if (!isParamSetByUser("color"))
1312  {
1313  // Set from deprecated --no-color
1314  if (getParam<bool>("no_color"))
1315  color = "off";
1316  // Set from environment
1317  else
1318  {
1319  char * c_color = std::getenv("MOOSE_COLOR");
1320  if (c_color)
1321  color.assign(std::string(c_color), "While assigning environment variable MOOSE_COLOR");
1322  }
1323  }
1324 
1325  if (color == "auto")
1326  Moose::setColorConsole(true);
1327  else if (color == "on")
1328  Moose::setColorConsole(true, true);
1329  else if (color == "off")
1330  Moose::setColorConsole(false);
1331  else
1332  mooseAssert(false, "Should not hit");
1333 
1334  // After setting color so that non-yellow deprecated is honored
1335  if (getParam<bool>("no_color"))
1336  mooseDeprecated("The --no-color flag is deprecated. Use '--color off' instead.");
1337  }
1338 
1339 // If there's no threading model active, but the user asked for
1340 // --n-threads > 1 on the command line, throw a mooseError. This is
1341 // intended to prevent situations where the user has potentially
1342 // built MOOSE incorrectly (neither TBB nor pthreads found) and is
1343 // asking for multiple threads, not knowing that there will never be
1344 // any threads launched.
1345 #if !LIBMESH_USING_THREADS
1346  if (libMesh::command_line_value("--n-threads", 1) > 1)
1347  mooseError("You specified --n-threads > 1, but there is no threading model active!");
1348 #endif
1349 
1350  // Build a minimal running application, ignoring the input file.
1351  if (getParam<bool>("minimal"))
1352  createMinimalApp();
1353 
1354  else if (getParam<bool>("display_version"))
1355  {
1356  Moose::out << getPrintableVersion() << std::endl;
1357  _early_exit_param = "--version";
1358  _ready_to_exit = true;
1359  return;
1360  }
1361  else if (getParam<bool>("help"))
1362  {
1363  _command_line->printUsage();
1364  _early_exit_param = "--help";
1365  _ready_to_exit = true;
1366  }
1367  else if (getParam<bool>("dump") || isParamSetByUser("dump_search"))
1368  {
1369  const std::string search =
1370  isParamSetByUser("dump_search") ? getParam<std::string>("dump_search") : "";
1371 
1372  JsonSyntaxTree tree(search);
1373 
1374  {
1375  TIME_SECTION("dump", 1, "Building Syntax Tree");
1377  }
1378 
1379  // Check if second arg is valid or not
1380  if ((tree.getRoot()).is_object())
1381  {
1382  // Turn off live printing so that it doesn't mess with the dump
1384 
1385  JsonInputFileFormatter formatter;
1386  Moose::out << "\n### START DUMP DATA ###\n"
1387  << formatter.toString(tree.getRoot()) << "\n### END DUMP DATA ###" << std::endl;
1388  _early_exit_param = "--dump";
1389  _ready_to_exit = true;
1390  }
1391  else
1392  mooseError("Search parameter '", search, "' was not found in the registered syntax.");
1393  }
1394  else if (getParam<bool>("registry"))
1395  {
1397 
1398  Moose::out << "Label\tType\tName\tClass\tFile\n";
1399 
1400  auto & objmap = Registry::allObjects();
1401  for (auto & entry : objmap)
1402  for (auto & obj : entry.second)
1403  Moose::out << entry.first << "\tobject\t" << obj->name() << "\t" << obj->_classname << "\t"
1404  << obj->_file << "\n";
1405 
1406  auto & actmap = Registry::allActions();
1407  for (auto & entry : actmap)
1408  {
1409  for (auto & act : entry.second)
1410  Moose::out << entry.first << "\taction\t" << act->_name << "\t" << act->_classname << "\t"
1411  << act->_file << "\n";
1412  }
1413  _early_exit_param = "--registry";
1414  _ready_to_exit = true;
1415  }
1416  else if (getParam<bool>("registry_hit"))
1417  {
1419 
1420  Moose::out << "### START REGISTRY DATA ###\n";
1421 
1422  hit::Section root("");
1423  auto sec = new hit::Section("registry");
1424  root.addChild(sec);
1425  auto objsec = new hit::Section("objects");
1426  sec->addChild(objsec);
1427 
1428  auto & objmap = Registry::allObjects();
1429  for (auto & entry : objmap)
1430  for (auto & obj : entry.second)
1431  {
1432  auto ent = new hit::Section("entry");
1433  objsec->addChild(ent);
1434  ent->addChild(new hit::Field("label", hit::Field::Kind::String, entry.first));
1435  ent->addChild(new hit::Field("type", hit::Field::Kind::String, "object"));
1436  ent->addChild(new hit::Field("name", hit::Field::Kind::String, obj->name()));
1437  ent->addChild(new hit::Field("class", hit::Field::Kind::String, obj->_classname));
1438  ent->addChild(new hit::Field("file", hit::Field::Kind::String, obj->_file));
1439  }
1440 
1441  auto actsec = new hit::Section("actions");
1442  sec->addChild(actsec);
1443  auto & actmap = Registry::allActions();
1444  for (auto & entry : actmap)
1445  for (auto & act : entry.second)
1446  {
1447  auto ent = new hit::Section("entry");
1448  actsec->addChild(ent);
1449  ent->addChild(new hit::Field("label", hit::Field::Kind::String, entry.first));
1450  ent->addChild(new hit::Field("type", hit::Field::Kind::String, "action"));
1451  ent->addChild(new hit::Field("task", hit::Field::Kind::String, act->_name));
1452  ent->addChild(new hit::Field("class", hit::Field::Kind::String, act->_classname));
1453  ent->addChild(new hit::Field("file", hit::Field::Kind::String, act->_file));
1454  }
1455 
1456  Moose::out << root.render();
1457 
1458  Moose::out << "\n### END REGISTRY DATA ###\n";
1459  _early_exit_param = "--registry_hit";
1460  _ready_to_exit = true;
1461  }
1462  else if (getParam<bool>("definition"))
1463  {
1465 
1466  JsonSyntaxTree tree("");
1468  SONDefinitionFormatter formatter;
1469  Moose::out << "%-START-SON-DEFINITION-%\n"
1470  << formatter.toString(tree.getRoot()) << "\n%-END-SON-DEFINITION-%\n";
1471  _early_exit_param = "--definition";
1472  _ready_to_exit = true;
1473  }
1474  else if (getParam<bool>("yaml") || isParamSetByUser("yaml_search"))
1475  {
1476  const std::string search =
1477  isParamSetByUser("yaml_search") ? getParam<std::string>("yaml_search") : "";
1479 
1481  _builder.buildFullTree(search);
1482 
1483  _early_exit_param = "--yaml";
1484  _ready_to_exit = true;
1485  }
1486  else if (getParam<bool>("json") || isParamSetByUser("json_search"))
1487  {
1488  const std::string search =
1489  isParamSetByUser("json_search") ? getParam<std::string>("json_search") : "";
1491 
1492  JsonSyntaxTree tree(search);
1494 
1496  "json", "**START JSON DATA**\n", "\n**END JSON DATA**", tree.getRoot().dump(2));
1497  _early_exit_param = "--json";
1498  _ready_to_exit = true;
1499  }
1500  else if (getParam<bool>("syntax"))
1501  {
1503 
1504  std::multimap<std::string, Syntax::ActionInfo> syntax = _syntax.getAssociatedActions();
1505  std::stringstream ss;
1506  for (const auto & it : syntax)
1507  ss << it.first << "\n";
1508  outputMachineReadableData("syntax", "**START SYNTAX DATA**\n", "**END SYNTAX DATA**", ss.str());
1509  _early_exit_param = "--syntax";
1510  _ready_to_exit = true;
1511  }
1512  else if (getParam<bool>("show_type"))
1513  {
1515 
1516  Moose::out << "MooseApp Type: " << type() << std::endl;
1517  _early_exit_param = "--show-type";
1518  _ready_to_exit = true;
1519  }
1520  else if (getParam<bool>("show_capabilities"))
1521  {
1523  outputMachineReadableData("show_capabilities",
1524  "**START JSON DATA**\n",
1525  "\n**END JSON DATA**",
1527  _ready_to_exit = true;
1528  }
1529  else if (isParamValid("check_capabilities"))
1530  {
1532  const auto & capabilities = getParam<std::string>("check_capabilities");
1533  auto [status, reason, doc] = Moose::Capabilities::getCapabilityRegistry().check(capabilities);
1534  const bool pass = status == CapabilityUtils::CERTAIN_PASS;
1535  _console << "Capabilities '" << capabilities << "' are " << (pass ? "" : "not ") << "fulfilled."
1536  << std::endl;
1537  _ready_to_exit = true;
1538  if (!pass)
1539  _exit_code = 77;
1540  return;
1541  }
1542  else if (!getInputFileNames().empty())
1543  {
1544  if (isParamSetByUser("recover"))
1545  {
1546  // We need to set the flag manually here since the recover parameter is a string type (takes
1547  // an optional filename)
1548  _recover = true;
1549  const auto & recover = getParam<std::string>("recover");
1550  if (recover.size())
1551  _restart_recover_base = recover;
1552  }
1553 
1554  _builder.build();
1555 
1556  if (isParamValid("required_capabilities"))
1557  {
1559 
1560  const auto required_capabilities = getParam<std::string>("required_capabilities");
1561  auto [status, reason, doc] =
1562  Moose::Capabilities::getCapabilityRegistry().check(required_capabilities);
1564  {
1565  mooseInfo("Required capabilities '", required_capabilities, "' not fulfilled.");
1566  _ready_to_exit = true;
1567  // we use code 77 as "skip" in the Testharness
1568  _exit_code = 77;
1569  return;
1570  }
1572  mooseError("Required capabilities '",
1573  required_capabilities,
1574  "' are not specific enough. A comparison test is performed on an undefined "
1575  "capability. Disambiguate this requirement by adding an existence/non-existence "
1576  "requirement. Example: 'unknown<1.2.3' should become 'unknown & unknown<1.2.3' "
1577  "or '!unknown | unknown<1.2.3'");
1578  }
1579 
1580  // Lambda to check for mutually exclusive parameters
1581  auto isExclusiveParamSetByUser =
1582  [this](const std::vector<std::string> & group, const std::string & param)
1583  {
1584  auto is_set = isParamSetByUser(param);
1585  if (is_set)
1586  for (const auto & p : group)
1587  if (p != param && isParamSetByUser(p))
1588  mooseError("Parameters '" + p + "' and '" + param +
1589  "' are mutually exclusive. Please choose only one of them.");
1590  return is_set;
1591  };
1592 
1593  // The following parameters set the final task and so are mutually exclusive.
1594  const std::vector<std::string> final_task_params = {
1595  "csg_only", "mesh_only", "split_mesh", "parse_neml2_only"};
1596  if (isExclusiveParamSetByUser(final_task_params, "csg_only"))
1597  {
1598  // Error checking on incompatible command line options
1600  mooseError("--csg-only cannot be used in conjunction with --distributed-mesh");
1601  const bool has_mesh_split = isParamSetByUser("split_file") || _use_split;
1602  if (has_mesh_split)
1603  mooseError("--csg-only is not compatible with any mesh splitting options");
1604  if (isParamSetByUser("refinements"))
1605  mooseError("--csg-only cannot be used in conjunction with -r refinements option");
1606  if (!isUltimateMaster())
1607  mooseError("--csg-only option cannot be used as a Subapp");
1608  if (_recover)
1609  mooseError("--csg-only option cannot be used in recovery mode");
1610 
1611  _syntax.registerTaskName("execute_csg_generators", true);
1612  _syntax.addDependency("execute_csg_generators", "execute_mesh_generators");
1613  _syntax.addDependency("recover_meta_data", "execute_csg_generators");
1614 
1615  _syntax.registerTaskName("csg_only", true);
1616  _syntax.addDependency("csg_only", "recover_meta_data");
1617  _syntax.addDependency("set_mesh_base", "csg_only");
1618  _action_warehouse.setFinalTask("csg_only");
1619  }
1620  else if (isExclusiveParamSetByUser(final_task_params, "mesh_only"))
1621  {
1622  // If we are looking to just check the input, there is no need to
1623  // call MeshOnlyAction and generate a mesh
1624  if (_check_input)
1625  _action_warehouse.setFinalTask("setup_mesh_complete");
1626  else
1627  {
1628  _syntax.registerTaskName("mesh_only", true);
1629  _syntax.addDependency("mesh_only", "setup_mesh_complete");
1630  _syntax.addDependency("determine_system_type", "mesh_only");
1631  _action_warehouse.setFinalTask("mesh_only");
1632  }
1633  }
1634  else if (isExclusiveParamSetByUser(final_task_params, "split_mesh"))
1635  {
1636  _split_mesh = true;
1637  _syntax.registerTaskName("split_mesh", true);
1638  _syntax.addDependency("split_mesh", "setup_mesh_complete");
1639  _syntax.addDependency("determine_system_type", "split_mesh");
1640  _action_warehouse.setFinalTask("split_mesh");
1641  }
1642  else if (isExclusiveParamSetByUser(final_task_params, "parse_neml2_only"))
1643  {
1644  _syntax.registerTaskName("parse_neml2");
1645  _syntax.addDependency("determine_system_type", "parse_neml2");
1646  _action_warehouse.setFinalTask("parse_neml2");
1647  }
1649 
1650  // Setup the AppFileBase for use by the Outputs or other systems that need output file info
1651  {
1652  // Extract the CommonOutputAction
1653  const auto common_actions = _action_warehouse.getActions<CommonOutputAction>();
1654  mooseAssert(common_actions.size() <= 1, "Should not be more than one CommonOutputAction");
1655  const Action * common = common_actions.empty() ? nullptr : *common_actions.begin();
1656 
1657  // If file_base is set in CommonOutputAction through parsing input, obtain the file_base
1658  if (common && common->isParamValid("file_base"))
1659  {
1660  _output_file_base = common->getParam<std::string>("file_base");
1661  _file_base_set_by_user = true;
1662  }
1663  else if (isUltimateMaster())
1664  {
1665  // if this app is a master, we use the first input file name as the default file base.
1666  // use proximate here because the input file is an absolute path
1667  const auto & base = getLastInputFileName();
1668  size_t pos = base.find_last_of('.');
1669  _output_file_base = base.substr(0, pos);
1670  // Note: we did not append "_out" in the file base here because we do not want to
1671  // have it in between the input file name and the object name for Output/*
1672  // syntax.
1673  }
1674  // default file base for multiapps is set by MultiApp
1675  }
1676  }
1677  // No input file provided but we have other arguments (so don't just show print usage)
1678  else if (!isParamSetByUser("input_file") && _command_line->getArguments().size() > 2)
1679  {
1680  mooseAssert(getInputFileNames().empty(), "Should be empty");
1681 
1682  if (_check_input)
1683  mooseError("You specified --check-input, but did not provide an input file. Add -i "
1684  "<inputfile> to your command line.");
1685 
1686  mooseError("No input files specified. Add -i <inputfile> to your command line.");
1687  }
1688  else if (isParamValid("language_server") && getParam<bool>("language_server"))
1689  {
1691 
1692  // Reset output to the buffer what was cached before it was turned it off
1693  if (!Moose::out.rdbuf() && _output_buffer_cache)
1694  Moose::out.rdbuf(_output_buffer_cache);
1695 
1696  // Start a language server that communicates using an iostream connection
1697  MooseServer moose_server(*this);
1698 
1699  moose_server.run();
1700 
1701  _early_exit_param = "--language-server";
1702  _ready_to_exit = true;
1703  }
1704 
1705  else /* The catch-all case for bad options or missing options, etc. */
1706  {
1707  _command_line->printUsage();
1708  _early_exit_param = "bad or missing";
1709  _ready_to_exit = true;
1710  _exit_code = 1;
1711  }
1712 
1713 #ifdef MOOSE_KOKKOS_ENABLED
1714  for (auto & action : _action_warehouse.allActionBlocks())
1715  if (action->isParamValid("_kokkos_action"))
1716  _has_kokkos_objects = true;
1717 #endif
1718 
1719  Moose::out << std::flush;
1720 }
1721 
1722 const std::vector<std::string> &
1724 {
1725  mooseAssert(_parser, "Parser is not set");
1726  return _parser->getInputFileNames();
1727 }
1728 
1729 const std::string &
1731 {
1732  mooseAssert(_parser, "Parser is not set");
1733  return _parser->getLastInputFileName();
1734 }
1735 
1736 std::string
1737 MooseApp::getOutputFileBase(bool for_non_moose_build_output) const
1738 {
1739  if (_file_base_set_by_user || for_non_moose_build_output || _multiapp_level)
1740  return _output_file_base;
1741  else
1742  return _output_file_base + "_out";
1743 }
1744 
1745 void
1746 MooseApp::setOutputFileBase(const std::string & output_file_base)
1747 {
1748  _output_file_base = output_file_base;
1749 
1750  // Reset the file base in the outputs
1752 
1753  // Reset the file base in multiapps (if they have been constructed yet)
1754  if (getExecutioner())
1755  for (auto & multi_app : feProblem().getMultiAppWarehouse().getObjects())
1756  multi_app->setAppOutputFileBase();
1757 
1758  _file_base_set_by_user = true;
1759 }
1760 
1761 void
1763 {
1764  TIME_SECTION("runInputFile", 3);
1765 
1766  // If early exit param has been set, then just return
1767  if (_ready_to_exit)
1768  return;
1769 
1771 
1772  if (isParamSetByUser("csg_only"))
1773  {
1774  _early_exit_param = "--csg-only";
1775  _ready_to_exit = true;
1776  }
1777  else if (isParamSetByUser("mesh_only"))
1778  {
1779  _early_exit_param = "--mesh-only";
1780  _ready_to_exit = true;
1781  }
1782  else if (isParamSetByUser("split_mesh"))
1783  {
1784  _early_exit_param = "--split-mesh";
1785  _ready_to_exit = true;
1786  }
1787  else if (isParamSetByUser("parse_neml2_only"))
1788  {
1789  _early_exit_param = "--parse-neml2-only";
1790  _ready_to_exit = true;
1791  }
1792  else if (getParam<bool>("list_constructed_objects"))
1793  {
1794  // TODO: ask multiapps for their constructed objects
1795  _early_exit_param = "--list-constructed-objects";
1796  _ready_to_exit = true;
1797  std::stringstream ss;
1798  for (const auto & obj : _factory.getConstructedObjects())
1799  ss << obj << '\n';
1801  "list_constructed_objects", "**START OBJECT DATA**\n", "\n**END OBJECT DATA**", ss.str());
1802  }
1803 }
1804 
1805 void
1807 {
1808  bool warn = _enable_unused_check == WARN_UNUSED;
1810 
1811  _builder.errorCheck(*_comm, warn, err);
1812 
1813  // Return early for mesh only mode, since we want error checking to run even though
1814  // an executor is not created for this case
1815  if (isParamSetByUser("mesh_only"))
1816  return;
1817 
1818  if (!_executor.get() && !_executioner.get())
1819  {
1820  if (!_early_exit_param.empty())
1821  {
1822  mooseAssert(_check_input,
1823  "Something went wrong, we should only get here if _check_input is true.");
1824  mooseError(
1825  "Incompatible command line arguments provided. --check-input cannot be called with ",
1827  ".");
1828  }
1829  // We should never get here
1830  mooseError("The Executor is being called without being initialized. This is likely "
1831  "caused by "
1832  "incompatible command line arguments");
1833  }
1834 
1835  auto apps = feProblem().getMultiAppWarehouse().getObjects();
1836  for (auto app : apps)
1837  for (unsigned int i = 0; i < app->numLocalApps(); i++)
1838  app->localApp(i)->errorCheck();
1839 }
1840 
1841 void
1843 {
1844  TIME_SECTION("executeExecutioner", 3);
1845 
1846  // If ready to exit has been set, then just return
1847  if (_ready_to_exit)
1848  return;
1849 
1850  // run the simulation
1851  if (_use_executor && _executor)
1852  {
1853  LibmeshPetscCall(Moose::PetscSupport::petscSetupOutput(_command_line.get()));
1854  _executor->init();
1855  errorCheck();
1856  auto result = _executor->exec();
1857  if (!result.convergedAll())
1858  mooseError(result.str());
1859  }
1860  else if (_executioner)
1861  {
1862  LibmeshPetscCall(Moose::PetscSupport::petscSetupOutput(_command_line.get()));
1863  _executioner->init();
1864  errorCheck();
1865  _executioner->execute();
1866  if (!_executioner->lastSolveConverged())
1867  setExitCode(1);
1868  }
1869  else
1870  mooseError("No executioner was specified (go fix your input file)");
1871 }
1872 
1873 bool
1875 {
1876  return _recover;
1877 }
1878 
1879 bool
1881 {
1882  return _restart;
1883 }
1884 
1885 bool
1887 {
1888  return _split_mesh;
1889 }
1890 
1891 bool
1893 {
1894  return !_restart_recover_base.empty();
1895 }
1896 
1897 bool
1899 {
1900  mooseDeprecated("MooseApp::hasRecoverFileBase is deprecated, use "
1901  "MooseApp::hasRestartRecoverFileBase() instead.");
1902  return !_restart_recover_base.empty();
1903 }
1904 
1905 void
1908 {
1910  switch (filter)
1911  {
1912  case RESTARTABLE_FILTER::RECOVERABLE:
1913  _recoverable_data_names.insert(name);
1914  break;
1915  default:
1916  mooseError("Unknown filter");
1917  }
1918 }
1919 
1920 std::vector<std::filesystem::path>
1921 MooseApp::backup(const std::filesystem::path & folder_base)
1922 {
1923  TIME_SECTION("backup", 2, "Backing Up Application to File");
1924 
1925  preBackup();
1926 
1928  return writer.write(folder_base);
1929 }
1930 
1931 std::unique_ptr<Backup>
1933 {
1934  TIME_SECTION("backup", 2, "Backing Up Application");
1935 
1937 
1938  preBackup();
1939 
1940  auto backup = std::make_unique<Backup>();
1941  writer.write(*backup->header, *backup->data);
1942 
1943  return backup;
1944 }
1945 
1946 void
1947 MooseApp::restore(const std::filesystem::path & folder_base, const bool for_restart)
1948 {
1949  TIME_SECTION("restore", 2, "Restoring Application from File");
1950 
1951  const DataNames filter_names = for_restart ? getRecoverableData() : DataNames{};
1952 
1953  _rd_reader.setInput(folder_base);
1954  _rd_reader.restore(filter_names);
1955 
1956  postRestore(for_restart);
1957 }
1958 
1959 void
1960 MooseApp::restore(std::unique_ptr<Backup> backup, const bool for_restart)
1961 {
1962  TIME_SECTION("restore", 2, "Restoring Application");
1963 
1964  const DataNames filter_names = for_restart ? getRecoverableData() : DataNames{};
1965 
1966  if (!backup)
1967  mooseError("MooseApp::restore(): Provided backup is not initialized");
1968 
1969  auto header = std::move(backup->header);
1970  mooseAssert(header, "Header not available");
1971 
1972  auto data = std::move(backup->data);
1973  mooseAssert(data, "Data not available");
1974 
1975  _rd_reader.setInput(std::move(header), std::move(data));
1976  _rd_reader.restore(filter_names);
1977 
1978  postRestore(for_restart);
1979 }
1980 
1981 void
1982 MooseApp::restoreFromInitialBackup(const bool for_restart)
1983 {
1984  mooseAssert(hasInitialBackup(), "Missing initial backup");
1985  restore(std::move(*_initial_backup), for_restart);
1986 }
1987 
1988 std::unique_ptr<Backup>
1990 {
1991  if (!_rd_reader.isRestoring())
1992  mooseError("MooseApp::finalizeRestore(): Not currently restoring");
1993 
1994  // This gives us access to the underlying streams so that we can return it if needed
1995  auto input_streams = _rd_reader.clear();
1996 
1997  std::unique_ptr<Backup> backup;
1998 
1999  // Give them back a backup if this restore started from a Backup, in which case
2000  // the two streams in the Backup are formed into StringInputStreams
2001  if (auto header_string_input = dynamic_cast<StringInputStream *>(input_streams.header.get()))
2002  {
2003  auto data_string_input = dynamic_cast<StringInputStream *>(input_streams.data.get());
2004  mooseAssert(data_string_input, "Should also be a string input");
2005 
2006  auto header_sstream = header_string_input->release();
2007  mooseAssert(header_sstream, "Header not available");
2008 
2009  auto data_sstream = data_string_input->release();
2010  mooseAssert(data_sstream, "Data not available");
2011 
2012  backup = std::make_unique<Backup>();
2013  backup->header = std::move(header_sstream);
2014  backup->data = std::move(data_sstream);
2015  }
2016 
2017  return backup;
2018 }
2019 
2020 void
2021 MooseApp::setCheckUnusedFlag(bool warn_is_error)
2022 {
2023  _enable_unused_check = warn_is_error ? ERROR_UNUSED : WARN_UNUSED;
2024 }
2025 
2026 void
2028 {
2030 }
2031 
2032 FEProblemBase &
2034 {
2035  mooseAssert(_executor.get() || _executioner.get(), "No executioner yet, calling too early!");
2036  return _executor.get() ? _executor->feProblem() : _executioner->feProblem();
2037 }
2038 
2039 void
2040 MooseApp::addExecutor(const std::string & type,
2041  const std::string & name,
2042  const InputParameters & params)
2043 {
2044  std::shared_ptr<Executor> executor = _factory.create<Executor>(type, name, params);
2045 
2046  if (_executors.count(executor->name()) > 0)
2047  mooseError("an executor with name '", executor->name(), "' already exists");
2048  _executors[executor->name()] = executor;
2049 }
2050 
2051 void
2052 MooseApp::addExecutorParams(const std::string & type,
2053  const std::string & name,
2054  const InputParameters & params)
2055 {
2056  _executor_params[name] = std::make_pair(type, std::make_unique<InputParameters>(params));
2057 }
2058 
2059 const Parser &
2061 {
2062  mooseAssert(_parser, "Not set");
2063  return *_parser;
2064 }
2065 
2066 Parser &
2068 {
2069  return const_cast<Parser &>(std::as_const(*this).parser());
2070 }
2071 
2072 void
2073 MooseApp::recursivelyCreateExecutors(const std::string & current_executor_name,
2074  std::list<std::string> & possible_roots,
2075  std::list<std::string> & current_branch)
2076 {
2077  // Did we already make this one?
2078  if (_executors.find(current_executor_name) != _executors.end())
2079  return;
2080 
2081  // Is this one already on the current branch (i.e. there is a cycle)
2082  if (std::find(current_branch.begin(), current_branch.end(), current_executor_name) !=
2083  current_branch.end())
2084  {
2085  std::stringstream exec_names_string;
2086 
2087  auto branch_it = current_branch.begin();
2088 
2089  exec_names_string << *branch_it++;
2090 
2091  for (; branch_it != current_branch.end(); ++branch_it)
2092  exec_names_string << ", " << *branch_it;
2093 
2094  exec_names_string << ", " << current_executor_name;
2095 
2096  mooseError("Executor cycle detected: ", exec_names_string.str());
2097  }
2098 
2099  current_branch.push_back(current_executor_name);
2100 
2101  // Build the dependencies first
2102  const auto & params = *_executor_params[current_executor_name].second;
2103 
2104  for (const auto & param : params)
2105  {
2106  if (params.have_parameter<ExecutorName>(param.first))
2107  {
2108  const auto & dependency_name = params.get<ExecutorName>(param.first);
2109 
2110  possible_roots.remove(dependency_name);
2111 
2112  if (!dependency_name.empty())
2113  recursivelyCreateExecutors(dependency_name, possible_roots, current_branch);
2114  }
2115  }
2116 
2117  // Add this Executor
2118  const auto & type = _executor_params[current_executor_name].first;
2119  addExecutor(type, current_executor_name, params);
2120 
2121  current_branch.pop_back();
2122 }
2123 
2124 void
2126 {
2127  // Do we have any?
2128  if (_executor_params.empty())
2129  return;
2130 
2131  // Holds the names of Executors that may be the root executor
2132  std::list<std::string> possibly_root;
2133 
2134  // What is already built
2135  std::map<std::string, bool> already_built;
2136 
2137  // The Executors that are currently candidates for being roots
2138  std::list<std::string> possible_roots;
2139 
2140  // The current line of dependencies - used for finding cycles
2141  std::list<std::string> current_branch;
2142 
2143  // Build the NullExecutor
2144  {
2145  auto params = _factory.getValidParams("NullExecutor");
2146  _null_executor = _factory.create<NullExecutor>("NullExecutor", "_null_executor", params);
2147  }
2148 
2149  for (const auto & params_entry : _executor_params)
2150  {
2151  const auto & name = params_entry.first;
2152 
2153  // Did we already make this one?
2154  if (_executors.find(name) != _executors.end())
2155  continue;
2156 
2157  possible_roots.emplace_back(name);
2158 
2159  recursivelyCreateExecutors(name, possible_roots, current_branch);
2160  }
2161 
2162  // If there is more than one possible root - error
2163  if (possible_roots.size() > 1)
2164  {
2165  auto root_string_it = possible_roots.begin();
2166 
2167  std::stringstream roots_string;
2168 
2169  roots_string << *root_string_it++;
2170 
2171  for (; root_string_it != possible_roots.end(); ++root_string_it)
2172  roots_string << ", " << *root_string_it;
2173 
2174  mooseError("Multiple Executor roots found: ", roots_string.str());
2175  }
2176 
2177  // Set the root executor
2178  _executor = _executors[possible_roots.front()];
2179 }
2180 
2181 Executor &
2182 MooseApp::getExecutor(const std::string & name, bool fail_if_not_found)
2183 {
2184  auto it = _executors.find(name);
2185 
2186  if (it != _executors.end())
2187  return *it->second;
2188 
2189  if (fail_if_not_found)
2190  mooseError("Executor not found: ", name);
2191 
2192  return *_null_executor;
2193 }
2194 
2195 Executioner *
2197 {
2198  return _executioner.get() ? _executioner.get() : _executor.get();
2199 }
2200 
2201 void
2203 {
2204  _error_overridden = true;
2205 }
2206 
2207 void
2209 {
2210  TIME_SECTION("run", 3);
2211  if (getParam<bool>("show_docs"))
2212  {
2213  auto binname = appBinaryName();
2214  if (binname == "")
2215  mooseError("could not locate installed tests to run (unresolved binary/app name)");
2216  auto docspath = MooseUtils::docsDir(binname);
2217  if (docspath == "")
2218  mooseError("no installed documentation found");
2219 
2220  auto docmsgfile = MooseUtils::pathjoin(docspath, "docmsg.txt");
2221  std::string docmsg = "file://" + MooseUtils::realpath(docspath) + "/index.html";
2222  if (MooseUtils::pathExists(docmsgfile) && MooseUtils::checkFileReadable(docmsgfile))
2223  {
2224  std::ifstream ifs(docmsgfile);
2225  std::string content((std::istreambuf_iterator<char>(ifs)),
2226  (std::istreambuf_iterator<char>()));
2227  content.replace(content.find("$LOCAL_SITE_HOME"), content.length(), docmsg);
2228  docmsg = content;
2229  }
2230 
2231  Moose::out << docmsg << "\n";
2232  _early_exit_param = "--docs";
2233  _ready_to_exit = true;
2234  return;
2235  }
2236 
2237  if (showInputs() || copyInputs() || runInputs())
2238  {
2239  _early_exit_param = "--show-input, --copy-inputs, or --run";
2240  _ready_to_exit = true;
2241  return;
2242  }
2243 
2244  try
2245  {
2246  TIME_SECTION("setup", 2, "Setting Up");
2247  setupOptions();
2248  runInputFile();
2249  }
2250  catch (Parser::Error & err)
2251  {
2252  mooseAssert(_parser->getThrowOnError(), "Should be true");
2253  throw err;
2254  }
2255  catch (MooseRuntimeError & err)
2256  {
2257  mooseAssert(Moose::_throw_on_error, "Should be true");
2258  throw err;
2259  }
2260  catch (std::exception & err)
2261  {
2262  mooseError(err.what());
2263  }
2264 
2265  if (!_check_input)
2266  {
2267  TIME_SECTION("execute", 2, "Executing");
2269  }
2270  else
2271  {
2272  errorCheck();
2273  // Output to stderr, so it is easier for peacock to get the result
2274  Moose::err << "Syntax OK" << std::endl;
2275  }
2276 }
2277 
2278 bool
2280 {
2281  if (getParam<bool>("show_inputs"))
2282  {
2283  const auto show_inputs_syntax = _pars.getCommandLineMetadata("show_inputs").switches;
2284  std::vector<std::string> dirs;
2285  const auto installable_inputs = getInstallableInputs();
2286 
2287  if (installable_inputs == "")
2288  {
2289  Moose::out
2290  << "Show inputs has not been overriden in this application.\nContact the developers of "
2291  "this appication and request that they override \"MooseApp::getInstallableInputs\".\n";
2292  }
2293  else
2294  {
2295  mooseAssert(!show_inputs_syntax.empty(), "show_inputs sytnax should not be empty");
2296 
2297  MooseUtils::tokenize(installable_inputs, dirs, 1, " ");
2298  Moose::out << "The following directories are installable into a user-writeable directory:\n\n"
2299  << installable_inputs << '\n'
2300  << "\nTo install one or more directories of inputs, execute the binary with the \""
2301  << show_inputs_syntax[0] << "\" flag. e.g.:\n$ "
2302  << _command_line->getExecutableName() << ' ' << show_inputs_syntax[0] << ' '
2303  << dirs[0] << '\n';
2304  }
2305  return true;
2306  }
2307  return false;
2308 }
2309 
2310 std::string
2312 {
2313  return "tests";
2314 }
2315 
2316 bool
2318 {
2319  if (isParamSetByUser("copy_inputs"))
2320  {
2321  if (comm().size() > 1)
2322  mooseError("The --copy-inputs option should not be ran in parallel");
2323 
2324  // Get command line argument following --copy-inputs on command line
2325  auto dir_to_copy = getParam<std::string>("copy_inputs");
2326 
2327  if (dir_to_copy.empty())
2328  mooseError("Error retrieving directory to copy");
2329  if (dir_to_copy.back() != '/')
2330  dir_to_copy += '/';
2331 
2332  // This binary name is the actual binary. That is, if we called a symlink it'll
2333  // be the name of what the symlink points to
2334  auto binname = appBinaryName();
2335  if (binname == "")
2336  mooseError("could not locate installed tests to run (unresolved binary/app name)");
2337 
2338  auto src_dir = MooseUtils::installedInputsDir(
2339  binname,
2340  dir_to_copy,
2341  "Rerun binary with " + _pars.getCommandLineMetadata("show_inputs").switches[0] +
2342  " to get a list of installable directories.");
2343 
2344  // Use the command line here because if we have a symlink to another binary,
2345  // we want to dump into a directory that is named after the symlink not the true binary
2346  auto dst_dir = _command_line->getExecutableNameBase() + "/" + dir_to_copy;
2347  auto cmdname = _command_line->getExecutableName();
2348  if (cmdname.find_first_of("/") != std::string::npos)
2349  cmdname = cmdname.substr(cmdname.find_first_of("/") + 1, std::string::npos);
2350 
2351  if (MooseUtils::pathExists(dst_dir))
2352  mooseError(
2353  "The directory \"./",
2354  dst_dir,
2355  "\" already exists.\nTo update/recopy the contents of this directory, rename (\"mv ",
2356  dst_dir,
2357  " new_dir_name\") or remove (\"rm -r ",
2358  dst_dir,
2359  "\") the existing directory.\nThen re-run \"",
2360  cmdname,
2361  " --copy-inputs ",
2362  dir_to_copy,
2363  "\".");
2364 
2365  std::string cmd = "mkdir -p " + dst_dir + "; rsync -av " + src_dir + " " + dst_dir;
2366 
2367  TIME_SECTION("copy_inputs", 2, "Copying Inputs");
2368 
2369  mooseAssert(comm().size() == 1, "Should be run in serial");
2370  const auto return_value = system(cmd.c_str());
2371  if (!WIFEXITED(return_value))
2372  mooseError("Process exited unexpectedly");
2373  setExitCode(WEXITSTATUS(return_value));
2374  if (exitCode() == 0)
2375  Moose::out << "Directory successfully copied into ./" << dst_dir << '\n';
2376  return true;
2377  }
2378  return false;
2379 }
2380 
2381 bool
2383 {
2384  if (isParamSetByUser("run"))
2385  {
2386  if (comm().size() > 1)
2387  mooseError("The --run option should not be ran in parallel");
2388 
2389  // Pass everything after --run on the cli to the TestHarness
2390  const auto find_run_it = std::as_const(*_command_line).findCommandLineParam("run");
2391  const auto & cl_entries = std::as_const(*_command_line).getEntries();
2392  mooseAssert(find_run_it != cl_entries.end(), "Didn't find the option");
2393  std::string test_args;
2394  for (auto it = std::next(find_run_it); it != cl_entries.end(); ++it)
2395  for (const auto & arg : it->raw_args)
2396  {
2397  test_args += " " + arg;
2399  }
2400 
2401  auto working_dir = MooseUtils::getCurrentWorkingDir();
2402  if (MooseUtils::findTestRoot() == "")
2403  {
2404  auto bin_name = appBinaryName();
2405  if (bin_name == "")
2406  mooseError("Could not locate binary name relative to installed location");
2407 
2408  auto cmd_name = Moose::getExecutableName();
2409  mooseError(
2410  "Could not locate installed tests from the current working directory:",
2411  working_dir,
2412  ".\nMake sure you are executing this command from within a writable installed inputs ",
2413  "directory.\nRun \"",
2414  cmd_name,
2415  " --copy-inputs <dir>\" to copy the contents of <dir> to a \"./",
2416  bin_name,
2417  "_<dir>\" directory.\nChange into that directory and try \"",
2418  cmd_name,
2419  " --run <dir>\" again.");
2420  }
2421 
2422  // Set this application as the app name for the moose_test_runner script that we're running
2423  setenv("MOOSE_TEST_RUNNER_APP_NAME", appBinaryName().c_str(), true);
2424 
2425  const std::string cmd = MooseUtils::runTestsExecutable() + test_args;
2426  Moose::out << "Working Directory: " << working_dir << "\nRunning Command: " << cmd << std::endl;
2427  mooseAssert(comm().size() == 1, "Should be run in serial");
2428  const auto return_value = system(cmd.c_str());
2429  if (!WIFEXITED(return_value))
2430  mooseError("Process exited unexpectedly");
2431  setExitCode(WEXITSTATUS(return_value));
2432  return true;
2433  }
2434 
2435  return false;
2436 }
2437 
2438 void
2439 MooseApp::checkReservedCapability(const std::string & capability)
2440 {
2441  // The list of these capabilities should match those within
2442  // Tester.checkRunnableBase() in the TestHarness
2443  static const std::set<std::string> reserved{
2444  "scale_refine", "valgrind", "recover", "heavy", "mpi_procs", "num_threads", "compute_device"};
2445  if (reserved.count(capability))
2446  ::mooseError("MooseApp::addCapability(): The capability \"",
2447  capability,
2448  "\" is reserved and may not be registered by an application.");
2449 }
2450 
2451 void
2453 {
2454  _output_position_set = true;
2455  _output_position = p;
2457 
2458  if (_executioner.get())
2459  _executioner->parentOutputPositionChanged();
2460 }
2461 
2462 std::list<std::string>
2464 {
2465  // Storage for the directory names
2466  std::list<std::string> checkpoint_dirs;
2467 
2468  // Add the directories added with Outputs/checkpoint=true input syntax
2469  checkpoint_dirs.push_back(getOutputFileBase() + "_cp");
2470 
2471  // Add the directories from any existing checkpoint output objects
2472  const auto & actions = _action_warehouse.getActionListByName("add_output");
2473  for (const auto & action : actions)
2474  {
2475  // Get the parameters from the MooseObjectAction
2476  MooseObjectAction * moose_object_action = dynamic_cast<MooseObjectAction *>(action);
2477  if (!moose_object_action)
2478  continue;
2479 
2480  const InputParameters & params = moose_object_action->getObjectParams();
2481  if (moose_object_action->getParam<std::string>("type") == "Checkpoint")
2482  {
2483  // Unless file_base was explicitly set by user, we cannot rely on it, as it will be changed
2484  // later
2485  const std::string cp_dir =
2486  _file_base_set_by_user ? params.get<std::string>("file_base")
2487  : (getOutputFileBase(true) + "_" + moose_object_action->name());
2488  checkpoint_dirs.push_back(cp_dir + "_cp");
2489  }
2490  }
2491  return checkpoint_dirs;
2492 }
2493 
2494 std::list<std::string>
2496 {
2497  auto checkpoint_dirs = getCheckpointDirectories();
2498  return MooseUtils::getFilesInDirs(checkpoint_dirs, false);
2499 }
2500 
2501 void
2503 {
2504  _start_time_set = true;
2505  _start_time = time;
2506 }
2507 
2508 std::string
2509 MooseApp::getFileName(bool stripLeadingPath) const
2510 {
2511  return _builder.getPrimaryFileName(stripLeadingPath);
2512 }
2513 
2516 {
2517  return _output_warehouse;
2518 }
2519 
2520 const OutputWarehouse &
2522 {
2523  return _output_warehouse;
2524 }
2525 
2526 std::string
2527 MooseApp::appNameToLibName(const std::string & app_name) const
2528 {
2529  std::string library_name(app_name);
2530 
2531  // Strip off the App part (should always be the last 3 letters of the name)
2532  size_t pos = library_name.find("App");
2533  if (pos != library_name.length() - 3)
2534  mooseError("Invalid application name: ", library_name);
2535  library_name.erase(pos);
2536 
2537  // Now get rid of the camel case, prepend lib, and append the method and suffix
2538  return std::string("lib") + MooseUtils::camelCaseToUnderscore(library_name) + '-' +
2539  QUOTE(METHOD) + ".la";
2540 }
2541 
2542 std::string
2543 MooseApp::libNameToAppName(const std::string & library_name) const
2544 {
2545  std::string app_name(library_name);
2546 
2547  // Strip off the leading "lib" and trailing ".la"
2548  if (pcrecpp::RE("lib(.+?)(?:-\\w+)?\\.la").Replace("\\1", &app_name) == 0)
2549  mooseError("Invalid library name: ", app_name);
2550 
2551  return MooseUtils::underscoreToCamelCase(app_name, true);
2552 }
2553 
2555 MooseApp::registerRestartableData(std::unique_ptr<RestartableDataValue> data,
2556  THREAD_ID tid,
2557  bool read_only,
2558  const RestartableDataMapName & metaname)
2559 {
2560  if (!metaname.empty() && tid != 0)
2561  mooseError(
2562  "The meta data storage for '", metaname, "' is not threaded, so the tid must be zero.");
2563 
2564  mooseAssert(metaname.empty() ||
2565  _restartable_meta_data.find(metaname) != _restartable_meta_data.end(),
2566  "The desired meta data name does not exist: " + metaname);
2567 
2568  // Select the data store for saving this piece of restartable data (mesh or everything else)
2569  auto & data_map =
2570  metaname.empty() ? _restartable_data[tid] : _restartable_meta_data[metaname].first;
2571 
2572  RestartableDataValue * stored_data = data_map.findData(data->name());
2573  if (stored_data)
2574  {
2575  if (data->typeId() != stored_data->typeId())
2576  mooseError("Type mismatch found in RestartableData registration of '",
2577  data->name(),
2578  "'\n\n Stored type: ",
2579  stored_data->type(),
2580  "\n New type: ",
2581  data->type());
2582  }
2583  else
2584  stored_data = &data_map.addData(std::move(data));
2585 
2586  if (!read_only)
2587  stored_data->setDeclared({});
2588 
2589  return *stored_data;
2590 }
2591 
2593 MooseApp::registerRestartableData(const std::string & libmesh_dbg_var(name),
2594  std::unique_ptr<RestartableDataValue> data,
2595  THREAD_ID tid,
2596  bool read_only,
2597  const RestartableDataMapName & metaname)
2598 {
2599  mooseDeprecated("The use of MooseApp::registerRestartableData with a data name is "
2600  "deprecated.\n\nUse the call without a name instead.");
2601 
2602  mooseAssert(name == data->name(), "Inconsistent name");
2603  return registerRestartableData(std::move(data), tid, read_only, metaname);
2604 }
2605 
2606 bool
2607 MooseApp::hasRestartableMetaData(const std::string & name,
2608  const RestartableDataMapName & metaname) const
2609 {
2610  auto it = _restartable_meta_data.find(metaname);
2611  if (it == _restartable_meta_data.end())
2612  return false;
2613  return it->second.first.hasData(name);
2614 }
2615 
2617 MooseApp::getRestartableMetaData(const std::string & name,
2618  const RestartableDataMapName & metaname,
2619  THREAD_ID tid)
2620 {
2621  if (tid != 0)
2622  mooseError(
2623  "The meta data storage for '", metaname, "' is not threaded, so the tid must be zero.");
2624 
2625  // Get metadata reference from RestartableDataMap and return a (non-const) reference to its value
2626  auto & restartable_data_map = getRestartableDataMap(metaname);
2627  RestartableDataValue * const data = restartable_data_map.findData(name);
2628  if (!data)
2629  mooseError("Unable to find RestartableDataValue object with name " + name +
2630  " in RestartableDataMap");
2631 
2632  return *data;
2633 }
2634 
2635 void
2637  const std::filesystem::path & folder_base)
2638 {
2639  const auto & map_name = getRestartableDataMapName(name);
2640  const auto meta_data_folder_base = metaDataFolderBase(folder_base, map_name);
2641  if (RestartableDataReader::isAvailable(meta_data_folder_base))
2642  {
2645  reader.setInput(meta_data_folder_base);
2646  reader.restore();
2647  }
2648 }
2649 
2650 void
2651 MooseApp::loadRestartableMetaData(const std::filesystem::path & folder_base)
2652 {
2653  for (const auto & name_map_pair : _restartable_meta_data)
2654  possiblyLoadRestartableMetaData(name_map_pair.first, folder_base);
2655 }
2656 
2657 std::vector<std::filesystem::path>
2659  const std::filesystem::path & folder_base)
2660 {
2661  if (processor_id() != 0)
2662  mooseError("MooseApp::writeRestartableMetaData(): Should only run on processor 0");
2663 
2664  const auto & map_name = getRestartableDataMapName(name);
2665  const auto meta_data_folder_base = metaDataFolderBase(folder_base, map_name);
2666 
2668  return writer.write(meta_data_folder_base);
2669 }
2670 
2671 std::vector<std::filesystem::path>
2672 MooseApp::writeRestartableMetaData(const std::filesystem::path & folder_base)
2673 {
2674  std::vector<std::filesystem::path> paths;
2675 
2676  if (processor_id() == 0)
2677  for (const auto & name_map_pair : _restartable_meta_data)
2678  {
2679  const auto map_paths = writeRestartableMetaData(name_map_pair.first, folder_base);
2680  paths.insert(paths.end(), map_paths.begin(), map_paths.end());
2681  }
2682 
2683  return paths;
2684 }
2685 
2686 void
2687 MooseApp::dynamicAppRegistration(const std::string & app_name,
2688  std::string library_path,
2689  const std::string & library_name,
2690  bool lib_load_deps)
2691 {
2692 #ifdef LIBMESH_HAVE_DLOPEN
2693  Parameters params;
2694  params.set<std::string>("app_name") = app_name;
2695  params.set<RegistrationType>("reg_type") = APPLICATION;
2696  params.set<std::string>("registration_method") = app_name + "__registerApps";
2697  params.set<std::string>("library_path") = library_path;
2698 
2699  const auto effective_library_name =
2700  library_name.empty() ? appNameToLibName(app_name) : library_name;
2701  params.set<std::string>("library_name") = effective_library_name;
2702  params.set<bool>("library_load_dependencies") = lib_load_deps;
2703 
2704  const auto paths = getLibrarySearchPaths(library_path);
2705  std::ostringstream oss;
2706 
2707  auto successfully_loaded = false;
2708  if (paths.empty())
2709  oss << '"' << app_name << "\" is not a registered application name.\n"
2710  << "No search paths were set. We made no attempts to locate the corresponding library "
2711  "file.\n";
2712  else
2713  {
2714  dynamicRegistration(params);
2715 
2716  // At this point the application should be registered so check it
2717  if (!AppFactory::instance().isRegistered(app_name))
2718  {
2719  oss << '"' << app_name << "\" is not a registered application name.\n"
2720  << "Unable to locate library archive for \"" << app_name
2721  << "\".\nWe attempted to locate the library archive \"" << effective_library_name
2722  << "\" in the following paths:\n\t";
2723  std::copy(paths.begin(), paths.end(), infix_ostream_iterator<std::string>(oss, "\n\t"));
2724  }
2725  else
2726  successfully_loaded = true;
2727  }
2728 
2729  if (!successfully_loaded)
2730  {
2731  oss << "\nMake sure you have compiled the library and either set the \"library_path\" "
2732  "variable in your input file or exported \"MOOSE_LIBRARY_PATH\".\n";
2733 
2734  mooseError(oss.str());
2735  }
2736 
2737 #else
2738  libmesh_ignore(app_name, library_path, library_name, lib_load_deps);
2739  mooseError("Dynamic Loading is either not supported or was not detected by libMesh configure.");
2740 #endif
2741 }
2742 
2743 void
2744 MooseApp::dynamicAllRegistration(const std::string & app_name,
2745  Factory * factory,
2746  ActionFactory * action_factory,
2747  Syntax * syntax,
2748  std::string library_path,
2749  const std::string & library_name)
2750 {
2751 #ifdef LIBMESH_HAVE_DLOPEN
2752  Parameters params;
2753  params.set<std::string>("app_name") = app_name;
2754  params.set<RegistrationType>("reg_type") = REGALL;
2755  params.set<std::string>("registration_method") = app_name + "__registerAll";
2756  params.set<std::string>("library_path") = library_path;
2757  params.set<std::string>("library_name") =
2758  library_name.empty() ? appNameToLibName(app_name) : library_name;
2759 
2760  params.set<Factory *>("factory") = factory;
2761  params.set<Syntax *>("syntax") = syntax;
2762  params.set<ActionFactory *>("action_factory") = action_factory;
2763  params.set<bool>("library_load_dependencies") = false;
2764 
2765  dynamicRegistration(params);
2766 #else
2767  libmesh_ignore(app_name, factory, action_factory, syntax, library_path, library_name);
2768  mooseError("Dynamic Loading is either not supported or was not detected by libMesh configure.");
2769 #endif
2770 }
2771 
2772 void
2774 {
2775  const auto paths = getLibrarySearchPaths(params.get<std::string>("library_path"));
2776  const auto library_name = params.get<std::string>("library_name");
2777 
2778  // Attempt to dynamically load the library
2779  for (const auto & path : paths)
2780  if (MooseUtils::checkFileReadable(path + '/' + library_name, false, false))
2782  path + '/' + library_name, params, params.get<bool>("library_load_dependencies"));
2783 }
2784 
2785 void
2786 MooseApp::loadLibraryAndDependencies(const std::string & library_filename,
2787  const Parameters & params,
2788  const bool load_dependencies)
2789 {
2790  std::string line;
2791  std::string dl_lib_filename;
2792 
2793  // This RE looks for absolute path libtool filenames (i.e. begins with a slash and ends with a
2794  // .la)
2795  pcrecpp::RE re_deps("(/\\S*\\.la)");
2796 
2797  std::ifstream la_handle(library_filename.c_str());
2798  if (la_handle.is_open())
2799  {
2800  while (std::getline(la_handle, line))
2801  {
2802  // Look for the system dependent dynamic library filename to open
2803  if (line.find("dlname=") != std::string::npos)
2804  // Magic numbers are computed from length of this string "dlname=' and line minus that
2805  // string plus quotes"
2806  dl_lib_filename = line.substr(8, line.size() - 9);
2807 
2808  if (line.find("dependency_libs=") != std::string::npos)
2809  {
2810  if (load_dependencies)
2811  {
2812  pcrecpp::StringPiece input(line);
2813  pcrecpp::StringPiece depend_library;
2814  while (re_deps.FindAndConsume(&input, &depend_library))
2815  // Recurse here to load dependent libraries in depth-first order
2816  loadLibraryAndDependencies(depend_library.as_string(), params, load_dependencies);
2817  }
2818 
2819  // There's only one line in the .la file containing the dependency libs so break after
2820  // finding it
2821  break;
2822  }
2823  }
2824  la_handle.close();
2825  }
2826 
2827  // This should only occur if we have static linkage.
2828  if (dl_lib_filename.empty())
2829  return;
2830 
2831  const auto & [dir, file_name] = MooseUtils::splitFileName(library_filename);
2832 
2833  // Time to load the library, First see if we've already loaded this particular dynamic library
2834  // 1) make sure we haven't already loaded this library
2835  // AND 2) make sure we have a library name (we won't for static linkage)
2836  // Note: Here was are going to assume uniqueness based on the filename alone. This has significant
2837  // implications for applications that have "diamond" inheritance of libraries (usually
2838  // modules). We will only load one of those libraries, versions be damned.
2839  auto dyn_lib_it = _lib_handles.find(file_name);
2840  if (dyn_lib_it == _lib_handles.end())
2841  {
2842  // Assemble the actual filename using the base path of the *.la file and the dl_lib_filename
2843  const auto dl_lib_full_path = MooseUtils::pathjoin(dir, dl_lib_filename);
2844 
2845  MooseUtils::checkFileReadable(dl_lib_full_path, false, /*throw_on_unreadable=*/true);
2846 
2847 #ifdef LIBMESH_HAVE_DLOPEN
2848  void * const lib_handle = dlopen(dl_lib_full_path.c_str(), RTLD_LAZY);
2849 #else
2850  void * const lib_handle = nullptr;
2851 #endif
2852 
2853  if (!lib_handle)
2854  mooseError("The library file \"",
2855  dl_lib_full_path,
2856  "\" exists and has proper permissions, but cannot by dynamically loaded.\nThis "
2857  "generally means that the loader was unable to load one or more of the "
2858  "dependencies listed in the supplied library (see otool or ldd).\n",
2859  dlerror());
2860 
2861  DynamicLibraryInfo lib_info;
2862  lib_info.library_handle = lib_handle;
2863  lib_info.full_path = library_filename;
2864 
2865  auto insert_ret = _lib_handles.insert(std::make_pair(file_name, lib_info));
2866  mooseAssert(insert_ret.second == true, "Error inserting into lib_handles map");
2867 
2868  dyn_lib_it = insert_ret.first;
2869  }
2870 
2871  // Library has been loaded, check to see if we've called the requested registration method
2872  const auto registration_method = params.get<std::string>("registration_method");
2873  auto & entry_sym_from_curr_lib = dyn_lib_it->second.entry_symbols;
2874 
2875  if (entry_sym_from_curr_lib.find(registration_method) == entry_sym_from_curr_lib.end())
2876  {
2877  // get the pointer to the method in the library. The dlsym()
2878  // function returns a null pointer if the symbol cannot be found,
2879  // we also explicitly set the pointer to NULL if dlsym is not
2880  // available.
2881 #ifdef LIBMESH_HAVE_DLOPEN
2882  void * registration_handle =
2883  dlsym(dyn_lib_it->second.library_handle, registration_method.c_str());
2884 #else
2885  void * registration_handle = nullptr;
2886 #endif
2887 
2888  if (registration_handle)
2889  {
2890  switch (params.get<RegistrationType>("reg_type"))
2891  {
2892  case APPLICATION:
2893  {
2894  using register_app_t = void (*)();
2895  register_app_t * const reg_ptr = reinterpret_cast<register_app_t *>(&registration_handle);
2896  (*reg_ptr)();
2897  break;
2898  }
2899  case REGALL:
2900  {
2901  using register_app_t = void (*)(Factory *, ActionFactory *, Syntax *);
2902  register_app_t * const reg_ptr = reinterpret_cast<register_app_t *>(&registration_handle);
2903  (*reg_ptr)(params.get<Factory *>("factory"),
2904  params.get<ActionFactory *>("action_factory"),
2905  params.get<Syntax *>("syntax"));
2906  break;
2907  }
2908  default:
2909  mooseError("Unhandled RegistrationType");
2910  }
2911 
2912  entry_sym_from_curr_lib.insert(registration_method);
2913  }
2914  else
2915  {
2916 
2917 #if defined(DEBUG) && defined(LIBMESH_HAVE_DLOPEN)
2918  // We found a dynamic library that doesn't have a dynamic
2919  // registration method in it. This shouldn't be an error, so
2920  // we'll just move on.
2921  if (!registration_handle)
2922  mooseWarning("Unable to find extern \"C\" method \"",
2923  registration_method,
2924  "\" in library: ",
2925  dyn_lib_it->first,
2926  ".\n",
2927  "This doesn't necessarily indicate an error condition unless you believe that "
2928  "the method should exist in that library.\n",
2929  dlerror());
2930 #endif
2931  }
2932  }
2933 }
2934 
2935 std::set<std::string>
2937 {
2938  // Return the paths but not the open file handles
2939  std::set<std::string> paths;
2940  for (const auto & it : _lib_handles)
2941  paths.insert(it.first);
2942 
2943  return paths;
2944 }
2945 
2946 std::set<std::string>
2947 MooseApp::getLibrarySearchPaths(const std::string & library_path) const
2948 {
2949  std::set<std::string> paths;
2950 
2951  if (!library_path.empty())
2952  {
2953  std::vector<std::string> tmp_paths;
2954  MooseUtils::tokenize(library_path, tmp_paths, 1, ":");
2955 
2956  paths.insert(tmp_paths.begin(), tmp_paths.end());
2957  }
2958 
2959  char * moose_lib_path_env = std::getenv("MOOSE_LIBRARY_PATH");
2960  if (moose_lib_path_env)
2961  {
2962  std::string moose_lib_path(moose_lib_path_env);
2963  std::vector<std::string> tmp_paths;
2964  MooseUtils::tokenize(moose_lib_path, tmp_paths, 1, ":");
2965 
2966  paths.insert(tmp_paths.begin(), tmp_paths.end());
2967  }
2968 
2969  return paths;
2970 }
2971 
2974 {
2976 }
2977 
2978 std::string
2980 {
2981  return std::string("");
2982 }
2983 
2984 void
2986 {
2987  _restart = value;
2988 }
2989 
2990 void
2992 {
2993  _recover = value;
2994 }
2995 
2996 void
2998 {
2999  TIME_SECTION("createMinimalApp", 3, "Creating Minimal App");
3000 
3001  // SetupMeshAction
3002  {
3003  // Build the Action parameters
3004  InputParameters action_params = _action_factory.getValidParams("SetupMeshAction");
3005  action_params.set<std::string>("type") = "GeneratedMesh";
3006 
3007  // Create The Action
3008  std::shared_ptr<MooseObjectAction> action = std::static_pointer_cast<MooseObjectAction>(
3009  _action_factory.create("SetupMeshAction", "Mesh", action_params));
3010 
3011  // Set the object parameters
3012  InputParameters & params = action->getObjectParams();
3013  params.set<MooseEnum>("dim") = "1";
3014  params.set<unsigned int>("nx") = 1;
3015 
3016  // Add Action to the warehouse
3018  }
3019 
3020  // Executioner
3021  {
3022  // Build the Action parameters
3023  InputParameters action_params = _action_factory.getValidParams("CreateExecutionerAction");
3024  action_params.set<std::string>("type") = "Transient";
3025 
3026  // Create the action
3027  std::shared_ptr<MooseObjectAction> action = std::static_pointer_cast<MooseObjectAction>(
3028  _action_factory.create("CreateExecutionerAction", "Executioner", action_params));
3029 
3030  // Set the object parameters
3031  InputParameters & params = action->getObjectParams();
3032  params.set<unsigned int>("num_steps") = 1;
3033  params.set<Real>("dt") = 1;
3034 
3035  // Add Action to the warehouse
3037  }
3038 
3039  // Problem
3040  {
3041  // Build the Action parameters
3042  InputParameters action_params = _action_factory.getValidParams("CreateProblemDefaultAction");
3043  action_params.set<bool>("_solve") = false;
3044 
3045  // Create the action
3046  std::shared_ptr<Action> action = std::static_pointer_cast<Action>(
3047  _action_factory.create("CreateProblemDefaultAction", "Problem", action_params));
3048 
3049  // Add Action to the warehouse
3051  }
3052 
3053  // Outputs
3054  {
3055  // Build the Action parameters
3056  InputParameters action_params = _action_factory.getValidParams("CommonOutputAction");
3057  action_params.set<bool>("console") = false;
3058 
3059  // Create action
3060  std::shared_ptr<Action> action =
3061  _action_factory.create("CommonOutputAction", "Outputs", action_params);
3062 
3063  // Add Action to the warehouse
3065  }
3066 
3068 }
3069 
3070 bool
3071 MooseApp::hasRelationshipManager(const std::string & name) const
3072 {
3073  return std::find_if(_relationship_managers.begin(),
3074  _relationship_managers.end(),
3075  [&name](const std::shared_ptr<RelationshipManager> & rm)
3076  { return rm->name() == name; }) != _relationship_managers.end();
3077 }
3078 
3079 namespace
3080 {
3081 void
3082 donateForWhom(const RelationshipManager & donor, RelationshipManager & acceptor)
3083 {
3084  auto & existing_for_whom = acceptor.forWhom();
3085 
3086  // Take all the for_whoms from the donor, and give them to the acceptor
3087  for (auto & fw : donor.forWhom())
3088  {
3089  if (std::find(existing_for_whom.begin(), existing_for_whom.end(), fw) ==
3090  existing_for_whom.end())
3091  acceptor.addForWhom(fw);
3092  }
3093 }
3094 }
3095 
3096 bool
3097 MooseApp::addRelationshipManager(std::shared_ptr<RelationshipManager> new_rm)
3098 {
3099  // We prefer to always add geometric RMs. There is no hurt to add RMs for replicated mesh
3100  // since MeshBase::delete_remote_elements{} is a no-op (empty) for replicated mesh.
3101  // The motivation here is that MooseMesh::_use_distributed_mesh may not be properly set
3102  // at the time we are adding geometric relationship managers. We deleted the following
3103  // old logic to add all geometric RMs regardless of there is a distributed mesh or not.
3104  // Otherwise, all geometric RMs will be improperly ignored for a distributed mesh generator.
3105 
3106  // if (!_action_warehouse.mesh()->isDistributedMesh() && !_split_mesh &&
3107  // (relationship_manager->isType(Moose::RelationshipManagerType::GEOMETRIC) &&
3108  // !(relationship_manager->isType(Moose::RelationshipManagerType::ALGEBRAIC) ||
3109  // relationship_manager->isType(Moose::RelationshipManagerType::COUPLING))))
3110  // return false;
3111 
3112  bool add = true;
3113 
3114  std::set<std::shared_ptr<RelationshipManager>> rms_to_erase;
3115 
3116  for (const auto & existing_rm : _relationship_managers)
3117  {
3118  if (*existing_rm >= *new_rm)
3119  {
3120  add = false;
3121  donateForWhom(*new_rm, *existing_rm);
3122  break;
3123  }
3124  // The new rm did not provide less or the same amount/type of ghosting as the existing rm, but
3125  // what about the other way around?
3126  else if (*new_rm >= *existing_rm)
3127  rms_to_erase.emplace(existing_rm);
3128  }
3129 
3130  if (add)
3131  {
3132  _relationship_managers.emplace(new_rm);
3133  for (const auto & rm_to_erase : rms_to_erase)
3134  {
3135  donateForWhom(*rm_to_erase, *new_rm);
3136  removeRelationshipManager(rm_to_erase);
3137  }
3138  }
3139 
3140  // Inform the caller whether the object was added or not
3141  return add;
3142 }
3143 
3144 const std::string &
3146 {
3147  static const std::string suffix = "-mesh.cpa.gz";
3148  return suffix;
3149 }
3150 
3151 std::filesystem::path
3152 MooseApp::metaDataFolderBase(const std::filesystem::path & folder_base,
3153  const std::string & map_suffix)
3154 {
3155  return RestartableDataIO::restartableDataFolder(folder_base /
3156  std::filesystem::path("meta_data" + map_suffix));
3157 }
3158 
3159 std::filesystem::path
3160 MooseApp::restartFolderBase(const std::filesystem::path & folder_base) const
3161 {
3162  auto folder = folder_base;
3163  folder += "-restart-" + std::to_string(processor_id());
3165 }
3166 
3167 const hit::Node *
3169 {
3170  if (const auto action = _action_warehouse.getCurrentAction())
3171  return action->parameters().getHitNode();
3172  return nullptr;
3173 }
3174 
3175 bool
3176 MooseApp::hasRMClone(const RelationshipManager & template_rm, const MeshBase & mesh) const
3177 {
3178  auto it = _template_to_clones.find(&template_rm);
3179  // C++ does short circuiting so we're safe here
3180  return (it != _template_to_clones.end()) && (it->second.find(&mesh) != it->second.end());
3181 }
3182 
3184 MooseApp::getRMClone(const RelationshipManager & template_rm, const MeshBase & mesh) const
3185 {
3186  auto outer_it = _template_to_clones.find(&template_rm);
3187  if (outer_it == _template_to_clones.end())
3188  mooseError("The template rm does not exist in our _template_to_clones map");
3189 
3190  auto & mesh_to_clone_map = outer_it->second;
3191  auto inner_it = mesh_to_clone_map.find(&mesh);
3192  if (inner_it == mesh_to_clone_map.end())
3193  mooseError("We should have the mesh key in our mesh");
3194 
3195  return *inner_it->second;
3196 }
3197 
3198 void
3199 MooseApp::removeRelationshipManager(std::shared_ptr<RelationshipManager> rm)
3200 {
3201  auto * const mesh = _action_warehouse.mesh().get();
3202  if (!mesh)
3203  mooseError("The MooseMesh should exist");
3204 
3205  const MeshBase * const undisp_lm_mesh = mesh->getMeshPtr();
3206  RelationshipManager * undisp_clone = nullptr;
3207  if (undisp_lm_mesh && hasRMClone(*rm, *undisp_lm_mesh))
3208  {
3209  undisp_clone = &getRMClone(*rm, *undisp_lm_mesh);
3210  const_cast<MeshBase *>(undisp_lm_mesh)->remove_ghosting_functor(*undisp_clone);
3211  }
3212 
3213  auto & displaced_mesh = _action_warehouse.displacedMesh();
3214  MeshBase * const disp_lm_mesh = displaced_mesh ? &displaced_mesh->getMesh() : nullptr;
3215  RelationshipManager * disp_clone = nullptr;
3216  if (disp_lm_mesh && hasRMClone(*rm, *disp_lm_mesh))
3217  {
3218  disp_clone = &getRMClone(*rm, *disp_lm_mesh);
3219  disp_lm_mesh->remove_ghosting_functor(*disp_clone);
3220  }
3221 
3222  if (_executioner)
3223  {
3224  auto & problem = feProblem();
3225  if (undisp_clone)
3226  {
3227  problem.removeAlgebraicGhostingFunctor(*undisp_clone);
3228  problem.removeCouplingGhostingFunctor(*undisp_clone);
3229  }
3230 
3231  auto * dp = problem.getDisplacedProblem().get();
3232  if (dp && disp_clone)
3233  dp->removeAlgebraicGhostingFunctor(*disp_clone);
3234  }
3235 
3236  _factory.releaseSharedObjects(*rm);
3237  _relationship_managers.erase(rm);
3238 }
3239 
3242  MooseMesh & moose_mesh,
3243  MeshBase & mesh,
3244  const DofMap * const dof_map)
3245 {
3246  auto & mesh_to_clone = _template_to_clones[&template_rm];
3247  auto it = mesh_to_clone.find(&mesh);
3248  if (it != mesh_to_clone.end())
3249  {
3250  // We've already created a clone for this mesh
3251  auto & clone_rm = *it->second;
3252  if (!clone_rm.dofMap() && dof_map)
3253  // We didn't have a DofMap before, but now we do, so we should re-init
3254  clone_rm.init(moose_mesh, mesh, dof_map);
3255  else if (clone_rm.dofMap() && dof_map && (clone_rm.dofMap() != dof_map))
3256  mooseError("Attempting to create and initialize an existing clone with a different DofMap. "
3257  "This should not happen.");
3258 
3259  return clone_rm;
3260  }
3261 
3262  // It's possible that this method is going to get called for multiple different MeshBase
3263  // objects. If that happens, then we *cannot* risk having a MeshBase object with a ghosting
3264  // functor that is init'd with another MeshBase object. So the safe thing to do is to make a
3265  // different RM for every MeshBase object that gets called here. Then the
3266  // RelationshipManagers stored here in MooseApp are serving as a template only
3267  auto pr = mesh_to_clone.emplace(
3268  std::make_pair(&const_cast<const MeshBase &>(mesh),
3269  dynamic_pointer_cast<RelationshipManager>(template_rm.clone())));
3270  mooseAssert(pr.second, "An insertion should have happened");
3271  auto & clone_rm = *pr.first->second;
3272  clone_rm.init(moose_mesh, mesh, dof_map);
3273  return clone_rm;
3274 }
3275 
3276 void
3278 {
3279  for (auto & rm : _relationship_managers)
3280  {
3282  {
3283  if (rm->attachGeometricEarly())
3284  {
3285  mesh.add_ghosting_functor(createRMFromTemplateAndInit(*rm, moose_mesh, mesh));
3287  }
3288  else
3289  {
3290  // If we have a geometric ghosting functor that can't be attached early, then we have to
3291  // prevent the mesh from deleting remote elements
3292  moose_mesh.allowRemoteElementRemoval(false);
3293 
3294  if (const MeshBase * const moose_mesh_base = moose_mesh.getMeshPtr())
3295  {
3296  if (moose_mesh_base != &mesh)
3297  mooseError("The MooseMesh MeshBase and the MeshBase we're trying to attach "
3298  "relationship managers to are different");
3299  }
3300  else
3301  // The MeshBase isn't attached to the MooseMesh yet, so have to tell it not to remove
3302  // remote elements independently
3304  }
3305  }
3306  }
3307 }
3308 
3309 void
3311  bool attach_geometric_rm_final)
3312 {
3313  for (auto & rm : _relationship_managers)
3314  {
3315  if (!rm->isType(rm_type))
3316  continue;
3317 
3318  // RM is already attached (this also handles the geometric early case)
3319  if (_attached_relationship_managers[rm_type].count(rm.get()))
3320  continue;
3321 
3323  {
3324  // The problem is not built yet - so the ActionWarehouse currently owns the mesh
3325  MooseMesh * const mesh = _action_warehouse.mesh().get();
3326 
3327  // "attach_geometric_rm_final = true" inidicate that it is the last chance to attach
3328  // geometric RMs. Therefore, we need to attach them.
3329  if (!rm->attachGeometricEarly() && !attach_geometric_rm_final)
3330  // Will attach them later (during algebraic). But also, we need to tell the mesh that we
3331  // shouldn't be deleting remote elements yet
3332  mesh->allowRemoteElementRemoval(false);
3333  else
3334  {
3335  MeshBase & undisp_mesh_base = mesh->getMesh();
3336  const DofMap * const undisp_sys_dof_map =
3337  _executioner ? &feProblem().getSolverSystem(0).dofMap() : nullptr;
3338  undisp_mesh_base.add_ghosting_functor(
3339  createRMFromTemplateAndInit(*rm, *mesh, undisp_mesh_base, undisp_sys_dof_map));
3340 
3341  // In the final stage, if there is a displaced mesh, we need to
3342  // clone ghosting functors for displacedMesh
3343  if (auto & disp_moose_mesh = _action_warehouse.displacedMesh();
3344  attach_geometric_rm_final && disp_moose_mesh)
3345  {
3346  MeshBase & disp_mesh_base = _action_warehouse.displacedMesh()->getMesh();
3347  const DofMap * disp_sys_dof_map = nullptr;
3348  if (_executioner && feProblem().getDisplacedProblem())
3349  disp_sys_dof_map = &feProblem().getDisplacedProblem()->solverSys(0).dofMap();
3350  disp_mesh_base.add_ghosting_functor(
3351  createRMFromTemplateAndInit(*rm, *disp_moose_mesh, disp_mesh_base, disp_sys_dof_map));
3352  }
3353  else if (_action_warehouse.displacedMesh())
3354  mooseError("The displaced mesh should not yet exist at the time that we are attaching "
3355  "early geometric relationship managers.");
3356 
3357  // Mark this RM as attached
3358  mooseAssert(!_attached_relationship_managers[rm_type].count(rm.get()), "Already attached");
3359  _attached_relationship_managers[rm_type].insert(rm.get());
3360  }
3361  }
3362  else // rm_type is algebraic or coupling
3363  {
3364  if (!_executioner && !_executor)
3365  mooseError("We must have an executioner by now or else we do not have to data to add "
3366  "algebraic or coupling functors to in MooseApp::attachRelationshipManagers");
3367 
3368  // Now we've built the problem, so we can use it
3369  auto & problem = feProblem();
3370  auto & undisp_moose_mesh = problem.mesh();
3371  auto & undisp_sys = feProblem().getSolverSystem(0);
3372  auto & undisp_sys_dof_map = undisp_sys.dofMap();
3373  auto & undisp_mesh = undisp_moose_mesh.getMesh();
3374 
3375  if (rm->useDisplacedMesh() && problem.getDisplacedProblem())
3376  {
3378  // We actually need to add this to the FEProblemBase NonlinearSystemBase's DofMap
3379  // because the DisplacedProblem "nonlinear" DisplacedSystem doesn't have any matrices
3380  // for which to do coupling. It's actually horrifying to me that we are adding a
3381  // coupling functor, that is going to determine its couplings based on a displaced
3382  // MeshBase object, to a System associated with the undisplaced MeshBase object (there
3383  // is only ever one EquationSystems object per MeshBase object and visa versa). So here
3384  // I'm left with the choice of whether to pass in a MeshBase object that is *not* the
3385  // MeshBase object that will actually determine the couplings or to pass in the MeshBase
3386  // object that is inconsistent with the System DofMap that we are adding the coupling
3387  // functor for! Let's err on the side of *libMesh* consistency and pass properly paired
3388  // MeshBase-DofMap
3389  problem.addCouplingGhostingFunctor(
3390  createRMFromTemplateAndInit(*rm, undisp_moose_mesh, undisp_mesh, &undisp_sys_dof_map),
3391  /*to_mesh = */ false);
3392 
3393  else if (rm_type == Moose::RelationshipManagerType::ALGEBRAIC)
3394  {
3395  auto & displaced_problem = *problem.getDisplacedProblem();
3396  auto & disp_moose_mesh = displaced_problem.mesh();
3397  auto & disp_mesh = disp_moose_mesh.getMesh();
3398  const DofMap * const disp_nl_dof_map = &displaced_problem.solverSys(0).dofMap();
3399  displaced_problem.addAlgebraicGhostingFunctor(
3400  createRMFromTemplateAndInit(*rm, disp_moose_mesh, disp_mesh, disp_nl_dof_map),
3401  /*to_mesh = */ false);
3402  }
3403  }
3404  else // undisplaced
3405  {
3407  problem.addCouplingGhostingFunctor(
3408  createRMFromTemplateAndInit(*rm, undisp_moose_mesh, undisp_mesh, &undisp_sys_dof_map),
3409  /*to_mesh = */ false);
3410 
3411  else if (rm_type == Moose::RelationshipManagerType::ALGEBRAIC)
3412  problem.addAlgebraicGhostingFunctor(
3413  createRMFromTemplateAndInit(*rm, undisp_moose_mesh, undisp_mesh, &undisp_sys_dof_map),
3414  /*to_mesh = */ false);
3415  }
3416 
3417  // Mark this RM as attached
3418  mooseAssert(!_attached_relationship_managers[rm_type].count(rm.get()), "Already attached");
3419  _attached_relationship_managers[rm_type].insert(rm.get());
3420  }
3421  }
3422 }
3423 
3424 std::vector<std::pair<std::string, std::string>>
3426 {
3427  std::vector<std::pair<std::string, std::string>> info_strings;
3428  info_strings.reserve(_relationship_managers.size());
3429 
3430  for (const auto & rm : _relationship_managers)
3431  {
3432  std::stringstream oss;
3433  oss << rm->getInfo();
3434 
3435  auto & for_whom = rm->forWhom();
3436 
3437  if (!for_whom.empty())
3438  {
3439  oss << " for ";
3440 
3441  std::copy(for_whom.begin(), for_whom.end(), infix_ostream_iterator<std::string>(oss, ", "));
3442  }
3443 
3444  info_strings.emplace_back(std::make_pair(Moose::stringify(rm->getType()), oss.str()));
3445  }
3446 
3447  // List the libMesh GhostingFunctors - Not that in libMesh all of the algebraic and coupling
3448  // Ghosting Functors are also attached to the mesh. This should catch them all.
3449  const auto & mesh = _action_warehouse.getMesh();
3450  if (mesh)
3451  {
3452  // Let us use an ordered map to avoid stochastic console behaviors.
3453  // I believe we won't have many RMs, and there is no performance issue.
3454  // Deterministic behaviors are good for setting up regression tests
3455  std::map<std::string, unsigned int> counts;
3456 
3457  for (auto & gf : as_range(mesh->getMesh().ghosting_functors_begin(),
3458  mesh->getMesh().ghosting_functors_end()))
3459  {
3460  const auto * gf_ptr = dynamic_cast<const RelationshipManager *>(gf);
3461  if (!gf_ptr)
3462  // Count how many occurences of the same Ghosting Functor types we are encountering
3463  counts[demangle(typeid(*gf).name())]++;
3464  }
3465 
3466  for (const auto & pair : counts)
3467  info_strings.emplace_back(std::make_pair(
3468  "Default", pair.first + (pair.second > 1 ? " x " + std::to_string(pair.second) : "")));
3469  }
3470 
3471  // List the libMesh GhostingFunctors - Not that in libMesh all of the algebraic and coupling
3472  // Ghosting Functors are also attached to the mesh. This should catch them all.
3473  const auto & d_mesh = _action_warehouse.getDisplacedMesh();
3474  if (d_mesh)
3475  {
3476  // Let us use an ordered map to avoid stochastic console behaviors.
3477  // I believe we won't have many RMs, and there is no performance issue.
3478  // Deterministic behaviors are good for setting up regression tests
3479  std::map<std::string, unsigned int> counts;
3480 
3481  for (auto & gf : as_range(d_mesh->getMesh().ghosting_functors_begin(),
3482  d_mesh->getMesh().ghosting_functors_end()))
3483  {
3484  const auto * gf_ptr = dynamic_cast<const RelationshipManager *>(gf);
3485  if (!gf_ptr)
3486  // Count how many occurences of the same Ghosting Functor types we are encountering
3487  counts[demangle(typeid(*gf).name())]++;
3488  }
3489 
3490  for (const auto & pair : counts)
3491  info_strings.emplace_back(
3492  std::make_pair("Default",
3493  pair.first + (pair.second > 1 ? " x " + std::to_string(pair.second) : "") +
3494  " for DisplacedMesh"));
3495  }
3496 
3497  return info_strings;
3498 }
3499 
3500 void
3502 {
3503  for (auto map_iter = _restartable_meta_data.begin(); map_iter != _restartable_meta_data.end();
3504  ++map_iter)
3505  {
3506  const RestartableDataMapName & name = map_iter->first;
3507  const RestartableDataMap & meta_data = map_iter->second.first;
3508 
3509  std::vector<std::string> not_declared;
3510 
3511  for (const auto & data : meta_data)
3512  if (!data.declared())
3513  not_declared.push_back(data.name());
3514 
3515  if (!not_declared.empty())
3516  {
3517  std::ostringstream oss;
3518  std::copy(
3519  not_declared.begin(), not_declared.end(), infix_ostream_iterator<std::string>(oss, ", "));
3520 
3521  mooseError("The following '",
3522  name,
3523  "' meta-data properties were retrieved but never declared: ",
3524  oss.str());
3525  }
3526  }
3527 }
3528 
3529 const RestartableDataMapName MooseApp::MESH_META_DATA = "MeshMetaData";
3531 
3534 {
3535  auto iter = _restartable_meta_data.find(name);
3536  if (iter == _restartable_meta_data.end())
3537  mooseError("Unable to find RestartableDataMap object for the supplied name '",
3538  name,
3539  "', did you call registerRestartableDataMapName in the application constructor?");
3540  return iter->second.first;
3541 }
3542 
3543 bool
3545 {
3546  return _restartable_meta_data.count(name);
3547 }
3548 
3549 void
3551 {
3552  if (!suffix.empty())
3553  std::transform(suffix.begin(), suffix.end(), suffix.begin(), ::tolower);
3554  suffix.insert(0, "_");
3555  _restartable_meta_data.emplace(
3556  std::make_pair(name, std::make_pair(RestartableDataMap(), suffix)));
3557 }
3558 
3559 const std::string &
3561 {
3562  const auto it = _restartable_meta_data.find(name);
3563  if (it == _restartable_meta_data.end())
3564  mooseError("MooseApp::getRestartableDataMapName: The name '", name, "' is not registered");
3565  return it->second.second;
3566 }
3567 
3568 PerfGraph &
3570 {
3572 
3573  auto perf_graph =
3574  std::make_unique<RestartableData<PerfGraph>>("perf_graph",
3575  this,
3576  type() + " (" + name() + ')',
3577  *this,
3578  getParam<bool>("perf_graph_live_all"),
3579  !getParam<bool>("disable_perf_graph_live"));
3580 
3581  return dynamic_cast<RestartableData<PerfGraph> &>(
3582  registerRestartableData(std::move(perf_graph), 0, false))
3583  .set();
3584 }
3585 
3588 {
3590 
3591  auto solution_invalidity =
3592  std::make_unique<RestartableData<SolutionInvalidity>>("solution_invalidity", nullptr, *this);
3593 
3594  return dynamic_cast<RestartableData<SolutionInvalidity> &>(
3595  registerRestartableData(std::move(solution_invalidity), 0, false))
3596  .set();
3597 }
3598 
3599 bool
3601 {
3602  return _action_warehouse.getCurrentTaskName() == "create_added_mesh_generators" ||
3604 }
3605 
3606 #ifdef MOOSE_LIBTORCH_ENABLED
3607 torch::DeviceType
3609 {
3610  const auto pname = "--compute-device";
3611  if (device_enum == "cuda")
3612  {
3613 #ifdef __linux__
3614  if (!torch::cuda::is_available())
3615  mooseError(pname, "=cuda: CUDA support is not available in the linked libtorch library");
3616  return torch::kCUDA;
3617 #else
3618  mooseError(pname, "=cuda: CUDA is not supported on your platform");
3619 #endif
3620  }
3621  else if (device_enum == "mps")
3622  {
3623 #ifdef __APPLE__
3624  if (!torch::mps::is_available())
3625  mooseError(pname, "=mps: MPS support is not available in the linked libtorch library");
3626  return torch::kMPS;
3627 #else
3628  mooseError(pname, "=mps: MPS is not supported on your platform");
3629 #endif
3630  }
3631 
3632  else if (device_enum != "cpu")
3633  mooseError("The device '",
3634  device_enum,
3635  "' is not currently supported by the MOOSE libtorch integration.");
3636  return torch::kCPU;
3637 }
3638 #endif
3639 
3640 void
3641 MooseApp::outputMachineReadableData(const std::string & param,
3642  const std::string & start_marker,
3643  const std::string & end_marker,
3644  const std::string & data) const
3645 {
3646  // Bool parameter, just to screen
3647  if (_pars.have_parameter<bool>(param))
3648  {
3649  Moose::out << start_marker << data << end_marker << std::endl;
3650  return;
3651  }
3652 
3653  // String parameter, to file
3654  const auto & filename = getParam<std::string>(param);
3655  // write to file
3656  std::ofstream out(filename.c_str());
3657  if (out.is_open())
3658  {
3659  std::ofstream out(filename.c_str());
3660  out << data << std::flush;
3661  out.close();
3662  }
3663  else
3664  mooseError("Unable to open file `", filename, "` for writing ", param, " data to it.");
3665 }
3666 
3667 void
3668 MooseApp::addCapability(const std::string & capability,
3669  CapabilityUtils::Type value,
3670  const std::string & doc)
3671 {
3672  checkReservedCapability(capability);
3674 }
3675 
3676 void
3677 MooseApp::addCapability(const std::string & capability, const char * value, const std::string & doc)
3678 {
3679  checkReservedCapability(capability);
3680  Moose::Capabilities::getCapabilityRegistry().add(capability, std::string(value), doc);
3681 }
3682 
3683 #ifdef MOOSE_MFEM_ENABLED
3684 void
3686 {
3687  const auto string_vec = MooseUtils::split(device_string, ",");
3688  auto string_set = std::set<std::string>(string_vec.begin(), string_vec.end());
3689  if (!_mfem_device)
3690  {
3691  _mfem_device = std::make_shared<mfem::Device>(device_string);
3692  _mfem_devices = std::move(string_set);
3693  _mfem_device->Print(Moose::out);
3694  }
3695  else if (!device_string.empty() && string_set != _mfem_devices)
3696  mooseError("Attempted to configure with MFEM devices '",
3697  MooseUtils::join(string_set, " "),
3698  "', but we have already configured the MFEM device object with the devices '",
3700  "'");
3701 }
3702 #endif
std::string name(const ElemQuality q)
GhostingFunctorIterator ghosting_functors_begin() const
std::list< std::string > getCheckpointFiles() const
Extract all possible checkpoint file names.
Definition: MooseApp.C:2495
virtual bool constructingMeshGenerators() const
Whether this app is constructing mesh generators.
Definition: MooseApp.C:3600
std::list< std::string > getCheckpointDirectories() const
Get all checkpoint directories.
Definition: MooseApp.C:2463
OStreamProxy err
static const std::string & checkpointSuffix()
The file suffix for the checkpoint mesh.
Definition: MooseApp.C:3145
std::string getFileName(bool stripLeadingPath=true) const
Return the primary (first) filename that was parsed Note: When stripLeadingPath is false...
Definition: MooseApp.C:2509
void mooseInfo(Args &&... args) const
Definition: MooseBase.h:321
std::string docsDir(const std::string &app_name)
Returns the directory of any installed docs/site.
Definition: MooseUtils.C:125
void build()
Parse an input file (or text string if provided) consisting of hit syntax and setup objects in the MO...
Definition: Builder.C:300
void addExecutorParams(const std::string &type, const std::string &name, const InputParameters &params)
Adds the parameters for an Executor to the list of parameters.
Definition: MooseApp.C:2052
virtual std::string getPrintableName() const
Get printable name of the application.
Definition: MooseApp.h:142
unsigned int _multiapp_level
Level of multiapp, the master is level 0. This used by the Console to indent output.
Definition: MooseApp.h:1555
virtual std::string getInstallableInputs() const
Method to retrieve the installable inputs from a given applications <app>Revision.h file.
Definition: MooseApp.C:2311
void write(std::ostream &header_stream, std::ostream &data_stream)
Writes the restartable data to header stream header_stream and data stream data_stream.
PerfGraph & _perf_graph
The PerfGraph object for this application (recoverable)
Definition: MooseApp.h:1251
bool show_trace
Set to true (the default) to print the stack trace with error and warning messages - false to omit it...
Definition: Moose.C:823
void setOutputPosition(const Point &p)
Tell the app to output in a specific position.
Definition: MooseApp.C:2452
std::string join(Iterator begin, Iterator end, const std::string &delimiter)
Python-like join function for strings over an iterator range.
Definition: MooseUtils.h:144
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:30
void setGlobalCommandLineParam(const std::string &name)
Sets the command line parameter with name as global.
std::unordered_map< std::string, std::pair< std::string, std::unique_ptr< InputParameters > > > _executor_params
Used in building the Executors Maps the name of the Executor block to the <type, params> ...
Definition: MooseApp.h:1271
bool isUltimateMaster() const
Whether or not this app is the ultimate master app.
Definition: MooseApp.h:820
Storage container for all InputParamter objects.
std::map< Moose::RelationshipManagerType, std::set< const RelationshipManager * > > _attached_relationship_managers
The relationship managers that have been attached (type -> RMs)
Definition: MooseApp.h:1354
unsigned int n_threads()
const InputParameters & _pars
The object&#39;s parameters.
Definition: MooseBase.h:366
Reader for restartable data written by the RestartableDataWriter.
std::string _restart_recover_base
The base name to restart/recover from. If blank then we will find the newest checkpoint file...
Definition: MooseApp.h:1336
void dynamicRegistration(const libMesh::Parameters &params)
Helper method for dynamic loading of objects.
Definition: MooseApp.C:2773
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
bool hasRestartableMetaData(const std::string &name, const RestartableDataMapName &metaname) const
Definition: MooseApp.C:2607
virtual void setupOptions()
Setup options based on InputParameters.
Definition: MooseApp.C:1273
PerfGraph & createRecoverablePerfGraph()
Creates a recoverable PerfGraph.
Definition: MooseApp.C:3569
std::shared_ptr< DisplacedProblem > displaced_problem
std::string libNameToAppName(const std::string &library_name) const
Converts a library name to an application name:
Definition: MooseApp.C:2543
const unsigned int invalid_uint
RelationshipManagerType
Main types of Relationship Managers.
Definition: MooseTypes.h:964
void registerCapabilities()
Register all base MooseApp capabilities to the Moose::Capabilities registry.
const std::shared_ptr< Parser > _parser
Parser for parsing the input file (owns the root hit node)
Definition: MooseApp.h:1230
std::string getFrameworkVersion() const
Returns the framework version.
Definition: MooseApp.C:1255
Base class for everything in MOOSE with a name and a type.
Definition: MooseBase.h:49
const std::multimap< std::string, ActionInfo > & getAssociatedActions() const
Return all Syntax to Action associations.
Definition: Syntax.C:374
void setRecover(bool value)
Definition: MooseApp.C:2991
void buildFullTree(const std::string &search_string)
Use MOOSE Factories to construct a full parse tree for documentation or echoing input.
Definition: Builder.C:579
std::vector< std::pair< std::string, std::string > > getRelationshipManagerInfo() const
Returns the Relationship managers info suitable for printing.
Definition: MooseApp.C:3425
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseBase.h:388
bool hasRMClone(const RelationshipManager &template_rm, const MeshBase &mesh) const
Definition: MooseApp.C:3176
torch::DeviceType determineLibtorchDeviceType(const MooseEnum &device) const
Function to determine the device which should be used by libtorch on this application.
Definition: MooseApp.C:3608
bool _file_base_set_by_user
Whether or not file base is set through input or setOutputFileBase by MultiApp.
Definition: MooseApp.h:1196
const Action * getCurrentAction() const
bool _output_position_set
Whether or not an output position has been set for this app.
Definition: MooseApp.h:1199
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
void addDependency(const std::string &task, const std::string &pre_req)
Definition: Syntax.C:60
std::unique_ptr< TheWarehouse > _the_warehouse
The combined warehouse for storing any MooseObject based object.
Definition: MooseApp.h:1552
InputParameters getValidParams(const std::string &name)
Definition: ActionFactory.C:94
void setCheckUnusedFlag(bool warn_is_error=false)
Set a flag so that the parser will either warn or error when unused variables are seen after parsing ...
Definition: MooseApp.C:2021
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
bool hasInitialBackup() const
Definition: MooseApp.h:1001
void setInput(std::unique_ptr< std::stringstream > header_stream, std::unique_ptr< std::stringstream > data_stream)
Sets the input stream for reading from the stringstreams header_stream and data_stream for the header...
static std::filesystem::path metaDataFolderBase(const std::filesystem::path &folder_base, const std::string &map_suffix)
The file suffix for meta data (header and data)
Definition: MooseApp.C:3152
bool _warnings_are_errors
Variable to toggle any warning into an error (includes deprecated code warnings)
Definition: Moose.C:818
std::string installedInputsDir(const std::string &app_name, const std::string &dir_name, const std::string &extra_error_msg="")
Returns the directory of any installed inputs or the empty string if none are found.
Definition: MooseUtils.C:103
InputParameterWarehouse & getInputParameterWarehouse()
Get the InputParameterWarehouse for MooseObjects.
Definition: MooseApp.C:2973
bool tokenizeAndConvert(const std::string &str, std::vector< T > &tokenized_vector, const std::string &delimiter=" \\\)
tokenizeAndConvert splits a string using delimiter and then converts to type T.
static const RestartableDataMapName MESH_META_DATA
Definition: MooseApp.h:130
std::unordered_map< RestartableDataMapName, std::pair< RestartableDataMap, std::string > > _restartable_meta_data
General storage for custom RestartableData that can be added to from outside applications.
Definition: MooseApp.h:1542
void registerTaskName(const std::string &task, bool should_auto_build=false)
Method to register a new task.
Definition: Syntax.C:20
virtual const std::type_info & typeId() const =0
The type ID of the underlying data.
std::shared_ptr< MooseMesh > & displacedMesh()
static const std::map< std::string, std::vector< std::shared_ptr< RegistryEntryBase > > > & allActions()
Returns a per-label keyed map of all Actions in the registry.
Definition: Registry.h:227
virtual std::string appBinaryName() const
Definition: MooseApp.h:144
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
const std::shared_ptr< MooseMesh > & getMesh() const
std::string getOutputFileBase(bool for_non_moose_build_output=false) const
Get the output file base name.
Definition: MooseApp.C:1737
static void addInputParam(InputParameters &params)
Definition: MooseApp.C:101
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
Definition: MooseUtils.h:1135
RelationshipManager & getRMClone(const RelationshipManager &template_rm, const MeshBase &mesh) const
Return the relationship manager clone originally created from the provided template relationship mana...
Definition: MooseApp.C:3184
void setFinalTask(const std::string &task)
void deallocateKokkosMemoryPool()
Deallocate Kokkos memory pool.
bool runInputs()
Handles the run input parameter logic: Checks to see whether a directory exists in user space and lau...
Definition: MooseApp.C:2382
void registerRestartableNameWithFilter(const std::string &name, Moose::RESTARTABLE_FILTER filter)
NOTE: This is an internal function meant for MOOSE use only!
Definition: MooseApp.C:1906
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
virtual void run()
Run the application.
Definition: MooseApp.C:2208
void removeRelationshipManager(std::shared_ptr< RelationshipManager > relationship_manager)
Purge this relationship manager from meshes and DofMaps and finally from us.
Definition: MooseApp.C:3199
Real _start_time
The time at which to start the simulation.
Definition: MooseApp.h:1208
Writer for restartable data, to be read by the RestartableDataReader.
This attribute describes sorting state.
Definition: TheWarehouse.h:112
void createExecutors()
After adding all of the Executor Params - this function will actually cause all of them to be built...
Definition: MooseApp.C:2125
void recursivelyCreateExecutors(const std::string &current_executor_name, std::list< std::string > &possible_roots, std::list< std::string > &current_branch)
Internal function used to recursively create the executor objects.
Definition: MooseApp.C:2073
bool forceRestart() const
Whether or not we are forcefully restarting (allowing the load of potentially incompatibie checkpoint...
Definition: MooseApp.h:1068
std::filesystem::path restartFolderBase(const std::filesystem::path &folder_base) const
The file suffix for restartable data.
Definition: MooseApp.C:3160
const bool _use_split
Whether or not we are using a (pre-)split mesh (automatically DistributedMesh)
Definition: MooseApp.h:1327
std::pair< std::filesystem::path, std::filesystem::path > splitFileName(const T &full_file)
Function for splitting path and filename.
Definition: MooseUtils.h:263
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
MeshBase & mesh
bool hasRelationshipManager(const std::string &name) const
Returns a Boolean indicating whether a RelationshipManater exists with the same name.
Definition: MooseApp.C:3071
std::list< std::string > getFilesInDirs(const std::list< std::string > &directory_list, const bool files_only=true)
Retrieves the names of all of the files contained within the list of directories passed into the rout...
Definition: MooseUtils.C:808
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
bool _check_input
true if we want to just check the input file
Definition: MooseApp.h:1347
TODO: delete this later - it is a temporary hack for dealing with inter-system dependencies.
Definition: Attributes.h:313
const Parallel::Communicator & comm() const
bool hasRestartableDataMap(const RestartableDataMapName &name) const
Definition: MooseApp.C:3544
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
std::set< std::string > _mfem_devices
MFEM supported devices based on user-provided config.
Definition: MooseApp.h:1623
Syntax _syntax
Syntax of the input file.
Definition: MooseApp.h:1214
Syntax & syntax()
Returns a writable reference to the syntax object.
Definition: MooseApp.h:225
std::map< std::string, std::shared_ptr< Executor > > _executors
Pointers to all of the Executors for this run.
Definition: MooseApp.h:1266
std::vector< std::filesystem::path > writeRestartableMetaData(const RestartableDataMapName &name, const std::filesystem::path &folder_base)
Writes the restartable meta data for name with a folder base of folder_base.
Definition: MooseApp.C:2658
ExecuteMooseObjectWarehouse< MultiApp > & getMultiAppWarehouse()
bool _trap_fpe
Whether or not FPE trapping should be turned on.
Definition: MooseApp.h:1333
int exitCode() const
Get the shell exit code for the application.
Definition: MooseApp.h:157
GhostingFunctorIterator ghosting_functors_end() const
processor_id_type processor_id() const
Returns the MPI processor ID of the current processor.
Definition: MooseApp.h:411
static const std::map< std::string, std::vector< std::shared_ptr< RegistryEntryBase > > > & allObjects()
Returns a per-label keyed map of all MooseObjects in the registry.
Definition: Registry.h:222
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
Helper class to hold streams for Backup and Restore operations.
Definition: Backup.h:18
const hit::Node * getCurrentActionHitNode() const
Definition: MooseApp.C:3168
ActionWarehouse _action_warehouse
Where built actions are stored.
Definition: MooseApp.h:1224
std::string realpath(const std::string &path)
Wrapper around PetscGetRealPath, which is a cross-platform replacement for realpath.
Definition: MooseUtils.C:1136
RestartableDataReader _rd_reader
Definition: MooseApp.h:1575
void checkMetaDataIntegrity() const
Function to check the integrity of the restartable meta data structure.
Definition: MooseApp.C:3501
const std::list< Action * > & getActionListByName(const std::string &task) const
Retrieve a constant list of Action pointers associated with the passed in task.
virtual const std::vector< std::string > & forWhom() const
The object (or Action) this RelationshipManager was built for.
static InputParameters validParams()
Definition: MooseApp.C:108
bool isRestarting() const
Whether or not this is a "restart" calculation.
Definition: MooseApp.C:1880
bool isSplitMesh() const
Whether or not this is a split mesh operation.
Definition: MooseApp.C:1886
RestartableDataMap & getRestartableDataMap(const RestartableDataMapName &name)
Return a reference to restartable data for the specific type flag.
Definition: MooseApp.C:3533
This class produces a dump of the InputFileParameters in the Standard Object Notation (SON) format fo...
Holds the syntax in a Json::Value tree.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Base class for actions.
Definition: Action.h:34
std::string hostname()
Get the hostname the current process is running on.
Definition: MooseUtils.C:624
FEProblemBase & feProblem() const
Definition: MooseApp.C:2033
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:40
MooseApp(const InputParameters &parameters)
Constructor is protected so that this object is constructed through the AppFactory object...
Definition: MooseApp.C:443
std::optional< MooseEnum > getComputeDevice() const
Get the device accelerated computations are supposed to be running on.
void allowRemoteElementRemoval(bool allow_removal)
Set whether to allow remote element removal.
Definition: MooseMesh.C:3936
std::vector< RestartableDataMap > _restartable_data
Where the restartable data is held (indexed on tid)
Definition: MooseApp.h:1242
std::string camelCaseToUnderscore(const std::string &camel_case_name)
Function for converting a camel case name to a name containing underscores.
Definition: MooseUtils.C:568
RelationshipManager & createRMFromTemplateAndInit(const RelationshipManager &template_rm, MooseMesh &moose_mesh, MeshBase &mesh, const libMesh::DofMap *dof_map=nullptr)
Take an input relationship manager, clone it, and then initialize it with provided mesh and optional ...
Definition: MooseApp.C:3241
void setOutputFileBase(const std::string &output_file_base)
Override the selection of the output file base name.
Definition: MooseApp.C:1746
std::vector< std::string > split(const std::string &str, const std::string &delimiter, std::size_t max_count=std::numeric_limits< std::size_t >::max())
Python like split functions for strings.
Definition: MooseUtils.C:1031
This class wraps provides and tracks access to command line parameters.
Definition: CommandLine.h:29
int _exit_code
The exit code.
Definition: MooseApp.h:1306
Storage for restartable data that is ordered based on insertion order.
CapabilityUtils::Result check(const std::string &requested_capabilities) const
check if the given required capabilities are fulfilled, returns a bool, a reason, and a verbose docum...
Definition: Capabilities.C:82
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
MPI_Status status
std::shared_ptr< MooseMesh > & mesh()
TODO: delete this later - it is a temporary hack for dealing with inter-system dependencies.
Definition: Attributes.h:294
MeshGeneratorSystem _mesh_generator_system
The system that manages the MeshGenerators.
Definition: MooseApp.h:1570
void attachRelationshipManagers(Moose::RelationshipManagerType rm_type, bool attach_geometric_rm_final=false)
Attach the relationship managers of the given type Note: Geometric relationship managers that are sup...
Definition: MooseApp.C:3310
const MeshBase * getMeshPtr() const
Definition: MooseMesh.C:3463
bool _start_time_set
Whether or not an start time has been set.
Definition: MooseApp.h:1205
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
Definition: SystemBase.C:1163
void allow_remote_element_removal(bool allow)
void libmesh_ignore(const Args &...)
void possiblyLoadRestartableMetaData(const RestartableDataMapName &name, const std::filesystem::path &folder_base)
Loads the restartable meta data for name if it is available with the folder base folder_base.
Definition: MooseApp.C:2636
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
bool showInputs() const
Prints a message showing the installable inputs for a given application (if getInstallableInputs has ...
Definition: MooseApp.C:2279
bool addRelationshipManager(std::shared_ptr< RelationshipManager > relationship_manager)
Transfers ownership of a RelationshipManager to the application for lifetime management.
Definition: MooseApp.C:3097
RestartableDataValue & getRestartableMetaData(const std::string &name, const RestartableDataMapName &metaname, THREAD_ID tid)
Definition: MooseApp.C:2617
std::shared_ptr< NullExecutor > _null_executor
Used to return an executor that does nothing.
Definition: MooseApp.h:1282
const T & get(std::string_view) const
const std::string & getLastInputFileName() const
Definition: MooseApp.C:1730
virtual void preBackup()
Insertion point for other apps that is called before backup()
Definition: MooseApp.h:739
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
void setErrorOverridden()
Set a flag so that the parser will throw an error if overridden parameters are detected.
Definition: MooseApp.C:2202
void resetFileBase()
Resets the file base for all FileOutput objects.
virtual void postRestore(const bool)
Insertion point for other apps that is called after restore()
Definition: MooseApp.h:773
T command_line_value(const std::string &, T)
void loadLibraryAndDependencies(const std::string &library_filename, const libMesh::Parameters &params, bool load_dependencies=true)
Recursively loads libraries and dependencies in the proper order to fully register a MOOSE applicatio...
Definition: MooseApp.C:2786
virtual std::unique_ptr< Base > create()=0
Tracks the libmesh system number that a MooseObject is associated with.
Definition: Attributes.h:275
const std::vector< std::shared_ptr< T > > & getObjects(THREAD_ID tid=0) const
Retrieve complete vector to the all/block/boundary restricted objects for a given thread...
bool _restart
Whether or not this is a restart run.
Definition: MooseApp.h:1321
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
std::unique_ptr< Backup > backup()
Backs up the application memory in a Backup.
Definition: MooseApp.C:1932
bool _deprecated_is_error
Variable to toggle only deprecated warnings as errors.
Definition: Moose.C:819
Generic AppFactory class for building Application objects.
Definition: AppFactory.h:55
RESTARTABLE_FILTER
The filter type applied to a particular piece of "restartable" data.
Definition: MooseTypes.h:792
void clearAppParams(const InputParameters &params, const ClearAppParamsKey)
Clears the stored parameters for the given application parameteres.
Definition: AppFactory.C:51
void mooseDeprecated(Args &&... args) const
Definition: MooseBase.h:314
void meshChanged()
Calls the meshChanged method for every output object.
void setErrorOnLoadWithDifferentNumberOfProcessors(bool value)
void setActive(bool active)
Turn on or off timing.
Definition: PerfGraph.h:129
RestartableDataValue & registerRestartableData(std::unique_ptr< RestartableDataValue > data, THREAD_ID tid, bool read_only, const RestartableDataMapName &metaname="")
Definition: MooseApp.C:2555
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
void initSyntaxFormatter(SyntaxFormatterType type, bool dump_mode)
Creates a syntax formatter for printing.
Definition: Builder.C:402
Specialized factory for generic Action System objects.
Definition: ActionFactory.h:48
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true, bool check_for_git_lfs_pointer=true)
Checks to see if a file is readable (exists and permissions)
Definition: MooseUtils.C:254
void setRestart(bool value)
Sets the restart/recover flags.
Definition: MooseApp.C:2985
AttribBoundaries tracks all boundary IDs associated with an object.
Definition: Attributes.h:188
std::shared_ptr< Executioner > _executioner
Pointer to the executioner of this run (typically build by actions)
Definition: MooseApp.h:1260
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:92
ActionFactory _action_factory
The Factory responsible for building Actions.
Definition: MooseApp.h:1221
std::string runTestsExecutable()
Returns the location of either a local repo run_tests script - or an installed test executor script i...
Definition: MooseUtils.C:65
void disableLivePrint()
Completely disables Live Print (cannot be restarted)
Definition: PerfGraph.C:67
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:93
void restoreFromInitialBackup(const bool for_restart)
Restores from a "initial" backup, that is, one set in _initial_backup.
Definition: MooseApp.C:1982
std::string underscoreToCamelCase(const std::string &underscore_name, bool leading_upper_case)
Function for converting an underscore name to a camel case name.
Definition: MooseUtils.C:580
const Parser & parser() const
Definition: MooseApp.C:2060
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
RegistrationType
Enumeration for holding the valid types of dynamic registrations allowed.
Definition: MooseApp.h:1545
Executioners are objects that do the actual work of solving your problem.
Definition: Executioner.h:30
enum MooseApp::UNUSED_CHECK _enable_unused_check
bool _recover
Whether or not this is a recovery run.
Definition: MooseApp.h:1318
void buildJsonSyntaxTree(JsonSyntaxTree &tree) const
Use MOOSE Factories to construct a parameter tree for documentation or echoing input.
Definition: Builder.C:419
Point _output_position
The output position.
Definition: MooseApp.h:1202
std::string toString(const nlohmann::json &root)
returns a string representation of the tree in input file format
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:374
const std::shared_ptr< CommandLine > _command_line
The CommandLine object.
Definition: MooseApp.h:1233
void errorCheck(const libMesh::Parallel::Communicator &comm, bool warn_unused, bool err_unused)
Definition: Builder.C:361
const nlohmann::json & getRoot() const
Get the root of the tree.
bool _error_overridden
Indicates whether warnings or errors are displayed when overridden parameters are detected...
Definition: MooseApp.h:1301
virtual std::string getVersion() const
Returns the current version of the framework or application (default: framework version).
Definition: MooseApp.C:1261
SolutionInvalidity & createRecoverableSolutionInvalidity()
Creates a recoverable SolutionInvalidity.
Definition: MooseApp.C:3587
bool _heap_profiling
Memory profiling.
Definition: MooseApp.h:1596
std::string getPrimaryFileName(bool stripLeadingPath=true) const
Return the primary (first) filename that was parsed.
Definition: Builder.C:179
TODO: delete this later - it is a temporary hack for dealing with inter-system dependencies.
Definition: Attributes.h:344
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
Class for storing and utilizing output objects.
std::string demangle(const char *name)
void addForWhom(const std::string &for_whom)
Add another name to for_whom.
Interface for objects interacting with the PerfGraph.
Executioner * getExecutioner() const
Retrieve the Executioner for this App.
Definition: MooseApp.C:2196
std::set< std::string > getLibrarySearchPaths(const std::string &library_path_from_param) const
Return the paths searched by MOOSE when loading libraries.
Definition: MooseApp.C:2947
The SolutionInvalidity will contain all the information about the occurrence(s) of solution invalidit...
std::unordered_map< std::string, DynamicLibraryInfo > _lib_handles
The library archive (name only), registration method and the handle to the method.
Definition: MooseApp.h:1371
void outputMachineReadableData(const std::string &param, const std::string &start_marker, const std::string &end_marker, const std::string &data) const
Outputs machine readable data (JSON, YAML, etc.) either to the screen (if no filename was provided as...
Definition: MooseApp.C:3641
static std::filesystem::path restartableDataFolder(const std::filesystem::path &folder_base)
virtual std::string type() const =0
String identifying the type of parameter stored.
static AppFactory & instance()
Get the instance of the AppFactory.
Definition: AppFactory.C:18
This class produces produces a dump of the InputParameters that appears like the normal input file sy...
Residual objects have this attribute.
Definition: Attributes.h:411
const std::string & getCurrentTaskName() const
const std::string & getRestartableDataMapName(const RestartableDataMapName &name) const
Definition: MooseApp.C:3560
static Capabilities & getCapabilityRegistry()
Definition: Capabilities.C:22
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
Helper class that hands out input streams to a stringstream.
std::string help
bool hasRecoverFileBase() const
Definition: MooseApp.C:1898
std::map< const RelationshipManager *, std::map< const MeshBase *, std::unique_ptr< RelationshipManager > > > _template_to_clones
Map from a template relationship manager to a map in which the key-value pairs represent the MeshBase...
Definition: MooseApp.h:1602
bool hasRestartRecoverFileBase() const
Return true if the recovery file base is set.
Definition: MooseApp.C:1892
void registerRestartableDataMapName(const RestartableDataMapName &name, std::string suffix="")
Reserve a location for storing custom RestartableDataMap objects.
Definition: MooseApp.C:3550
static void checkReservedCapability(const std::string &capability)
Helper that reports an error if the given capability is reserved and should not be added via addCapab...
Definition: MooseApp.C:2439
void restore(const std::filesystem::path &folder_base, const bool for_restart)
Restore an application from file.
Definition: MooseApp.C:1947
bool _trap_fpe
Variable indicating whether we will enable FPE trapping for this run.
void loadRestartableMetaData(const std::filesystem::path &folder_base)
Loads all available restartable meta data if it is available with the folder base folder_base...
Definition: MooseApp.C:2651
std::filesystem::path pathjoin(const std::filesystem::path &p)
Definition: MooseUtils.C:59
void addCommandLineParam(const std::string &name, const std::string &syntax, const std::string &doc_string)
virtual void executeExecutioner()
Execute the Executioner that was built.
Definition: MooseApp.C:1842
bool _distributed_mesh_on_command_line
This variable indicates that DistributedMesh should be used for the libMesh mesh underlying MooseMesh...
Definition: MooseApp.h:1315
void addExecutor(const std::string &type, const std::string &name, const InputParameters &params)
Definition: MooseApp.C:2040
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
RelationshipManagers are used for describing what kinds of non-local resources are needed for an obje...
PetscErrorCode petscSetupOutput(CommandLine *cmd_line)
Definition: PetscSupport.C:251
void add_command_line_name(const std::string &name)
Moose::Builder _builder
Builder for building app related parser tree.
Definition: MooseApp.h:1239
const std::shared_ptr< MooseMesh > & getDisplacedMesh() const
std::string RestartableDataMapName
Definition: MooseTypes.h:214
std::set< std::shared_ptr< RelationshipManager > > _relationship_managers
The relationship managers that have been added.
Definition: MooseApp.h:1350
OutputWarehouse _output_warehouse
OutputWarehouse object for this App.
Definition: MooseApp.h:1227
std::string _output_file_base
The output file basename.
Definition: MooseApp.h:1193
std::streambuf * _output_buffer_cache
Cache output buffer so the language server can turn it off then back on.
Definition: MooseApp.h:1587
static void addAppParam(InputParameters &params)
Definition: MooseApp.C:94
bool _cpu_profiling
CPU profiling.
Definition: MooseApp.h:1593
T & set(const std::string &)
const std::vector< std::shared_ptr< Action > > & allActionBlocks() const
Returns a reference to all of the actions.
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
Concrete definition of a parameter value for a specified type.
void build()
Builds all auto-buildable tasks.
OStreamProxy out
void registerAll(Factory &f, ActionFactory &af, Syntax &s)
Register objects that are in MOOSE.
Definition: Moose.C:67
virtual void runInputFile()
Actually build everything in the input file.
Definition: MooseApp.C:1762
bool setColorConsole(bool use_color, bool force=false)
Turns color escape sequences on/off for info written to stdout.
Definition: Moose.C:789
std::variant< bool, int, std::string > Type
A capability can have a bool, int, or string value.
virtual std::string header() const
Returns a string to be printed at the beginning of a simulation.
Definition: MooseApp.C:2979
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
Definition: MooseBase.h:299
Holding syntax for parsing input files.
Definition: Syntax.h:21
class infix_ostream_iterator if void
Definition: InfixIterator.h:26
std::unordered_set< std::string > DataNames
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:271
bool _has_kokkos_objects
Flag whether there is any Kokkos object added by actions.
Definition: MooseApp.h:1650
static const std::string MESH_META_DATA_SUFFIX
Definition: MooseApp.h:131
SolverSystem & getSolverSystem(unsigned int sys_num)
Get non-constant reference to a solver system.
Factory _factory
Definition: MooseApp.h:1298
void executeAllActions()
This method loops over all actions in the warehouse and executes them.
std::unique_ptr< InputParameterWarehouse > _input_parameter_warehouse
Input parameter storage structure; unique_ptr so we can control its destruction order.
Definition: MooseApp.h:1218
const InputParameters::CommandLineMetadata & getCommandLineMetadata(const std::string &name) const
virtual std::unique_ptr< GhostingFunctor > clone() const
std::string getCurrentWorkingDir()
Returns the current working directory as a string.
Definition: MooseUtils.C:436
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
const std::vector< std::string > & getInputFileNames() const
Definition: MooseApp.C:1723
void setMFEMDevice(const std::string &device_string, Moose::PassKey< MFEMProblemSolve >)
Create/configure the MFEM device with the provided device_string.
Definition: MooseApp.C:3685
Tracks whether the object is on the displaced mesh.
Definition: Attributes.h:481
static void addCapability(const std::string &capability, CapabilityUtils::Type value, const std::string &doc)
register a new capability
Definition: MooseApp.C:3668
InputStreams clear()
Clears the contents of the reader (header stream, data stream, header)
void makedirs(const std::string &dir_name, bool throw_on_failure=false)
Recursively make directories.
Definition: MooseUtils.C:449
std::unique_ptr< Backup > finalizeRestore()
Finalizes (closes) the restoration process done in restore().
Definition: MooseApp.C:1989
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:199
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
bool appendingMeshGenerators() const
Whether or not mesh generators are currently being appended (append_mesh_generator task) ...
static const std::string allow_data_driven_param
The name of the boolean parameter on the MooseApp that will enable data driven generation.
void restore(const DataNames &filter_names={})
Restores the restartable data.
std::vector< std::string > switches
The switches for the parameter (i.e., [-t, –timing])
void dynamicAllRegistration(const std::string &app_name, Factory *factory, ActionFactory *action_factory, Syntax *syntax, std::string library_path, const std::string &library_name)
Thes methods are called to register applications or objects on demand.
Definition: MooseApp.C:2744
std::string toString(const nlohmann::json &root)
Returns a string representation of the tree in input file format.
const DataNames & getRecoverableData() const
Return a reference to the recoverable data object.
Definition: MooseApp.h:721
void setDeclared(const SetDeclaredKey)
Sets that this restartable value has been declared.
const std::shared_ptr< libMesh::Parallel::Communicator > _comm
The MPI communicator this App is going to use.
Definition: MooseApp.h:1190
std::string getPrintableVersion() const
Non-virtual method for printing out the version string in a consistent format.
Definition: MooseApp.C:1267
std::shared_ptr< mfem::Device > _mfem_device
The MFEM Device object.
Definition: MooseApp.h:1620
std::vector< const T * > getActions()
Retrieve all actions in a specific type ordered by their names.
bool pathExists(const std::string &path)
Definition: MooseUtils.C:247
void createMinimalApp()
Method for creating the minimum required actions for an application (no input file) ...
Definition: MooseApp.C:2997
void setExitCode(const int exit_code)
Sets the exit code that the application will exit with.
Definition: MooseApp.h:162
Exception to be thrown whenever we have _throw_on_error set and a mooseError() is emitted...
Definition: MooseError.h:133
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition: MooseApp.C:1874
DataNames _recoverable_data_names
Data names that will only be read from the restart file during RECOVERY.
Definition: MooseApp.h:1248
Executor * getExecutor() const
Definition: MooseApp.h:335
bool _ready_to_exit
Definition: MooseApp.h:1304
The PerfGraph will hold the master list of all registered performance segments and the head PerfNode...
Definition: PerfGraph.h:43
bool copyInputs()
Handles the copy_inputs input parameter logic: Checks to see whether the passed argument is valid (a ...
Definition: MooseApp.C:2317
bool _throw_on_error
Variable to turn on exceptions during mooseError(), should only be used within MOOSE unit tests or wh...
Definition: Moose.C:820
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition: MooseBase.h:205
void clear()
This method deletes all of the Actions in the warehouse.
A scope guard that guarantees that whatever happens between when it gets created and when it is destr...
void disableCheckUnusedFlag()
Removes warnings and error checks for unrecognized variables in the input file.
Definition: MooseApp.C:2027
void add(const std::string &capability, CapabilityUtils::Type value, const std::string &doc)
register a new capability
Definition: Capabilities.C:33
bool _split_mesh
Whether or not we are performing a split mesh operation (–split-mesh)
Definition: MooseApp.h:1324
void ErrorVector unsigned int
const bool _use_executor
Indicates whether we are operating in the new/experimental executor mode instead of using the legacy ...
Definition: MooseApp.h:1279
Abstract definition of a RestartableData value.
Class for parsing input files.
Definition: Parser.h:87
Meta-action for creating common output object parameters This action serves two purpose, first it adds common output object parameters.
OutputWarehouse & getOutputWarehouse()
Get the OutputWarehouse objects.
Definition: MooseApp.C:2515
std::string getExecutableName()
Gets the name of the running executable on Mac OS X and linux.
std::string appNameToLibName(const std::string &app_name) const
Converts an application name to a library name: Examples: AnimalApp -> libanimal-oprof.la (assuming METHOD=oprof) ThreeWordAnimalApp -> libthree_word_animal-dbg.la (assuming METHOD=dbg)
Definition: MooseApp.C:2527
void addOptionalValuedCommandLineParam(const std::string &name, const std::string &syntax, const T &value, const std::string &doc_string)
Add a command line parameter with an optional value.
static InputParameters validParams()
Definition: MooseBase.C:28
static char addKnownLabel(const std::string &label)
addKnownLabel whitelists a label as valid for purposes of the checkLabels function.
Definition: Registry.C:84
virtual ~MooseApp()
Definition: MooseApp.C:1214
unsigned int THREAD_ID
Definition: MooseTypes.h:209
void setStartTime(Real time)
Set the starting time for the simulation.
Definition: MooseApp.C:2502
std::shared_ptr< Executor > _executor
Pointer to the Executor of this run.
Definition: MooseApp.h:1263
The Executor class directs the execution flow of simulations.
Definition: Executor.h:26
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
std::string findTestRoot()
Searches in the current working directory and then recursively up in each parent directory looking fo...
Definition: MooseUtils.C:75
uint8_t dof_id_type
void errorCheck()
Runs post-initialization error checking that cannot be run correctly unless the simulation has been f...
Definition: MooseApp.C:1806
std::set< std::string > getLoadedLibraryPaths() const
Return the paths of loaded libraries.
Definition: MooseApp.C:2936
std::string _early_exit_param
Indicates if simulation is ready to exit, and keeps track of which param caused it to exit...
Definition: MooseApp.h:1303
static bool isAvailable(const std::filesystem::path &folder_base)
void dynamicAppRegistration(const std::string &app_name, std::string library_path, const std::string &library_name, bool lib_load_deps)
Definition: MooseApp.C:2687
std::unique_ptr< Backup > *const _initial_backup
The backup for use in initial setup; this will get set from the _initial_backup input parameter that ...
Definition: MooseApp.h:1611