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 : #include "libmesh/tensor_value.h"
28 :
29 :
30 : namespace libMesh
31 : {
32 :
33 :
34 0 : LIBMESH_DEFAULT_VECTORIZED_FE(0,RAVIART_THOMAS)
35 0 : LIBMESH_DEFAULT_VECTORIZED_FE(1,RAVIART_THOMAS)
36 2818920 : LIBMESH_DEFAULT_VECTORIZED_FE(2,RAVIART_THOMAS)
37 9290274 : LIBMESH_DEFAULT_VECTORIZED_FE(3,RAVIART_THOMAS)
38 0 : LIBMESH_DEFAULT_VECTORIZED_FE(0,L2_RAVIART_THOMAS)
39 0 : LIBMESH_DEFAULT_VECTORIZED_FE(1,L2_RAVIART_THOMAS)
40 329274 : LIBMESH_DEFAULT_VECTORIZED_FE(2,L2_RAVIART_THOMAS)
41 759660 : LIBMESH_DEFAULT_VECTORIZED_FE(3,L2_RAVIART_THOMAS)
42 :
43 :
44 : // Anonymous namespace for local helper functions
45 : namespace {
46 440724 : void raviart_thomas_nodal_soln(const Elem * elem,
47 : const Order order,
48 : const std::vector<Number> & elem_soln,
49 : const int dim,
50 : const int vdim,
51 : std::vector<Number> & nodal_soln,
52 : const bool add_p_level)
53 : {
54 440724 : const unsigned int n_nodes = elem->n_nodes();
55 440724 : const ElemType elem_type = elem->type();
56 :
57 477451 : const Order totalorder = order + add_p_level*elem->p_level();
58 :
59 440724 : nodal_soln.resize(n_nodes*vdim);
60 :
61 36727 : FEType p_refined_fe_type(totalorder, RAVIART_THOMAS);
62 :
63 440724 : if (elem_type != TRI6 && elem_type != TRI7 &&
64 363549 : elem_type != QUAD8 && elem_type != QUAD9 &&
65 310236 : elem_type != TET14 && elem_type != HEX27)
66 0 : libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(elem_type) << " selected for RAVIART_THOMAS FE family!");
67 :
68 440724 : const unsigned int n_sf = FEInterface::n_shape_functions(p_refined_fe_type, elem, false);
69 :
70 73454 : std::vector<Point> refspace_nodes;
71 440724 : FEVectorBase::get_refspace_nodes(elem_type,refspace_nodes);
72 36727 : libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
73 36727 : libmesh_assert_equal_to (elem_soln.size(), n_sf);
74 :
75 : // Need to create new fe object so the shape function has the FETransformation
76 : // applied to it.
77 477451 : std::unique_ptr<FEVectorBase> vis_fe = FEVectorBase::build(dim, p_refined_fe_type);
78 :
79 36727 : const std::vector<std::vector<RealGradient>> & vis_phi = vis_fe->get_phi();
80 :
81 440724 : vis_fe->reinit(elem,&refspace_nodes);
82 :
83 : // Zero before summation
84 36727 : std::fill(nodal_soln.begin(), nodal_soln.end(), 0);
85 :
86 7425444 : for (unsigned int n = 0; n < n_nodes; n++)
87 : // u = Sum (u_i phi_i)
88 44231472 : for (unsigned int i=0; i<n_sf; i++)
89 143030808 : for (int d = 0; d < vdim; d++)
90 141045408 : nodal_soln[vdim*n+d] += elem_soln[i]*(vis_phi[i][n](d));
91 :
92 477451 : return;
93 367270 : } // raviart_thomas_nodal_soln
94 :
95 :
96 :
97 21185754 : unsigned int raviart_thomas_n_dofs(const ElemType t, const Order o)
98 : {
99 18002843 : libmesh_assert_greater (o, 0);
100 21185754 : switch (t)
101 : {
102 116940 : case TRI6:
103 : case TRI7:
104 750304 : return o*(o+2);
105 59736 : case QUAD8:
106 : case QUAD9:
107 359036 : return 2*o*(o+1);
108 7573984 : case TET14:
109 9277697 : return o*(o+1)*(o+3)/2;
110 10940253 : case HEX27:
111 11002719 : return 3*o*o*(o+1);
112 0 : case INVALID_ELEM:
113 0 : return 0;
114 0 : default:
115 0 : libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for RAVIART_THOMAS FE family!");
116 : }
117 : }
118 :
119 :
120 :
121 3525296 : unsigned int raviart_thomas_n_dofs(const Elem * e, const Order o)
122 : {
123 631841 : libmesh_assert(e);
124 3814752 : return raviart_thomas_n_dofs(e->type(), o);
125 : }
126 :
127 :
128 :
129 75336374 : unsigned int raviart_thomas_n_dofs_at_node(const ElemType t,
130 : const Order o,
131 : const unsigned int n)
132 : {
133 6465181 : libmesh_assert_greater (o, 0);
134 75336374 : switch (t)
135 : {
136 4854096 : case TRI6:
137 : case TRI7:
138 : {
139 4433100 : switch (n)
140 : {
141 211752 : case 0:
142 : case 1:
143 : case 2:
144 211752 : return 0;
145 2088504 : case 3:
146 : case 4:
147 : case 5:
148 2088504 : return o;
149 29892 : case 6:
150 29892 : libmesh_assert_equal_to(t, TRI7);
151 29892 : return 0;
152 0 : default:
153 0 : libmesh_error_msg("ERROR: Invalid node ID " << n);
154 : }
155 : }
156 3682814 : case QUAD8:
157 : case QUAD9:
158 : {
159 3377068 : switch (n)
160 : {
161 155456 : case 0:
162 : case 1:
163 : case 2:
164 : case 3:
165 155456 : return 0;
166 1592176 : case 4:
167 : case 5:
168 : case 6:
169 : case 7:
170 1592176 : return o;
171 18034 : case 8:
172 18034 : libmesh_assert_equal_to(t, QUAD9);
173 18034 : return 0;
174 0 : default:
175 0 : libmesh_error_msg("ERROR: Invalid node ID " << n);
176 : }
177 : }
178 29936850 : case TET14:
179 : {
180 29936850 : switch (n)
181 : {
182 1844736 : case 0:
183 : case 1:
184 : case 2:
185 : case 3:
186 : case 4:
187 : case 5:
188 : case 6:
189 : case 7:
190 : case 8:
191 : case 9:
192 1844736 : return 0;
193 688128 : case 10:
194 : case 11:
195 : case 12:
196 : case 13:
197 8141916 : return o*(o+1)/2;
198 0 : default:
199 0 : libmesh_error_msg("ERROR: Invalid node ID " << n);
200 : }
201 : }
202 36862614 : case HEX27:
203 : {
204 33657039 : switch (n)
205 : {
206 2416500 : case 0:
207 : case 1:
208 : case 2:
209 : case 3:
210 : case 4:
211 : case 5:
212 : case 6:
213 : case 7:
214 : case 8:
215 : case 9:
216 : case 10:
217 : case 11:
218 : case 12:
219 : case 13:
220 : case 14:
221 : case 15:
222 : case 16:
223 : case 17:
224 : case 18:
225 : case 19:
226 2416500 : return 0;
227 7845084 : case 20:
228 : case 21:
229 : case 22:
230 : case 23:
231 : case 24:
232 : case 25:
233 7845084 : return o*o;
234 112725 : case 26:
235 112725 : return 0;
236 0 : default:
237 0 : libmesh_error_msg("ERROR: Invalid node ID " << n);
238 : }
239 : }
240 0 : case INVALID_ELEM:
241 0 : return 0;
242 0 : default:
243 0 : libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for RAVIART_THOMAS FE family!");
244 : }
245 : }
246 :
247 :
248 :
249 13777267 : unsigned int raviart_thomas_n_dofs_at_node(const Elem & e,
250 : const Order o,
251 : const unsigned int n)
252 : {
253 15221189 : return raviart_thomas_n_dofs_at_node(e.type(), o, n);
254 : }
255 :
256 :
257 :
258 4437205 : unsigned int raviart_thomas_n_dofs_per_elem(const ElemType t,
259 : const Order o)
260 : {
261 377605 : libmesh_assert_greater (o, 0);
262 4437205 : switch (t)
263 : {
264 59784 : case TRI6:
265 : case TRI7:
266 696168 : return o*(o-1);
267 33064 : case QUAD8:
268 : case QUAD9:
269 398044 : return 2*o*(o-1);
270 172032 : case TET14:
271 2207511 : return (o+1)*o*(o-1)/2;
272 1307514 : case HEX27:
273 1420239 : return 3*o*o*(o-1);
274 0 : case INVALID_ELEM:
275 0 : return 0;
276 0 : default:
277 0 : libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for RAVIART_THOMAS FE family!");
278 : }
279 : }
280 :
281 :
282 :
283 4059600 : unsigned int raviart_thomas_n_dofs_per_elem(const Elem & e,
284 : const Order o)
285 : {
286 4437205 : return raviart_thomas_n_dofs_per_elem(e.type(), o);
287 : }
288 :
289 :
290 : #ifdef LIBMESH_ENABLE_AMR
291 0 : void raviart_thomas_compute_constraints (DofConstraints & /*constraints*/,
292 : DofMap & /*dof_map*/,
293 : const unsigned int /*variable_number*/,
294 : const Elem * libmesh_dbg_var(elem),
295 : const unsigned Dim)
296 : {
297 : // Only constrain elements in 2,3D.
298 0 : if (Dim == 1)
299 0 : return;
300 :
301 0 : libmesh_assert(elem);
302 :
303 0 : libmesh_not_implemented();
304 : } // raviart_thomas_compute_constraints()
305 : #endif // #ifdef LIBMESH_ENABLE_AMR
306 :
307 : } // anonymous namespace
308 :
309 : #define RAVIART_LOW_D_ERROR_MESSAGE \
310 : libmesh_error_msg("ERROR: This method makes no sense for low-D elements!");
311 :
312 :
313 : // Do full-specialization for every dimension, instead
314 : // of explicit instantiation at the end of this file.
315 : template <>
316 0 : void FE<0,RAVIART_THOMAS>::nodal_soln(const Elem *,
317 : const Order,
318 : const std::vector<Number> &,
319 : std::vector<Number> &,
320 : bool,
321 : const unsigned)
322 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
323 :
324 : template <>
325 0 : void FE<1,RAVIART_THOMAS>::nodal_soln(const Elem *,
326 : const Order,
327 : const std::vector<Number> &,
328 : std::vector<Number> &,
329 : bool,
330 : const unsigned)
331 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
332 :
333 : template <>
334 97200 : void FE<2,RAVIART_THOMAS>::nodal_soln(const Elem * elem,
335 : const Order order,
336 : const std::vector<Number> & elem_soln,
337 : std::vector<Number> & nodal_soln,
338 : const bool add_p_level,
339 : const unsigned vdim)
340 97200 : { raviart_thomas_nodal_soln(elem, order, elem_soln, 2 /*dim*/, vdim, nodal_soln, add_p_level); }
341 :
342 : template <>
343 308124 : void FE<3,RAVIART_THOMAS>::nodal_soln(const Elem * elem,
344 : const Order order,
345 : const std::vector<Number> & elem_soln,
346 : std::vector<Number> & nodal_soln,
347 : const bool add_p_level,
348 : const unsigned)
349 308124 : { raviart_thomas_nodal_soln(elem, order, elem_soln, 3 /*dim*/, 3 /*vdim*/, nodal_soln, add_p_level); }
350 :
351 : template <>
352 0 : void FE<0,L2_RAVIART_THOMAS>::nodal_soln(const Elem *,
353 : const Order,
354 : const std::vector<Number> &,
355 : std::vector<Number> &,
356 : bool,
357 : const unsigned)
358 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
359 :
360 : template <>
361 0 : void FE<1,L2_RAVIART_THOMAS>::nodal_soln(const Elem *,
362 : const Order,
363 : const std::vector<Number> &,
364 : std::vector<Number> &,
365 : bool,
366 : const unsigned)
367 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
368 :
369 : template <>
370 16200 : void FE<2,L2_RAVIART_THOMAS>::nodal_soln(const Elem * elem,
371 : const Order order,
372 : const std::vector<Number> & elem_soln,
373 : std::vector<Number> & nodal_soln,
374 : const bool add_p_level,
375 : const unsigned vdim)
376 16200 : { raviart_thomas_nodal_soln(elem, order, elem_soln, 2 /*dim*/, vdim, nodal_soln, add_p_level); }
377 :
378 : template <>
379 19200 : void FE<3,L2_RAVIART_THOMAS>::nodal_soln(const Elem * elem,
380 : const Order order,
381 : const std::vector<Number> & elem_soln,
382 : std::vector<Number> & nodal_soln,
383 : const bool add_p_level,
384 : const unsigned)
385 19200 : { raviart_thomas_nodal_soln(elem, order, elem_soln, 3 /*dim*/, 3 /*vdim*/, nodal_soln, add_p_level); }
386 :
387 0 : LIBMESH_FE_SIDE_NODAL_SOLN(RAVIART_THOMAS)
388 0 : LIBMESH_FE_SIDE_NODAL_SOLN(L2_RAVIART_THOMAS)
389 :
390 :
391 : // Do full-specialization for every dimension, instead
392 : // of explicit instantiation at the end of this function.
393 : // This could be macro-ified.
394 0 : template <> unsigned int FE<0,RAVIART_THOMAS>::n_dofs(const ElemType, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
395 0 : template <> unsigned int FE<1,RAVIART_THOMAS>::n_dofs(const ElemType, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
396 0 : template <> unsigned int FE<2,RAVIART_THOMAS>::n_dofs(const ElemType t, const Order o) { return raviart_thomas_n_dofs(t, o); }
397 17371002 : template <> unsigned int FE<3,RAVIART_THOMAS>::n_dofs(const ElemType t, const Order o) { return raviart_thomas_n_dofs(t, o); }
398 :
399 0 : template <> unsigned int FE<0,RAVIART_THOMAS>::n_dofs(const Elem *, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
400 0 : template <> unsigned int FE<1,RAVIART_THOMAS>::n_dofs(const Elem *, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
401 640568 : template <> unsigned int FE<2,RAVIART_THOMAS>::n_dofs(const Elem * e, const Order o) { return raviart_thomas_n_dofs(e, o); }
402 2080262 : template <> unsigned int FE<3,RAVIART_THOMAS>::n_dofs(const Elem * e, const Order o) { return raviart_thomas_n_dofs(e, o); }
403 :
404 0 : template <> unsigned int FE<0,L2_RAVIART_THOMAS>::n_dofs(const ElemType, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
405 0 : template <> unsigned int FE<1,L2_RAVIART_THOMAS>::n_dofs(const ElemType, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
406 0 : template <> unsigned int FE<2,L2_RAVIART_THOMAS>::n_dofs(const ElemType t, const Order o) { return raviart_thomas_n_dofs(t, o); }
407 0 : template <> unsigned int FE<3,L2_RAVIART_THOMAS>::n_dofs(const ElemType t, const Order o) { return raviart_thomas_n_dofs(t, o); }
408 :
409 0 : template <> unsigned int FE<0,L2_RAVIART_THOMAS>::n_dofs(const Elem *, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
410 0 : template <> unsigned int FE<1,L2_RAVIART_THOMAS>::n_dofs(const Elem *, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
411 468772 : template <> unsigned int FE<2,L2_RAVIART_THOMAS>::n_dofs(const Elem * e, const Order o) { return raviart_thomas_n_dofs(e, o); }
412 625150 : template <> unsigned int FE<3,L2_RAVIART_THOMAS>::n_dofs(const Elem * e, const Order o) { return raviart_thomas_n_dofs(e, o); }
413 :
414 0 : template <> unsigned int FE<0,RAVIART_THOMAS>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { RAVIART_LOW_D_ERROR_MESSAGE }
415 0 : template <> unsigned int FE<1,RAVIART_THOMAS>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { RAVIART_LOW_D_ERROR_MESSAGE }
416 6620214 : template <> unsigned int FE<2,RAVIART_THOMAS>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return raviart_thomas_n_dofs_at_node(t, o, n); }
417 53494971 : template <> unsigned int FE<3,RAVIART_THOMAS>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return raviart_thomas_n_dofs_at_node(t, o, n); }
418 :
419 0 : template <> unsigned int FE<0,RAVIART_THOMAS>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { RAVIART_LOW_D_ERROR_MESSAGE }
420 0 : template <> unsigned int FE<1,RAVIART_THOMAS>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { RAVIART_LOW_D_ERROR_MESSAGE }
421 1916696 : template <> unsigned int FE<2,RAVIART_THOMAS>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return raviart_thomas_n_dofs_at_node(e, o, n); }
422 13304493 : template <> unsigned int FE<3,RAVIART_THOMAS>::n_dofs_at_node(const Elem & e, const Order o, const unsigned int n) { return raviart_thomas_n_dofs_at_node(e, o, n); }
423 :
424 0 : template <> unsigned int FE<0,L2_RAVIART_THOMAS>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { RAVIART_LOW_D_ERROR_MESSAGE }
425 0 : template <> unsigned int FE<1,L2_RAVIART_THOMAS>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { RAVIART_LOW_D_ERROR_MESSAGE }
426 1283735 : template <> unsigned int FE<2,L2_RAVIART_THOMAS>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
427 3095338 : template <> unsigned int FE<3,L2_RAVIART_THOMAS>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
428 :
429 0 : template <> unsigned int FE<0,L2_RAVIART_THOMAS>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { RAVIART_LOW_D_ERROR_MESSAGE }
430 0 : template <> unsigned int FE<1,L2_RAVIART_THOMAS>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { RAVIART_LOW_D_ERROR_MESSAGE }
431 289116 : template <> unsigned int FE<2,L2_RAVIART_THOMAS>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
432 855380 : template <> unsigned int FE<3,L2_RAVIART_THOMAS>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
433 :
434 0 : template <> unsigned int FE<0,RAVIART_THOMAS>::n_dofs_per_elem(const ElemType, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
435 0 : template <> unsigned int FE<1,RAVIART_THOMAS>::n_dofs_per_elem(const ElemType, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
436 0 : template <> unsigned int FE<2,RAVIART_THOMAS>::n_dofs_per_elem(const ElemType t, const Order o) { return raviart_thomas_n_dofs_per_elem(t, o); }
437 0 : template <> unsigned int FE<3,RAVIART_THOMAS>::n_dofs_per_elem(const ElemType t, const Order o) { return raviart_thomas_n_dofs_per_elem(t, o); }
438 :
439 0 : template <> unsigned int FE<0,RAVIART_THOMAS>::n_dofs_per_elem(const Elem &, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
440 0 : template <> unsigned int FE<1,RAVIART_THOMAS>::n_dofs_per_elem(const Elem &, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
441 1094212 : template <> unsigned int FE<2,RAVIART_THOMAS>::n_dofs_per_elem(const Elem & e, const Order o) { return raviart_thomas_n_dofs_per_elem(e, o); }
442 3342993 : template <> unsigned int FE<3,RAVIART_THOMAS>::n_dofs_per_elem(const Elem & e, const Order o) { return raviart_thomas_n_dofs_per_elem(e, o); }
443 :
444 : // L2 Raviart-Thomas elements have all their dofs per element
445 0 : template <> unsigned int FE<0,L2_RAVIART_THOMAS>::n_dofs_per_elem(const ElemType, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
446 0 : template <> unsigned int FE<1,L2_RAVIART_THOMAS>::n_dofs_per_elem(const ElemType, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
447 0 : template <> unsigned int FE<2,L2_RAVIART_THOMAS>::n_dofs_per_elem(const ElemType t, const Order o) { return n_dofs(t, o); }
448 0 : template <> unsigned int FE<3,L2_RAVIART_THOMAS>::n_dofs_per_elem(const ElemType t, const Order o) { return n_dofs(t, o); }
449 :
450 0 : template <> unsigned int FE<0,L2_RAVIART_THOMAS>::n_dofs_per_elem(const Elem &, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
451 0 : template <> unsigned int FE<1,L2_RAVIART_THOMAS>::n_dofs_per_elem(const Elem &, const Order) { RAVIART_LOW_D_ERROR_MESSAGE }
452 206626 : template <> unsigned int FE<2,L2_RAVIART_THOMAS>::n_dofs_per_elem(const Elem & e, const Order o) { return n_dofs(&e, o); }
453 257937 : template <> unsigned int FE<3,L2_RAVIART_THOMAS>::n_dofs_per_elem(const Elem & e, const Order o) { return n_dofs(&e, o); }
454 :
455 : // Raviart-Thomas FEMs are always normally continuous
456 0 : template <> FEContinuity FE<0,RAVIART_THOMAS>::get_continuity() const { RAVIART_LOW_D_ERROR_MESSAGE }
457 0 : template <> FEContinuity FE<1,RAVIART_THOMAS>::get_continuity() const { RAVIART_LOW_D_ERROR_MESSAGE }
458 0 : template <> FEContinuity FE<2,RAVIART_THOMAS>::get_continuity() const { return H_DIV; }
459 0 : template <> FEContinuity FE<3,RAVIART_THOMAS>::get_continuity() const { return H_DIV; }
460 :
461 : // L2 Raviart-Thomas FEMs are discontinuous
462 0 : template <> FEContinuity FE<0,L2_RAVIART_THOMAS>::get_continuity() const { RAVIART_LOW_D_ERROR_MESSAGE }
463 0 : template <> FEContinuity FE<1,L2_RAVIART_THOMAS>::get_continuity() const { RAVIART_LOW_D_ERROR_MESSAGE }
464 0 : template <> FEContinuity FE<2,L2_RAVIART_THOMAS>::get_continuity() const { return DISCONTINUOUS; }
465 0 : template <> FEContinuity FE<3,L2_RAVIART_THOMAS>::get_continuity() const { return DISCONTINUOUS; }
466 :
467 : // Raviart-Thomas FEMs are not hierarchic
468 0 : template <> bool FE<0,RAVIART_THOMAS>::is_hierarchic() const { RAVIART_LOW_D_ERROR_MESSAGE }
469 0 : template <> bool FE<1,RAVIART_THOMAS>::is_hierarchic() const { RAVIART_LOW_D_ERROR_MESSAGE }
470 0 : template <> bool FE<2,RAVIART_THOMAS>::is_hierarchic() const { return false; }
471 0 : template <> bool FE<3,RAVIART_THOMAS>::is_hierarchic() const { return false; }
472 0 : template <> bool FE<0,L2_RAVIART_THOMAS>::is_hierarchic() const { RAVIART_LOW_D_ERROR_MESSAGE }
473 0 : template <> bool FE<1,L2_RAVIART_THOMAS>::is_hierarchic() const { RAVIART_LOW_D_ERROR_MESSAGE }
474 0 : template <> bool FE<2,L2_RAVIART_THOMAS>::is_hierarchic() const { return false; }
475 0 : template <> bool FE<3,L2_RAVIART_THOMAS>::is_hierarchic() const { return false; }
476 :
477 : // Raviart-Thomas FEM shapes always need to be reinit'ed (because of orientation dependence)
478 0 : template <> bool FE<0,RAVIART_THOMAS>::shapes_need_reinit() const { RAVIART_LOW_D_ERROR_MESSAGE }
479 0 : template <> bool FE<1,RAVIART_THOMAS>::shapes_need_reinit() const { RAVIART_LOW_D_ERROR_MESSAGE }
480 722284 : template <> bool FE<2,RAVIART_THOMAS>::shapes_need_reinit() const { return true; }
481 2337292 : template <> bool FE<3,RAVIART_THOMAS>::shapes_need_reinit() const { return true; }
482 :
483 : // Do L2 Raviart-Thomas FEM shapes always need to be reinit'ed because of orientation dependence?
484 0 : template <> bool FE<0,L2_RAVIART_THOMAS>::shapes_need_reinit() const { RAVIART_LOW_D_ERROR_MESSAGE }
485 0 : template <> bool FE<1,L2_RAVIART_THOMAS>::shapes_need_reinit() const { RAVIART_LOW_D_ERROR_MESSAGE }
486 351430 : template <> bool FE<2,L2_RAVIART_THOMAS>::shapes_need_reinit() const { return true; }
487 463761 : template <> bool FE<3,L2_RAVIART_THOMAS>::shapes_need_reinit() const { return true; }
488 :
489 : #ifdef LIBMESH_ENABLE_AMR
490 : template <>
491 0 : void FE<0,RAVIART_THOMAS>::compute_constraints (DofConstraints &,
492 : DofMap &,
493 : const unsigned int,
494 : const Elem *)
495 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
496 :
497 : template <>
498 0 : void FE<1,RAVIART_THOMAS>::compute_constraints (DofConstraints &,
499 : DofMap &,
500 : const unsigned int,
501 : const Elem *)
502 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
503 :
504 : template <>
505 0 : void FE<2,RAVIART_THOMAS>::compute_constraints (DofConstraints & constraints,
506 : DofMap & dof_map,
507 : const unsigned int variable_number,
508 : const Elem * elem)
509 0 : { raviart_thomas_compute_constraints(constraints, dof_map, variable_number, elem, /*Dim=*/2); }
510 :
511 : template <>
512 0 : void FE<3,RAVIART_THOMAS>::compute_constraints (DofConstraints & constraints,
513 : DofMap & dof_map,
514 : const unsigned int variable_number,
515 : const Elem * elem)
516 0 : { raviart_thomas_compute_constraints(constraints, dof_map, variable_number, elem, /*Dim=*/3); }
517 :
518 : template <>
519 0 : void FE<0,L2_RAVIART_THOMAS>::compute_constraints (DofConstraints &,
520 : DofMap &,
521 : const unsigned int,
522 : const Elem *)
523 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
524 :
525 : template <>
526 0 : void FE<1,L2_RAVIART_THOMAS>::compute_constraints (DofConstraints &,
527 : DofMap &,
528 : const unsigned int,
529 : const Elem *)
530 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
531 :
532 : template <>
533 0 : void FE<2,L2_RAVIART_THOMAS>::compute_constraints (DofConstraints & constraints,
534 : DofMap & dof_map,
535 : const unsigned int variable_number,
536 : const Elem * elem)
537 0 : { raviart_thomas_compute_constraints(constraints, dof_map, variable_number, elem, /*Dim=*/2); }
538 :
539 : template <>
540 0 : void FE<3,L2_RAVIART_THOMAS>::compute_constraints (DofConstraints & constraints,
541 : DofMap & dof_map,
542 : const unsigned int variable_number,
543 : const Elem * elem)
544 0 : { raviart_thomas_compute_constraints(constraints, dof_map, variable_number, elem, /*Dim=*/3); }
545 : #endif // LIBMESH_ENABLE_AMR
546 :
547 : // Specialize useless shape function methods
548 : template <>
549 0 : RealGradient FE<0,RAVIART_THOMAS>::shape(const ElemType, const Order,const unsigned int,const Point &)
550 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
551 : template <>
552 0 : RealGradient FE<0,RAVIART_THOMAS>::shape(const Elem *,const Order,const unsigned int,const Point &,const bool)
553 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
554 : template <>
555 0 : RealGradient FE<0,L2_RAVIART_THOMAS>::shape(const ElemType, const Order,const unsigned int,const Point &)
556 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
557 : template <>
558 0 : RealGradient FE<0,L2_RAVIART_THOMAS>::shape(const Elem *,const Order,const unsigned int,const Point &,const bool)
559 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
560 : template <>
561 0 : RealGradient FE<0,RAVIART_THOMAS>::shape_deriv(const ElemType, const Order,const unsigned int,
562 : const unsigned int,const Point &)
563 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
564 : template <>
565 0 : RealGradient FE<0,RAVIART_THOMAS>::shape_deriv(const Elem *,const Order,const unsigned int,
566 : const unsigned int,const Point &,const bool)
567 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
568 : template <>
569 0 : RealGradient FE<0,L2_RAVIART_THOMAS>::shape_deriv(const ElemType, const Order,const unsigned int,
570 : const unsigned int,const Point &)
571 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
572 : template <>
573 0 : RealGradient FE<0,L2_RAVIART_THOMAS>::shape_deriv(const Elem *,const Order,const unsigned int,
574 : const unsigned int,const Point &,const bool)
575 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
576 :
577 : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
578 : template <>
579 0 : RealGradient FE<0,RAVIART_THOMAS>::shape_second_deriv(const ElemType, const Order,const unsigned int,
580 : const unsigned int,const Point &)
581 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
582 : template <>
583 0 : RealGradient FE<0,RAVIART_THOMAS>::shape_second_deriv(const Elem *,const Order,const unsigned int,
584 : const unsigned int,const Point &,const bool)
585 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
586 : template <>
587 0 : RealGradient FE<0,L2_RAVIART_THOMAS>::shape_second_deriv(const ElemType, const Order,const unsigned int,
588 : const unsigned int,const Point &)
589 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
590 : template <>
591 0 : RealGradient FE<0,L2_RAVIART_THOMAS>::shape_second_deriv(const Elem *,const Order,const unsigned int,
592 : const unsigned int,const Point &,const bool)
593 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
594 :
595 : #endif
596 :
597 : template <>
598 0 : RealGradient FE<1,RAVIART_THOMAS>::shape(const ElemType, const Order,const unsigned int,const Point &)
599 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
600 : template <>
601 0 : RealGradient FE<1,RAVIART_THOMAS>::shape(const Elem *,const Order,const unsigned int,const Point &,const bool)
602 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
603 : template <>
604 0 : RealGradient FE<1,L2_RAVIART_THOMAS>::shape(const ElemType, const Order,const unsigned int,const Point &)
605 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
606 : template <>
607 0 : RealGradient FE<1,L2_RAVIART_THOMAS>::shape(const Elem *,const Order,const unsigned int,const Point &,const bool)
608 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
609 : template <>
610 0 : RealGradient FE<1,RAVIART_THOMAS>::shape_deriv(const ElemType, const Order,const unsigned int,
611 : const unsigned int,const Point &)
612 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
613 : template <>
614 0 : RealGradient FE<1,RAVIART_THOMAS>::shape_deriv(const Elem *,const Order,const unsigned int,
615 : const unsigned int,const Point &,const bool)
616 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
617 : template <>
618 0 : RealGradient FE<1,L2_RAVIART_THOMAS>::shape_deriv(const ElemType, const Order,const unsigned int,
619 : const unsigned int,const Point &)
620 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
621 : template <>
622 0 : RealGradient FE<1,L2_RAVIART_THOMAS>::shape_deriv(const Elem *,const Order,const unsigned int,
623 : const unsigned int,const Point &,const bool)
624 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
625 :
626 : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
627 : template <>
628 0 : RealGradient FE<1,RAVIART_THOMAS>::shape_second_deriv(const ElemType, const Order,const unsigned int,
629 : const unsigned int,const Point &)
630 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
631 : template <>
632 0 : RealGradient FE<1,RAVIART_THOMAS>::shape_second_deriv(const Elem *,const Order,const unsigned int,
633 : const unsigned int,const Point &,const bool)
634 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
635 : template <>
636 0 : RealGradient FE<1,L2_RAVIART_THOMAS>::shape_second_deriv(const ElemType, const Order,const unsigned int,
637 : const unsigned int,const Point &)
638 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
639 : template <>
640 0 : RealGradient FE<1,L2_RAVIART_THOMAS>::shape_second_deriv(const Elem *,const Order,const unsigned int,
641 : const unsigned int,const Point &,const bool)
642 0 : { RAVIART_LOW_D_ERROR_MESSAGE }
643 :
644 : #endif
645 :
646 : } // namespace libMesh
|