libMesh
Loading...
Searching...
No Matches
fe_raviart_shape_3D.C
Go to the documentation of this file.
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// Local includes
20#include "libmesh/fe.h"
21#include "libmesh/elem.h"
22#include "libmesh/enum_to_string.h"
23
24namespace libMesh
25{
26
27template <>
29 const Order order,
30 const unsigned int i,
31 const Point & p,
32 const bool add_p_level)
33{
34#if LIBMESH_DIM == 3
35 libmesh_assert(elem);
36
37 const Order totalorder = order + add_p_level*elem->p_level();
38 libmesh_assert_less(i, n_dofs(elem->type(), totalorder));
39
40 const char sign = elem->positive_face_orientation(i) ? 1 : -1;
41
42 const Real xi = p(0);
43 const Real eta = p(1);
44 const Real zeta = p(2);
45
46 switch (totalorder)
47 {
48 // linear Raviart-Thomas shape functions
49 case FIRST:
50 {
51 switch (elem->type())
52 {
53 case HEX27:
54 {
55 // Even with a loose inverse_map tolerance we ought to
56 // be nearly on the element interior in master
57 // coordinates
58 libmesh_assert_less_equal ( std::fabs(xi), 1.0+10*TOLERANCE );
59 libmesh_assert_less_equal ( std::fabs(eta), 1.0+10*TOLERANCE );
60 libmesh_assert_less_equal ( std::fabs(zeta), 1.0+10*TOLERANCE );
61
62 switch(i)
63 {
64 case 0:
65 return sign * RealGradient( 0.0, 0.0, 0.125*(zeta-1.0) );
66 case 1:
67 return sign * RealGradient( 0.0, 0.125*(eta-1.0), 0.0 );
68 case 2:
69 return sign * RealGradient( 0.125*(xi+1.0), 0.0, 0.0 );
70 case 3:
71 return sign * RealGradient( 0.0, 0.125*(1.0+eta), 0.0 );
72 case 4:
73 return sign * RealGradient( 0.125*(xi-1.0), 0.0, 0.0 );
74 case 5:
75 return sign * RealGradient( 0.0, 0.0, 0.125*(1.0+zeta) );
76
77 default:
78 libmesh_error_msg("Invalid i = " << i);
79 }
80 }
81
82 case TET14:
83 {
84 switch(i)
85 {
86 case 0:
87 return sign * RealGradient( 2.0*xi, 2.0*eta, 2.0*zeta-2.0 );
88 case 1:
89 return sign * RealGradient( 2.0*xi, 2.0*eta-2.0, 2.0*zeta );
90 case 2:
91 return sign * RealGradient( 2.0*xi, 2.0*eta, 2.0*zeta );
92 case 3:
93 return sign * RealGradient( 2.0*xi-2.0, 2.0*eta, 2.0*zeta );
94
95 default:
96 libmesh_error_msg("Invalid i = " << i);
97 }
98 }
99
100 default:
101 libmesh_error_msg("ERROR: Unsupported 3D element type!: " << Utility::enum_to_string(elem->type()));
102 }
103 }
104
105 // unsupported order
106 default:
107 libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
108 }
109
110#else // LIBMESH_DIM != 3
111 libmesh_ignore(elem, order, i, p, add_p_level);
112 libmesh_not_implemented();
113#endif
114}
115
116
117template <>
119 const Order order,
120 const unsigned int i,
121 const Point & p,
122 const bool add_p_level)
123{
124 return FE<3,RAVIART_THOMAS>::shape(elem, order, i, p, add_p_level);
125}
126
127
128template <>
130 const Order,
131 const unsigned int,
132 const Point &)
133{
134 libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
135 return RealGradient();
136}
137
138
139template <>
141 const Order,
142 const unsigned int,
143 const Point &)
144{
145 libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
146 return RealGradient();
147}
148
149
150template <>
152 const Elem * elem,
153 const unsigned int i,
154 const Point & p,
155 const bool add_p_level)
156{
157 return FE<3,RAVIART_THOMAS>::shape(elem, fet.order, i, p, add_p_level);
158}
159
160
161template <>
163 const Elem * elem,
164 const unsigned int i,
165 const Point & p,
166 const bool add_p_level)
167{
168 return FE<3,L2_RAVIART_THOMAS>::shape(elem, fet.order, i, p, add_p_level);
169}
170
171
172template <>
174 const Order order,
175 const unsigned int i,
176 const unsigned int j,
177 const Point &,
178 const bool add_p_level)
179{
180#if LIBMESH_DIM == 3
181 libmesh_assert(elem);
182 libmesh_assert_less (j, 3);
183
184 const Order totalorder = order + add_p_level*elem->p_level();
185 libmesh_assert_less(i, n_dofs(elem->type(), totalorder));
186
187 const char sign = elem->positive_face_orientation(i) ? 1 : -1;
188
189 switch (totalorder)
190 {
191 // linear Raviart-Thomas shape function first derivatives
192 case FIRST:
193 {
194 switch (elem->type())
195 {
196 case HEX27:
197 {
198 switch (j)
199 {
200 // d()/dxi
201 case 0:
202 {
203 switch(i)
204 {
205 case 0:
206 case 1:
207 case 3:
208 case 5:
209 return RealGradient();
210 case 2:
211 case 4:
212 return sign * RealGradient( 0.125, 0.0, 0.0 );
213
214 default:
215 libmesh_error_msg("Invalid i = " << i);
216 } // switch(i)
217
218 } // j = 0
219
220 // d()/deta
221 case 1:
222 {
223 switch(i)
224 {
225 case 0:
226 case 2:
227 case 4:
228 case 5:
229 return RealGradient();
230 case 1:
231 case 3:
232 return sign * RealGradient( 0.0, 0.125, 0.0 );
233
234 default:
235 libmesh_error_msg("Invalid i = " << i);
236 } // switch(i)
237
238 } // j = 1
239
240 // d()/dzeta
241 case 2:
242 {
243 switch(i)
244 {
245 case 1:
246 case 2:
247 case 3:
248 case 4:
249 return RealGradient();
250 case 0:
251 case 5:
252 return sign * RealGradient( 0.0, 0.0, 0.125 );
253
254 default:
255 libmesh_error_msg("Invalid i = " << i);
256 } // switch(i)
257
258 } // j = 2
259
260 default:
261 libmesh_error_msg("Invalid j = " << j);
262 }
263 }
264
265 case TET14:
266 {
267 switch (j)
268 {
269 // d()/dxi
270 case 0:
271 {
272 switch(i)
273 {
274 case 0:
275 case 1:
276 case 2:
277 case 3:
278 return sign * RealGradient( 2.0, 0.0, 0.0 );
279
280 default:
281 libmesh_error_msg("Invalid i = " << i);
282 } // switch(i)
283
284 } // j = 0
285
286 // d()/deta
287 case 1:
288 {
289 switch(i)
290 {
291 case 0:
292 case 1:
293 case 2:
294 case 3:
295 return sign * RealGradient( 0.0, 2.0, 0.0 );
296
297 default:
298 libmesh_error_msg("Invalid i = " << i);
299 } // switch(i)
300
301 } // j = 1
302
303 // d()/dzeta
304 case 2:
305 {
306 switch(i)
307 {
308 case 0:
309 case 1:
310 case 2:
311 case 3:
312 return sign * RealGradient( 0.0, 0.0, 2.0 );
313
314 default:
315 libmesh_error_msg("Invalid i = " << i);
316 } // switch(i)
317
318 } // j = 2
319
320 default:
321 libmesh_error_msg("Invalid j = " << j);
322 }
323 }
324
325 default:
326 libmesh_error_msg("ERROR: Unsupported 3D element type!: " << Utility::enum_to_string(elem->type()));
327 }
328 }
329 // unsupported order
330 default:
331 libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
332 }
333
334#else // LIBMESH_DIM != 3
335 libmesh_ignore(elem, order, i, j, p, add_p_level);
336 libmesh_not_implemented();
337#endif
338}
339
340
341template <>
343 const Order order,
344 const unsigned int i,
345 const unsigned int j,
346 const Point & p,
347 const bool add_p_level)
348{
349 return FE<3,RAVIART_THOMAS>::shape_deriv(elem, order, i, j, p, add_p_level);
350}
351
352
353template <>
355 const Order,
356 const unsigned int,
357 const unsigned int,
358 const Point &)
359{
360 libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
361 return RealGradient();
362}
363
364
365template <>
367 const Order,
368 const unsigned int,
369 const unsigned int,
370 const Point &)
371{
372 libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
373 return RealGradient();
374}
375
376
377template <>
379 const Elem * elem,
380 const unsigned int i,
381 const unsigned int j,
382 const Point & p,
383 const bool add_p_level)
384{
385 return FE<3,RAVIART_THOMAS>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
386}
387
388
389template <>
391 const Elem * elem,
392 const unsigned int i,
393 const unsigned int j,
394 const Point & p,
395 const bool add_p_level)
396{
397 return FE<3,L2_RAVIART_THOMAS>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
398}
399
400
401#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
402
403template <>
405 const Order order,
406 const unsigned int libmesh_dbg_var(i),
407 const unsigned int libmesh_dbg_var(j),
408 const Point &,
409 const bool add_p_level)
410{
411#if LIBMESH_DIM == 3
412
413 libmesh_assert(elem);
414
415 // j = 0 ==> d^2 phi / dxi^2
416 // j = 1 ==> d^2 phi / dxi deta
417 // j = 2 ==> d^2 phi / deta^2
418 // j = 3 ==> d^2 phi / dxi dzeta
419 // j = 4 ==> d^2 phi / deta dzeta
420 // j = 5 ==> d^2 phi / dzeta^2
421 libmesh_assert_less (j, 6);
422
423 const Order totalorder = order + add_p_level*elem->p_level();
424 libmesh_assert_less(i, n_dofs(elem->type(), totalorder));
425
426 switch (totalorder)
427 {
428 // linear Raviart-Thomas shape function second derivatives
429 case FIRST:
430 {
431 switch (elem->type())
432 {
433 // All second derivatives for linear hexes and tets are zero.
434 case HEX27:
435 case TET14:
436 return RealGradient();
437
438 default:
439 libmesh_error_msg("ERROR: Unsupported 3D element type!: " << Utility::enum_to_string(elem->type()));
440
441 } //switch(type)
442 }
443
444 // unsupported order
445 default:
446 libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
447 }
448
449#else // LIBMESH_DIM != 3
450 libmesh_assert(true || p(0));
451 libmesh_ignore(elem, order, i, j, add_p_level);
452 libmesh_not_implemented();
453#endif
454}
455
456
457template <>
459 const Order order,
460 const unsigned int i,
461 const unsigned int j,
462 const Point & p,
463 const bool add_p_level)
464{
465 return FE<3,RAVIART_THOMAS>::shape_second_deriv(elem, order, i, j, p, add_p_level);
466}
467
468
469template <>
471 const Order,
472 const unsigned int,
473 const unsigned int,
474 const Point &)
475{
476 libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
477 return RealGradient();
478}
479
480
481template <>
483 const Order,
484 const unsigned int,
485 const unsigned int,
486 const Point &)
487{
488 libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
489 return RealGradient();
490}
491
492
493template <>
495 const Elem * elem,
496 const unsigned int i,
497 const unsigned int j,
498 const Point & p,
499 const bool add_p_level)
500{
501 return FE<3,RAVIART_THOMAS>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
502}
503
504
505template <>
507 const Elem * elem,
508 const unsigned int i,
509 const unsigned int j,
510 const Point & p,
511 const bool add_p_level)
512{
513 return FE<3,L2_RAVIART_THOMAS>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
514}
515
516#endif
517
518} // namespace libMesh
This is the base class from which all geometric element types are derived.
Definition elem.h:96
bool positive_face_orientation(const unsigned int i) const
Definition elem.C:3643
virtual ElemType type() const =0
unsigned int p_level() const
Definition elem.h:3125
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition fe_type.h:197
OrderWrapper order
The approximation order of the element (at 0 p-refinement level).
Definition fe_type.h:203
static OutputShape shape(const ElemType t, const Order o, const unsigned int i, const Point &p)
static OutputShape shape_second_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
static OutputShape shape_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
ElemType
Defines an enum for geometric element types.
void libmesh_ignore(const Args &...)
libmesh_assert(ctx)
static constexpr Real TOLERANCE
RealVectorValue RealGradient
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real