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 : // 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 9404190 : unsigned int l2_lagrange_n_dofs(const ElemType t, const Order o)
38 : {
39 9404190 : switch (o)
40 : {
41 :
42 : // linear Lagrange shape functions
43 7961630 : case FIRST:
44 : {
45 7961630 : switch (t)
46 : {
47 0 : case NODEELEM:
48 0 : return 1;
49 :
50 294 : case EDGE2:
51 : case EDGE3:
52 : case EDGE4:
53 294 : return 2;
54 :
55 363532 : case TRI3:
56 : case TRISHELL3:
57 : case TRI6:
58 : case TRI7:
59 363532 : return 3;
60 :
61 1014 : case QUAD4:
62 : case QUADSHELL4:
63 : case QUAD8:
64 : case QUADSHELL8:
65 : case QUAD9:
66 : case QUADSHELL9:
67 1014 : return 4;
68 :
69 973578 : case TET4:
70 : case TET10:
71 : case TET14:
72 973578 : return 4;
73 :
74 126745 : case HEX8:
75 : case HEX20:
76 : case HEX27:
77 126745 : return 8;
78 :
79 6982 : case PRISM6:
80 : case PRISM15:
81 : case PRISM18:
82 : case PRISM20:
83 : case PRISM21:
84 6982 : return 6;
85 :
86 0 : case PYRAMID5:
87 : case PYRAMID13:
88 : case PYRAMID14:
89 : case PYRAMID18:
90 0 : return 5;
91 :
92 0 : case INVALID_ELEM:
93 0 : return 0;
94 :
95 0 : default:
96 0 : libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
97 : }
98 : }
99 :
100 :
101 : // quadratic Lagrange shape functions
102 1317882 : case SECOND:
103 : {
104 1317882 : switch (t)
105 : {
106 0 : case NODEELEM:
107 0 : return 1;
108 :
109 588 : case EDGE2:
110 : case EDGE3:
111 588 : return 3;
112 :
113 70672 : case TRI3:
114 : case TRI6:
115 : case TRI7:
116 70672 : return 6;
117 :
118 0 : case QUAD8:
119 : case QUADSHELL8:
120 0 : return 8;
121 :
122 2028 : case QUAD4:
123 : case QUAD9:
124 : case QUADSHELL9:
125 2028 : return 9;
126 :
127 668571 : case TET4:
128 : case TET10:
129 : case TET14:
130 668571 : return 10;
131 :
132 0 : case HEX20:
133 0 : return 20;
134 :
135 142671 : case HEX8:
136 : case HEX27:
137 142671 : return 27;
138 :
139 0 : case PRISM15:
140 0 : return 15;
141 :
142 27928 : case PRISM6:
143 : case PRISM18:
144 : case PRISM20:
145 : case PRISM21:
146 27928 : return 18;
147 :
148 0 : case PYRAMID13:
149 0 : return 13;
150 :
151 0 : case PYRAMID5:
152 : case PYRAMID14:
153 : case PYRAMID18:
154 0 : return 14;
155 :
156 0 : case INVALID_ELEM:
157 0 : return 0;
158 :
159 0 : default:
160 0 : libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
161 : }
162 : }
163 :
164 124678 : case THIRD:
165 : {
166 124678 : switch (t)
167 : {
168 0 : case NODEELEM:
169 0 : return 1;
170 :
171 0 : case EDGE2:
172 : case EDGE3:
173 : case EDGE4:
174 0 : return 4;
175 :
176 1272 : case TRI7:
177 1272 : return 7;
178 :
179 4572 : case TET14:
180 4572 : return 14;
181 :
182 6982 : case PRISM20:
183 6982 : return 20;
184 :
185 38766 : case PRISM21:
186 38766 : return 21;
187 :
188 0 : case PYRAMID18:
189 0 : return 18;
190 :
191 0 : case INVALID_ELEM:
192 0 : return 0;
193 :
194 0 : default:
195 0 : libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
196 : }
197 : }
198 :
199 0 : default:
200 0 : libmesh_error_msg("ERROR: Invalid Order " << Utility::enum_to_string(o) << " selected for L2_LAGRANGE FE family!");
201 : }
202 : }
203 :
204 :
205 :
206 8644421 : unsigned int l2_lagrange_n_dofs(const Elem * e, const Order o)
207 : {
208 989147 : libmesh_assert(e);
209 9404190 : return l2_lagrange_n_dofs(e->type(), o);
210 : }
211 :
212 : } // anonymous namespace
213 :
214 :
215 : // Instantiate (side_) nodal_soln() function for every dimension
216 113883 : LIBMESH_FE_NODAL_SOLN(L2_LAGRANGE, lagrange_nodal_soln)
217 0 : LIBMESH_FE_SIDE_NODAL_SOLN(L2_LAGRANGE)
218 :
219 :
220 : // Do full-specialization for every dimension, instead
221 : // of explicit instantiation at the end of this function.
222 : // This could be macro-ified.
223 0 : template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
224 0 : template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
225 0 : template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
226 0 : template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
227 :
228 0 : template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_n_dofs(e, o); }
229 2484 : template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_n_dofs(e, o); }
230 1721482 : template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_n_dofs(e, o); }
231 5772696 : template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_n_dofs(e, o); }
232 :
233 : // L2 Lagrange elements have all dofs on elements (hence none on nodes)
234 0 : template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
235 2898 : template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
236 3100738 : template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
237 13568922 : template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
238 :
239 0 : template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
240 2187 : template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
241 456497 : template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
242 3137577 : template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
243 :
244 : // L2 Lagrange elements have all dofs on elements
245 0 : template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
246 0 : template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
247 0 : template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
248 0 : template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_n_dofs(t, o); }
249 :
250 0 : template <> unsigned int FE<0,L2_LAGRANGE>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_n_dofs(&e, o); }
251 1971 : template <> unsigned int FE<1,L2_LAGRANGE>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_n_dofs(&e, o); }
252 533355 : template <> unsigned int FE<2,L2_LAGRANGE>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_n_dofs(&e, o); }
253 1372202 : template <> unsigned int FE<3,L2_LAGRANGE>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_n_dofs(&e, o); }
254 :
255 : // L2 Lagrange FEMs are DISCONTINUOUS
256 0 : template <> FEContinuity FE<0,L2_LAGRANGE>::get_continuity() const { return DISCONTINUOUS; }
257 9945 : template <> FEContinuity FE<1,L2_LAGRANGE>::get_continuity() const { return DISCONTINUOUS; }
258 33976 : template <> FEContinuity FE<2,L2_LAGRANGE>::get_continuity() const { return DISCONTINUOUS; }
259 60471 : template <> FEContinuity FE<3,L2_LAGRANGE>::get_continuity() const { return DISCONTINUOUS; }
260 :
261 : // Lagrange FEMs are not hierarchic
262 0 : template <> bool FE<0,L2_LAGRANGE>::is_hierarchic() const { return false; }
263 36 : template <> bool FE<1,L2_LAGRANGE>::is_hierarchic() const { return false; }
264 190 : template <> bool FE<2,L2_LAGRANGE>::is_hierarchic() const { return false; }
265 458 : template <> bool FE<3,L2_LAGRANGE>::is_hierarchic() const { return false; }
266 :
267 : // Lagrange FEM shapes do not need reinit (is this always true?)
268 0 : template <> bool FE<0,L2_LAGRANGE>::shapes_need_reinit() const { return false; }
269 432 : template <> bool FE<1,L2_LAGRANGE>::shapes_need_reinit() const { return false; }
270 971364 : template <> bool FE<2,L2_LAGRANGE>::shapes_need_reinit() const { return false; }
271 2325475 : template <> bool FE<3,L2_LAGRANGE>::shapes_need_reinit() const { return false; }
272 :
273 : // We don't need any constraints for this DISCONTINUOUS basis, hence these
274 : // are NOOPs
275 : #ifdef LIBMESH_ENABLE_AMR
276 : template <>
277 0 : void FE<2,L2_LAGRANGE>::compute_constraints (DofConstraints &,
278 : DofMap &,
279 : const unsigned int,
280 : const Elem *)
281 0 : { }
282 :
283 : template <>
284 0 : void FE<3,L2_LAGRANGE>::compute_constraints (DofConstraints &,
285 : DofMap &,
286 : const unsigned int,
287 : const Elem *)
288 0 : { }
289 : #endif // LIBMESH_ENABLE_AMR
290 :
291 : } // namespace libMesh
|