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 :
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 2763872 : LIBMESH_DEFAULT_VECTORIZED_FE(2,RAVIART_THOMAS)
37 8516220 : 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 410997 : 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 410997 : const unsigned int n_nodes = elem->n_nodes();
55 410997 : const ElemType elem_type = elem->type();
56 :
57 437815 : const Order totalorder = order + add_p_level*elem->p_level();
58 :
59 410997 : nodal_soln.resize(n_nodes*vdim);
60 :
61 26818 : FEType p_refined_fe_type(totalorder, RAVIART_THOMAS);
62 :
63 410997 : if (elem_type != TRI6 && elem_type != TRI7 &&
64 336747 : elem_type != QUAD8 && elem_type != QUAD9 &&
65 289743 : 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 410997 : const unsigned int n_sf = FEInterface::n_shape_functions(p_refined_fe_type, elem, false);
69 :
70 53636 : std::vector<Point> refspace_nodes;
71 410997 : FEVectorBase::get_refspace_nodes(elem_type,refspace_nodes);
72 26818 : libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
73 26818 : 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 437815 : std::unique_ptr<FEVectorBase> vis_fe = FEVectorBase::build(dim, p_refined_fe_type);
78 :
79 26818 : const std::vector<std::vector<RealGradient>> & vis_phi = vis_fe->get_phi();
80 :
81 410997 : vis_fe->reinit(elem,&refspace_nodes);
82 :
83 : // Zero before summation
84 26818 : std::fill(nodal_soln.begin(), nodal_soln.end(), 0);
85 :
86 6875589 : for (unsigned int n = 0; n < n_nodes; n++)
87 : // u = Sum (u_i phi_i)
88 41101632 : for (unsigned int i=0; i<n_sf; i++)
89 132690510 : for (int d = 0; d < vdim; d++)
90 123007374 : nodal_soln[vdim*n+d] += elem_soln[i]*(vis_phi[i][n](d));
91 :
92 437815 : return;
93 357361 : } // raviart_thomas_nodal_soln
94 :
95 :
96 :
97 15779388 : unsigned int raviart_thomas_n_dofs(const ElemType t, const Order o)
98 : {
99 12698906 : libmesh_assert_greater (o, 0);
100 15779388 : switch (t)
101 : {
102 105998 : case TRI6:
103 : case TRI7:
104 730164 : return o*(o+2);
105 54528 : case QUAD8:
106 : case QUAD9:
107 349826 : return 2*o*(o+1);
108 5630528 : case TET14:
109 7253889 : return o*(o+1)*(o+3)/2;
110 7560261 : case HEX27:
111 7604901 : 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 3352610 : unsigned int raviart_thomas_n_dofs(const Elem * e, const Order o)
122 : {
123 510398 : libmesh_assert(e);
124 3590880 : return raviart_thomas_n_dofs(e->type(), o);
125 : }
126 :
127 :
128 :
129 70705682 : unsigned int raviart_thomas_n_dofs_at_node(const ElemType t,
130 : const Order o,
131 : const unsigned int n)
132 : {
133 4782769 : libmesh_assert_greater (o, 0);
134 70705682 : switch (t)
135 : {
136 4693514 : case TRI6:
137 : case TRI7:
138 : {
139 4330984 : switch (n)
140 : {
141 181860 : case 0:
142 : case 1:
143 : case 2:
144 181860 : return 0;
145 2020620 : case 3:
146 : case 4:
147 : case 5:
148 2020620 : return o;
149 25810 : case 6:
150 25810 : libmesh_assert_equal_to(t, TRI7);
151 25810 : return 0;
152 0 : default:
153 0 : libmesh_error_msg("ERROR: Invalid node ID " << n);
154 : }
155 : }
156 3577169 : case QUAD8:
157 : case QUAD9:
158 : {
159 3309958 : switch (n)
160 : {
161 135416 : case 0:
162 : case 1:
163 : case 2:
164 : case 3:
165 135416 : return 0;
166 1546696 : case 4:
167 : case 5:
168 : case 6:
169 : case 7:
170 1546696 : return o;
171 15979 : case 8:
172 15979 : libmesh_assert_equal_to(t, QUAD9);
173 15979 : return 0;
174 0 : default:
175 0 : libmesh_error_msg("ERROR: Invalid node ID " << n);
176 : }
177 : }
178 28009810 : case TET14:
179 : {
180 28009810 : switch (n)
181 : {
182 1333504 : 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 1333504 : return 0;
193 500224 : case 10:
194 : case 11:
195 : case 12:
196 : case 13:
197 7620956 : return o*(o+1)/2;
198 0 : default:
199 0 : libmesh_error_msg("ERROR: Invalid node ID " << n);
200 : }
201 : }
202 34425189 : case HEX27:
203 : {
204 32105889 : switch (n)
205 : {
206 1746000 : 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 1746000 : return 0;
227 7333434 : case 20:
228 : case 21:
229 : case 22:
230 : case 23:
231 : case 24:
232 : case 25:
233 7333434 : return o*o;
234 81900 : case 26:
235 81900 : 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 13100431 : unsigned int raviart_thomas_n_dofs_at_node(const Elem & e,
250 : const Order o,
251 : const unsigned int n)
252 : {
253 14093129 : return raviart_thomas_n_dofs_at_node(e.type(), o, n);
254 : }
255 :
256 :
257 :
258 4187692 : unsigned int raviart_thomas_n_dofs_per_elem(const ElemType t,
259 : const Order o)
260 : {
261 287530 : libmesh_assert_greater (o, 0);
262 4187692 : switch (t)
263 : {
264 51620 : case TRI6:
265 : case TRI7:
266 673540 : return o*(o-1);
267 28954 : case QUAD8:
268 : case QUAD9:
269 386674 : return 2*o*(o-1);
270 125056 : case TET14:
271 2030295 : return (o+1)*o*(o-1)/2;
272 1222239 : case HEX27:
273 1304139 : 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 3900162 : unsigned int raviart_thomas_n_dofs_per_elem(const Elem & e,
284 : const Order o)
285 : {
286 4187692 : 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 93150 : 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 93150 : { raviart_thomas_nodal_soln(elem, order, elem_soln, 2 /*dim*/, vdim, nodal_soln, add_p_level); }
341 :
342 : template <>
343 282447 : 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 282447 : { 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 12188508 : 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 611218 : template <> unsigned int FE<2,RAVIART_THOMAS>::n_dofs(const Elem * e, const Order o) { return raviart_thomas_n_dofs(e, o); }
402 1885740 : 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 6424862 : 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 50187691 : 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 1845821 : 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 12247308 : 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 1060214 : 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 3127478 : 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 697344 : template <> bool FE<2,RAVIART_THOMAS>::shapes_need_reinit() const { return true; }
481 2176628 : 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
|