LCOV - code coverage report
Current view: top level - include/systems - equation_systems.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4493 (1fc31f) with base e7717b Lines: 49 55 89.1 %
Date: 2026-07-08 01:01:35 Functions: 19 45 42.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : #ifndef LIBMESH_EQUATION_SYSTEMS_H
      21             : #define LIBMESH_EQUATION_SYSTEMS_H
      22             : 
      23             : // Local Includes
      24             : #include "libmesh/libmesh_common.h"
      25             : #include "libmesh/parameters.h"
      26             : #include "libmesh/system.h"
      27             : #include "libmesh/parallel_object.h"
      28             : 
      29             : // HP aCC needs these for some reason
      30             : #ifdef __HP_aCC
      31             : # include "libmesh/frequency_system.h"
      32             : # include "libmesh/transient_system.h"
      33             : # include "libmesh/newmark_system.h"
      34             : # include "libmesh/steady_system.h"
      35             : #endif
      36             : 
      37             : // C++ includes
      38             : #include <cstddef>
      39             : #include <functional>
      40             : #include <map>
      41             : #include <set>
      42             : #include <string>
      43             : #include <string_view>
      44             : #include <vector>
      45             : #include <memory>
      46             : 
      47             : namespace libMesh
      48             : {
      49             : 
      50             : // Forward Declarations
      51             : class Elem;
      52             : class MeshBase;
      53             : enum XdrMODE : int;
      54             : 
      55             : /**
      56             :  * This is the \p EquationSystems class.  It is in charge
      57             :  * of handling all the various equation systems defined
      58             :  * for a \p MeshBase.  It may have multiple systems, which may
      59             :  * be active or inactive, so that at different solution
      60             :  * stages only a sub-set may be solved for.  Also, through
      61             :  * the templated access, different types of systems
      62             :  * may be handled.  Also other features, like flags,
      63             :  * parameters, I/O etc are provided.
      64             :  *
      65             :  * \author Benjamin S. Kirk
      66             :  * \date 2002-2007
      67             :  * \brief Manages multiples systems of equations.
      68             :  */
      69       24720 : class EquationSystems : public ReferenceCountedObject<EquationSystems>,
      70             :                         public ParallelObject
      71             : 
      72             : {
      73             : public:
      74             : 
      75             :   /**
      76             :    * Define enumeration to set properties in EquationSystems::read()
      77             :    */
      78             :   enum ReadFlags { READ_HEADER           = 1,
      79             :                    READ_DATA             = 2,
      80             :                    READ_ADDITIONAL_DATA  = 4,
      81             :                    READ_LEGACY_FORMAT    = 8,
      82             :                    TRY_READ_IFEMS        = 16,
      83             :                    READ_BASIC_ONLY       = 32 };
      84             : 
      85             :   /**
      86             :    * Define enumeration to set properties in EquationSystems::write()
      87             :    */
      88             :   enum WriteFlags { WRITE_DATA             = 1,
      89             :                     WRITE_ADDITIONAL_DATA  = 2,
      90             :                     WRITE_PARALLEL_FILES   = 4,
      91             :                     WRITE_SERIAL_FILES     = 8 };
      92             : 
      93             :   /**
      94             :    * Constructor.
      95             :    */
      96             :   EquationSystems (MeshBase & mesh);
      97             : 
      98             :   /**
      99             :    * Destructor.  Should be virtual, since the user may want to derive
     100             :    * subclasses of EquationSystems.
     101             :    */
     102             :   virtual ~EquationSystems ();
     103             : 
     104             :   /**
     105             :    * Restores the data structure to a pristine state.
     106             :    */
     107             :   virtual void clear ();
     108             : 
     109             :   /**
     110             :    * Initialize all the systems
     111             :    */
     112             :   virtual void init ();
     113             : 
     114             :   /**
     115             :    * Handle any mesh changes and reinitialize all the systems on the
     116             :    * updated mesh
     117             :    */
     118             :   virtual void reinit ();
     119             : 
     120             :   /**
     121             :    * Handle the association of a completely *new* mesh with the
     122             :    * EquationSystem and all the Systems assigned to it.
     123             :    */
     124             :   virtual void reinit_mesh ();
     125             : 
     126             :   /**
     127             :    * Enable or disable default ghosting functors on the Mesh and on
     128             :    * all Systems.  Standard ghosting is enabled by default.  If
     129             :    * disabled, default ghosting will also be disabled on any later
     130             :    * added systems.
     131             :    *
     132             :    * Unless other equivalent ghosting functors have been added,
     133             :    * removing the default coupling functor is only safe for explicit
     134             :    * solves, and removing the default algebraic ghosting functor is
     135             :    * only safe for codes where no evaluations on neighbor cells (e.g.
     136             :    * no jump error estimators) are done.
     137             :    */
     138             :   virtual void enable_default_ghosting (bool enable);
     139             : 
     140             :   /**
     141             :    * Updates local values for all the systems
     142             :    */
     143             :   void update ();
     144             : 
     145             :   /**
     146             :    * \returns The number of equation systems.
     147             :    */
     148             :   unsigned int n_systems() const;
     149             : 
     150             :   /**
     151             :    * \returns \p true if the system named \p name exists within
     152             :    * this EquationSystems object.
     153             :    */
     154             :   bool has_system (std::string_view name) const;
     155             : 
     156             :   /**
     157             :    * \returns A constant reference to the system named \p name.
     158             :    * The template argument defines the return type.  For example,
     159             :    * const SteadySystem & sys = eq.get_system<SteadySystem> ("sys");
     160             :    * is an example of how the method might be used
     161             :    */
     162             :   template <typename T_sys>
     163             :   const T_sys & get_system (std::string_view name) const;
     164             : 
     165             :   /**
     166             :    * \returns A writable reference to the system named \p name.
     167             :    * The template argument defines the return type.  For example,
     168             :    * const SteadySystem & sys = eq.get_system<SteadySystem> ("sys");
     169             :    * is an example of how the method might be used
     170             :    */
     171             :   template <typename T_sys>
     172             :   T_sys & get_system (std::string_view name);
     173             : 
     174             :   /**
     175             :    * \returns A constant reference to system number \p num.
     176             :    * The template argument defines the return type.  For example,
     177             :    * const SteadySystem & sys = eq.get_system<SteadySystem> (0);
     178             :    * is an example of how the method might be used
     179             :    */
     180             :   template <typename T_sys>
     181             :   const T_sys & get_system (const unsigned int num) const;
     182             : 
     183             :   /**
     184             :    * \returns A writable reference to the system number \p num.
     185             :    * The template argument defines the return type.  For example,
     186             :    * const SteadySystem & sys = eq.get_system<SteadySystem> (0);
     187             :    * is an example of how the method might be used
     188             :    */
     189             :   template <typename T_sys>
     190             :   T_sys & get_system (const unsigned int num);
     191             : 
     192             :   /**
     193             :    * \returns A constant reference to the system named \p name.
     194             :    */
     195             :   const System & get_system (std::string_view name) const;
     196             : 
     197             :   /**
     198             :    * \returns A writable reference to the system named \p name.
     199             :    */
     200             :   System & get_system (std::string_view name);
     201             : 
     202             :   /**
     203             :    * \returns A constant reference to system number \p num.
     204             :    */
     205             :   const System & get_system (const unsigned int num) const;
     206             : 
     207             :   /**
     208             :    * \returns A writable reference to the system number \p num.
     209             :    */
     210             :   System & get_system (const unsigned int num);
     211             : 
     212             :   /**
     213             :    * Add the system of type \p system_type named \p name to the
     214             :    * systems array.
     215             :    */
     216             :   virtual System & add_system (std::string_view system_type,
     217             :                                std::string_view name);
     218             : 
     219             :   /**
     220             :    * Add the system named \p name to the systems array.
     221             :    */
     222             :   template <typename T_sys>
     223             :   T_sys & add_system (std::string_view name);
     224             : 
     225             :   /**
     226             :    * \returns The total number of variables in all
     227             :    * systems.
     228             :    */
     229             :   unsigned int n_vars () const;
     230             : 
     231             :   /**
     232             :    * \returns The total number of degrees of freedom
     233             :    * in all systems.
     234             :    */
     235             :   std::size_t n_dofs () const;
     236             : 
     237             :   /**
     238             :    * \returns The number of active degrees of freedom
     239             :    * for the EquationSystems object.
     240             :    */
     241             :   std::size_t n_active_dofs() const;
     242             : 
     243             :   /**
     244             :    * Call \p solve on all the individual equation systems.
     245             :    *
     246             :    * By default this function solves each equation system once,
     247             :    * in the order they were added.  For more sophisticated decoupled
     248             :    * problems the user may with to override this behavior in a derived
     249             :    * class.
     250             :    */
     251             :   virtual void solve ();
     252             : 
     253             :   /**
     254             :    * Call \p adjoint_solve on all the individual equation systems.
     255             :    *
     256             :    * By default this function solves each system's adjoint once,
     257             :    * in the reverse order from that in which they were added.  For
     258             :    * more sophisticated decoupled problems the user may with to
     259             :    * override this behavior in a derived class.
     260             :    */
     261             :   virtual void adjoint_solve (const QoISet & qoi_indices = QoISet());
     262             : 
     263             :   /**
     264             :    * Call \p sensitivity_solve on all the individual equation systems.
     265             :    *
     266             :    * By default this function solves each sensitivity system once,
     267             :    * in the order in which in which they were added.  For
     268             :    * more sophisticated decoupled problems the user may with to
     269             :    * override this behavior in a derived class.
     270             :    */
     271             :   virtual void sensitivity_solve (const ParameterVector & parameters);
     272             : 
     273             :   /**
     274             :    * Fill the input vector \p var_names with the names
     275             :    * of the variables for each system. If \p type is passed,
     276             :    * only variables of the specified type will be populated.
     277             :    * If systems_names!=nullptr, only include names from the
     278             :    * specified systems.
     279             :    */
     280             :   void build_variable_names (std::vector<std::string> & var_names,
     281             :                              const FEType * type=nullptr,
     282             :                              const std::set<std::string> * system_names=nullptr) const;
     283             : 
     284             :   /**
     285             :    * \returns Whether \p type can be represented as elemental data.
     286             :    *
     287             :    * Elemental data variables are CONSTANT element-interior fields,
     288             :    * regardless of their p_refinement flag.
     289             :    */
     290             :   static bool is_elemental_data_fe_type (const FEType & type);
     291             : 
     292             :   /**
     293             :    * Filter \p var_names to names of variables that can be represented as
     294             :    * elemental data. If \p var_names is empty, all eligible variable names are
     295             :    * returned. Vector-valued variables are decomposed into component names.
     296             :    * If \p system_names!=nullptr, only include names from the specified systems.
     297             :    */
     298             :   void build_elemental_data_variable_names
     299             :     (std::vector<std::string> & var_names,
     300             :      const std::set<std::string> * system_names=nullptr) const;
     301             : 
     302             :   /**
     303             :    * Fill the input vector \p soln with the solution values for the
     304             :    * system named \p name.
     305             :    *
     306             :    * \note The input vector \p soln will only be assembled on
     307             :    * processor 0, so this method is only applicable to outputting plot
     308             :    * files from processor 0.
     309             :    */
     310             :   void build_solution_vector (std::vector<Number> & soln,
     311             :                               std::string_view system_name,
     312             :                               std::string_view variable_name = "all_vars") const;
     313             : 
     314             :   /**
     315             :    * Fill the input vector \p soln with solution values.  The
     316             :    * entries will be in node-major format (corresponding to
     317             :    * the names from \p build_variable_names()).
     318             :    *
     319             :    * If systems_names!=nullptr, only include data from the
     320             :    * specified systems.
     321             :    *
     322             :    * If \p add_sides is true, append data for plotting on "side
     323             :    * elements" too.
     324             :    */
     325             :   void build_solution_vector (std::vector<Number> & soln,
     326             :                               const std::set<std::string> * system_names=nullptr,
     327             :                               bool add_sides=false) const;
     328             : 
     329             :   /**
     330             :    * A version of build_solution_vector which is appropriate for
     331             :    * "parallel" output formats like Nemesis.
     332             :    *
     333             :    * \returns A std::unique_ptr to a node-major NumericVector of total
     334             :    * length n_nodes*n_vars that various I/O classes can then use to
     335             :    * get the local values they need to write on each processor.
     336             :    */
     337             :   std::unique_ptr<NumericVector<Number>>
     338             :   build_parallel_solution_vector(const std::set<std::string> * system_names=nullptr,
     339             :                                  bool add_sides=false) const;
     340             : 
     341             :   /**
     342             :    * Retrieve \p vars_active_subdomains, which indicates the active
     343             :    * subdomains for each variable in \p names.
     344             :    */
     345             :   void get_vars_active_subdomains(const std::vector<std::string> & names,
     346             :                                   std::vector<std::set<subdomain_id_type>> & vars_active_subdomains) const;
     347             : 
     348             :   /**
     349             :    * Retrieve the solution data for elemental data variables. If 'names' is
     350             :    * populated, only the variables corresponding to those names will be
     351             :    * retrieved. This can be used to filter which variables are retrieved.
     352             :    *
     353             :    * This is the more appropriately-named replacement for the get_solution()
     354             :    * function defined above.
     355             :    */
     356             :   void build_elemental_solution_vector (std::vector<Number> & soln,
     357             :                                         std::vector<std::string> & names) const;
     358             : 
     359             :   /**
     360             :    * Finds system and variable numbers for any variables of 'type' or of
     361             :    * 'types' corresponding to the entries in the input 'names' vector.
     362             :    * If 'names' is empty, this returns all variables of the type.
     363             :    * The names of vector variables are decomposed into individual ones
     364             :    * suffixed with their cartesian component, but there will still be
     365             :    * a single pair of system numbers for such vector variables. Thus,
     366             :    * the size of the 'names' vector modified by this function may not
     367             :    * be equal to that of the returned vector of pairs. Nevertheless, both
     368             :    * should be sorted in accordance with ExodusII format, and so the
     369             :    * developer just needs to know to separate dof_indices when
     370             :    * accessing the system solution for vector variables.
     371             :    *
     372             :    * This function is designed to work for either a single type or a
     373             :    * vector of types, but not both. This is because it can't simply be
     374             :    * called a second time with another type as it filters (deletes) the
     375             :    * names of those on the first call that used a different type. Thus,
     376             :    * the 'types' argument is for the case where variables of multiple
     377             :    * types are allowed to pass through.
     378             :    *
     379             :    * TODO: find a more generic way to handle this whole procedure.
     380             :    */
     381             :   std::vector<std::pair<unsigned int, unsigned int>>
     382             :   find_variable_numbers (std::vector<std::string> & names,
     383             :                          const FEType * type=nullptr,
     384             :                          const std::vector<FEType> * types=nullptr) const;
     385             : 
     386             :   /**
     387             :    * Finds system and variable numbers for variables that can be represented
     388             :    * as elemental data. See find_variable_numbers() for name filtering,
     389             :    * component decomposition, and sorting details.
     390             :    */
     391             :   std::vector<std::pair<unsigned int, unsigned int>>
     392             :   find_elemental_data_variable_numbers (std::vector<std::string> & names) const;
     393             : 
     394             :   /**
     395             :    * Builds a parallel vector of elemental data solution values corresponding to the entries
     396             :    * in the input 'names' vector. This vector is approximately uniformly
     397             :    * distributed across all of the available processors.
     398             :    *
     399             :    * The related function build_elemental_solution_vector() is
     400             :    * implemented by calling this function and then calling
     401             :    * localize_to_one() on the resulting vector.
     402             :    *
     403             :    * Returns a nullptr if no elemental data variables exist in the 'names'
     404             :    * vector (if it is empty, then it will return all variables in the system
     405             :    * of this type if any) or a std::unique_ptr to
     406             :    * a var-major numeric vector of total length n_elem * n_vars, where
     407             :    * n_vars includes all components of vectors, ordered according to:
     408             :    * [u0, u1, ... uN, v0, v1, ... vN, w0, w1, ... wN] for elemental data
     409             :    * variables (u, v, w) on a mesh with N elements.
     410             :    */
     411             :   std::unique_ptr<NumericVector<Number>>
     412             :   build_parallel_elemental_solution_vector (std::vector<std::string> & names) const;
     413             : 
     414             :   /**
     415             :    * Fill the input vector \p soln with solution values.  The
     416             :    * entries will be in geometry-major format: element, then local
     417             :    * node/vertex, then variable.
     418             : 
     419             :    * If systems_names!=nullptr, only include data from the
     420             :    * specified systems.
     421             : 
     422             :    * If vertices_only == true, then for higher-order elements only
     423             :    * the solution at the vertices is computed. This can be useful
     424             :    * when plotting discontinuous solutions on higher-order elements
     425             :    * and only a lower-order representation is required.
     426             :    *
     427             :    * If add_sides == true, append data for plotting on "side
     428             :    * elements" too.
     429             :    */
     430             :   void build_discontinuous_solution_vector
     431             :   (std::vector<Number> & soln,
     432             :    const std::set<std::string> * system_names = nullptr,
     433             :    const std::vector<std::string> * var_names = nullptr,
     434             :    bool vertices_only = false,
     435             :    bool add_sides = false) const;
     436             : 
     437             :   /*
     438             :    * Returns true iff the given side of the given element is *never*
     439             :    * added to output from that element, because it is considered to be
     440             :    * redundant with respect to the same data added from the
     441             :    * neighboring element sharing that side.  This helper function is
     442             :    * used with the add_sides option when building solution vectors
     443             :    * here and when outputting solution vectors in MeshOutput
     444             :    * (currently just Exodus) I/O.
     445             :    */
     446             :   static bool redundant_added_side(const Elem & elem, unsigned int side);
     447             : 
     448             : 
     449             :   /**
     450             :    * Read & initialize the systems from disk using the XDR data format.
     451             :    * This format allows for machine-independent binary output.
     452             :    *
     453             :    * Set which sections of the file to read by bitwise OR'ing the
     454             :    * EquationSystems::ReadFlags enumeration together. For example, to
     455             :    * read all sections of the file, set read_flags to:
     456             :    * (READ_HEADER | READ_DATA | READ_ADDITIONAL_DATA)
     457             :    *
     458             :    * \note The equation system can be defined without initializing
     459             :    * the data vectors to any solution values.  This can be done
     460             :    * by omitting READ_DATA in the read_flags parameter.
     461             :    *
     462             :    * If XdrMODE is omitted, it will be inferred as READ for filenames
     463             :    * containing .xda or as DECODE for filenames containing .xdr
     464             :    *
     465             :    * \param name Name of the file to be read.
     466             :    * \param read_flags Single flag created by bitwise-OR'ing several flags together.
     467             :    * \param mode Controls whether reading is done in binary or ascii mode.
     468             :    * \param partition_agnostic If true then the mesh and degrees of freedom
     469             :    * will be temporarily renumbered in a partition agnostic way so that
     470             :    * files written using "n" mpi processes can be re-read on "m" mpi
     471             :    * processes.  This renumbering is not compatible with meshes
     472             :    * that have two nodes in exactly the same position!
     473             :    */
     474             :   template <typename InValType = Number>
     475             :   void read (std::string_view name,
     476             :              const XdrMODE,
     477             :              const unsigned int read_flags=(READ_HEADER | READ_DATA),
     478             :              bool partition_agnostic = true);
     479             : 
     480             :   template <typename InValType = Number>
     481             :   void read (std::string_view name,
     482             :              const unsigned int read_flags=(READ_HEADER | READ_DATA),
     483             :              bool partition_agnostic = true);
     484             : 
     485             :   template <typename InValType = Number>
     486             :   void read (Xdr & io,
     487             :              std::function<std::unique_ptr<Xdr>()> & local_io_functor,
     488             :              const unsigned int read_flags=(READ_HEADER | READ_DATA),
     489             :              bool partition_agnostic = true);
     490             : 
     491             :   /**
     492             :    * Write the systems to disk using the XDR data format.
     493             :    * This format allows for machine-independent binary output.
     494             :    *
     495             :    * Set the writing properties using the EquationSystems::WriteFlags
     496             :    * enumeration. Set which sections to write out by bitwise OR'ing
     497             :    * the enumeration values. Write everything by setting write_flags to:
     498             :    * (WRITE_DATA | WRITE_ADDITIONAL_DATA)
     499             :    *
     500             :    * \note The solution data can be omitted by calling
     501             :    * this routine with WRITE_DATA omitted in the write_flags argument.
     502             :    *
     503             :    * If XdrMODE is omitted, it will be inferred as WRITE for filenames
     504             :    * containing .xda or as ENCODE for filenames containing .xdr
     505             :    *
     506             :    * \param name Name of the file to be read.
     507             :    * \param write_flags Single flag created by bitwise-OR'ing several flags together.
     508             :    * \param mode Controls whether reading is done in binary or ascii mode.
     509             :    * \param partition_agnostic If true then the mesh and degrees of freedom
     510             :    * will be temporarily renumbered in a partition agnostic way so that
     511             :    * files written using "n" mpi processes can be re-read on "m" mpi
     512             :    * processes.  This renumbering is not compatible with meshes
     513             :    * that have two nodes in exactly the same position!
     514             :    */
     515             :   void write (std::string_view name,
     516             :               const XdrMODE,
     517             :               const unsigned int write_flags=(WRITE_DATA),
     518             :               bool partition_agnostic = true) const;
     519             : 
     520             :   void write (std::string_view name,
     521             :               const unsigned int write_flags=(WRITE_DATA),
     522             :               bool partition_agnostic = true) const;
     523             : 
     524             :   void write (std::ostream name,
     525             :               const unsigned int write_flags=(WRITE_DATA),
     526             :               bool partition_agnostic = true) const;
     527             : 
     528             :   void write (Xdr & io,
     529             :               const unsigned int write_flags=(WRITE_DATA),
     530             :               bool partition_agnostic = true,
     531             :               Xdr * const local_io = nullptr) const;
     532             : 
     533             :   /**
     534             :    * \returns \p true when this equation system contains
     535             :    * identical data, up to the given threshold.  Delegates
     536             :    * most of the comparisons to perform to the responsible
     537             :    * systems
     538             :    */
     539             :   virtual bool compare (const EquationSystems & other_es,
     540             :                         const Real threshold,
     541             :                         const bool verbose) const;
     542             : 
     543             :   /**
     544             :    * \returns A string containing information about the
     545             :    * systems, flags, and parameters.
     546             :    */
     547             :   virtual std::string get_info() const;
     548             : 
     549             :   /**
     550             :    * Prints information about the equation systems, by default to
     551             :    * libMesh::out.
     552             :    */
     553             :   void print_info (std::ostream & os=libMesh::out) const;
     554             : 
     555             :   /**
     556             :    * Same as above, but allows you to also use stream syntax.
     557             :    */
     558             :   friend std::ostream & operator << (std::ostream & os,
     559             :                                      const EquationSystems & es);
     560             : 
     561             :   /**
     562             :    * \returns A constant reference to the mesh
     563             :    */
     564             :   const MeshBase & get_mesh() const;
     565             : 
     566             :   /**
     567             :    * \returns A reference to the mesh
     568             :    */
     569             :   MeshBase & get_mesh();
     570             : 
     571             :   /**
     572             :    * Serializes a distributed mesh and its associated
     573             :    * degree of freedom numbering for all systems
     574             :    **/
     575             :   void allgather ();
     576             : 
     577             :   /**
     578             :    * Calls to reinit() will also do two-step coarsen-then-refine
     579             :    **/
     580             :   void enable_refine_in_reinit() { this->_refine_in_reinit = true; }
     581             : 
     582             :   /**
     583             :    * Calls to reinit() will not try to coarsen or refine the mesh
     584             :    **/
     585             :   void disable_refine_in_reinit() { this->_refine_in_reinit = false; }
     586             : 
     587             :   /**
     588             :    * \returns Whether or not calls to reinit() will try to coarsen/refine the mesh
     589             :    **/
     590             :   bool refine_in_reinit_flag() { return this->_refine_in_reinit; }
     591             : 
     592             :   /**
     593             :    * Handle any mesh changes and project any solutions onto the
     594             :    * updated mesh.
     595             :    *
     596             :    * \returns Whether or not the mesh may have changed.
     597             :    */
     598             :   bool reinit_solutions ();
     599             : 
     600             :   /**
     601             :    * Reinitialize all systems on the current mesh.
     602             :    */
     603             :   virtual void reinit_systems ();
     604             : 
     605             :   /**
     606             :    * Data structure holding arbitrary parameters.
     607             :    */
     608             :   Parameters parameters;
     609             : 
     610             : 
     611             : protected:
     612             : 
     613             : 
     614             :   /**
     615             :    * The mesh data structure
     616             :    */
     617             :   MeshBase & _mesh;
     618             : 
     619             :   /**
     620             :    * Data structure holding the systems.
     621             :    */
     622             :   std::map<std::string, std::unique_ptr<System>, std::less<>> _systems;
     623             : 
     624             :   /**
     625             :    * Flag for whether to call coarsen/refine in reinit().
     626             :    * Default value: true
     627             :    */
     628             :   bool _refine_in_reinit;
     629             : 
     630             :   /**
     631             :    * Flag for whether to enable default ghosting on newly added Systems.
     632             :    * Default value: true
     633             :    */
     634             :   bool _enable_default_ghosting;
     635             : 
     636             : private:
     637             :   /**
     638             :    * Implementation detail for find_variable_numbers() variants.
     639             :    */
     640             :   std::vector<std::pair<unsigned int, unsigned int>>
     641             :   find_variable_numbers_by_predicate
     642             :     (std::vector<std::string> & names,
     643             :      const std::function<bool(const FEType &)> & type_filter) const;
     644             : 
     645             :   /**
     646             :    * This function is used in the implementation of add_system,
     647             :    * it loops over the nodes and elements of the Mesh, adding the
     648             :    * system to each one.  The main reason to separate this part
     649             :    * is to avoid coupling this header file to mesh.h, and elem.h.
     650             :    */
     651             :   void _add_system_to_nodes_and_elems();
     652             : 
     653             :   /**
     654             :    * This just calls DofMap::remove_default_ghosting() but using a
     655             :    * shim lets us forward-declare DofMap.
     656             :    */
     657             :   void _remove_default_ghosting(unsigned int sys_num);
     658             : };
     659             : 
     660             : 
     661             : 
     662             : // ------------------------------------------------------------
     663             : // EquationSystems inline methods
     664             : inline
     665        6248 : const MeshBase & EquationSystems::get_mesh () const
     666             : {
     667      122658 :   return _mesh;
     668             : }
     669             : 
     670             : 
     671             : 
     672             : inline
     673         246 : MeshBase & EquationSystems::get_mesh ()
     674             : {
     675      278869 :   return _mesh;
     676             : }
     677             : 
     678             : 
     679             : inline
     680           0 : unsigned int EquationSystems::n_systems () const
     681             : {
     682           0 :   return cast_int<unsigned int>(_systems.size());
     683             : }
     684             : 
     685             : 
     686             : 
     687             : 
     688             : template <typename T_sys>
     689             : inline
     690       15707 : T_sys & EquationSystems::add_system (std::string_view name)
     691             : {
     692       15707 :   if (!_systems.count(name))
     693             :     {
     694       14833 :       const unsigned int sys_num = this->n_systems();
     695             : 
     696        1434 :       auto result = _systems.emplace
     697       28710 :         (name, std::make_unique<T_sys>(*this, std::string(name),
     698             :                                        sys_num));
     699             : 
     700       15311 :       if (!_enable_default_ghosting)
     701           0 :         this->_remove_default_ghosting(sys_num);
     702             : 
     703             :       // Tell all the \p DofObject entities to add a system.
     704       15311 :       this->_add_system_to_nodes_and_elems();
     705             : 
     706             :       // Return reference to newly added item
     707         478 :       auto it = result.first;
     708         478 :       auto & sys_ptr = it->second;
     709         478 :       return cast_ref<T_sys &>(*sys_ptr);
     710             :     }
     711             :   else
     712             :     {
     713             :       // We now allow redundant add_system calls, to make it
     714             :       // easier to load data from files for user-derived system
     715             :       // subclasses
     716         396 :       return this->get_system<T_sys>(name);
     717             :     }
     718             : }
     719             : 
     720             : 
     721             : 
     722             : inline
     723         894 : bool EquationSystems::has_system (std::string_view name) const
     724             : {
     725         894 :   if (_systems.find(name) == _systems.end())
     726           0 :     return false;
     727         894 :   return true;
     728             : }
     729             : 
     730             : 
     731             : 
     732             : 
     733             : template <typename T_sys>
     734             : inline
     735       29811 : const T_sys & EquationSystems::get_system (const unsigned int num) const
     736             : {
     737         808 :   libmesh_assert_less (num, this->n_systems());
     738             : 
     739       31643 :   for (auto & pr : _systems)
     740             :     {
     741         848 :       const auto & sys_ptr = pr.second;
     742       31643 :       if (sys_ptr->number() == num)
     743       29811 :         return cast_ref<const T_sys &>(*sys_ptr);
     744             :     }
     745             :   // Error if we made it here
     746           0 :   libmesh_error_msg("ERROR: no system number " << num << " found!");
     747             : }
     748             : 
     749             : 
     750             : 
     751             : 
     752             : template <typename T_sys>
     753             : inline
     754      381299 : T_sys & EquationSystems::get_system (const unsigned int num)
     755             : {
     756       17968 :   libmesh_assert_less (num, this->n_systems());
     757             : 
     758      402453 :   for (auto & pr : _systems)
     759             :     {
     760       18606 :       auto & sys_ptr = pr.second;
     761      402453 :       if (sys_ptr->number() == num)
     762      381299 :         return cast_ref<T_sys &>(*sys_ptr);
     763             :     }
     764             : 
     765             :   // Error if we made it here
     766           0 :   libmesh_error_msg("ERROR: no system number " << num << " found!");
     767             : }
     768             : 
     769             : 
     770             : 
     771             : 
     772             : 
     773             : 
     774             : template <typename T_sys>
     775             : inline
     776       88837 : const T_sys & EquationSystems::get_system (std::string_view name) const
     777             : {
     778        2536 :   auto pos = _systems.find(name);
     779             : 
     780             :   // Check for errors
     781       88837 :   libmesh_error_msg_if(pos == _systems.end(), "ERROR: no system named \"" << name << "\" found!");
     782             : 
     783             :   // Attempt dynamic cast
     784        2536 :   const auto & sys_ptr = pos->second;
     785       91373 :   return cast_ref<const T_sys &>(*sys_ptr);
     786             : }
     787             : 
     788             : 
     789             : 
     790             : 
     791             : 
     792             : 
     793             : template <typename T_sys>
     794             : inline
     795       14967 : T_sys & EquationSystems::get_system (std::string_view name)
     796             : {
     797         418 :   auto pos = _systems.find(name);
     798             : 
     799             :   // Check for errors
     800       14967 :   libmesh_error_msg_if(pos == _systems.end(), "ERROR: no system named " << name << " found!");
     801             : 
     802             :   // Attempt dynamic cast
     803         418 :   auto & sys_ptr = pos->second;
     804       15385 :   return cast_ref<T_sys &>(*sys_ptr);
     805             : }
     806             : 
     807             : 
     808             : 
     809             : 
     810             : 
     811             : 
     812             : 
     813             : inline
     814        1790 : const System & EquationSystems::get_system (std::string_view name) const
     815             : {
     816       61577 :   return this->get_system<System>(name);
     817             : }
     818             : 
     819             : 
     820             : 
     821             : inline
     822         418 : System & EquationSystems::get_system (std::string_view name)
     823             : {
     824       16004 :   return this->get_system<System>(name);
     825             : }
     826             : 
     827             : 
     828             : 
     829             : inline
     830         808 : const System & EquationSystems::get_system (const unsigned int num) const
     831             : {
     832       29811 :   return this->get_system<System>(num);
     833             : }
     834             : 
     835             : 
     836             : 
     837             : inline
     838       17968 : System & EquationSystems::get_system (const unsigned int num)
     839             : {
     840      381299 :   return this->get_system<System>(num);
     841             : }
     842             : 
     843             : 
     844             : } // namespace libMesh
     845             : 
     846             : 
     847             : #endif // LIBMESH_EQUATION_SYSTEMS_H

Generated by: LCOV version 1.14