LCOV - code coverage report
Current view: top level - include/multiapps - MultiApp.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 11 13 84.6 %
Date: 2025-07-17 01:28:37 Functions: 11 13 84.6 %
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             : #include "MooseObject.h"
      13             : #include "SetupInterface.h"
      14             : #include "Restartable.h"
      15             : #include "PerfGraphInterface.h"
      16             : #include "Backup.h"
      17             : 
      18             : #include "libmesh/communicator.h"
      19             : #include "libmesh/point.h"
      20             : 
      21             : #include "nlohmann/json.h"
      22             : 
      23             : class UserObject;
      24             : class FEProblemBase;
      25             : class FEProblem;
      26             : class Executioner;
      27             : class MooseApp;
      28             : class MultiAppTransfer;
      29             : class MultiAppCoordTransform;
      30             : class Positions;
      31             : 
      32             : // libMesh forward declarations
      33             : namespace libMesh
      34             : {
      35             : class BoundingBox;
      36             : namespace MeshTools
      37             : {
      38             : class BoundingBox;
      39             : }
      40             : template <typename T>
      41             : class NumericVector;
      42             : } // namespace libMesh
      43             : 
      44             : /// Holds app partitioning information relevant to the a particular rank for a
      45             : /// multiapp scenario.
      46             : struct LocalRankConfig
      47             : {
      48             :   /// The number of simulations that should/will be run locally on this rank.
      49             :   dof_id_type num_local_sims;
      50             :   /// The (global) index of the first local simulation for this rank.  All
      51             :   /// ranks that are used to perform multi-proc parallel runs for a given
      52             :   /// simulation will have the same first_local_sim_index as each other.
      53             :   dof_id_type first_local_sim_index;
      54             :   /// The number of (sub)apps that should/will be run locally on this rank.
      55             :   /// This will generally be identical to num_local_sims unless operating in
      56             :   /// some sort of "batch" mode where a single subapp is reused for multiple
      57             :   /// simulations.
      58             :   dof_id_type num_local_apps;
      59             :   /// The (global) index of the first local app for this rank.  All ranks that
      60             :   /// are used to perform multi-proc parallel runs for a given app will have
      61             :   /// the same first_local_app_index as each other.  This will generally be
      62             :   /// identical to first_local_sim_index unless operating in some sort of "batch" mode
      63             :   /// where a single subapp is reused for multiple simulations.
      64             :   dof_id_type first_local_app_index;
      65             :   /// This is true if this rank is the primary/zero rank for a (sub)app slot.
      66             :   /// A slot is all ranks that are grouped together to run a single (sub)app
      67             :   /// together.  This field will be true for exactly one rank in each slot.
      68             :   /// This is important for things like multiapp transfers where you want to
      69             :   /// only transfer data to a given subapp once even though it may be running on
      70             :   /// multiple procs/ranks.
      71             :   bool is_first_local_rank;
      72             :   /// For every rank working on a subapp, we store the first rank on each
      73             :   /// process to make the communication to root simpler on the main app
      74             :   processor_id_type my_first_rank;
      75             : };
      76             : 
      77             : /// Returns app partitioning information relevant to the given rank for a
      78             : /// multiapp scenario with the given number of apps (napps) and parallel/mpi
      79             : /// procs (nprocs).  min_app_procs and max_app_procs define the min and max
      80             : /// number of procs that must/can be used in parallel to run a given (sub)app.
      81             : /// batch_mode affects whether 1 subapp is assigned per rank to be re-used to
      82             : /// run each of the (napps) simulations or whether 1 subapp is created for
      83             : /// each napps simulation (globally).
      84             : ///
      85             : /// Each proc calls this function in order to determine which (sub)apps among
      86             : /// the global list of all subapps for a multiapp should be run by the given
      87             : /// rank.
      88             : LocalRankConfig rankConfig(processor_id_type rank,
      89             :                            processor_id_type nprocs,
      90             :                            dof_id_type napps,
      91             :                            processor_id_type min_app_procs,
      92             :                            processor_id_type max_app_procs,
      93             :                            bool batch_mode = false);
      94             : 
      95             : /**
      96             :  * Helper class for holding Sub-app backups
      97             :  *
      98             :  * Stores the backups and also triggers a backup on store and restore on load
      99             :  */
     100             : class SubAppBackups : public std::vector<std::unique_ptr<Backup>>
     101             : {
     102             : };
     103             : 
     104             : /**
     105             :  * A MultiApp represents one or more MOOSE applications that are running simultaneously.
     106             :  * These other MOOSE apps generally represent some "sub-solve" or "embedded-solves"
     107             :  * of the overall nonlinear solve. If your system support dynamic libraries unregistered
     108             :  * Multiapps can be loaded on the fly by setting the exporting the appropriate library
     109             :  * path using "MOOSE_LIBRARY_PATH" or by specifying a single input file library path
     110             :  * in Multiapps InputParameters object.
     111             :  */
     112             : class MultiApp : public MooseObject,
     113             :                  public SetupInterface,
     114             :                  public Restartable,
     115             :                  public PerfGraphInterface
     116             : {
     117             : public:
     118             :   static InputParameters validParams();
     119             : 
     120             :   MultiApp(const InputParameters & parameters);
     121             : 
     122           0 :   virtual void preExecute() {}
     123             : 
     124             :   /**
     125             :    * Method called towards the end of the simulation to execute on final.
     126             :    */
     127             :   virtual void finalize();
     128             : 
     129             :   /**
     130             :    * Method called at the end of the simulation (after finalize).
     131             :    */
     132             :   virtual void postExecute();
     133             : 
     134             :   /**
     135             :    * Called just after construction to allow derived classes to set _positions and create
     136             :    * sub-apps accordingly.
     137             :    */
     138             :   void setupPositions();
     139             : 
     140             :   /**
     141             :    * Create the i-th local app
     142             :    * @param[in] i local app index
     143             :    */
     144             :   virtual void createLocalApp(const unsigned int i);
     145             : 
     146             :   /**
     147             :    * Method to be called in main-app initial setup for create sub-apps if using positions is false.
     148             :    */
     149             :   virtual void initialSetup() override;
     150             : 
     151             :   /**
     152             :    * Gets called just before transfers are done _to_ the MultiApp
     153             :    * (Which is just before the MultiApp is solved).
     154             :    */
     155             :   virtual void preTransfer(Real dt, Real target_time);
     156             : 
     157             :   /**
     158             :    * Re-solve all of the Apps.
     159             :    *
     160             :    * Can be called multiple times to resolve the same timestep
     161             :    * if auto_advance=false. Time is not actually advanced until
     162             :    * advanceStep() is called.
     163             :    *
     164             :    * Note that auto_advance=false might not be compatible with
     165             :    * the options for the MultiApp
     166             :    *
     167             :    * @return Whether or not all of the solves were successful (i.e. all solves made it to the
     168             :    * target_time)
     169             :    */
     170             :   virtual bool solveStep(Real dt, Real target_time, bool auto_advance = true) = 0;
     171             : 
     172             :   /**
     173             :    * Advances the multi-apps time step which is important for dt selection.
     174             :    * (Note this does not advance the *time*. That is done in Transient::endStep,
     175             :    * which is called either directly from solveStep() for loose coupling cases
     176             :    * or through finishStep() for Picard coupling cases)
     177             :    */
     178         181 :   virtual void incrementTStep(Real /*target_time*/) {}
     179             : 
     180             :   /**
     181             :    * Calls multi-apps executioners' endStep and postStep methods which creates output and advances
     182             :    * time (not the time step; see incrementTStep()) among other things. This method is only called
     183             :    * for Picard calculations because for loosely coupled calculations the executioners' endStep and
     184             :    * postStep methods are called from solveStep(). This may be called with the optional flag \p
     185             :    * recurse_through_multiapp_levels which may be useful if this method is being called for the
     186             :    * *final* time of program execution
     187             :    */
     188           0 :   virtual void finishStep(bool /*recurse_through_multiapp_levels*/ = false) {}
     189             : 
     190             :   /**
     191             :    * Save off the state of every Sub App
     192             :    *
     193             :    * This allows us to "Restore" this state later
     194             :    */
     195             :   virtual void backup();
     196             : 
     197             :   /**
     198             :    * Restore the state of every Sub App. This allows us to "Restore" this state later
     199             :    * If the app is not forced to restore, it is only done as needed (and also for the
     200             :    * apps underneath as needed)
     201             :    *
     202             :    * @param force Whether the restoration has to happen no matter what.
     203             :    */
     204             :   virtual void restore(bool force = true);
     205             : 
     206             :   /**
     207             :    * Whether or not this MultiApp should be restored at the beginning of
     208             :    * each Picard iteration.
     209             :    */
     210       41746 :   bool needsRestoration() { return !_no_restore; }
     211             : 
     212             :   /**
     213             :    * @param app The global app number to get the Executioner for
     214             :    * @return The Executioner associated with that App.
     215             :    */
     216             :   virtual Executioner * getExecutioner(unsigned int app);
     217             : 
     218             :   /**
     219             :    * Get the BoundingBox for the mesh associated with app
     220             :    * The bounding box will be shifted to be in the correct position
     221             :    * within the master domain.
     222             :    * If the MultiApp is in an RZ coordinate system the box will be
     223             :    * the size it would be if the geometry were 3D (ie if you were to revolve
     224             :    * the geometry around the axis to create the 3D geometry).
     225             :    * @param app The global app number you want to get the bounding box for
     226             :    * @param displaced_mesh True if the bounding box is retrieved for the displaced mesh, other false
     227             :    * @param coord_transform An optional coordinate transformation object
     228             :    */
     229             :   virtual libMesh::BoundingBox
     230             :   getBoundingBox(unsigned int app,
     231             :                  bool displaced_mesh,
     232             :                  const MultiAppCoordTransform * coord_transform = nullptr);
     233             : 
     234             :   /**
     235             :    * Get the FEProblemBase this MultiApp is part of.
     236             :    */
     237      167246 :   FEProblemBase & problemBase() { return _fe_problem; }
     238             : 
     239             :   /**
     240             :    * Get the FEProblemBase for the global app desired.
     241             :    * @param app The global app number
     242             :    */
     243             :   FEProblemBase & appProblemBase(unsigned int app);
     244             : 
     245             :   /**
     246             :    * Get the FEProblem for the global app is part of.
     247             :    * @param app The global app number
     248             :    */
     249             :   FEProblem & appProblem(unsigned int app);
     250             : 
     251             :   /**
     252             :    * Get a UserObject base for a specific global app
     253             :    * @param app The global app number you want to get a UserObject from.
     254             :    * @param name The name of the UserObject.
     255             :    */
     256             :   const UserObject & appUserObjectBase(unsigned int app, const std::string & name);
     257             : 
     258             :   /**
     259             :    * Get a Postprocessor value for a specified global app
     260             :    * @param app The global app number you want to get a Postprocessor from.
     261             :    * @param name The name of the Postprocessor.
     262             :    */
     263             :   Real appPostprocessorValue(unsigned int app, const std::string & name);
     264             : 
     265             :   /**
     266             :    * Get the vector to transfer to for this MultiApp.
     267             :    * In general this is the Auxiliary system solution vector.
     268             :    * @param app The global app number you want the transfer vector for.
     269             :    * @param var_name The name of the variable you are going to be transferring to.
     270             :    * @return The vector to fill.
     271             :    */
     272             :   virtual libMesh::NumericVector<libMesh::Number> & appTransferVector(unsigned int app,
     273             :                                                                       std::string var_name);
     274             : 
     275             :   /**
     276             :    * @return Number of Global Apps in this MultiApp
     277             :    */
     278     1214560 :   unsigned int numGlobalApps() const { return _total_num_apps; }
     279             : 
     280             :   /**
     281             :    * @return Number of Apps on local processor.
     282             :    */
     283       51204 :   unsigned int numLocalApps() { return _apps.size(); }
     284             : 
     285             :   /**
     286             :    * @return The global number of the first app on the local processor.
     287             :    */
     288       28415 :   unsigned int firstLocalApp() { return _first_local_app; }
     289             : 
     290             :   /**
     291             :    * @return Whether this rank is the first rank of the subapp(s) it's involved in
     292             :    */
     293             :   bool isFirstLocalRank() const;
     294             : 
     295             :   /**
     296             :    * Whether or not this MultiApp has an app on this processor.
     297             :    */
     298       28227 :   bool hasApp() { return _has_an_app; }
     299             : 
     300             :   /**
     301             :    * Whether or not the given global app number is on this processor.
     302             :    * @param global_app The global app number in question
     303             :    * @return True if the global app is on this processor
     304             :    */
     305             :   bool hasLocalApp(unsigned int global_app) const;
     306             : 
     307             :   /**
     308             :    * Get the local MooseApp object
     309             :    * @param local_app The local app number
     310             :    */
     311             :   MooseApp * localApp(unsigned int local_app);
     312             : 
     313             :   /**
     314             :    * The physical position of a global App number
     315             :    * @param app The global app number you want the position for.
     316             :    * @return the position
     317             :    */
     318             :   const Point & position(unsigned int app) const;
     319             : 
     320             :   /**
     321             :    * "Reset" the App corresponding to the global App number
     322             :    * passed in.  "Reset" means that the App will be deleted
     323             :    * and recreated.  The time for the new App will be set
     324             :    * to the current simulation time.  This might be handy
     325             :    * if some sub-app in your simulation needs to get replaced
     326             :    * by a "new" piece of material.
     327             :    *
     328             :    * @param global_app The global app number to reset.
     329             :    * @param time The time to set as the the time for the new app, this should really be the time the
     330             :    * old app was at.
     331             :    */
     332             :   virtual void resetApp(unsigned int global_app, Real time = 0.0);
     333             : 
     334             :   /**
     335             :    * Move the global_app to Point p.
     336             :    *
     337             :    * @param global_app The global app number in question
     338             :    * @param p The new position of the App.
     339             :    */
     340             :   virtual void moveApp(unsigned int global_app, Point p);
     341             : 
     342             :   /**
     343             :    * For apps outputting in position we need to change their output positions
     344             :    * if their parent app moves.
     345             :    */
     346             :   virtual void parentOutputPositionChanged();
     347             : 
     348             :   /**
     349             :    * Get the MPI communicator this MultiApp is operating on.
     350             :    * @return The MPI comm for this MultiApp
     351             :    */
     352      149803 :   MPI_Comm & comm() { return _my_comm; }
     353             : 
     354             :   /**
     355             :    * Whether or not this processor is the "root" processor for the sub communicator.
     356             :    * The "root" processor has rank 0 in the sub communicator
     357             :    */
     358       26362 :   bool isRootProcessor() { return _my_rank == 0; }
     359             : 
     360             :   /**
     361             :    * Whether or not this MultiApp is using positions or its own way for constructing sub-apps.
     362             :    */
     363      192387 :   bool usingPositions() const { return _use_positions; }
     364             : 
     365             :   /**
     366             :    * Whether or not this MultiApp is being run in position,
     367             :    * eg with the coordinate transform already applied
     368             :    */
     369      381502 :   bool runningInPosition() const { return _run_in_position; }
     370             : 
     371             :   /**
     372             :    * Add a transfer that is associated with this multiapp
     373             :    */
     374             :   void addAssociatedTransfer(MultiAppTransfer & transfer);
     375             : 
     376             :   /**
     377             :    * Transform a bounding box according to the transformations in the provided coordinate
     378             :    * transformation object
     379             :    */
     380             :   static void transformBoundingBox(libMesh::BoundingBox & box,
     381             :                                    const MultiAppCoordTransform & transform);
     382             : 
     383             :   /**
     384             :    * Sets all the app's output file bases. @see MooseApp::setOutputFileBase for usage
     385             :    */
     386             :   void setAppOutputFileBase();
     387             : 
     388             : protected:
     389             :   /// function that provides cli_args to subapps
     390             :   virtual std::vector<std::string> cliArgs() const;
     391             : 
     392             :   /**
     393             :    * _must_ fill in _positions with the positions of the sub-aps
     394             :    */
     395             :   virtual void fillPositions();
     396             : 
     397             :   /**
     398             :    * Fill command line arguments for sub apps
     399             :    */
     400             :   void readCommandLineArguments();
     401             : 
     402             :   /**
     403             :    * Helper function for creating an App instance.
     404             :    *
     405             :    * @param i The local app number to create.
     406             :    * @param start_time The initial time for the App
     407             :    */
     408             :   void createApp(unsigned int i, Real start_time);
     409             : 
     410             :   /**
     411             :    * Create an MPI communicator suitable for each app.
     412             :    *
     413             :    * Also find out which communicator we are using and what our first local app is.
     414             :    */
     415             :   void buildComm();
     416             : 
     417             :   /**
     418             :    * Map a global App number to the local number.
     419             :    * Note: This will error if given a global number that doesn't map to a local number.
     420             :    *
     421             :    * @param global_app The global app number.
     422             :    * @return The local app number.
     423             :    */
     424             :   unsigned int globalAppToLocal(unsigned int global_app);
     425             : 
     426             :   /// call back executed right before app->runInputFile()
     427             :   virtual void preRunInputFile();
     428             : 
     429             :   /**
     430             :    * @return The command line arguments to be applied to the subapp
     431             :    * with index \p local_app
     432             :    *
     433             :    * The method is virtual because it is needed to allow for batch runs
     434             :    * within the stochastic tools module; see SamplerFullSolveMultiApp for
     435             :    * an example.
     436             :    */
     437             :   virtual std::vector<std::string> getCommandLineArgs(const unsigned int local_app);
     438             : 
     439             :   /**
     440             :    * Build communicators and reserve backups.
     441             :    */
     442             :   void init(unsigned int num_apps, bool batch_mode = false);
     443             : 
     444             :   /**
     445             :    * Same as other init method, except defining a custom rank configuration
     446             :    */
     447             :   void init(unsigned int num_apps, const LocalRankConfig & config);
     448             : 
     449             :   /**
     450             :    * Create the provided number of apps.
     451             :    *
     452             :    * This is called in the setupPositions().
     453             :    */
     454             :   void createApps();
     455             : 
     456             :   /**
     457             :    * Preserve the solution from the previous simulation,
     458             :    * and it is used as an initial guess for the next run
     459             :    */
     460             :   void keepSolutionDuringRestore(bool keep_solution_during_restore);
     461             : 
     462             :   /**
     463             :    * Set the output file base of the application which corresponds to the index passed to the
     464             :    * function.
     465             :    *
     466             :    * @param index The sub-application index
     467             :    */
     468             :   void setAppOutputFileBase(unsigned int index);
     469             : 
     470             :   /**
     471             :    * Helper for constructing the name of the multiapp
     472             :    *
     473             :    * @param base_name The base name of the multiapp, usually name()
     474             :    * @param index The index of the app
     475             :    * @param total The total number of apps, which is used to pad the name with zeros
     476             :    * @return std::string The name of the multiapp
     477             :    */
     478             :   static std::string
     479             :   getMultiAppName(const std::string & base_name, dof_id_type index, dof_id_type total);
     480             : 
     481             :   /// The FEProblemBase this MultiApp is part of
     482             :   FEProblemBase & _fe_problem;
     483             : 
     484             :   /// The type of application to build
     485             :   std::string _app_type;
     486             : 
     487             :   /// The positions of all of the apps, using input constant vectors (to be deprecated)
     488             :   std::vector<Point> _positions;
     489             :   /// The positions of all of the apps, using the Positions system
     490             :   std::vector<const Positions *> _positions_objs;
     491             :   /// The offsets, in case multiple Positions objects are specified
     492             :   std::vector<unsigned int> _positions_index_offsets;
     493             : 
     494             :   /// Toggle use of "positions". Subapps are created at each different position.
     495             :   /// List of positions can be created using the Positions system
     496             :   const bool _use_positions;
     497             : 
     498             :   /// The input file for each app's simulation
     499             :   std::vector<FileName> _input_files;
     500             : 
     501             :   /// Whether to create the first app on rank 0 while all other MPI ranks are idle
     502             :   const bool & _wait_for_first_app_init;
     503             : 
     504             :   /// Number of positions for each input file
     505             :   std::vector<unsigned int> _npositions_inputfile;
     506             : 
     507             :   /// The output file basename for each multiapp
     508             :   std::string _output_base;
     509             : 
     510             :   /// The total number of apps to simulate
     511             :   unsigned int _total_num_apps;
     512             : 
     513             :   /// The number of apps this object is involved in simulating
     514             :   unsigned int _my_num_apps;
     515             : 
     516             :   /// The number of the first app on this processor
     517             :   unsigned int _first_local_app;
     518             : 
     519             :   /// The original comm handle
     520             :   const MPI_Comm & _orig_comm;
     521             : 
     522             :   /// The communicator object that holds the MPI_Comm that we're going to use
     523             :   libMesh::Parallel::Communicator _my_communicator;
     524             : 
     525             :   /// The MPI communicator this object is going to use.
     526             :   MPI_Comm & _my_comm;
     527             : 
     528             :   /// The number of processors in the original comm
     529             :   int _orig_num_procs;
     530             : 
     531             :   /// The mpi "rank" of this processor in the original communicator
     532             :   int _orig_rank;
     533             : 
     534             :   /// Node Name
     535             :   std::string _node_name;
     536             : 
     537             :   /// The mpi "rank" of this processor in the sub communicator
     538             :   int _my_rank;
     539             : 
     540             :   /// Pointers to each of the Apps
     541             :   std::vector<std::shared_ptr<MooseApp>> _apps;
     542             : 
     543             :   /// Flag if this multi-app computed its bounding box (valid only for non-displaced meshes)
     544             :   std::vector<bool> _has_bounding_box;
     545             : 
     546             :   /// This multi-app's bounding box
     547             :   std::vector<libMesh::BoundingBox> _bounding_box;
     548             : 
     549             :   /// Relative bounding box inflation
     550             :   Real _inflation;
     551             : 
     552             :   /// Additional padding added to the bounding box, useful for 1D meshes
     553             :   Point _bounding_box_padding;
     554             : 
     555             :   /// Maximum number of processors to give to each app
     556             :   processor_id_type _max_procs_per_app;
     557             : 
     558             :   /// Minimum number of processors to give to each app
     559             :   processor_id_type _min_procs_per_app;
     560             : 
     561             :   /// Whether or not to move the output of the MultiApp into position
     562             :   bool _output_in_position;
     563             : 
     564             :   /// The offset time so the MultiApp local time relative to the global time
     565             :   const Real _global_time_offset;
     566             : 
     567             :   /// The times at which to reset apps
     568             :   std::vector<Real> _reset_times;
     569             : 
     570             :   /// The apps to be reset
     571             :   std::vector<unsigned int> _reset_apps;
     572             : 
     573             :   /// Whether or not apps have been reset at each time
     574             :   std::vector<bool> _reset_happened;
     575             : 
     576             :   /// The time at which to move apps
     577             :   Real _move_time;
     578             : 
     579             :   /// The apps to be moved
     580             :   std::vector<unsigned int> _move_apps;
     581             : 
     582             :   /// The new positions for the apps to be moved
     583             :   std::vector<Point> _move_positions;
     584             : 
     585             :   /// Whether or not the move has happened
     586             :   bool _move_happened;
     587             : 
     588             :   /// Whether or not this processor as an App _at all_
     589             :   bool _has_an_app;
     590             : 
     591             :   /// CommandLine arguments (controllable!)
     592             :   const std::vector<CLIArgString> & _cli_args;
     593             : 
     594             :   /// CommandLine arguments from files
     595             :   std::vector<std::string> _cli_args_from_file;
     596             : 
     597             :   /// Flag indicates if or not restart from the latest solution
     598             :   bool _keep_solution_during_restore;
     599             : 
     600             :   /// Flag indicates if or not restart the auxiliary system from the latest auxiliary solution
     601             :   bool _keep_aux_solution_during_restore;
     602             : 
     603             :   /// Whether or not to skip restoring completely
     604             :   const bool _no_restore;
     605             : 
     606             :   /// The solution from the end of the previous solve, this is cloned from the Nonlinear solution during restore
     607             :   std::vector<std::unique_ptr<libMesh::NumericVector<Real>>> _end_solutions;
     608             : 
     609             :   /// The auxiliary solution from the end of the previous solve, this is cloned from the auxiliary solution during restore
     610             :   std::vector<std::unique_ptr<NumericVector<Real>>> _end_aux_solutions;
     611             : 
     612             :   /// The app configuration resulting from calling init
     613             :   LocalRankConfig _rank_config;
     614             : 
     615             :   /// Transfers associated with this multiapp
     616             :   std::vector<MultiAppTransfer *> _associated_transfers;
     617             : 
     618             :   /// Whether to run the child apps with their meshes transformed with the coordinate transforms
     619             :   const bool _run_in_position;
     620             : 
     621             :   /// The cached subapp backups (passed from the parent app)
     622             :   SubAppBackups & _sub_app_backups;
     623             : 
     624             :   /// Timers
     625             :   const PerfID _solve_step_timer;
     626             :   const PerfID _init_timer;
     627             :   const PerfID _backup_timer;
     628             :   const PerfID _restore_timer;
     629             :   const PerfID _reset_timer;
     630             : 
     631             : private:
     632             :   /// The parameter that was used to set the command line args, if any
     633             :   mutable std::optional<std::string> _cli_args_param;
     634             : };
     635             : 
     636             : void dataStore(std::ostream & stream, SubAppBackups & backups, void * context);
     637             : void dataLoad(std::istream & stream, SubAppBackups & backups, void * context);

Generated by: LCOV version 1.14