22 #include "libmesh/fe.h" 
   23 #include "libmesh/elem.h" 
   24 #include "libmesh/fe_interface.h" 
   25 #include "libmesh/number_lookups.h" 
   32 void hermite_compute_coefs(
const Elem * elem, std::vector<std::vector<Real>> & dxdxi
 
   35                            , std::vector<Real> & dydxi, std::vector<Real> & dzdeta, std::vector<Real> & dxdzeta,
 
   36                            std::vector<Real> & dzdxi, std::vector<Real> & dxdeta, std::vector<Real> & dydzeta
 
   44   const FEType map_fe_type(mapping_order, mapping_family);
 
   46   const int n_mapping_shape_functions =
 
   55   for (
int p = 0; p != 2; ++p)
 
   68       for (
int i = 0; i != n_mapping_shape_functions; ++i)
 
   70           const Real ddxi = shape_deriv_ptr
 
   71             (elem, mapping_order, i, 0, dofpt[p], 
false);
 
   72           const Real ddeta = shape_deriv_ptr
 
   73             (elem, mapping_order, i, 1, dofpt[p], 
false);
 
   74           const Real ddzeta = shape_deriv_ptr
 
   75             (elem, mapping_order, i, 2, dofpt[p], 
false);
 
   80           dxdxi[0][p] += point_i(0) * ddxi;
 
   81           dxdxi[1][p] += point_i(1) * ddeta;
 
   82           dxdxi[2][p] += point_i(2) * ddzeta;
 
   84           dydxi[p] += point_i(1) * ddxi;
 
   85           dzdeta[p] += point_i(2) * ddeta;
 
   86           dxdzeta[p] += point_i(0) * ddzeta;
 
   87           dzdxi[p] += point_i(2) * ddxi;
 
   88           dxdeta[p] += point_i(0) * ddeta;
 
   89           dydzeta[p] += point_i(1) * ddzeta;
 
  111 Real hermite_bases_3D (std::vector<unsigned int> & bases1D,
 
  112                        const std::vector<std::vector<Real>> & dxdxi,
 
  120   unsigned int e = o-2;
 
  156           libmesh_error_msg(
"Invalid basis node = " << i/8);
 
  159       unsigned int basisnum = i%8;
 
  166           coef = dxdxi[0][bases1D[0]];
 
  167           bases1D[0] += 2; 
break;
 
  169           coef = dxdxi[1][bases1D[1]];
 
  170           bases1D[1] += 2; 
break;
 
  172           coef = dxdxi[0][bases1D[0]] * dxdxi[1][bases1D[1]];
 
  173           bases1D[0] += 2; bases1D[1] += 2; 
break;
 
  175           coef = dxdxi[2][bases1D[2]];
 
  176           bases1D[2] += 2; 
break;
 
  178           coef = dxdxi[0][bases1D[0]] * dxdxi[2][bases1D[2]];
 
  179           bases1D[0] += 2; bases1D[2] += 2; 
break;
 
  181           coef = dxdxi[1][bases1D[1]] * dxdxi[2][bases1D[2]];
 
  182           bases1D[1] += 2; bases1D[2] += 2; 
break;
 
  184           coef = dxdxi[0][bases1D[0]] * dxdxi[1][bases1D[1]] * dxdxi[2][bases1D[2]];
 
  185           bases1D[0] += 2; bases1D[1] += 2; bases1D[2] += 2; 
break;
 
  187           libmesh_error_msg(
"Invalid basisnum = " << basisnum);
 
  191   else if (i < 64 + 12*4*e)
 
  193       unsigned int basisnum = (i - 64) % (4*e);
 
  194       switch ((i - 64) / (4*e))
 
  197           bases1D[0] = basisnum / 4 + 4;
 
  198           bases1D[1] = basisnum % 4 / 2 * 2;
 
  199           bases1D[2] = basisnum % 2 * 2;
 
  200           if (basisnum % 4 / 2)
 
  206           bases1D[0] = basisnum % 4 / 2 * 2 + 1;
 
  207           bases1D[1] = basisnum / 4 + 4;
 
  208           bases1D[2] = basisnum % 2 * 2;
 
  209           if (basisnum % 4 / 2)
 
  215           bases1D[0] = basisnum / 4 + 4;
 
  216           bases1D[1] = basisnum % 4 / 2 * 2 + 1;
 
  217           bases1D[2] = basisnum % 2 * 2;
 
  218           if (basisnum % 4 / 2)
 
  224           bases1D[0] = basisnum % 4 / 2 * 2;
 
  225           bases1D[1] = basisnum / 4 + 4;
 
  226           bases1D[2] = basisnum % 2 * 2;
 
  227           if (basisnum % 4 / 2)
 
  233           bases1D[0] = basisnum % 4 / 2 * 2;
 
  234           bases1D[1] = basisnum % 2 * 2;
 
  235           bases1D[2] = basisnum / 4 + 4;
 
  236           if (basisnum % 4 / 2)
 
  242           bases1D[0] = basisnum % 4 / 2 * 2 + 1;
 
  243           bases1D[1] = basisnum % 2 * 2;
 
  244           bases1D[2] = basisnum / 4 + 4;
 
  245           if (basisnum % 4 / 2)
 
  251           bases1D[0] = basisnum % 4 / 2 * 2 + 1;
 
  252           bases1D[1] = basisnum % 2 * 2 + 1;
 
  253           bases1D[2] = basisnum / 4 + 4;
 
  254           if (basisnum % 4 / 2)
 
  260           bases1D[0] = basisnum % 4 / 2 * 2;
 
  261           bases1D[1] = basisnum % 2 * 2 + 1;
 
  262           bases1D[2] = basisnum / 4 + 4;
 
  263           if (basisnum % 4 / 2)
 
  269           bases1D[0] = basisnum / 4 + 4;
 
  270           bases1D[1] = basisnum % 4 / 2 * 2;
 
  271           bases1D[2] = basisnum % 2 * 2 + 1;
 
  272           if (basisnum % 4 / 2)
 
  278           bases1D[0] = basisnum % 4 / 2 * 2 + 1;
 
  279           bases1D[1] = basisnum / 4 + 4;
 
  280           bases1D[2] = basisnum % 2 * 2;
 
  281           if (basisnum % 4 / 2)
 
  287           bases1D[0] = basisnum / 4 + 4;
 
  288           bases1D[1] = basisnum % 4 / 2 * 2 + 1;
 
  289           bases1D[2] = basisnum % 2 * 2 + 1;
 
  290           if (basisnum % 4 / 2)
 
  296           bases1D[0] = basisnum % 4 / 2 * 2;
 
  297           bases1D[1] = basisnum / 4 + 4;
 
  298           bases1D[2] = basisnum % 2 * 2 + 1;
 
  299           if (basisnum % 4 / 2)
 
  305           libmesh_error_msg(
"Invalid basis node = " << (i - 64) / (4*e));
 
  309   else if (i < 64 + 12*4*e + 6*2*e*e)
 
  311       unsigned int basisnum = (i - 64 - 12*4*e) % (2*e*e);
 
  312       switch ((i - 64 - 12*4*e) / (2*e*e))
 
  317           bases1D[2] = basisnum % 2 * 2;
 
  323           bases1D[1] = basisnum % 2 * 2;
 
  329           bases1D[0] = basisnum % 2 * 2 + 1;
 
  337           bases1D[1] = basisnum % 2 * 2 + 1;
 
  343           bases1D[0] = basisnum % 2 * 2;
 
  352           bases1D[2] = basisnum % 2 * 2 + 1;
 
  357           libmesh_error_msg(
"Invalid basis node = " << (i - 64 - 12*4*e) / (2*e*e));
 
  363       unsigned int basisnum = i - 64 - 12*4*e;
 
  388   libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
 
  397                           const unsigned int i,
 
  399                           const bool add_p_level)
 
  403   std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
 
  406   std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
 
  407   std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
 
  410   hermite_compute_coefs(elem, dxdxi
 
  412                         , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
 
  418   const Order totalorder =
 
  419     static_cast<Order>(order + add_p_level * elem->
p_level());
 
  432               libmesh_assert_less (i, 64);
 
  434               std::vector<unsigned int> bases1D;
 
  436               Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
 
  444             libmesh_error_msg(
"ERROR: Unsupported element type " << type);
 
  449       libmesh_error_msg(
"ERROR: Unsupported polynomial order " << totalorder);
 
  462   libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
 
  471                                 const unsigned int i,
 
  472                                 const unsigned int j,
 
  474                                 const bool add_p_level)
 
  479   std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
 
  482   std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
 
  483   std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
 
  486   hermite_compute_coefs(elem, dxdxi
 
  488                         , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
 
  494   const Order totalorder =
 
  495     static_cast<Order>(order + add_p_level * elem->
p_level());
 
  508               libmesh_assert_less (i, 64);
 
  510               std::vector<unsigned int> bases1D;
 
  512               Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
 
  535                   libmesh_error_msg(
"Invalid shape function derivative j = " << j);
 
  540             libmesh_error_msg(
"ERROR: Unsupported element type " << type);
 
  545       libmesh_error_msg(
"ERROR: Unsupported polynomial order " << totalorder);
 
  550 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  559   libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
 
  567                                        const unsigned int i,
 
  568                                        const unsigned int j,
 
  570                                        const bool add_p_level)
 
  574   std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
 
  577   std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
 
  578   std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
 
  581   hermite_compute_coefs(elem, dxdxi
 
  583                         , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
 
  589   const Order totalorder =
 
  590     static_cast<Order>(order + add_p_level * elem->
p_level());
 
  603               libmesh_assert_less (i, 64);
 
  605               std::vector<unsigned int> bases1D;
 
  607               Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
 
  648                   libmesh_error_msg(
"Invalid shape function derivative j = " << j);
 
  653             libmesh_error_msg(
"ERROR: Unsupported element type " << type);
 
  658       libmesh_error_msg(
"ERROR: Unsupported polynomial order " << totalorder);
 
  662 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES