libMesh
fe_l2_lagrange.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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 // Local includes
21 #include "libmesh/dof_map.h"
22 #include "libmesh/elem.h"
23 #include "libmesh/enum_to_string.h"
24 #include "libmesh/fe.h"
25 #include "libmesh/fe_interface.h"
26 #include "libmesh/fe_macro.h"
27 
28 namespace libMesh
29 {
30 
31 // ------------------------------------------------------------
32 // Lagrange-specific implementations
33 
34 
35 // Anonymous namespace for local helper functions
36 namespace {
37 unsigned int l2_lagrange_n_dofs(const ElemType t, const Order o)
38 {
39  switch (o)
40  {
41 
42  // linear Lagrange shape functions
43  case FIRST:
44  {
45  switch (t)
46  {
47  case NODEELEM:
48  return 1;
49 
50  case EDGE2:
51  case EDGE3:
52  case EDGE4:
53  return 2;
54 
55  case TRI3:
56  case TRISHELL3:
57  case TRI6:
58  case TRI7:
59  return 3;
60 
61  case QUAD4:
62  case QUADSHELL4:
63  case QUAD8:
64  case QUADSHELL8:
65  case QUAD9:
66  return 4;
67 
68  case TET4:
69  case TET10:
70  case TET14:
71  return 4;
72 
73  case HEX8:
74  case HEX20:
75  case HEX27:
76  return 8;
77 
78  case PRISM6:
79  case PRISM15:
80  case PRISM18:
81  case PRISM20:
82  case PRISM21:
83  return 6;
84 
85  case PYRAMID5:
86  case PYRAMID13:
87  case PYRAMID14:
88  case PYRAMID18:
89  return 5;
90 
91  case INVALID_ELEM:
92  return 0;
93 
94  default:
95  libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
96  }
97  }
98 
99 
100  // quadratic Lagrange shape functions
101  case SECOND:
102  {
103  switch (t)
104  {
105  case NODEELEM:
106  return 1;
107 
108  case EDGE2:
109  case EDGE3:
110  return 3;
111 
112  case TRI3:
113  case TRI6:
114  case TRI7:
115  return 6;
116 
117  case QUAD8:
118  case QUADSHELL8:
119  return 8;
120 
121  case QUAD4:
122  case QUAD9:
123  return 9;
124 
125  case TET4:
126  case TET10:
127  case TET14:
128  return 10;
129 
130  case HEX20:
131  return 20;
132 
133  case HEX8:
134  case HEX27:
135  return 27;
136 
137  case PRISM15:
138  return 15;
139 
140  case PRISM6:
141  case PRISM18:
142  case PRISM20:
143  case PRISM21:
144  return 18;
145 
146  case PYRAMID13:
147  return 13;
148 
149  case PYRAMID5:
150  case PYRAMID14:
151  case PYRAMID18:
152  return 14;
153 
154  case INVALID_ELEM:
155  return 0;
156 
157  default:
158  libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
159  }
160  }
161 
162  case THIRD:
163  {
164  switch (t)
165  {
166  case NODEELEM:
167  return 1;
168 
169  case EDGE2:
170  case EDGE3:
171  case EDGE4:
172  return 4;
173 
174  case TRI7:
175  return 7;
176 
177  case TET14:
178  return 14;
179 
180  case PRISM20:
181  return 20;
182 
183  case PRISM21:
184  return 21;
185 
186  case PYRAMID18:
187  return 18;
188 
189  case INVALID_ELEM:
190  return 0;
191 
192  default:
193  libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
194  }
195  }
196 
197  default:
198  libmesh_error_msg("ERROR: Invalid Order " << Utility::enum_to_string(o) << " selected for L2_LAGRANGE FE family!");
199  }
200 }
201 
202 } // anonymous namespace
203 
204 
205 // Instantiate (side_) nodal_soln() function for every dimension
208 
209 
210 // Do full-specialization for every dimension, instead
211 // of explicit instantiation at the end of this function.
212 // This could be macro-ified.
213 template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
214 template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
215 template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
216 template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
217 
218 
219 // L2 Lagrange elements have all dofs on elements (hence none on nodes)
220 template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
221 template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
222 template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
223 template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
224 
225 
226 // L2 Lagrange elements have all dofs on elements
227 template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
228 template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
229 template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
230 template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
231 
232 // L2 Lagrange FEMs are DISCONTINUOUS
237 
238 // Lagrange FEMs are not hierarchic
239 template <> bool FE<0,L2_LAGRANGE>::is_hierarchic() const { return false; }
240 template <> bool FE<1,L2_LAGRANGE>::is_hierarchic() const { return false; }
241 template <> bool FE<2,L2_LAGRANGE>::is_hierarchic() const { return false; }
242 template <> bool FE<3,L2_LAGRANGE>::is_hierarchic() const { return false; }
243 
244 // Lagrange FEM shapes do not need reinit (is this always true?)
245 template <> bool FE<0,L2_LAGRANGE>::shapes_need_reinit() const { return false; }
246 template <> bool FE<1,L2_LAGRANGE>::shapes_need_reinit() const { return false; }
247 template <> bool FE<2,L2_LAGRANGE>::shapes_need_reinit() const { return false; }
248 template <> bool FE<3,L2_LAGRANGE>::shapes_need_reinit() const { return false; }
249 
250 // We don't need any constraints for this DISCONTINUOUS basis, hence these
251 // are NOOPs
252 #ifdef LIBMESH_ENABLE_AMR
253 template <>
255  DofMap &,
256  const unsigned int,
257  const Elem *)
258 { }
259 
260 template <>
262  DofMap &,
263  const unsigned int,
264  const Elem *)
265 { }
266 #endif // LIBMESH_ENABLE_AMR
267 
268 } // namespace libMesh
static unsigned int n_dofs(const ElemType t, const Order o)
ElemType
Defines an enum for geometric element types.
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
static unsigned int n_dofs_at_node(const ElemType t, const Order o, const unsigned int n)
virtual bool shapes_need_reinit() const override
The libMesh namespace provides an interface to certain functionality in the library.
virtual bool is_hierarchic() const override
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:169
LIBMESH_FE_NODAL_SOLN(BERNSTEIN, bernstein_nodal_soln)
Definition: fe_bernstein.C:397
LIBMESH_FE_SIDE_NODAL_SOLN(HIERARCHIC_VEC)
static unsigned int n_dofs_per_elem(const ElemType t, const Order o)
virtual FEContinuity get_continuity() const override
void lagrange_nodal_soln(const Elem *elem, const Order order, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln, bool add_p_level=true)
Helper functions for Lagrange-based basis functions.
Definition: fe_lagrange.C:43
std::string enum_to_string(const T e)
static void compute_constraints(DofConstraints &constraints, DofMap &dof_map, const unsigned int variable_number, const Elem *elem)
Computes the constraint matrix contributions (for non-conforming adapted meshes) corresponding to var...
FEContinuity
defines an enum for finite element types to libmesh_assert a certain level (or type? Hcurl?) of continuity.
The constraint matrix storage format.
Definition: dof_map.h:98