LCOV - code coverage report
Current view: top level - include/base - reduced_dof_map.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4624 (b6265e) with base 1fb77f Lines: 13 14 92.9 %
Date: 2026-11-03 16:49:57 Functions: 11 13 84.6 %
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             : #ifndef LIBMESH_REDUCED_DOF_MAP_H
      19             : #define LIBMESH_REDUCED_DOF_MAP_H
      20             : 
      21             : #include "libmesh/libmesh_common.h"
      22             : #include "libmesh/dof_map_base.h"
      23             : #include "libmesh/variable.h"
      24             : #include "libmesh/sparsity_pattern.h"
      25             : 
      26             : #include <memory>
      27             : #include <string>
      28             : #include <unordered_map>
      29             : #include <unordered_set>
      30             : #include <vector>
      31             : 
      32             : namespace libMesh
      33             : {
      34             : class MeshBase;
      35             : class System;
      36             : class DofMap;
      37             : class Elem;
      38             : class Node;
      39             : 
      40             : /**
      41             :  * A degree of freedom map for a reduced space: a subset of the degrees of freedom of a full \p
      42             :  * DofMap, renumbered contiguously. Each retained degree of freedom keeps the rank that owns it in
      43             :  * the full space, so the reduced numbering on each rank preserves the full numbering order.
      44             :  *
      45             :  * Subclasses select the retained degrees of freedom through \p retain_field_dof() and \p
      46             :  * retain_scalar_dof(). Static condensation, for instance, retains the degrees of freedom on
      47             :  * element boundaries, and constraint elimination retains the unconstrained ones. The constraining
      48             :  * degrees of freedom of every constrained degree of freedom on an element are retained as well,
      49             :  * whether or not the constrained one is, because constrained element matrices and vectors couple
      50             :  * them.
      51             :  *
      52             :  * This class provides the reduced numbering (\p reduced_dof()), the reduced degrees of freedom of
      53             :  * each local element and variable (\p dof_indices()), the variables present in the reduced space
      54             :  * along with a stand-in \p System for them, and the sparsity pattern of matrices in the reduced
      55             :  * space. This is the information needed to assemble reduced matrices and to build field splits
      56             :  * of the reduced space.
      57             :  */
      58         128 : class ReducedDofMap : public DofMapBase
      59             : {
      60             : public:
      61             :   virtual ~ReducedDofMap();
      62             : 
      63             :   /**
      64             :    * Build the reduced space from the current state of the full degree of freedom map
      65             :    */
      66             :   virtual void reinit();
      67             : 
      68             :   virtual void clear() override;
      69             : 
      70             :   /**
      71             :    * Whether \p reinit() has built the reduced space
      72             :    */
      73         400 :   bool initialized() const { return _initialized; }
      74             : 
      75             :   virtual unsigned int n_variables() const override;
      76             : 
      77             :   virtual const Variable & variable(const unsigned int c) const override;
      78             : 
      79             :   /**
      80             :    * Fills \p di with the reduced degree of freedom indices of variable \p vn on the active local
      81             :    * element \p elem, including the constraining degrees of freedom of its constrained degrees of
      82             :    * freedom
      83             :    */
      84             :   virtual void dof_indices(const Elem * const elem,
      85             :                            std::vector<dof_id_type> & di,
      86             :                            const unsigned int vn,
      87             :                            int p_level = -12345) const override;
      88             : 
      89             :   /**
      90             :    * Reduced degree of freedom maps are queried by element only
      91             :    */
      92             :   virtual void dof_indices(const Node * const node,
      93             :                            std::vector<dof_id_type> & di,
      94             :                            const unsigned int vn) const override;
      95             : 
      96             :   /**
      97             :    * \returns The reduced index of \p full_dof. \p full_dof must be retained and must be either
      98             :    * local or used by a local element
      99             :    */
     100             :   dof_id_type reduced_dof(dof_id_type full_dof) const;
     101             : 
     102             :   /**
     103             :    * \returns The local retained degrees of freedom in the full numbering, sorted. The reduced
     104             :    * index of entry \p i is <tt>first_dof() + i</tt>
     105             :    */
     106           0 :   const std::vector<dof_id_type> & local_retained_dofs() const { return _local_retained_dofs; }
     107             : 
     108             :   /**
     109             :    * Nests this reduced space in \p parent's, or in the full space if \p parent is null. Only
     110             :    * degrees of freedom that \p parent retains can be retained, and the parent space is the space
     111             :    * this one reduces: its vectors are the ones operators on this space are prolonged to and
     112             :    * restricted from. Takes effect at the next \p reinit(), which must follow the parent's
     113             :    */
     114         360 :   void set_parent(const ReducedDofMap * parent) { _parent = parent; }
     115             : 
     116             :   /**
     117             :    * \returns The reduced space this one is nested in, or null for the full space
     118             :    */
     119       75518 :   const ReducedDofMap * parent() const { return _parent; }
     120             : 
     121             :   /**
     122             :    * \returns The index of \p full_dof in the parent space, or \p DofObject::invalid_id if the
     123             :    * parent does not retain it. \p full_dof must be local or used by an active local element
     124             :    */
     125             :   dof_id_type parent_dof(dof_id_type full_dof) const;
     126             : 
     127             :   /**
     128             :    * \returns The number of degrees of freedom in the parent space, globally and locally, and the
     129             :    * parent index range of this rank
     130             :    */
     131             :   dof_id_type parent_n_dofs() const;
     132             :   dof_id_type parent_n_local_dofs() const;
     133             :   dof_id_type parent_first_dof() const;
     134             :   dof_id_type parent_end_dof() const;
     135             : 
     136             :   /**
     137             :    * \returns The local retained degrees of freedom in the parent numbering, sorted. Entry \p i is
     138             :    * the parent index of reduced index <tt>first_dof() + i</tt>
     139             :    */
     140         756 :   const std::vector<dof_id_type> & local_retained_parent_dofs() const
     141        2268 :   { return _local_retained_parent_dofs; }
     142             : 
     143             :   /**
     144             :    * \returns The nonlocal reduced degrees of freedom used by active local elements, sorted: the
     145             :    * ghost entries of a ghosted vector on this space
     146             :    */
     147           6 :   const std::vector<dof_id_type> & send_list() const { return _send_list; }
     148             : 
     149             :   /**
     150             :    * \returns The ghost entries of a ghosted vector on the parent space
     151             :    */
     152             :   const std::vector<dof_id_type> & parent_send_list() const;
     153             : 
     154             :   /**
     155             :    * Whether field degree of freedom \p field_dof is retained: the parent retains it and \p
     156             :    * retain_field_dof() accepts it
     157             :    */
     158             :   bool retains_field_dof(const Elem & elem,
     159             :                          unsigned int node_num,
     160             :                          unsigned int var_num,
     161             :                          dof_id_type field_dof) const;
     162             : 
     163             :   /**
     164             :    * Whether SCALAR degree of freedom \p scalar_dof is retained: the parent retains it and \p
     165             :    * retain_scalar_dof() accepts it
     166             :    */
     167             :   bool retains_scalar_dof(dof_id_type scalar_dof) const;
     168             : 
     169             :   /**
     170             :    * \returns The reduced degree of freedom indices on the active local element with id \p
     171             :    * elem_id, by reduced variable number. Concatenated, these are in the order in which \p
     172             :    * retained_dof_added() saw them
     173             :    */
     174             :   const std::vector<std::vector<dof_id_type>> & elem_dof_indices(dof_id_type elem_id) const;
     175             : 
     176             :   /**
     177             :    * \returns The stand-in system that holds the variables of the reduced space
     178             :    */
     179             :   const System & reduced_system() const;
     180             : 
     181             :   /**
     182             :    * \returns The mesh
     183             :    */
     184             :   const MeshBase & mesh() const { return _mesh; }
     185             : 
     186             :   /**
     187             :    * \returns The sparsity pattern of matrices in the reduced space. Its rows are indexed by the
     188             :    * local full degrees of freedom; use \p reduced_n_nz() and \p reduced_n_oz() for preallocation
     189             :    */
     190             :   const SparsityPattern::Build & reduced_sparsity() const;
     191             : 
     192             :   /**
     193             :    * \returns The number of on-processor nonzeros in each local row of the reduced space
     194             :    */
     195         396 :   const std::vector<dof_id_type> & reduced_n_nz() const { return _reduced_nnz; }
     196             : 
     197             :   /**
     198             :    * \returns The number of off-processor nonzeros in each local row of the reduced space
     199             :    */
     200         396 :   const std::vector<dof_id_type> & reduced_n_oz() const { return _reduced_noz; }
     201             : 
     202             :   /**
     203             :    * \returns The reduced index of \p full_dof, or \p DofObject::invalid_id if \p full_dof is
     204             :    * not retained. \p full_dof must be local or used by an active local element
     205             :    */
     206             :   dof_id_type find_reduced_dof(dof_id_type full_dof) const;
     207             : 
     208             :   /**
     209             :    * This space's rule for retaining field degree of freedom \p field_dof of variable \p var_num on
     210             :    * \p elem, among those the parent retains. \p node_num is the element-local node holding it, or
     211             :    * \p invalid_uint for an element degree of freedom
     212             :    */
     213             :   virtual bool retain_field_dof(const Elem & elem,
     214             :                                 unsigned int node_num,
     215             :                                 unsigned int var_num,
     216             :                                 dof_id_type field_dof) const = 0;
     217             : 
     218             :   /**
     219             :    * This space's rule for retaining degree of freedom \p scalar_dof of a SCALAR variable, among
     220             :    * those the parent retains
     221             :    */
     222         108 :   virtual bool retain_scalar_dof(dof_id_type /*scalar_dof*/) const { return true; }
     223             : 
     224             : protected:
     225             :   /**
     226             :    * @param reduced_system_name The name of the stand-in system holding the reduced variables
     227             :    */
     228             :   ReducedDofMap(MeshBase & mesh,
     229             :                 System & system,
     230             :                 const DofMap & dof_map,
     231             :                 std::string reduced_system_name);
     232             : 
     233             :   /**
     234             :    * Called by \p reinit() each time \p full_dof is first retained on \p elem, in the order of the
     235             :    * element's reduced indices
     236             :    */
     237             :   virtual void retained_dof_added(const Elem & elem, dof_id_type full_dof);
     238             : 
     239             :   /**
     240             :    * Called by \p reinit() for each field degree of freedom on \p elem that the parent retains and
     241             :    * \p retain_field_dof() rejects
     242             :    */
     243             :   virtual void unretained_dof_found(const Elem & elem, dof_id_type full_dof);
     244             : 
     245             :   MeshBase & _mesh;
     246             :   System & _system;
     247             :   const DofMap & _dof_map;
     248             : 
     249             : private:
     250             :   /**
     251             :    * Retain \p full_dof on \p elem, along with its constraining degrees of freedom, recursively
     252             :    * @param elem_seen The full degrees of freedom already retained on \p elem
     253             :    * @param elem_var_dofs The retained full degrees of freedom of the current variable on \p elem
     254             :    */
     255             :   void retain_dof_and_constraining_dofs(const Elem * elem,
     256             :                                         dof_id_type full_dof,
     257             :                                         std::unordered_set<dof_id_type> & elem_seen,
     258             :                                         std::vector<dof_id_type> & elem_var_dofs);
     259             : 
     260             :   /**
     261             :    * Retain on \p elem the constraining degrees of freedom of \p full_dof, if it is constrained
     262             :    */
     263             :   void retain_constraining_dofs(const Elem * elem,
     264             :                                 dof_id_type full_dof,
     265             :                                 std::unordered_set<dof_id_type> & elem_seen,
     266             :                                 std::vector<dof_id_type> & elem_var_dofs);
     267             : 
     268             :   /**
     269             :    * Record that \p full_dof is retained, on this rank or on its owner
     270             :    */
     271             :   void retain_dof(dof_id_type full_dof);
     272             : 
     273             :   /// The name of the stand-in reduced system
     274             :   const std::string _reduced_system_name;
     275             : 
     276             :   /// The reduced space this one is nested in, or null for the full space
     277             :   const ReducedDofMap * _parent;
     278             : 
     279             :   /// The local retained degrees of freedom in the parent numbering, sorted
     280             :   std::vector<dof_id_type> _local_retained_parent_dofs;
     281             : 
     282             :   /// The nonlocal reduced degrees of freedom used by active local elements, sorted
     283             :   std::vector<dof_id_type> _send_list;
     284             : 
     285             :   /// Whether \p reinit() has built the reduced space
     286             :   bool _initialized;
     287             : 
     288             :   /// The local retained degrees of freedom in the full numbering, sorted
     289             :   std::vector<dof_id_type> _local_retained_dofs;
     290             : 
     291             :   /// The reduced index of each local full degree of freedom, offset by the first local full degree
     292             :   /// of freedom. Unretained degrees of freedom map to \p DofObject::invalid_id
     293             :   std::vector<dof_id_type> _local_full_to_reduced;
     294             : 
     295             :   /// The reduced indices of the nonlocal degrees of freedom on local elements, \p
     296             :   /// DofObject::invalid_id for unretained ones
     297             :   std::unordered_map<dof_id_type, dof_id_type> _nonlocal_full_to_reduced;
     298             : 
     299             :   /// Local retained degrees of freedom, nonlocal retained ones by owner, and nonlocal unretained
     300             :   /// ones on local elements. Only used during \p reinit()
     301             :   std::unordered_set<dof_id_type> _local_retained_set;
     302             :   std::unordered_map<processor_id_type, std::unordered_set<dof_id_type>> _nonlocal_retained;
     303             :   std::unordered_set<dof_id_type> _nonlocal_unretained;
     304             : 
     305             :   /// The reduced degrees of freedom of each active local element, by reduced variable number
     306             :   std::unordered_map<dof_id_type, std::vector<std::vector<dof_id_type>>> _elem_reduced_dofs;
     307             : 
     308             :   /// The variables in the reduced space
     309             :   std::vector<Variable> _reduced_vars;
     310             : 
     311             :   /// A stand-in system to give the reduced variables a system number
     312             :   System * _reduced_system;
     313             : 
     314             :   /// The reduced space sparsity pattern
     315             :   std::unique_ptr<SparsityPattern::Build> _reduced_sp;
     316             : 
     317             :   /// Number of on-processor nonzeros in each local row of the reduced space
     318             :   std::vector<dof_id_type> _reduced_nnz;
     319             : 
     320             :   /// Number of off-processor nonzeros in each local row of the reduced space
     321             :   std::vector<dof_id_type> _reduced_noz;
     322             : };
     323             : 
     324             : inline const System & ReducedDofMap::reduced_system() const
     325             : {
     326             :   libmesh_assert(_reduced_system);
     327             :   return *_reduced_system;
     328             : }
     329             : 
     330         120 : inline const SparsityPattern::Build & ReducedDofMap::reduced_sparsity() const
     331             : {
     332         120 :   libmesh_assert(_reduced_sp);
     333         120 :   return *_reduced_sp;
     334             : }
     335             : 
     336             : }
     337             : 
     338             : #endif // LIBMESH_REDUCED_DOF_MAP_H

Generated by: LCOV version 1.14