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);
885 #else // LIBMESH_DIM != 3 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);
2307 #else // LIBMESH_DIM != 3 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)
2386 #endif //LIBMESH_ENABLE_HIGHER_ORDER_SHAPES class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
ElemType
Defines an enum for geometric element types.
Order
defines an enum for polynomial orders.
static OutputShape shape(const ElemType t, const Order o, const unsigned int i, const Point &p)
This is the base class from which all geometric element types are derived.
static OutputShape shape_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
unsigned int p_level() const
OrderWrapper order
The approximation order of the element.
The libMesh namespace provides an interface to certain functionality in the library.
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...
LIBMESH_DEFAULT_VECTORIZED_FE(template<>Real FE< 0, BERNSTEIN)
A specific instantiation of the FEBase class.
void libmesh_ignore(const Args &...)
bool positive_edge_orientation(const unsigned int i) const
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))
std::string enum_to_string(const T e)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool positive_face_orientation(const unsigned int i) const
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
const Point & point(const unsigned int i) const
static OutputShape shape_second_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)