20 #include "libmesh/fe.h"
21 #include "libmesh/elem.h"
22 #include "libmesh/number_lookups.h"
31 Real fe_hierarchic_3D_shape(
const Elem * elem,
35 const bool add_p_level);
37 Real fe_hierarchic_3D_shape_deriv(
const Elem * elem,
42 const bool add_p_level);
44 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
46 Real fe_hierarchic_3D_shape_second_deriv(
const Elem * elem,
51 const bool add_p_level);
53 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
62 return std::min(std::min(elem->
point(a),elem->
point(b)),
66 void cube_indices(
const Elem * elem,
67 const unsigned int totalorder,
87 const unsigned int e = totalorder - 1u;
89 libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u)*(totalorder+1u));
91 Real xi_saved = xi, eta_saved = eta, zeta_saved = zeta;
152 else if (i < 8 + 2*e)
161 else if (i < 8 + 3*e)
170 else if (i < 8 + 4*e)
179 else if (i < 8 + 5*e)
188 else if (i < 8 + 6*e)
197 else if (i < 8 + 7*e)
206 else if (i < 8 + 8*e)
215 else if (i < 8 + 9*e)
224 else if (i < 8 + 10*e)
233 else if (i < 8 + 11*e)
242 else if (i < 8 + 12*e)
251 else if (i < 8 + 12*e + e*e)
253 unsigned int basisnum = i - 8 - 12*e;
257 const Point min_point = get_min_point(elem, 1, 2, 0, 3);
259 if (elem->
point(0) == min_point)
273 else if (elem->
point(3) == min_point)
287 else if (elem->
point(2) == min_point)
301 else if (elem->
point(1) == min_point)
318 else if (i < 8 + 12*e + 2*e*e)
320 unsigned int basisnum = i - 8 - 12*e - e*e;
324 const Point min_point = get_min_point(elem, 0, 1, 5, 4);
326 if (elem->
point(0) == min_point)
340 else if (elem->
point(1) == min_point)
354 else if (elem->
point(5) == min_point)
368 else if (elem->
point(4) == min_point)
385 else if (i < 8 + 12*e + 3*e*e)
387 unsigned int basisnum = i - 8 - 12*e - 2*e*e;
391 const Point min_point = get_min_point(elem, 1, 2, 6, 5);
393 if (elem->
point(1) == min_point)
407 else if (elem->
point(2) == min_point)
421 else if (elem->
point(6) == min_point)
435 else if (elem->
point(5) == min_point)
452 else if (i < 8 + 12*e + 4*e*e)
454 unsigned int basisnum = i - 8 - 12*e - 3*e*e;
458 const Point min_point = get_min_point(elem, 2, 3, 7, 6);
460 if (elem->
point(3) == min_point)
474 else if (elem->
point(7) == min_point)
488 else if (elem->
point(6) == min_point)
502 else if (elem->
point(2) == min_point)
519 else if (i < 8 + 12*e + 5*e*e)
521 unsigned int basisnum = i - 8 - 12*e - 4*e*e;
525 const Point min_point = get_min_point(elem, 3, 0, 4, 7);
527 if (elem->
point(0) == min_point)
541 else if (elem->
point(4) == min_point)
555 else if (elem->
point(7) == min_point)
569 else if (elem->
point(3) == min_point)
586 else if (i < 8 + 12*e + 6*e*e)
588 unsigned int basisnum = i - 8 - 12*e - 5*e*e;
592 const Point min_point = get_min_point(elem, 4, 5, 6, 7);
594 if (elem->
point(4) == min_point)
608 else if (elem->
point(5) == min_point)
622 else if (elem->
point(6) == min_point)
636 else if (elem->
point(7) == min_point)
656 unsigned int basisnum = i - 8 - 12*e - 6*e*e;
662 #endif // LIBMESH_DIM > 2
677 libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge/face orientation.");
689 libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge/face orientation.");
698 const unsigned int i,
700 const bool add_p_level)
702 return fe_hierarchic_3D_shape(elem, order, i, p, add_p_level);
710 const unsigned int i,
712 const bool add_p_level)
714 return fe_hierarchic_3D_shape(elem, order, i, p, add_p_level);
726 libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge/face orientation.");
739 libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge/face orientation.");
748 const unsigned int i,
749 const unsigned int j,
751 const bool add_p_level)
753 return fe_hierarchic_3D_shape_deriv(elem, order, i, j, p, add_p_level);
760 const unsigned int i,
761 const unsigned int j,
763 const bool add_p_level)
765 return fe_hierarchic_3D_shape_deriv(elem, order, i, j, p, add_p_level);
770 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
779 libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge/face orientation.");
792 libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge/face orientation.");
801 const unsigned int i,
802 const unsigned int j,
804 const bool add_p_level)
806 return fe_hierarchic_3D_shape_second_deriv(elem, order, i, j, p, add_p_level);
814 const unsigned int i,
815 const unsigned int j,
817 const bool add_p_level)
819 return fe_hierarchic_3D_shape_second_deriv(elem, order, i, j, p, add_p_level);
822 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
832 Real fe_hierarchic_3D_shape(
const Elem * elem,
834 const unsigned int i,
836 const bool add_p_level)
843 const Order totalorder =
844 static_cast<Order>(order+add_p_level*elem->
p_level());
850 libmesh_assert_less (totalorder, 2);
851 libmesh_fallthrough();
854 libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u)*(totalorder+1u));
861 unsigned int i0, i1, i2;
863 cube_indices(elem, totalorder, i, xi, eta, zeta, i0, i1, i2);
871 libmesh_error_msg(
"Invalid element type = " << type);
874 #else // LIBMESH_DIM != 3
876 libmesh_not_implemented();
882 Real fe_hierarchic_3D_shape_deriv(
const Elem * elem,
884 const unsigned int i,
885 const unsigned int j,
887 const bool add_p_level)
892 libmesh_assert_less (j, 3);
895 const Real eps = 1.e-6;
903 pp =
Point(p(0)+eps, p(1), p(2));
904 pm =
Point(p(0)-eps, p(1), p(2));
911 pp =
Point(p(0), p(1)+eps, p(2));
912 pm =
Point(p(0), p(1)-eps, p(2));
919 pp =
Point(p(0), p(1), p(2)+eps);
920 pm =
Point(p(0), p(1), p(2)-eps);
925 libmesh_error_msg(
"Invalid derivative index j = " << j);
930 #else // LIBMESH_DIM != 3
932 libmesh_not_implemented();
938 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
940 Real fe_hierarchic_3D_shape_second_deriv(
const Elem * elem,
942 const unsigned int i,
943 const unsigned int j,
945 const bool add_p_level)
949 const Real eps = 1.e-6;
958 pp =
Point(p(0)+eps, p(1), p(2));
959 pm =
Point(p(0)-eps, p(1), p(2));
967 pp =
Point(p(0), p(1)+eps, p(2));
968 pm =
Point(p(0), p(1)-eps, p(2));
976 pp =
Point(p(0), p(1)+eps, p(2));
977 pm =
Point(p(0), p(1)-eps, p(2));
985 pp =
Point(p(0), p(1), p(2)+eps);
986 pm =
Point(p(0), p(1), p(2)-eps);
994 pp =
Point(p(0), p(1), p(2)+eps);
995 pm =
Point(p(0), p(1), p(2)-eps);
1003 pp =
Point(p(0), p(1), p(2)+eps);
1004 pm =
Point(p(0), p(1), p(2)-eps);
1009 libmesh_error_msg(
"Invalid derivative index j = " << j);
1017 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES