20 #include "libmesh/fe.h" 
   21 #include "libmesh/elem.h" 
   22 #include "libmesh/number_lookups.h" 
   32 Real fe_hierarchic_2D_shape(
const Elem * elem,
 
   36                             const bool add_p_level);
 
   38 Real fe_hierarchic_2D_shape_deriv(
const Elem * elem,
 
   43                                   const bool add_p_level);
 
   45 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
   47 Real fe_hierarchic_2D_shape_second_deriv(
const Elem * elem,
 
   52                                          const bool add_p_level);
 
   54 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 
   69   libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge orientation.");
 
   81   libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge orientation.");
 
   92                              const bool add_p_level)
 
   94   return fe_hierarchic_2D_shape(elem, order, i, p, add_p_level);
 
  102                                 const unsigned int i,
 
  104                                 const bool add_p_level)
 
  106   return fe_hierarchic_2D_shape(elem, order, i, p, add_p_level);
 
  118   libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge orientation.");
 
  131   libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge orientation.");
 
  140                                    const unsigned int i,
 
  141                                    const unsigned int j,
 
  143                                    const bool add_p_level)
 
  145   return fe_hierarchic_2D_shape_deriv(elem, order, i, j, p, add_p_level);
 
  153                                       const unsigned int i,
 
  154                                       const unsigned int j,
 
  156                                       const bool add_p_level)
 
  158   return fe_hierarchic_2D_shape_deriv(elem, order, i, j, p, add_p_level);
 
  163 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  172   libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge orientation.");
 
  185   libmesh_error_msg(
"Hierarchic shape functions require an Elem for edge orientation.");
 
  194                                           const unsigned int i,
 
  195                                           const unsigned int j,
 
  197                                           const bool add_p_level)
 
  199   return fe_hierarchic_2D_shape_second_deriv(elem, order, i, j, p, add_p_level);
 
  207                                              const unsigned int i,
 
  208                                              const unsigned int j,
 
  210                                              const bool add_p_level)
 
  212   return fe_hierarchic_2D_shape_second_deriv(elem, order, i, j, p, add_p_level);
 
  215 #endif //  LIBMESH_ENABLE_SECOND_DERIVATIVES 
  225 Real fe_hierarchic_2D_shape(
const Elem * elem,
 
  227                             const unsigned int i,
 
  229                             const bool add_p_level)
 
  233   const Order totalorder =
 
  234     static_cast<Order>(order+add_p_level*elem->
p_level());
 
  235   libmesh_assert_greater (totalorder, 0);
 
  237   switch (elem->
type())
 
  243         const Real zeta1 = p(0);
 
  244         const Real zeta2 = p(1);
 
  245         const Real zeta0 = 1. - zeta1 - zeta2;
 
  247         libmesh_assert_less (i, (totalorder+1u)*(totalorder+2u)/2);
 
  258         else if (i < totalorder + 2u)
 
  261             if (zeta0 + zeta1 == 0.)
 
  264             const unsigned int basisorder = i - 1;
 
  267             if (basisorder%2 && (elem->
point(0) > elem->
point(1)))
 
  270             Real edgeval = (zeta1 - zeta0) / (zeta1 + zeta0);
 
  271             Real crossfunc = zeta0 + zeta1;
 
  272             for (
unsigned int n=1; n != basisorder; ++n)
 
  273               crossfunc *= (zeta0 + zeta1);
 
  275             return f0 * crossfunc *
 
  277                                       basisorder, edgeval);
 
  279         else if (i < 2u*totalorder + 1)
 
  282             if (zeta1 + zeta2 == 0.)
 
  285             const unsigned int basisorder = i - totalorder;
 
  288             if (basisorder%2 && (elem->
point(1) > elem->
point(2)))
 
  291             Real edgeval = (zeta2 - zeta1) / (zeta2 + zeta1);
 
  292             Real crossfunc = zeta2 + zeta1;
 
  293             for (
unsigned int n=1; n != basisorder; ++n)
 
  294               crossfunc *= (zeta2 + zeta1);
 
  296             return f1 * crossfunc *
 
  298                                       basisorder, edgeval);
 
  300         else if (i < 3u*totalorder)
 
  303             if (zeta0 + zeta2 == 0.)
 
  306             const unsigned int basisorder = i - (2u*totalorder) + 1;
 
  309             if (basisorder%2 && (elem->
point(2) > elem->
point(0)))
 
  312             Real edgeval = (zeta0 - zeta2) / (zeta0 + zeta2);
 
  313             Real crossfunc = zeta0 + zeta2;
 
  314             for (
unsigned int n=1; n != basisorder; ++n)
 
  315               crossfunc *= (zeta0 + zeta2);
 
  317             return f2 * crossfunc *
 
  319                                       basisorder, edgeval);
 
  324             const unsigned int basisnum = i - (3u*totalorder);
 
  330             for (
unsigned int n = 0; n != exp0; ++n)
 
  332             for (
unsigned int n = 0; n != exp1; ++n)
 
  342       libmesh_assert_less (totalorder, 2);
 
  343       libmesh_fallthrough();
 
  349         const Real xi  = p(0);
 
  350         const Real eta = p(1);
 
  352         libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u));
 
  371         else if (i < totalorder + 3u)
 
  372           { i0 = i - 2; i1 = 0; }
 
  373         else if (i < 2u*totalorder + 2)
 
  374           { i0 = 1; i1 = i - totalorder - 1; }
 
  375         else if (i < 3u*totalorder + 1)
 
  376           { i0 = i - 2u*totalorder; i1 = 1; }
 
  377         else if (i < 4u*totalorder)
 
  378           { i0 = 0; i1 = i - 3u*totalorder + 1; }
 
  382             unsigned int basisnum = i - 4*totalorder;
 
  391         if ((i0%2) && (i0 > 2) && (i1 == 0))
 
  393         else if ((i0%2) && (i0>2) && (i1 == 1))
 
  395         else if ((i0 == 0) && (i1%2) && (i1>2))
 
  397         else if ((i0 == 1) && (i1%2) && (i1>2))
 
  405       libmesh_error_msg(
"ERROR: Unsupported element type = " << elem->
type());
 
  413 Real fe_hierarchic_2D_shape_deriv(
const Elem * elem,
 
  415                                   const unsigned int i,
 
  416                                   const unsigned int j,
 
  418                                   const bool add_p_level)
 
  424   const Order totalorder =
 
  425     static_cast<Order>(order+add_p_level*elem->
p_level());
 
  427   libmesh_assert_greater (totalorder, 0);
 
  436         const Real eps = 1.e-6;
 
  438         libmesh_assert_less (j, 2);
 
  445               const Point pp(p(0)+eps, p(1));
 
  446               const Point pm(p(0)-eps, p(1));
 
  455               const Point pp(p(0), p(1)+eps);
 
  456               const Point pm(p(0), p(1)-eps);
 
  463             libmesh_error_msg(
"Invalid derivative index j = " << j);
 
  469       libmesh_assert_less (totalorder, 2);
 
  470       libmesh_fallthrough();
 
  476         const Real xi  = p(0);
 
  477         const Real eta = p(1);
 
  479         libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u));
 
  498         else if (i < totalorder + 3u)
 
  499           { i0 = i - 2; i1 = 0; }
 
  500         else if (i < 2u*totalorder + 2)
 
  501           { i0 = 1; i1 = i - totalorder - 1; }
 
  502         else if (i < 3u*totalorder + 1u)
 
  503           { i0 = i - 2u*totalorder; i1 = 1; }
 
  504         else if (i < 4u*totalorder)
 
  505           { i0 = 0; i1 = i - 3u*totalorder + 1; }
 
  509             unsigned int basisnum = i - 4*totalorder;
 
  518         if ((i0%2) && (i0 > 2) && (i1 == 0))
 
  520         else if ((i0%2) && (i0>2) && (i1 == 1))
 
  522         else if ((i0 == 0) && (i1%2) && (i1>2))
 
  524         else if ((i0 == 1) && (i1%2) && (i1>2))
 
  540             libmesh_error_msg(
"Invalid derivative index j = " << j);
 
  545       libmesh_error_msg(
"ERROR: Unsupported element type = " << type);
 
  553 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  555 Real fe_hierarchic_2D_shape_second_deriv(
const Elem * elem,
 
  557                                          const unsigned int i,
 
  558                                          const unsigned int j,
 
  560                                          const bool add_p_level)
 
  566   const Real eps = 1.e-6;
 
  575         pp = 
Point(p(0)+eps, p(1));
 
  576         pm = 
Point(p(0)-eps, p(1));
 
  584         pp = 
Point(p(0), p(1)+eps);
 
  585         pm = 
Point(p(0), p(1)-eps);
 
  593         pp = 
Point(p(0), p(1)+eps);
 
  594         pm = 
Point(p(0), p(1)-eps);
 
  599       libmesh_error_msg(
"Invalid derivative index j = " << j);
 
  607 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES