Line data Source code
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 : #pragma once
11 :
12 : #ifdef MOOSE_LIBTORCH_ENABLED
13 : // Libtorch includes
14 : #include <torch/types.h>
15 : #include <torch/mps.h>
16 : #include <torch/cuda.h>
17 : #include <c10/core/DeviceType.h>
18 : #endif
19 :
20 : #ifdef MOOSE_MFEM_ENABLED
21 : #include "libmesh/ignore_warnings.h"
22 : #include <mfem.hpp>
23 : #include "libmesh/restore_warnings.h"
24 : #endif
25 :
26 : // MOOSE includes
27 : #include "Moose.h"
28 : #include "Builder.h"
29 : #include "ActionWarehouse.h"
30 : #include "Factory.h"
31 : #include "ActionFactory.h"
32 : #include "OutputWarehouse.h"
33 : #include "RestartableData.h"
34 : #include "RestartableDataMap.h"
35 : #include "ConsoleStreamInterface.h"
36 : #include "PerfGraph.h"
37 : #include "PerfGraphInterface.h"
38 : #include "TheWarehouse.h"
39 : #include "RankMap.h"
40 : #include "MeshGeneratorSystem.h"
41 : #include "ChainControlDataSystem.h"
42 : #include "RestartableDataReader.h"
43 : #include "Backup.h"
44 : #include "MooseBase.h"
45 : #include "Capabilities.h"
46 : #include "MoosePassKey.h"
47 : #include "SystemInfo.h"
48 : #include "Syntax.h"
49 :
50 : #include "libmesh/parallel_object.h"
51 : #include "libmesh/mesh_base.h"
52 : #include "libmesh/point.h"
53 :
54 : // C++ includes
55 : #include <list>
56 : #include <map>
57 : #include <set>
58 : #include <unordered_set>
59 : #include <typeindex>
60 : #include <filesystem>
61 : #include <variant>
62 :
63 : // Forward declarations
64 : class Executioner;
65 : class Executor;
66 : class NullExecutor;
67 : class FEProblemBase;
68 : class InputParameterWarehouse;
69 : class CommandLine;
70 : class RelationshipManager;
71 : class SolutionInvalidity;
72 : class MultiApp;
73 : #ifdef MOOSE_MFEM_ENABLED
74 : class MFEMProblemSolve;
75 : #endif
76 :
77 : namespace libMesh
78 : {
79 : class ExodusII_IO;
80 : }
81 : namespace hit
82 : {
83 : class Node;
84 : }
85 :
86 : /**
87 : * Base class for MOOSE-based applications
88 : *
89 : * This generic class for application provides:
90 : * - parsing command line arguments,
91 : * - parsing an input file,
92 : * - executing the simulation
93 : *
94 : * Each application should register its own objects and register its own special syntax
95 : */
96 : class MooseApp : public PerfGraphInterface, public libMesh::ParallelObject, public MooseBase
97 : {
98 : public:
99 : /// Get the device accelerated computations are supposed to be running on.
100 : std::optional<MooseEnum> getComputeDevice() const;
101 :
102 : #ifdef MOOSE_LIBTORCH_ENABLED
103 : /// Get the device torch is supposed to be running on.
104 62 : torch::DeviceType getLibtorchDevice() const { return _libtorch_device; }
105 : #endif
106 :
107 : /**
108 : * Stores configuration options relating to the fixed-point solving
109 : * capability. This is used for communicating input-file-based config from
110 : * the MultiApp object/syntax to the execution (e.g. executor) system.
111 : */
112 : struct FixedPointConfig
113 : {
114 68460 : FixedPointConfig() : sub_relaxation_factor(1.0) {}
115 : /// relaxation factor to be used for a MultiApp's subapps.
116 : Real sub_relaxation_factor;
117 : /// The names of variables to transform for fixed point solve algorithms (e.g. secant, etc.).
118 : std::vector<std::string> sub_transformed_vars;
119 : /// The names of postprocessors to transform for fixed point solve algorithms (e.g. secant, etc.).
120 : std::vector<PostprocessorName> sub_transformed_pps;
121 : };
122 :
123 : static const RestartableDataMapName MESH_META_DATA;
124 : static const std::string MESH_META_DATA_SUFFIX;
125 :
126 : static InputParameters validParams();
127 :
128 : virtual ~MooseApp();
129 :
130 33363814 : TheWarehouse & theWarehouse() { return *_the_warehouse; }
131 :
132 : /**
133 : * Get printable name of the application.
134 : */
135 102 : virtual std::string getPrintableName() const { return "Application"; }
136 :
137 21 : virtual std::string appBinaryName() const
138 : {
139 21 : auto name = Moose::getExecutableName();
140 21 : name = name.substr(0, name.find_last_of("-"));
141 21 : if (name.find_first_of("/") != std::string::npos)
142 21 : name = name.substr(name.find_first_of("/") + 1, std::string::npos);
143 21 : return name;
144 0 : }
145 :
146 : /**
147 : * Get the shell exit code for the application
148 : * @return The shell exit code
149 : */
150 51589 : int exitCode() const { return _exit_code; }
151 :
152 : /**
153 : * Sets the exit code that the application will exit with.
154 : */
155 245 : void setExitCode(const int exit_code) { _exit_code = exit_code; }
156 :
157 : /**
158 : * The RankMap is a useful object for determining how the processes
159 : * are laid out on the physical nodes of the cluster
160 : */
161 962 : const RankMap & rankMap() { return _rank_map; }
162 :
163 : /**
164 : * Get the PerfGraph for this app
165 : */
166 105404150 : PerfGraph & perfGraph() { return _perf_graph; }
167 :
168 : /**
169 : * Get the SolutionInvalidity for this app
170 : */
171 : ///@{
172 12972147 : SolutionInvalidity & solutionInvalidity() { return _solution_invalidity; }
173 : const SolutionInvalidity & solutionInvalidity() const { return _solution_invalidity; }
174 : ///@}
175 :
176 : /**
177 : * Run the application
178 : */
179 : virtual void run();
180 :
181 : /**
182 : * Returns the framework version.
183 : */
184 : std::string getFrameworkVersion() const;
185 :
186 : /**
187 : * Returns the current version of the framework or application (default: framework version).
188 : */
189 : virtual std::string getVersion() const;
190 :
191 : /**
192 : * Non-virtual method for printing out the version string in a consistent format.
193 : */
194 : std::string getPrintableVersion() const;
195 :
196 : /**
197 : * Setup options based on InputParameters.
198 : */
199 : virtual void setupOptions();
200 :
201 : /**
202 : * Return a writable reference to the ActionWarehouse associated with this app
203 : */
204 8783738 : ActionWarehouse & actionWarehouse() { return _action_warehouse; }
205 : /**
206 : * Return a const reference to the ActionWarehouse associated with this app
207 : */
208 : const ActionWarehouse & actionWarehouse() const { return _action_warehouse; }
209 :
210 : /**
211 : * Returns a writable reference to the builder
212 : */
213 91623 : Moose::Builder & builder() { return _builder; }
214 :
215 : /**
216 : * Returns a writable reference to the syntax object.
217 : */
218 2420 : Syntax & syntax() { return _syntax; }
219 :
220 : /**
221 : * @return the input file names set in the Parser
222 : */
223 : const std::vector<std::string> & getInputFileNames() const;
224 :
225 : /**
226 : * @return The last input filename set (if any)
227 : */
228 : const std::string & getLastInputFileName() const;
229 :
230 : /**
231 : * Override the selection of the output file base name.
232 : * Note: This method is supposed to be called by MultiApp only.
233 : */
234 : void setOutputFileBase(const std::string & output_file_base);
235 :
236 : /**
237 : * Get the output file base name.
238 : * @param for_non_moose_build_output True for getting the file base for outputs generated with
239 : * Outputs/[outputname] input syntax.
240 : * @return The file base name used by output objects
241 : * Note: for_non_moose_build_output does not affect the returned value when this is a subapp.
242 : * for_non_moose_build_output also does not affect the returned value when Outputs/file_base
243 : * parameter is available. When for_non_moose_build_output does affect the returned value,
244 : * i.e. master without Outputs/file_base, the suffix _out is removed.
245 : */
246 : std::string getOutputFileBase(bool for_non_moose_build_output = false) const;
247 :
248 : /**
249 : * Tell the app to output in a specific position.
250 : */
251 : void setOutputPosition(const Point & p);
252 :
253 : /**
254 : * Get all checkpoint directories
255 : * @return A Set of checkpoint directories
256 : */
257 : std::list<std::string> getCheckpointDirectories() const;
258 :
259 : /**
260 : * Extract all possible checkpoint file names
261 : * @return A Set of checkpoint filenames
262 : */
263 : std::list<std::string> getCheckpointFiles() const;
264 :
265 : /**
266 : * Whether or not an output position has been set.
267 : * @return True if it has
268 : */
269 172245 : bool hasOutputPosition() const { return _output_position_set; }
270 :
271 : /**
272 : * Get the output position.
273 : * @return The position offset for the output.
274 : */
275 9820 : Point getOutputPosition() const { return _output_position; }
276 :
277 : /**
278 : * Set the starting time for the simulation. This will override any choice
279 : * made in the input file.
280 : *
281 : * @param time The start time for the simulation.
282 : */
283 : void setStartTime(Real time);
284 :
285 : /**
286 : * @return Whether or not a start time has been programmatically set using setStartTime()
287 : */
288 31683 : bool hasStartTime() const { return _start_time_set; }
289 :
290 : /**
291 : * @return The start time
292 : */
293 18457 : Real getStartTime() const { return _start_time; }
294 :
295 : /**
296 : * Each App has it's own local time. The "global" time of the whole problem might be
297 : * different. This offset is how far off the local App time is from the global time.
298 : */
299 12416 : void setGlobalTimeOffset(Real offset) { _global_time_offset = offset; }
300 :
301 : /**
302 : * Each App has it's own local time. The "global" time of the whole problem might be
303 : * different. This offset is how far off the local App time is from the global time.
304 : */
305 390321 : Real getGlobalTimeOffset() const { return _global_time_offset; }
306 :
307 : /**
308 : * Return the primary (first) filename that was parsed
309 : * Note: When stripLeadingPath is false, this function returns the same name as
310 : * getInputFileName() method when the input file is not a link.
311 : */
312 : std::string getFileName(bool stripLeadingPath = true) const;
313 :
314 : /**
315 : * Set a flag so that the parser will throw an error if overridden parameters are detected
316 : */
317 : void setErrorOverridden();
318 :
319 : /**
320 : * Removes warnings and error checks for unrecognized variables in the input file
321 : */
322 : void disableCheckUnusedFlag();
323 :
324 : /**
325 : * Retrieve the Executioner for this App
326 : */
327 : Executioner * getExecutioner() const;
328 8 : Executor * getExecutor() const { return _executor.get(); }
329 92 : NullExecutor * getNullExecutor() const { return _null_executor.get(); }
330 : bool useExecutor() const { return _use_executor; }
331 : FEProblemBase & feProblem() const;
332 :
333 : /**
334 : * Set the Executioner for this App
335 : */
336 62858 : void setExecutioner(std::shared_ptr<Executioner> && executioner) { _executioner = executioner; }
337 : void setExecutor(std::shared_ptr<Executor> && executor) { _executor = executor; }
338 : void
339 : addExecutor(const std::string & type, const std::string & name, const InputParameters & params);
340 :
341 : /**
342 : * Adds the parameters for an Executor to the list of parameters. This is done
343 : * so that the Executors can be created in _exactly_ the correct order.
344 : */
345 : void addExecutorParams(const std::string & type,
346 : const std::string & name,
347 : const InputParameters & params);
348 :
349 : /**
350 : * @return The Parser
351 : **/
352 : ///@{
353 : const Parser & parser() const;
354 : Parser & parser();
355 : ///@}
356 :
357 : /**
358 : * After adding all of the Executor Params - this function will actually cause all of them to be
359 : * built
360 : */
361 : void createExecutors();
362 :
363 : /**
364 : * Get an Executor
365 : *
366 : * @param name The name of the Executor
367 : * @param fail_if_not_found Whether or not to fail if the executor doesn't exist. If this is
368 : * false then this function will return a NullExecutor
369 : */
370 : Executor & getExecutor(const std::string & name, bool fail_if_not_found = true);
371 :
372 : /**
373 : * This info is stored here because we need a "globalish" place to put it in
374 : * order to allow communication between a multiapp and solver-specific
375 : * internals (i.e. relating to fixed-point inner loops like picard, etc.)
376 : * for handling subapp-specific modifications necessary for those solve
377 : * processes.
378 : */
379 74448 : FixedPointConfig & fixedPointConfig() { return _fixed_point_config; }
380 :
381 : /**
382 : * Returns a writable Boolean indicating whether this app will use a Nonlinear or Eigen System.
383 : */
384 126130 : bool & useNonlinear() { return _use_nonlinear; }
385 :
386 : /**
387 : * Returns a writable Boolean indicating whether this app will use an eigenvalue executioner.
388 : */
389 126146 : bool & useEigenvalue() { return _use_eigen_value; }
390 :
391 : /**
392 : * Retrieve a writable reference to the Factory associated with this App.
393 : */
394 8716621 : Factory & getFactory() { return _factory; }
395 :
396 : /**
397 : * Retrieve a writable reference to the ActionFactory associated with this App.
398 : */
399 9140328 : ActionFactory & getActionFactory() { return _action_factory; }
400 :
401 : /**
402 : * Returns the MPI processor ID of the current processor.
403 : */
404 200713 : processor_id_type processor_id() const { return _comm->rank(); }
405 :
406 : /**
407 : * Get the command line
408 : * @return The reference to the command line object
409 : * Setup options based on InputParameters.
410 : */
411 221742 : std::shared_ptr<CommandLine> commandLine() const { return _command_line; }
412 :
413 : /**
414 : * Set the flag to indicate whether or not we need to use a separate Exodus reader to read the
415 : * mesh BEFORE we create the mesh.
416 : */
417 442 : void setExodusFileRestart(bool flag) { _initial_from_file = flag; }
418 :
419 : /**
420 : * Whether or not we need to use a separate Exodus reader to read the mesh BEFORE we create the
421 : * mesh.
422 : */
423 74857 : bool getExodusFileRestart() const { return _initial_from_file; }
424 :
425 : /**
426 : * Set the Exodus reader to restart variables from an Exodus mesh file
427 : */
428 297 : void setExReaderForRestart(std::shared_ptr<libMesh::ExodusII_IO> && exreader)
429 : {
430 297 : _ex_reader = exreader;
431 297 : }
432 :
433 : /**
434 : * Get the Exodus reader to restart variables from an Exodus mesh file
435 : */
436 150261 : libMesh::ExodusII_IO * getExReaderForRestart() const { return _ex_reader.get(); }
437 :
438 : /**
439 : * Actually build everything in the input file.
440 : */
441 : virtual void runInputFile();
442 :
443 : /**
444 : * Execute the Executioner that was built.
445 : */
446 : virtual void executeExecutioner();
447 :
448 : /**
449 : * Returns true if the user specified --distributed-mesh (or
450 : * --parallel-mesh, for backwards compatibility) on the command line
451 : * and false otherwise.
452 : */
453 66327 : bool getDistributedMeshOnCommandLine() const { return _distributed_mesh_on_command_line; }
454 :
455 : /**
456 : * Whether or not this is a "recover" calculation. More specifically whether this simulation has
457 : * been recovered with something like the \p --recover command line argument. Note that this will
458 : * never return true when \p isRestarting is true
459 : */
460 : bool isRecovering() const;
461 :
462 : /**
463 : * Whether or not this is a "restart" calculation. More specifically whether this has been
464 : * restarted using the \p Problem/restart_file_base parameter. Note that this will only return
465 : * true when doing \emph checkpoint restart. This will be false if doing \emph exodus restart.
466 : * Finally this will never return true when \p isRecovering is true
467 : */
468 : bool isRestarting() const;
469 :
470 : /**
471 : * Whether or not this is a split mesh operation.
472 : */
473 : bool isSplitMesh() const;
474 :
475 : ///@{
476 : /**
477 : * Return true if the recovery file base is set
478 : */
479 : bool hasRestartRecoverFileBase() const;
480 : bool hasRecoverFileBase() const;
481 : ///@}
482 :
483 : ///@{
484 : /**
485 : * The file_base for the recovery file.
486 : */
487 15312 : std::string getRestartRecoverFileBase() const { return _restart_recover_base; }
488 : std::string getRecoverFileBase() const
489 : {
490 : mooseDeprecated("MooseApp::getRecoverFileBase is deprecated, use "
491 : "MooseApp::getRestartRecoverFileBase() instead.");
492 : return _restart_recover_base;
493 : }
494 : ///@}
495 :
496 : /**
497 : * mutator for recover_base (set by RecoverBaseAction)
498 : */
499 3421 : void setRestartRecoverFileBase(const std::string & file_base)
500 : {
501 3421 : if (file_base.empty())
502 2937 : _restart_recover_base = MooseUtils::getLatestCheckpointFilePrefix(getCheckpointFiles());
503 : else
504 484 : _restart_recover_base = file_base;
505 3413 : }
506 :
507 : /**
508 : * Whether or not this simulation should only run half its transient (useful for testing
509 : * recovery)
510 : */
511 117086 : bool testCheckpointHalfTransient() const { return _test_checkpoint_half_transient; }
512 :
513 : /**
514 : * Whether or not this simulation should fail a timestep and repeat (for testing).
515 : * Selection rules for which time step to fail in TransientBase.C constructor.
516 : */
517 61632 : bool testReStep() const { return _test_restep; }
518 :
519 : /**
520 : * Store a map of outputter names and file numbers
521 : * The MultiApp system requires this to get the file numbering to propagate down through the
522 : * Multiapps.
523 : * @param numbers Map of outputter names and file numbers
524 : *
525 : * @see MultiApp TransientMultiApp OutputWarehouse
526 : */
527 12416 : void setOutputFileNumbers(const std::map<std::string, unsigned int> & numbers)
528 : {
529 12416 : _output_file_numbers = numbers;
530 12416 : }
531 :
532 : /**
533 : * Store a map of outputter names and file numbers
534 : * The MultiApp system requires this to get the file numbering to propogate down through the
535 : * multiapps.
536 : *
537 : * @see MultiApp TransientMultiApp
538 : */
539 8460 : const std::map<std::string, unsigned int> & getOutputFileNumbers() const
540 : {
541 8460 : return _output_file_numbers;
542 : }
543 :
544 : /**
545 : * Get the OutputWarehouse objects
546 : */
547 : OutputWarehouse & getOutputWarehouse();
548 : const OutputWarehouse & getOutputWarehouse() const;
549 :
550 : /**
551 : * Get SystemInfo object
552 : * @return A pointer to the SystemInformation object
553 : */
554 92727 : const SystemInfo & getSystemInfo() const { return _sys_info; }
555 :
556 : ///@{
557 : /**
558 : * Thes methods are called to register applications or objects on demand. This method
559 : * attempts to load a dynamic library and register it when it is needed. Throws an error if
560 : * no suitable library is found that contains the app_name in question.
561 : */
562 : void dynamicAllRegistration(const std::string & app_name,
563 : Factory * factory,
564 : ActionFactory * action_factory,
565 : Syntax * syntax,
566 : std::string library_path,
567 : const std::string & library_name);
568 : void dynamicAppRegistration(const std::string & app_name,
569 : std::string library_path,
570 : const std::string & library_name,
571 : bool lib_load_deps);
572 : ///@}
573 :
574 : /**
575 : * Converts an application name to a library name:
576 : * Examples:
577 : * AnimalApp -> libanimal-oprof.la (assuming METHOD=oprof)
578 : * ThreeWordAnimalApp -> libthree_word_animal-dbg.la (assuming METHOD=dbg)
579 : */
580 : std::string appNameToLibName(const std::string & app_name) const;
581 :
582 : /**
583 : * Converts a library name to an application name:
584 : */
585 : std::string libNameToAppName(const std::string & library_name) const;
586 :
587 : /**
588 : * Return the paths of loaded libraries
589 : */
590 : std::set<std::string> getLoadedLibraryPaths() const;
591 :
592 : /**
593 : * Return the paths searched by MOOSE when loading libraries
594 : */
595 : std::set<std::string> getLibrarySearchPaths(const std::string & library_path_from_param) const;
596 :
597 : /**
598 : * Get the InputParameterWarehouse for MooseObjects
599 : */
600 : InputParameterWarehouse & getInputParameterWarehouse();
601 :
602 : /*
603 : * Register a piece of restartable data. This is data that will get
604 : * written / read to / from a restart file.
605 : *
606 : * @param data The actual data object.
607 : * @param tid The thread id of the object. Use 0 if the object is not threaded.
608 : * @param read_only Restrict the data for read-only
609 : * @param metaname (optional) register the data to the meta data storage (tid must be 0)
610 : */
611 : RestartableDataValue & registerRestartableData(std::unique_ptr<RestartableDataValue> data,
612 : THREAD_ID tid,
613 : bool read_only,
614 : const RestartableDataMapName & metaname = "");
615 :
616 : /*
617 : * Deprecated method to register a piece of restartable data.
618 : *
619 : * Use the call without a data name instead.
620 : */
621 : RestartableDataValue & registerRestartableData(const std::string & name,
622 : std::unique_ptr<RestartableDataValue> data,
623 : THREAD_ID tid,
624 : bool read_only,
625 : const RestartableDataMapName & metaname = "");
626 :
627 : /*
628 : * Check if a restartable meta data exists or not.
629 : *
630 : * @param name The full (unique) name.
631 : * @param metaname The name to the meta data storage
632 : */
633 : bool hasRestartableMetaData(const std::string & name,
634 : const RestartableDataMapName & metaname) const;
635 :
636 : /*
637 : * Retrieve restartable meta data from restartable data map
638 : *
639 : * @param name The full (unique) name.
640 : * @param metaname The name to the meta data storage
641 : * @return A reference to the restartable meta data value
642 : */
643 : RestartableDataValue & getRestartableMetaData(const std::string & name,
644 : const RestartableDataMapName & metaname,
645 : THREAD_ID tid);
646 :
647 : /**
648 : * Loads the restartable meta data for \p name if it is available with the folder base \p
649 : * folder_base
650 : */
651 : void possiblyLoadRestartableMetaData(const RestartableDataMapName & name,
652 : const std::filesystem::path & folder_base);
653 : /**
654 : * Loads all available restartable meta data if it is available with the folder base \p
655 : * folder_base
656 : */
657 : void loadRestartableMetaData(const std::filesystem::path & folder_base);
658 :
659 : /**
660 : * Writes the restartable meta data for \p name with a folder base of \p folder_base
661 : *
662 : * @return The files that were written
663 : */
664 : std::vector<std::filesystem::path>
665 : writeRestartableMetaData(const RestartableDataMapName & name,
666 : const std::filesystem::path & folder_base);
667 : /**
668 : * Writes all available restartable meta data with a file base of \p file_base
669 : *
670 : * @return The files that were written
671 : */
672 : std::vector<std::filesystem::path>
673 : writeRestartableMetaData(const std::filesystem::path & folder_base);
674 :
675 : /**
676 : * Return reference to the restartable data object
677 : * @return A reference to the restartable data object
678 : */
679 : ///@{
680 : const std::vector<RestartableDataMap> & getRestartableData() const { return _restartable_data; }
681 54 : std::vector<RestartableDataMap> & getRestartableData() { return _restartable_data; }
682 : ///@}
683 :
684 : /**
685 : * Return a reference to restartable data for the specific type flag.
686 : */
687 : RestartableDataMap & getRestartableDataMap(const RestartableDataMapName & name);
688 :
689 : /**
690 : * @return Whether or not the restartable data has the given name registered.
691 : */
692 : bool hasRestartableDataMap(const RestartableDataMapName & name) const;
693 :
694 : /**
695 : * Reserve a location for storing custom RestartableDataMap objects.
696 : *
697 : * This should be called in the constructor of an application.
698 : *
699 : * @param name A key to use for accessing the data object
700 : * @param suffix The suffix to use when appending to checkpoint output, if not supplied the
701 : * given name is used to generate the suffix (MyMetaData -> _mymetadata)
702 : */
703 : void registerRestartableDataMapName(const RestartableDataMapName & name, std::string suffix = "");
704 :
705 : /**
706 : * @return The output name for the restartable data with name \p name
707 : */
708 : const std::string & getRestartableDataMapName(const RestartableDataMapName & name) const;
709 :
710 : /**
711 : * Return a reference to the recoverable data object
712 : * @return A const reference to the recoverable data
713 : */
714 533 : const DataNames & getRecoverableData() const { return _recoverable_data_names; }
715 :
716 : /**
717 : * Backs up the application to the folder \p folder_base
718 : *
719 : * @return The files that are written in the backup
720 : */
721 : std::vector<std::filesystem::path> backup(const std::filesystem::path & folder_base);
722 : /**
723 : * Backs up the application memory in a Backup.
724 : *
725 : * @return The backup
726 : */
727 : std::unique_ptr<Backup> backup();
728 :
729 : /**
730 : * Insertion point for other apps that is called before backup()
731 : */
732 45394 : virtual void preBackup() {}
733 :
734 : /**
735 : * Restore an application from file
736 :
737 : * @param folder_base The backup folder base
738 : * @param for_restart Whether this restoration is explicitly for the first restoration of restart
739 : * data
740 : *
741 : * You must call finalizeRestore() after this in order to finalize the restoration.
742 : * The restore process is kept open in order to restore additional data after
743 : * the initial restore (that is, the restoration of data that has already been declared).
744 : */
745 : void restore(const std::filesystem::path & folder_base, const bool for_restart);
746 :
747 : /**
748 : * Restore an application from the backup \p backup
749 : *
750 : * @param backup The backup
751 : * @param for_restart Whether this restoration is explicitly for the first restoration of restart
752 : * data
753 : *
754 : * You must call finalizeRestore() after this in order to finalize the restoration.
755 : * The restore process is kept open in order to restore additional data after
756 : * the initial restore (that is, the restoration of data that has already been declared).
757 : */
758 : void restore(std::unique_ptr<Backup> backup, const bool for_restart);
759 :
760 : /**
761 : * Insertion point for other apps that is called after restore()
762 : *
763 : * @param for_restart Whether this restoration is explicitly for the
764 : * first restoration of restart data
765 : */
766 14343 : virtual void postRestore(const bool /* for_restart */) {}
767 :
768 : /**
769 : * Restores from a "initial" backup, that is, one set in _initial_backup.
770 : *
771 : * @param for_restart Whether this restoration is explicitly for the first restoration of restart
772 : * data
773 : *
774 : * This is only used for restoration of multiapp subapps, which have been given
775 : * a Backup from their parent on initialization. Said Backup is passed to this app
776 : * via the "_initial_backup" private input parameter.
777 : *
778 : * See restore() for more information
779 : */
780 : void restoreFromInitialBackup(const bool for_restart);
781 :
782 : /**
783 : * Finalizes (closes) the restoration process done in restore().
784 : *
785 : * @return The underlying Backup that was used to do the restoration (if any, will be null when
786 : * backed up from file); can be ignored to destruct it
787 : *
788 : * This releases access to the stream in which the restore was loaded from
789 : * and makes it no longer possible to restore additional data.
790 : */
791 : std::unique_ptr<Backup> finalizeRestore();
792 :
793 : /**
794 : * Returns a string to be printed at the beginning of a simulation
795 : */
796 : virtual std::string header() const;
797 :
798 : /**
799 : * The MultiApp Level
800 : * @return The current number of levels from the master app
801 : */
802 5949704 : unsigned int multiAppLevel() const { return _multiapp_level; }
803 :
804 : /**
805 : * The MultiApp number
806 : * @return The numbering in all the sub-apps on the same level
807 : */
808 60824 : unsigned int multiAppNumber() const { return _multiapp_number; }
809 :
810 : /**
811 : * Whether or not this app is the ultimate master app. (ie level == 0)
812 : */
813 1179775 : bool isUltimateMaster() const { return !_multiapp_level; }
814 :
815 : /**
816 : * Returns whether to use the parent app mesh as the mesh for this app
817 : */
818 331478 : bool useMasterMesh() const { return _use_master_mesh; }
819 :
820 : /**
821 : * Returns a pointer to the master mesh
822 : */
823 981 : const MooseMesh * masterMesh() const { return _master_mesh; }
824 :
825 : /**
826 : * Returns a pointer to the master displaced mesh
827 : */
828 849 : const MooseMesh * masterDisplacedMesh() const { return _master_displaced_mesh; }
829 :
830 : /**
831 : * Gets the system that manages the MeshGenerators
832 : */
833 308845 : MeshGeneratorSystem & getMeshGeneratorSystem() { return _mesh_generator_system; }
834 :
835 : /**
836 : * Gets the system that manages the ChainControls
837 : */
838 368826 : ChainControlDataSystem & getChainControlDataSystem() { return _chain_control_system; }
839 :
840 : /**
841 : * Add a mesh generator that will act on the meshes in the system
842 : *
843 : * @param type The type of MeshGenerator
844 : * @param name The name of the MeshGenerator
845 : * @param params The params used to construct the MeshGenerator
846 : *
847 : * See MeshGeneratorSystem::addMeshGenerator()
848 : */
849 56270 : void addMeshGenerator(const std::string & type,
850 : const std::string & name,
851 : const InputParameters & params)
852 : {
853 56270 : _mesh_generator_system.addMeshGenerator(type, name, params);
854 56266 : }
855 :
856 : /**
857 : * @returns Whether or not a mesh generator exists with the name \p name.
858 : */
859 : bool hasMeshGenerator(const MeshGeneratorName & name) const
860 : {
861 : return _mesh_generator_system.hasMeshGenerator(name);
862 : }
863 :
864 : /**
865 : * @returns The MeshGenerator with the name \p name.
866 : */
867 231 : const MeshGenerator & getMeshGenerator(const std::string & name) const
868 : {
869 231 : return _mesh_generator_system.getMeshGenerator(name);
870 : }
871 :
872 : /**
873 : * @returns The final mesh generated by the mesh generator system
874 : */
875 : std::unique_ptr<MeshBase> getMeshGeneratorMesh()
876 : {
877 : return _mesh_generator_system.getSavedMesh(_mesh_generator_system.mainMeshGeneratorName());
878 : }
879 :
880 : /**
881 : * @returns The names of all mesh generators
882 : *
883 : * See MeshGeneratorSystem::getMeshGeneratorNames()
884 : */
885 107314 : std::vector<std::string> getMeshGeneratorNames() const
886 : {
887 107314 : return _mesh_generator_system.getMeshGeneratorNames();
888 : }
889 :
890 : /**
891 : * Append a mesh generator that will act on the final mesh generator in the system
892 : *
893 : * @param type The type of MeshGenerator
894 : * @param name The name of the MeshGenerator
895 : * @param params The params used to construct the MeshGenerator
896 : *
897 : * See MeshGeneratorSystem::appendMeshGenerator()
898 : */
899 : const MeshGenerator &
900 25 : appendMeshGenerator(const std::string & type, const std::string & name, InputParameters params)
901 : {
902 25 : return _mesh_generator_system.appendMeshGenerator(type, name, params);
903 : }
904 :
905 : /**
906 : * Whether this app is constructing mesh generators
907 : *
908 : * This is virtual to allow MooseUnitApp to override it so that we can
909 : * construct MeshGenerators in unit tests
910 : */
911 : virtual bool constructingMeshGenerators() const;
912 :
913 : ///@{
914 : /**
915 : * Sets the restart/recover flags
916 : * @param state The state to set the flag to
917 : */
918 : void setRestart(bool value);
919 : void setRecover(bool value);
920 : ///@}
921 :
922 : /// Returns whether the Application is running in check input mode
923 : bool checkInput() const { return _check_input; }
924 :
925 : /// Returns whether FPE trapping is turned on (either because of debug or user requested)
926 3949693 : bool getFPTrapFlag() const { return _trap_fpe; }
927 :
928 : /**
929 : * Returns a Boolean indicating whether a RelationshipManater exists with the same name.
930 : */
931 : bool hasRelationshipManager(const std::string & name) const;
932 :
933 : /**
934 : * Transfers ownership of a RelationshipManager to the application for lifetime management.
935 : * The RelationshipManager will NOT be duplicately added if an equivalent RelationshipManager
936 : * is already active. In that case, it's possible that the object will be destroyed if the
937 : * reference count drops to zero.
938 : */
939 : bool addRelationshipManager(std::shared_ptr<RelationshipManager> relationship_manager);
940 :
941 : /// The file suffix for the checkpoint mesh
942 : static const std::string & checkpointSuffix();
943 : /// The file suffix for meta data (header and data)
944 : static std::filesystem::path metaDataFolderBase(const std::filesystem::path & folder_base,
945 : const std::string & map_suffix);
946 : /// The file suffix for restartable data
947 : std::filesystem::path restartFolderBase(const std::filesystem::path & folder_base) const;
948 :
949 : /**
950 : * @return The hit node that is responsible for creating the current action that is running,
951 : * if any
952 : *
953 : * Can be used to link objects that are created by an action to the action that
954 : * created them in input
955 : */
956 : const hit::Node * getCurrentActionHitNode() const;
957 :
958 : /**
959 : * Attach the relationship managers of the given type
960 : * Note: Geometric relationship managers that are supposed to be attached late
961 : * will be attached when Algebraic are attached.
962 : */
963 : void attachRelationshipManagers(Moose::RelationshipManagerType rm_type,
964 : bool attach_geometric_rm_final = false);
965 :
966 : /**
967 : * Attach geometric relationship managers to the given \p MeshBase object. This API is designed to
968 : * work with \p MeshGenerators which are executed at the very beginning of a simulation. No
969 : * attempt will be made to add relationship managers to a displaced mesh, because it doesn't exist
970 : * yet.
971 : */
972 : void attachRelationshipManagers(MeshBase & mesh, MooseMesh & moose_mesh);
973 :
974 : /**
975 : * Retrieve the relationship managers
976 : */
977 : const std::vector<std::shared_ptr<RelationshipManager>> & getReleationshipManagers();
978 :
979 : /**
980 : * Returns the Relationship managers info suitable for printing.
981 : */
982 : std::vector<std::pair<std::string, std::string>> getRelationshipManagerInfo() const;
983 :
984 : /**
985 : * Return the app level ExecFlagEnum, this contains all the available flags for the app.
986 : */
987 1072720 : const ExecFlagEnum & getExecuteOnEnum() const { return _execute_flags; }
988 :
989 : /**
990 : * @return Whether or not this app currently has an "initial" backup
991 : *
992 : * See _initial_backup and restoreFromInitialBackup() for more info.
993 : */
994 4409 : bool hasInitialBackup() const
995 : {
996 4409 : return _initial_backup != nullptr && *_initial_backup != nullptr;
997 : }
998 :
999 : /**
1000 : * Whether to enable automatic scaling by default
1001 : */
1002 62069 : bool defaultAutomaticScaling() const { return _automatic_automatic_scaling; }
1003 :
1004 : // Return the communicator for this application
1005 123 : const std::shared_ptr<libMesh::Parallel::Communicator> getCommunicator() const { return _comm; }
1006 :
1007 : /**
1008 : * Return the container of relationship managers
1009 : */
1010 51 : const std::set<std::shared_ptr<RelationshipManager>> & relationshipManagers() const
1011 : {
1012 51 : return _relationship_managers;
1013 : }
1014 :
1015 : /**
1016 : * Function to check the integrity of the restartable meta data structure
1017 : */
1018 : void checkMetaDataIntegrity() const;
1019 :
1020 : ///@{
1021 : /**
1022 : * Iterator based access to the extra RestartableDataMap objects; see Checkpoint.C for use case.
1023 : *
1024 : * These are MOOSE internal functions and should not be used otherwise.
1025 : */
1026 37 : auto getRestartableDataMapBegin() { return _restartable_meta_data.begin(); }
1027 :
1028 74 : auto getRestartableDataMapEnd() { return _restartable_meta_data.end(); }
1029 : ///@}
1030 :
1031 : /**
1032 : * Whether this application should by default error on Jacobian nonzero reallocations. The
1033 : * application level setting can always be overridden by setting the \p
1034 : * error_on_jacobian_nonzero_reallocation parameter in the \p Problem block of the input file
1035 : */
1036 162 : virtual bool errorOnJacobianNonzeroReallocation() const { return false; }
1037 :
1038 : /**
1039 : * Registers an interface object for accessing with getInterfaceObjects.
1040 : *
1041 : * This should be called within the constructor of the interface in interest.
1042 : */
1043 : template <class T>
1044 : void registerInterfaceObject(T & interface);
1045 :
1046 : /**
1047 : * Gets the registered interface objects for a given interface.
1048 : *
1049 : * For this to work, the interface must register itself using registerInterfaceObject.
1050 : */
1051 : template <class T>
1052 : const std::vector<T *> & getInterfaceObjects() const;
1053 :
1054 : static void addAppParam(InputParameters & params);
1055 : static void addInputParam(InputParameters & params);
1056 :
1057 : /**
1058 : * Whether or not we are forcefully restarting (allowing the load of potentially
1059 : * incompatibie checkpoints); used within RestartableDataReader
1060 : */
1061 71762 : bool forceRestart() const { return _force_restart; }
1062 :
1063 : /// Returns whether the flag for unused parameters is set to throw a warning only
1064 3453 : bool unusedFlagIsWarning() const { return _enable_unused_check == WARN_UNUSED; }
1065 :
1066 : /// Returns whether the flag for unused parameters is set to throw an error
1067 3443 : bool unusedFlagIsError() const { return _enable_unused_check == ERROR_UNUSED; }
1068 :
1069 : #ifdef MOOSE_MFEM_ENABLED
1070 : /**
1071 : * Create/configure the MFEM device with the provided \p device_string. More than one device can
1072 : * be configured. If supplying multiple devices, they should be comma separated
1073 : */
1074 : void setMFEMDevice(const std::string & device_string, Moose::PassKey<MFEMProblemSolve>);
1075 :
1076 : /**
1077 : * Get the MFEM device object
1078 : */
1079 8315 : std::shared_ptr<mfem::Device> getMFEMDevice(Moose::PassKey<MultiApp>) { return _mfem_device; }
1080 :
1081 : /**
1082 : * Get the configured MFEM devices
1083 : */
1084 : const std::set<std::string> & getMFEMDevices(Moose::PassKey<MultiApp>) const;
1085 : #endif
1086 :
1087 : protected:
1088 : /**
1089 : * Helper method for dynamic loading of objects
1090 : */
1091 : void dynamicRegistration(const libMesh::Parameters & params);
1092 :
1093 : /**
1094 : * Recursively loads libraries and dependencies in the proper order to fully register a
1095 : * MOOSE application that may have several dependencies. REQUIRES: dynamic linking loader support.
1096 : */
1097 : void loadLibraryAndDependencies(const std::string & library_filename,
1098 : const libMesh::Parameters & params,
1099 : bool load_dependencies = true);
1100 :
1101 : /// Constructor is protected so that this object is constructed through the AppFactory object
1102 : MooseApp(const InputParameters & parameters);
1103 :
1104 : /**
1105 : * NOTE: This is an internal function meant for MOOSE use only!
1106 : *
1107 : * Register a piece of restartable data that will be used in a filter in/out during
1108 : * deserialization. Note however that this data will always be written to the restart file.
1109 : *
1110 : * @param name The full (unique) name.
1111 : * @param filter The filter name where to direct the name
1112 : */
1113 : void registerRestartableNameWithFilter(const std::string & name,
1114 : Moose::RESTARTABLE_FILTER filter);
1115 :
1116 : /**
1117 : * Runs post-initialization error checking that cannot be run correctly unless the simulation
1118 : * has been fully set up and initialized.
1119 : */
1120 : void errorCheck();
1121 :
1122 : /**
1123 : * Outputs machine readable data (JSON, YAML, etc.) either to the screen (if no filename was
1124 : * provided as an argument to the parameter param) or to a file (if a filename was provided).
1125 : */
1126 : void outputMachineReadableData(const std::string & param,
1127 : const std::string & start_marker,
1128 : const std::string & end_marker,
1129 : const std::string & data) const;
1130 : ///@{ register a new capability
1131 : static void addCapability(const std::string & capability,
1132 : CapabilityUtils::Type value,
1133 : const std::string & doc);
1134 : static void
1135 : addCapability(const std::string & capability, const char * value, const std::string & doc);
1136 : //@}
1137 :
1138 : /// The string representation of the type of this object as registered (see registerApp(AppName))
1139 : const std::string _type;
1140 :
1141 : /// The MPI communicator this App is going to use
1142 : const std::shared_ptr<libMesh::Parallel::Communicator> _comm;
1143 :
1144 : /// The output file basename
1145 : std::string _output_file_base;
1146 :
1147 : /// Whether or not file base is set through input or setOutputFileBase by MultiApp
1148 : bool _file_base_set_by_user;
1149 :
1150 : /// Whether or not an output position has been set for this app
1151 : bool _output_position_set;
1152 :
1153 : /// The output position
1154 : Point _output_position;
1155 :
1156 : /// Whether or not an start time has been set
1157 : bool _start_time_set;
1158 :
1159 : /// The time at which to start the simulation
1160 : Real _start_time;
1161 :
1162 : /// Offset of the local App time to the "global" problem time
1163 : Real _global_time_offset;
1164 :
1165 : /// Syntax of the input file
1166 : Syntax _syntax;
1167 :
1168 : /// Input parameter storage structure; unique_ptr so we can control
1169 : /// its destruction order
1170 : std::unique_ptr<InputParameterWarehouse> _input_parameter_warehouse;
1171 :
1172 : /// The Factory responsible for building Actions
1173 : ActionFactory _action_factory;
1174 :
1175 : /// Where built actions are stored
1176 : ActionWarehouse _action_warehouse;
1177 :
1178 : /// OutputWarehouse object for this App
1179 : OutputWarehouse _output_warehouse;
1180 :
1181 : /// Parser for parsing the input file (owns the root hit node)
1182 : const std::shared_ptr<Parser> _parser;
1183 :
1184 : /// The CommandLine object
1185 : const std::shared_ptr<CommandLine> _command_line;
1186 :
1187 : /// System Information
1188 : SystemInfo _sys_info;
1189 :
1190 : /// Builder for building app related parser tree
1191 : Moose::Builder _builder;
1192 :
1193 : /// Where the restartable data is held (indexed on tid)
1194 : std::vector<RestartableDataMap> _restartable_data;
1195 :
1196 : /**
1197 : * Data names that will only be read from the restart file during RECOVERY.
1198 : * e.g. these names are _excluded_ during restart.
1199 : */
1200 : DataNames _recoverable_data_names;
1201 :
1202 : /// The PerfGraph object for this application (recoverable)
1203 : PerfGraph & _perf_graph;
1204 :
1205 : /// The SolutionInvalidity object for this application
1206 : SolutionInvalidity & _solution_invalidity;
1207 :
1208 : /// The RankMap is a useful object for determining how the processes are laid out on the physical hardware
1209 : const RankMap _rank_map;
1210 :
1211 : /// Pointer to the executioner of this run (typically build by actions)
1212 : std::shared_ptr<Executioner> _executioner;
1213 :
1214 : /// Pointer to the Executor of this run
1215 : std::shared_ptr<Executor> _executor;
1216 :
1217 : /// Pointers to all of the Executors for this run
1218 : std::map<std::string, std::shared_ptr<Executor>> _executors;
1219 :
1220 : /// Used in building the Executors
1221 : /// Maps the name of the Executor block to the <type, params>
1222 : std::unordered_map<std::string, std::pair<std::string, std::unique_ptr<InputParameters>>>
1223 : _executor_params;
1224 :
1225 : /// Multiapp-related fixed point algorithm configuration details
1226 : /// primarily intended to be passed to and used by the executioner/executor system.
1227 : FixedPointConfig _fixed_point_config;
1228 :
1229 : /// Indicates whether we are operating in the new/experimental executor mode
1230 : /// instead of using the legacy executioner system.
1231 : const bool _use_executor;
1232 :
1233 : /// Used to return an executor that does nothing
1234 : std::shared_ptr<NullExecutor> _null_executor;
1235 :
1236 : /// Boolean to indicate whether to use a Nonlinear or EigenSystem (inspected by actions)
1237 : bool _use_nonlinear;
1238 :
1239 : /// Boolean to indicate whether to use an eigenvalue executioner
1240 : bool _use_eigen_value;
1241 :
1242 : /// Indicates whether warnings, errors, or no output is displayed when unused parameters are detected
1243 : enum UNUSED_CHECK
1244 : {
1245 : OFF,
1246 : WARN_UNUSED,
1247 : ERROR_UNUSED
1248 : } _enable_unused_check;
1249 :
1250 : Factory _factory;
1251 :
1252 : /// Indicates whether warnings or errors are displayed when overridden parameters are detected
1253 : bool _error_overridden;
1254 : /// Indicates if simulation is ready to exit, and keeps track of which param caused it to exit
1255 : std::string _early_exit_param;
1256 : bool _ready_to_exit;
1257 : /// The exit code
1258 : int _exit_code;
1259 :
1260 : /// This variable indicates when a request has been made to restart from an Exodus file
1261 : bool _initial_from_file;
1262 :
1263 : /// The Exodus reader when _initial_from_file is set to true
1264 : std::shared_ptr<libMesh::ExodusII_IO> _ex_reader;
1265 :
1266 : /// This variable indicates that DistributedMesh should be used for the libMesh mesh underlying MooseMesh.
1267 : bool _distributed_mesh_on_command_line;
1268 :
1269 : /// Whether or not this is a recovery run
1270 : bool _recover;
1271 :
1272 : /// Whether or not this is a restart run
1273 : bool _restart;
1274 :
1275 : /// Whether or not we are performing a split mesh operation (--split-mesh)
1276 : bool _split_mesh;
1277 :
1278 : /// Whether or not we are using a (pre-)split mesh (automatically DistributedMesh)
1279 : const bool _use_split;
1280 :
1281 : /// Whether or not we are forcefully attempting to load checkpoints (--force-restart)
1282 : const bool _force_restart;
1283 :
1284 : /// Whether or not FPE trapping should be turned on.
1285 : bool _trap_fpe;
1286 :
1287 : /// The base name to restart/recover from. If blank then we will find the newest checkpoint file.
1288 : std::string _restart_recover_base;
1289 :
1290 : /// Whether or not this simulation should only run half its transient (useful for testing recovery)
1291 : const bool _test_checkpoint_half_transient;
1292 : /// Whether or not this simulation should fail its middle timestep and repeat (for testing)
1293 : const bool _test_restep;
1294 :
1295 : /// Map of outputer name and file number (used by MultiApps to propagate file numbers down through the multiapps)
1296 : std::map<std::string, unsigned int> _output_file_numbers;
1297 :
1298 : /// true if we want to just check the input file
1299 : bool _check_input;
1300 :
1301 : /// The relationship managers that have been added
1302 : std::set<std::shared_ptr<RelationshipManager>> _relationship_managers;
1303 :
1304 : /// The relationship managers that have been attached (type -> RMs)
1305 : std::map<Moose::RelationshipManagerType, std::set<const RelationshipManager *>>
1306 : _attached_relationship_managers;
1307 :
1308 : /// A map from undisplaced relationship managers to their displaced clone (stored as the base
1309 : /// GhostingFunctor). Anytime we clone in attachRelationshipManagers we create a map entry from
1310 : /// the cloned undisplaced relationship manager to its displaced clone counterpart. We leverage
1311 : /// this map when removing relationship managers/ghosting functors
1312 : std::unordered_map<RelationshipManager *, std::shared_ptr<libMesh::GhostingFunctor>>
1313 : _undisp_to_disp_rms;
1314 :
1315 : struct DynamicLibraryInfo
1316 : {
1317 : void * library_handle;
1318 : std::string full_path;
1319 : std::unordered_set<std::string> entry_symbols;
1320 : };
1321 :
1322 : /// The library archive (name only), registration method and the handle to the method
1323 : std::unordered_map<std::string, DynamicLibraryInfo> _lib_handles;
1324 :
1325 : private:
1326 : /**
1327 : * Internal function used to recursively create the executor objects.
1328 : *
1329 : * Called by createExecutors
1330 : *
1331 : * @param current_executor_name The name of the executor currently needing to be built
1332 : * @param possible_roots The names of executors that are currently candidates for being the root
1333 : */
1334 : void recursivelyCreateExecutors(const std::string & current_executor_name,
1335 : std::list<std::string> & possible_roots,
1336 : std::list<std::string> & current_branch);
1337 :
1338 : /**
1339 : * Register all base MooseApp capabilities to the Moose::Capabilities registry.
1340 : * Apps and Modules may register additional capabilities in their registerAll
1341 : * function.
1342 : */
1343 : void registerCapabilities();
1344 :
1345 : /**
1346 : * Purge this relationship manager from meshes and DofMaps and finally from us. This method is
1347 : * private because only this object knows when we should remove relationship managers: when we are
1348 : * adding relationship managers to this object's storage, we perform an operator>= comparison
1349 : * between our existing RMs and the RM we are trying to add. If any comparison returns true, we do
1350 : * not add the new RM because the comparison indicates that we would gain no new coverage.
1351 : * However, if no comparison return true, then we add the new RM and we turn the comparison
1352 : * around! Consequently if our new RM is >= than any of our preexisting RMs, we remove those
1353 : * preexisting RMs using this method
1354 : */
1355 : void removeRelationshipManager(std::shared_ptr<RelationshipManager> relationship_manager);
1356 :
1357 : #ifdef MOOSE_LIBTORCH_ENABLED
1358 : /**
1359 : * Function to determine the device which should be used by libtorch on this
1360 : * application. We use this function to decide what is available on different
1361 : * builds.
1362 : * @param device Enum to describe if a cpu or a gpu should be used.
1363 : */
1364 : torch::DeviceType determineLibtorchDeviceType(const MooseEnum & device) const;
1365 : #endif
1366 :
1367 : ///@{
1368 : /// Structs that are used in the _interface_registry
1369 : struct InterfaceRegistryObjectsBase
1370 : {
1371 227653 : virtual ~InterfaceRegistryObjectsBase() {}
1372 : };
1373 :
1374 : template <class T>
1375 : struct InterfaceRegistryObjects : public InterfaceRegistryObjectsBase
1376 : {
1377 : std::vector<T *> _objects;
1378 : };
1379 : ///@}
1380 :
1381 : /** Method for creating the minimum required actions for an application (no input file)
1382 : *
1383 : * Mimics the following input file:
1384 : *
1385 : * [Mesh]
1386 : * type = GeneratedMesh
1387 : * dim = 1
1388 : * nx = 1
1389 : * []
1390 : *
1391 : * [Executioner]
1392 : * type = Transient
1393 : * num_steps = 1
1394 : * dt = 1
1395 : * []
1396 : *
1397 : * [Problem]
1398 : * solve = false
1399 : * []
1400 : *
1401 : * [Outputs]
1402 : * console = false
1403 : * []
1404 : */
1405 : void createMinimalApp();
1406 :
1407 : /**
1408 : * Set a flag so that the parser will either warn or error when unused variables are seen after
1409 : * parsing is complete.
1410 : */
1411 : void setCheckUnusedFlag(bool warn_is_error = false);
1412 :
1413 : /**
1414 : * @return whether we have created any clones for the provided template relationship manager and
1415 : * mesh yet. This may be false for instance when we are in the initial add relationship manager
1416 : * stage and haven't attempted attaching any relationship managers to the mesh or dof map yet
1417 : * (which is when we generate the clones). It's also maybe possible that we've created a clone of
1418 : * a given \p template_rm but not for the provided mesh so we return false in that case as well
1419 : */
1420 : bool hasRMClone(const RelationshipManager & template_rm, const MeshBase & mesh) const;
1421 :
1422 : /**
1423 : * Return the relationship manager clone originally created from the provided template
1424 : * relationship manager and mesh
1425 : */
1426 : RelationshipManager & getRMClone(const RelationshipManager & template_rm,
1427 : const MeshBase & mesh) const;
1428 :
1429 : /**
1430 : * Take an input relationship manager, clone it, and then initialize it with provided mesh and
1431 : * optional \p dof_map
1432 : * @param template_rm The relationship manager template from which we will clone
1433 : * @param moose_mesh The moose mesh to use for initialization
1434 : * @param mesh The mesh to use for initialization
1435 : * @param dof_map An optional parameter that, if provided, will be used to help init the cloned
1436 : * relationship manager
1437 : * @return a reference to the cloned and initialized relationship manager
1438 : */
1439 : RelationshipManager & createRMFromTemplateAndInit(const RelationshipManager & template_rm,
1440 : MooseMesh & moose_mesh,
1441 : MeshBase & mesh,
1442 : const libMesh::DofMap * dof_map = nullptr);
1443 :
1444 : /**
1445 : * Creates a recoverable PerfGraph.
1446 : *
1447 : * This is a separate method so that it can be used in the constructor (multiple calls
1448 : * are required to declare it).
1449 : */
1450 : PerfGraph & createRecoverablePerfGraph();
1451 :
1452 : /**
1453 : * Creates a recoverable SolutionInvalidity.
1454 : *
1455 : * This is a separate method so that it can be used in the constructor (multiple calls
1456 : * are required to declare it).
1457 : */
1458 : SolutionInvalidity & createRecoverableSolutionInvalidity();
1459 :
1460 : /**
1461 : * Prints a message showing the installable inputs for a given application (if
1462 : * getInstallableInputs has been overridden for an application).
1463 : */
1464 : bool showInputs() const;
1465 :
1466 : /**
1467 : * Method to retrieve the installable inputs from a given applications <app>Revision.h file.
1468 : */
1469 : virtual std::string getInstallableInputs() const;
1470 :
1471 : /**
1472 : * Handles the copy_inputs input parameter logic: Checks to see whether the passed argument is
1473 : * valid (a readable installed directory) and recursively copies those files into a
1474 : * read/writable location for the user.
1475 : * @return a Boolean value used to indicate whether the application should exit early
1476 : */
1477 : bool copyInputs();
1478 :
1479 : /**
1480 : * Handles the run input parameter logic: Checks to see whether a directory exists in user space
1481 : * and launches the TestHarness to process the given directory.
1482 : * @return a Boolean value used to indicate whether the application should exit early
1483 : */
1484 : bool runInputs();
1485 :
1486 : /**
1487 : * Helper that reports an error if the given capability is reserved and
1488 : * should not be added via addCapability().
1489 : */
1490 : static void checkReservedCapability(const std::string & capability);
1491 :
1492 : /// General storage for custom RestartableData that can be added to from outside applications
1493 : std::unordered_map<RestartableDataMapName, std::pair<RestartableDataMap, std::string>>
1494 : _restartable_meta_data;
1495 :
1496 : /// Enumeration for holding the valid types of dynamic registrations allowed
1497 : enum RegistrationType
1498 : {
1499 : APPLICATION,
1500 : REGALL
1501 : };
1502 :
1503 : /// The combined warehouse for storing any MooseObject based object
1504 : std::unique_ptr<TheWarehouse> _the_warehouse;
1505 :
1506 : /// Level of multiapp, the master is level 0. This used by the Console to indent output
1507 : unsigned int _multiapp_level;
1508 :
1509 : /// Numbering in all the sub-apps on the same level
1510 : unsigned int _multiapp_number;
1511 :
1512 : /// Whether to use the parent app mesh for this app
1513 : const bool _use_master_mesh;
1514 :
1515 : /// The mesh from master app
1516 : const MooseMesh * const _master_mesh;
1517 :
1518 : /// The displaced mesh from master app
1519 : const MooseMesh * const _master_displaced_mesh;
1520 :
1521 : /// The system that manages the MeshGenerators
1522 : MeshGeneratorSystem _mesh_generator_system;
1523 :
1524 : /// The system that manages the ChainControls
1525 : ChainControlDataSystem _chain_control_system;
1526 :
1527 : RestartableDataReader _rd_reader;
1528 :
1529 : /**
1530 : * Execution flags for this App. Note: These are copied on purpose instead of maintaining a
1531 : * reference to the ExecFlagRegistry registry. In the Multiapp case, the registry may be
1532 : * augmented, changing the flags "known" to the application in the middle of executing the setup.
1533 : * This causes issues with the application having to process flags that aren't specifically
1534 : * registered.
1535 : */
1536 : const ExecFlagEnum _execute_flags;
1537 :
1538 : /// Cache output buffer so the language server can turn it off then back on
1539 : std::streambuf * _output_buffer_cache;
1540 :
1541 : /// Whether to turn on automatic scaling by default
1542 : const bool _automatic_automatic_scaling;
1543 :
1544 : /// CPU profiling
1545 : bool _cpu_profiling = false;
1546 :
1547 : /// Memory profiling
1548 : bool _heap_profiling = false;
1549 :
1550 : /// Map from a template relationship manager to a map in which the key-value pairs represent the \p
1551 : /// MeshBase object and the clone of the template relationship manager, e.g. the top-level map key
1552 : std::map<const RelationshipManager *,
1553 : std::map<const MeshBase *, std::unique_ptr<RelationshipManager>>>
1554 : _template_to_clones;
1555 :
1556 : /// Registration for interface objects
1557 : std::map<std::type_index, std::unique_ptr<InterfaceRegistryObjectsBase>> _interface_registry;
1558 :
1559 : /// The backup for use in initial setup; this will get set from the _initial_backup
1560 : /// input parameter that typically gets set from a MultiApp that has a backup
1561 : /// This is a pointer to a pointer because at the time of construction of the app,
1562 : /// the backup will not be filled yet.
1563 : std::unique_ptr<Backup> * const _initial_backup;
1564 :
1565 : #ifdef MOOSE_LIBTORCH_ENABLED
1566 : /// The libtorch device this app is using (converted from compute_device)
1567 : const torch::DeviceType _libtorch_device;
1568 : #endif
1569 :
1570 : #ifdef MOOSE_MFEM_ENABLED
1571 : /// The MFEM Device object
1572 : std::shared_ptr<mfem::Device> _mfem_device;
1573 :
1574 : /// MFEM supported devices based on user-provided config
1575 : std::set<std::string> _mfem_devices;
1576 : #endif
1577 :
1578 : // Allow FEProblemBase to set the recover/restart state, so make it a friend
1579 : friend class FEProblemBase;
1580 : friend class Restartable;
1581 : friend class SubProblem;
1582 : };
1583 :
1584 : template <class T>
1585 : void
1586 968120 : MooseApp::registerInterfaceObject(T & interface)
1587 : {
1588 : static_assert(!std::is_base_of<MooseObject, T>::value, "T is not an interface");
1589 :
1590 968120 : InterfaceRegistryObjects<T> * registry = nullptr;
1591 968120 : auto it = _interface_registry.find(typeid(T));
1592 968120 : if (it == _interface_registry.end())
1593 : {
1594 241831 : auto new_registry = std::make_unique<InterfaceRegistryObjects<T>>();
1595 241831 : registry = new_registry.get();
1596 241831 : _interface_registry.emplace(typeid(T), std::move(new_registry));
1597 241831 : }
1598 : else
1599 726289 : registry = static_cast<InterfaceRegistryObjects<T> *>(it->second.get());
1600 :
1601 : mooseAssert(std::count(registry->_objects.begin(), registry->_objects.end(), &interface) == 0,
1602 : "Interface already registered");
1603 968120 : registry->_objects.push_back(&interface);
1604 968120 : }
1605 :
1606 : template <class T>
1607 : const std::vector<T *> &
1608 4558678 : MooseApp::getInterfaceObjects() const
1609 : {
1610 : static_assert(!std::is_base_of<MooseObject, T>::value, "T is not an interface");
1611 :
1612 4558678 : const auto it = _interface_registry.find(typeid(T));
1613 4558678 : if (it != _interface_registry.end())
1614 4557097 : return static_cast<InterfaceRegistryObjects<T> *>(it->second.get())->_objects;
1615 1581 : const static std::vector<T *> empty;
1616 1581 : return empty;
1617 : }
1618 :
1619 : #ifdef MOOSE_MFEM_ENABLED
1620 : inline const std::set<std::string> &
1621 8315 : MooseApp::getMFEMDevices(Moose::PassKey<MultiApp>) const
1622 : {
1623 8315 : return _mfem_devices;
1624 : }
1625 : #endif
|