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 : #ifndef LIBMESH_DOF_MAP_BASE_H 19 : #define LIBMESH_DOF_MAP_BASE_H 20 : 21 : #include "libmesh/id_types.h" 22 : #include "libmesh/parallel_object.h" 23 : #include <vector> 24 : 25 : namespace libMesh 26 : { 27 : class Variable; 28 : class Elem; 29 : class Node; 30 : 31 : /** 32 : * This base class provides a minimal set of interfaces for satisfying user requests for 33 : * - variables that contribute degrees of freedom to this map 34 : * - distribution of degrees of freedom among ranks in parallel (e.g. MPI) simulations 35 : * - degrees of freedom associated with nodes and elements 36 : * This minimal set of interfaces is sufficient for providing information for use cases such 37 : * as building field splits for advanced preconditioning techniques 38 : * 39 : * Sub-classes of this base class may not be fully-featured stand-alone degree of freedom maps. 40 : * For instance a sub-class may not be constructible without information from an already constructed 41 : * fully-featured degree of freedom map. As an example, a degree of freedom map for a statically 42 : * condensed system of equations will require *a priori* and flow naturally from a degree of freedom 43 : * map for the full non-condensed system. In this example, the partitioning of the statically 44 : * condensed degrees of freedom may logically follow the partitioning in the global system, e.g. a 45 : * face degree of freedom in the global system that is assigned to process i by the full degree of 46 : * freedom map will retain its rank assignment in the statically condensed degree of freedom map. 47 : * Because the statically condensed dof map can lazily use the information from the full dof map, 48 : * it does not require its own partitioning capabilities. Consequently, partitioning interfaces 49 : * are not present in this base interface 50 : */ 51 : class DofMapBase : public ParallelObject 52 : { 53 : public: 54 : DofMapBase(const Parallel::Communicator & comm); 55 : 56 : /** 57 : * \returns The number of variables in the global solution vector. Defaults 58 : * to 1, should be 1 for a scalar equation, 3 for 2D incompressible Navier 59 : * Stokes (u,v,p), etc... 60 : */ 61 : virtual unsigned int n_variables() const = 0; 62 : 63 : /** 64 : * \returns The variable description object for variable \p c. 65 : */ 66 : virtual const Variable & variable(const unsigned int c) const = 0; 67 : 68 : /** 69 : * \returns The first dof index that is local to partition \p proc. 70 : */ 71 : dof_id_type first_dof(const processor_id_type proc) const; 72 : 73 10402189 : dof_id_type first_dof() const { return this->first_dof(this->processor_id()); } 74 : 75 : /** 76 : * \returns The first dof index that is after all indices local to 77 : * processor \p proc. 78 : * 79 : * Analogous to the end() member function of STL containers. 80 : */ 81 : dof_id_type end_dof(const processor_id_type proc) const; 82 : 83 3798938 : dof_id_type end_dof() const { return this->end_dof(this->processor_id()); } 84 : 85 : /** 86 : * Fills the vector \p di with the global degree of freedom indices 87 : * for the element. For one variable, and potentially for a 88 : * non-default element p refinement level 89 : */ 90 : virtual void dof_indices(const Elem * const elem, 91 : std::vector<dof_id_type> & di, 92 : const unsigned int vn, 93 : int p_level = -12345) const = 0; 94 : 95 : /** 96 : * Fills the vector \p di with the global degree of freedom indices 97 : * for the \p node, for one variable \p vn. 98 : */ 99 : virtual void dof_indices(const Node * const node, 100 : std::vector<dof_id_type> & di, 101 : const unsigned int vn) const = 0; 102 : /** 103 : * \returns The total number of degrees of freedom in the problem. 104 : */ 105 264075272 : dof_id_type n_dofs() const { return _n_dfs; } 106 : 107 : /** 108 : * \returns The number of degrees of freedom on partition \p proc. 109 : */ 110 : dof_id_type n_dofs_on_processor(const processor_id_type proc) const; 111 : 112 : /** 113 : * \returns The number of degrees of freedom on this processor. 114 : */ 115 1899482 : dof_id_type n_local_dofs() const { return this->n_dofs_on_processor(this->processor_id()); } 116 : 117 : virtual void clear(); 118 : 119 : #ifdef LIBMESH_ENABLE_AMR 120 : /** 121 : * \returns The total number of degrees of freedom on old_dof_objects 122 : */ 123 2678326 : dof_id_type n_old_dofs() const { return _n_old_dfs; } 124 : 125 : /** 126 : * \returns The first old dof index that is local to partition \p proc. 127 : */ 128 : dof_id_type first_old_dof(const processor_id_type proc) const; 129 : 130 5597 : dof_id_type first_old_dof() const { return this->first_old_dof(this->processor_id()); } 131 : 132 : /** 133 : * \returns The first old dof index that is after all indices local 134 : * to processor \p proc. 135 : * 136 : * Analogous to the end() member function of STL containers. 137 : */ 138 : dof_id_type end_old_dof(const processor_id_type proc) const; 139 : 140 2579 : dof_id_type end_old_dof() const { return this->end_old_dof(this->processor_id()); } 141 : #endif // LIBMESH_ENABLE_AMR 142 : 143 : protected: 144 : /** 145 : * compute the key degree of freedom information given the local number of degrees of freedom on 146 : * this process 147 : * \returns The total number of DOFs for the System, summed across all procs. 148 : */ 149 : std::size_t compute_dof_info(dof_id_type n_local_dofs); 150 : 151 : /** 152 : * First DOF index on processor \p p. 153 : */ 154 : std::vector<dof_id_type> _first_df; 155 : 156 : /** 157 : * Last DOF index (plus 1) on processor \p p. 158 : */ 159 : std::vector<dof_id_type> _end_df; 160 : 161 : /** 162 : * Total number of degrees of freedom. 163 : */ 164 : dof_id_type _n_dfs; 165 : 166 : #ifdef LIBMESH_ENABLE_AMR 167 : 168 : /** 169 : * Total number of degrees of freedom on old dof objects 170 : */ 171 : dof_id_type _n_old_dfs; 172 : 173 : /** 174 : * First old DOF index on processor \p p. 175 : */ 176 : std::vector<dof_id_type> _first_old_df; 177 : 178 : /** 179 : * Last old DOF index (plus 1) on processor \p p. 180 : */ 181 : std::vector<dof_id_type> _end_old_df; 182 : #endif 183 : }; 184 : 185 7399180 : inline dof_id_type DofMapBase::first_dof(const processor_id_type proc) const 186 : { 187 7399180 : libmesh_assert_less(proc, _first_df.size()); 188 99291953 : return _first_df[proc]; 189 : } 190 : 191 7031097 : inline dof_id_type DofMapBase::end_dof(const processor_id_type proc) const 192 : { 193 7031097 : libmesh_assert_less(proc, _end_df.size()); 194 81136515 : return _end_df[proc]; 195 : } 196 : 197 626598 : inline dof_id_type DofMapBase::n_dofs_on_processor(const processor_id_type proc) const 198 : { 199 626598 : libmesh_assert_less(proc, _first_df.size()); 200 4549672 : return cast_int<dof_id_type>(_end_df[proc] - _first_df[proc]); 201 : } 202 : 203 : #ifdef LIBMESH_ENABLE_AMR 204 2579 : inline dof_id_type DofMapBase::first_old_dof(const processor_id_type proc) const 205 : { 206 2579 : libmesh_assert_less(proc, _first_old_df.size()); 207 46647 : return _first_old_df[proc]; 208 : } 209 : 210 2579 : inline dof_id_type DofMapBase::end_old_dof(const processor_id_type proc) const 211 : { 212 2579 : libmesh_assert_less(proc, _end_old_df.size()); 213 49673 : return _end_old_df[proc]; 214 : } 215 : #endif // LIBMESH_ENABLE_AMR 216 : } 217 : #endif // LIBMESH_DOF_MAP_BASE_H