19#include "libmesh/libmesh_config.h"
21#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
24#include "libmesh/fe.h"
25#include "libmesh/elem.h"
26#include "libmesh/enum_to_string.h"
38 static const unsigned int hex20_i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
39 static const unsigned int hex20_i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
40 static const unsigned int hex20_i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
47 static const Real hex20_scal20[] = {-0.25, -0.25, -0.25, -0.25, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0};
48 static const Real hex20_scal21[] = {-0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0, 0};
49 static const Real hex20_scal22[] = {0, -0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0};
50 static const Real hex20_scal23[] = {0, 0, -0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0};
51 static const Real hex20_scal24[] = {-0.25, 0, 0, -0.25, -0.25, 0, 0, -0.25, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0, 0, 0.5};
52 static const Real hex20_scal25[] = {0, 0, 0, 0, -0.25, -0.25, -0.25, -0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5};
53 static const Real hex20_scal26[] = {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25};
56 unsigned int a,
unsigned int b,
57 unsigned int c,
unsigned int d)
59 return std::min(std::min(elem->
point(a),elem->
point(
b)),
78 const bool add_p_level)
86 const Order totalorder =
87 order + add_p_level*elem->
p_level();
89 auto hex_remap = [i, elem] (
const Point & p_in,
90 const unsigned int * hex_i0,
91 const unsigned int * hex_i1,
92 const unsigned int * hex_i2) {
94 const Real xi = p_in(0);
95 const Real eta = p_in(1);
96 const Real zeta = p_in(2);
97 Point p_to_remap = p_in;
98 Real & xi_mapped = p_to_remap(0);
99 Real & eta_mapped = p_to_remap(1);
100 Real & zeta_mapped = p_to_remap(2);
105 if ((hex_i0[i] >= 2) && (hex_i1[i] == 0) && (hex_i2[i] == 0))
111 else if ((hex_i0[i] == 1) && (hex_i1[i] >= 2) && (hex_i2[i] == 0))
117 else if ((hex_i0[i] >= 2) && (hex_i1[i] == 1) && (hex_i2[i] == 0))
123 else if ((hex_i0[i] == 0) && (hex_i1[i] >= 2) && (hex_i2[i] == 0))
129 else if ((hex_i0[i] == 0) && (hex_i1[i] == 0) && (hex_i2[i] >=2 ))
135 else if ((hex_i0[i] == 1) && (hex_i1[i] == 0) && (hex_i2[i] >=2 ))
141 else if ((hex_i0[i] == 1) && (hex_i1[i] == 1) && (hex_i2[i] >=2 ))
147 else if ((hex_i0[i] == 0) && (hex_i1[i] == 1) && (hex_i2[i] >=2 ))
153 else if ((hex_i0[i] >=2 ) && (hex_i1[i] == 0) && (hex_i2[i] == 1))
159 else if ((hex_i0[i] == 1) && (hex_i1[i] >=2 ) && (hex_i2[i] == 1))
165 else if ((hex_i0[i] >=2 ) && (hex_i1[i] == 1) && (hex_i2[i] == 1))
171 else if ((hex_i0[i] == 0) && (hex_i1[i] >=2 ) && (hex_i2[i] == 1))
182 if ((hex_i2[i] == 0) && (hex_i0[i] >= 2) && (hex_i1[i] >= 2))
184 const Point min_point = get_min_point(elem, 1, 2, 0, 3);
186 if (elem->
point(0) == min_point)
200 else if (elem->
point(3) == min_point)
214 else if (elem->
point(2) == min_point)
228 else if (elem->
point(1) == min_point)
247 else if ((hex_i1[i] == 0) && (hex_i0[i] >= 2) && (hex_i2[i] >= 2))
249 const Point min_point = get_min_point(elem, 0, 1, 5, 4);
251 if (elem->
point(0) == min_point)
265 else if (elem->
point(1) == min_point)
279 else if (elem->
point(5) == min_point)
293 else if (elem->
point(4) == min_point)
312 else if ((hex_i0[i] == 1) && (hex_i1[i] >= 2) && (hex_i2[i] >= 2))
314 const Point min_point = get_min_point(elem, 1, 2, 6, 5);
316 if (elem->
point(1) == min_point)
330 else if (elem->
point(2) == min_point)
344 else if (elem->
point(6) == min_point)
358 else if (elem->
point(5) == min_point)
377 else if ((hex_i1[i] == 1) && (hex_i0[i] >= 2) && (hex_i2[i] >= 2))
379 const Point min_point = get_min_point(elem, 2, 3, 7, 6);
381 if (elem->
point(3) == min_point)
395 else if (elem->
point(7) == min_point)
409 else if (elem->
point(6) == min_point)
423 else if (elem->
point(2) == min_point)
442 else if ((hex_i0[i] == 0) && (hex_i1[i] >= 2) && (hex_i2[i] >= 2))
444 const Point min_point = get_min_point(elem, 3, 0, 4, 7);
446 if (elem->
point(0) == min_point)
460 else if (elem->
point(4) == min_point)
474 else if (elem->
point(7) == min_point)
488 else if (elem->
point(3) == min_point)
507 else if ((hex_i2[i] == 1) && (hex_i0[i] >= 2) && (hex_i1[i] >= 2))
509 const Point min_point = get_min_point(elem, 4, 5, 6, 7);
511 if (elem->
point(4) == min_point)
525 else if (elem->
point(5) == min_point)
539 else if (elem->
point(6) == min_point)
553 else if (elem->
point(7) == min_point)
587 libmesh_assert_less (i, 4);
590 const Real zeta1 = p(0);
591 const Real zeta2 = p(1);
592 const Real zeta3 = p(2);
593 const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
597 case 0:
return zeta0;
598 case 1:
return zeta1;
599 case 2:
return zeta2;
600 case 3:
return zeta3;
603 libmesh_error_msg(
"Invalid shape function index i = " << i);
612 libmesh_assert_less (i, 8);
615 const Real xi = p(0);
616 const Real eta = p(1);
617 const Real zeta = p(2);
623 static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
624 static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
625 static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
650 libmesh_assert_less (i, 10);
653 const Real zeta1 = p(0);
654 const Real zeta2 = p(1);
655 const Real zeta3 = p(2);
656 const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
660 case 0:
return zeta0*zeta0;
661 case 1:
return zeta1*zeta1;
662 case 2:
return zeta2*zeta2;
663 case 3:
return zeta3*zeta3;
664 case 4:
return 2.*zeta0*zeta1;
665 case 5:
return 2.*zeta1*zeta2;
666 case 6:
return 2.*zeta0*zeta2;
667 case 7:
return 2.*zeta3*zeta0;
668 case 8:
return 2.*zeta1*zeta3;
669 case 9:
return 2.*zeta2*zeta3;
672 libmesh_error_msg(
"Invalid shape function index i = " << i);
679 libmesh_assert_less (i, 20);
682 const Real xi = p(0);
683 const Real eta = p(1);
684 const Real zeta = p(2);
722 libmesh_assert_less (i, 27);
725 const Real xi = p(0);
726 const Real eta = p(1);
727 const Real zeta = p(2);
733 static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
734 static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
735 static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
825 libmesh_assert_less (i, 64);
832 static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3};
833 static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3, 0, 0, 0, 0, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3};
834 static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
836 const Point p_mapped = hex_remap(p, i0, i1, i2);
858 libmesh_assert_less (i, 125);
865 static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4};
866 static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
867 static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4};
869 const Point p_mapped = hex_remap(p, i0, i1, i2);
883 libmesh_error_msg(
"Invalid totalorder = " << totalorder);
887 libmesh_not_implemented();
899 libmesh_error_msg(
"Bernstein polynomials require the element type \nbecause edge and face orientation is needed.");
907 const unsigned int i,
909 const bool add_p_level)
917 const unsigned int i,
918 const unsigned int j,
920 const bool add_p_level)
927 const Order totalorder =
928 order + add_p_level*elem->
p_level();
930 libmesh_assert_less (j, 3);
953 libmesh_assert_less (i, 8);
956 const Real xi = p(0);
957 const Real eta = p(1);
958 const Real zeta = p(2);
964 static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
965 static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
966 static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
989 libmesh_error_msg(
"Invalid derivative index j = " << j);
1015 libmesh_assert_less (i, 20);
1018 const Real xi = p(0);
1019 const Real eta = p(1);
1020 const Real zeta = p(2);
1127 libmesh_error_msg(
"Invalid derivative index j = " << j);
1134 libmesh_assert_less (i, 27);
1137 const Real xi = p(0);
1138 const Real eta = p(1);
1139 const Real zeta = p(2);
1145 static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
1146 static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
1147 static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
1170 libmesh_error_msg(
"Invalid derivative index j = " << j);
2304 libmesh_error_msg(
"Invalid totalorder = " << totalorder);
2309 libmesh_not_implemented();
2321 libmesh_error_msg(
"Bernstein polynomials require the element type \nbecause edge and face orientation is needed.");
2328 const unsigned int i,
2329 const unsigned int j,
2331 const bool add_p_level)
2339#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
2344 const unsigned int i,
2345 const unsigned int j,
2347 const bool add_p_level)
2361 libmesh_error_msg(
"Bernstein polynomials require the element type \nbecause edge and face orientation is needed.");
2369 const unsigned int i,
2370 const unsigned int j,
2372 const bool add_p_level)
This is the base class from which all geometric element types are derived.
const Point & point(const unsigned int i) const
bool positive_edge_orientation(const unsigned int i) const
bool positive_face_orientation(const unsigned int i) const
virtual ElemType type() const =0
unsigned int p_level() const
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
OrderWrapper order
The approximation order of the element (at 0 p-refinement level).
A specific instantiation of the FEBase class.
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.
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
LIBMESH_DEFAULT_VECTORIZED_FE(template<>Real FE< 0, BERNSTEIN)
OutputShape fe_fdm_deriv(const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p, const bool add_p_level, OutputShape(*shape_func)(const Elem *, const Order, const unsigned int, const Point &, const bool))
Helper functions for finite differenced derivatives in cases where analytical calculations haven't be...
ElemType
Defines an enum for geometric element types.
void libmesh_ignore(const Args &...)
OutputShape fe_fdm_second_deriv(const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p, const bool add_p_level, OutputShape(*deriv_func)(const Elem *, const Order, const unsigned int, const unsigned int, const Point &, const bool))
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real