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_STATIC_CONDENSATION_DOF_MAP_H 19 : #define LIBMESH_STATIC_CONDENSATION_DOF_MAP_H 20 : 21 : #include "libmesh/libmesh_config.h" 22 : 23 : #include "libmesh/id_types.h" 24 : #include "libmesh/libmesh_common.h" 25 : #include "libmesh/reduced_dof_map.h" 26 : 27 : #include <unordered_map> 28 : #include <unordered_set> 29 : 30 : namespace libMesh 31 : { 32 : class MeshBase; 33 : class System; 34 : class DofMap; 35 : class Elem; 36 : 37 : /** 38 : * A class holding degree of freedom information pertinent to static condensation. 39 : * Static condensation is a process for reducing the number of unknowns in a 40 : * linear(ized) system. It is often used in conjunction with a hybridized discontinuous Galerkin 41 : * (HDG) method to reduce the number of unknowns in the linear system to something more on the order 42 : * of a continuous Galerkin (CG) method as opposed to a discontinuous Galerkin method. In the HDG 43 : * example, degrees of freedom on the element interiors are condensed out and only the degrees of 44 : * freedom on element faces are retained in the condensed system. Static condensation is not only 45 : * applicable to HDG methods, however. One could also use static condensation with a high order CG 46 : * method, again removing internal degrees of freedom and leaving those on element boundaries. 47 : * 48 : * Users may query this class for condensed space degree of freedom information associated with 49 : * elements. Queries with nodes are not supported. This class also holds information for mapping 50 : * degree of freedom indices in the global, uncondensed space to local element degree of freedom 51 : * numbers. This information is essential in order to build the element Schur complement matrices 52 : * that are used to map global system vector and matrix data to the condensed system vector and 53 : * matrix data 54 : */ 55 90 : class StaticCondensationDofMap : public ReducedDofMap 56 : { 57 : public: 58 : StaticCondensationDofMap(MeshBase & mesh, System & system, const DofMap & dof_map); 59 : virtual ~StaticCondensationDofMap(); 60 : 61 : /** 62 : * Build the reduced space and the element global to local index maps 63 : */ 64 : virtual void reinit() override; 65 : 66 : /** 67 : * Add \p vars to the list of variables not to condense. This can be useful when some variable's 68 : * equation is discretized with a DG method or if including the variable in the condensed block 69 : * diagonal would result in it being singular 70 : */ 71 : void dont_condense_vars(const std::unordered_set<unsigned int> & vars); 72 : 73 : /** 74 : * @returns our list of variables for whom we do not condense out any dofs 75 : */ 76 : const std::unordered_set<unsigned int> & uncondensed_vars() const { return _uncondensed_vars; } 77 : 78 : virtual void clear() override; 79 : 80 : /** 81 : * Degrees of freedom on element boundaries and degrees of freedom of uncondensed variables are 82 : * retained 83 : */ 84 : virtual bool retain_field_dof(const Elem & elem, 85 : unsigned int node_num, 86 : unsigned int var_num, 87 : dof_id_type field_dof) const override; 88 : 89 : protected: 90 : virtual void retained_dof_added(const Elem & elem, dof_id_type full_dof) override; 91 : 92 : virtual void unretained_dof_found(const Elem & elem, dof_id_type full_dof) override; 93 : 94 : private: 95 : /** 96 : * Data stored on a per-element basis used to compute element Schur complements and their 97 : * applications to vectors 98 : */ 99 : struct DofData 100 : { 101 : /// A map from the global degree of freedom number for the full system (condensed + uncondensed) 102 : /// to an element local number. If this map is queried with a condensed dof, nothing will be 103 : /// found. The size of this container will be the number of uncondensed degrees of freedom whose 104 : /// basis functions are nonzero on the element 105 : std::unordered_map<dof_id_type, dof_id_type> uncondensed_global_to_local_map; 106 : /// A map from the global degree of freedom number for the full system (condensed + uncondensed) 107 : /// to an element local number. If this map is queried with an uncondensed dof, nothing will be 108 : /// found. The size of this container will be the number of condensed degrees of freedom whose 109 : /// basis functions are nonzero on the element 110 : std::unordered_map<dof_id_type, dof_id_type> condensed_global_to_local_map; 111 : /// The parent-space indices of the uncondensed and condensed degrees of freedom, by element 112 : /// local number 113 : std::vector<dof_id_type> uncondensed_parent_dofs; 114 : std::vector<dof_id_type> condensed_parent_dofs; 115 : }; 116 : 117 : /// Friend the static condensation matrix class so they can inspect our degree of freedom data 118 : friend class StaticCondensation; 119 : 120 : /// A map from element ID to Schur complement data 121 : std::unordered_map<dof_id_type, DofData> _elem_to_dof_data; 122 : 123 : /// Variables for which we will keep all dofs 124 : std::unordered_set<unsigned int> _uncondensed_vars; 125 : }; 126 : 127 : inline void 128 16 : StaticCondensationDofMap::dont_condense_vars(const std::unordered_set<unsigned int> & vars) 129 : { 130 16 : _uncondensed_vars.insert(vars.begin(), vars.end()); 131 16 : } 132 : } 133 : 134 : #endif // LIBMESH_STATIC_CONDENSATION_DOF_MAP_H