LCOV - code coverage report
Current view: top level - include/base - MooseApp.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33416 (b10b36) with base 9fbd27 Lines: 119 120 99.2 %
Date: 2026-07-23 16:15:30 Functions: 85 86 98.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14