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