LCOV - code coverage report
Current view: top level - include/systems - equation_systems.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4308 (b969c4) with base 7aa2c3 Lines: 48 55 87.3 %
Date: 2025-11-07 13:38:09 Functions: 19 45 42.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14