LCOV - code coverage report
Current view: top level - src/fe - fe_hermite_shape_3D.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 204 400 51.0 %
Date: 2025-08-19 19:27:09 Functions: 10 16 62.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : // Local includes
      20             : #include "libmesh/fe.h"
      21             : #include "libmesh/elem.h"
      22             : #include "libmesh/fe_interface.h"
      23             : #include "libmesh/number_lookups.h"
      24             : #include "libmesh/enum_to_string.h"
      25             : 
      26             : namespace
      27             : {
      28             : using namespace libMesh;
      29             : 
      30             : // Compute the static coefficients for an element
      31    39923712 : void hermite_compute_coefs(const Elem * elem, std::vector<std::vector<Real>> & dxdxi
      32             : 
      33             : #ifdef DEBUG
      34             :                            , std::vector<Real> & dydxi, std::vector<Real> & dzdeta, std::vector<Real> & dxdzeta,
      35             :                            std::vector<Real> & dzdxi, std::vector<Real> & dxdeta, std::vector<Real> & dydzeta
      36             : #endif
      37             :                            )
      38             : {
      39    39923712 :   const FEFamily mapping_family = FEMap::map_fe_type(*elem);
      40    39923712 :   const FEType map_fe_type(elem->default_order(), mapping_family);
      41             : 
      42             :   // Note: we explicitly don't consider the elem->p_level() when
      43             :   // computing the number of mapping shape functions.
      44             :   const int n_mapping_shape_functions =
      45    39923712 :     FEInterface::n_shape_functions (map_fe_type, /*extra_order=*/0, elem);
      46             : 
      47    39923712 :   static const Point dofpt[2] = {Point(-1,-1,-1), Point(1,1,1)};
      48             : 
      49             :   FEInterface::shape_deriv_ptr shape_deriv_ptr =
      50    39923712 :     FEInterface::shape_deriv_function(map_fe_type, elem);
      51             : 
      52   119771136 :   for (int p = 0; p != 2; ++p)
      53             :     {
      54    79847424 :       dxdxi[0][p] = 0;
      55    79847424 :       dxdxi[1][p] = 0;
      56    86501376 :       dxdxi[2][p] = 0;
      57             : #ifdef DEBUG
      58     6653952 :       dydxi[p] = 0;
      59     6653952 :       dzdeta[p] = 0;
      60     6653952 :       dxdzeta[p] = 0;
      61     6653952 :       dzdxi[p] = 0;
      62     6653952 :       dxdeta[p] = 0;
      63     6653952 :       dydzeta[p] = 0;
      64             : #endif
      65  2235727872 :       for (int i = 0; i != n_mapping_shape_functions; ++i)
      66             :         {
      67             :           const Real ddxi = shape_deriv_ptr
      68  2155880448 :             (map_fe_type, elem, i, 0, dofpt[p], /*add_p_level=*/false);
      69             :           const Real ddeta = shape_deriv_ptr
      70  2155880448 :             (map_fe_type, elem, i, 1, dofpt[p], /*add_p_level=*/false);
      71             :           const Real ddzeta = shape_deriv_ptr
      72  2155880448 :             (map_fe_type, elem, i, 2, dofpt[p], /*add_p_level=*/false);
      73             : 
      74             :           // dxdeta, dxdzeta, dydxi, dydzeta, dzdxi, dzdeta should all
      75             :           // be 0!
      76   359313408 :           const Point & point_i = elem->point(i);
      77  2155880448 :           dxdxi[0][p] += point_i(0) * ddxi;
      78  2155880448 :           dxdxi[1][p] += point_i(1) * ddeta;
      79  2335537152 :           dxdxi[2][p] += point_i(2) * ddzeta;
      80             : #ifdef DEBUG
      81   179656704 :           dydxi[p] += point_i(1) * ddxi;
      82   179656704 :           dzdeta[p] += point_i(2) * ddeta;
      83   179656704 :           dxdzeta[p] += point_i(0) * ddzeta;
      84   179656704 :           dzdxi[p] += point_i(2) * ddxi;
      85   179656704 :           dxdeta[p] += point_i(0) * ddeta;
      86   179656704 :           dydzeta[p] += point_i(1) * ddzeta;
      87             : #endif
      88             :         }
      89             : 
      90             :       // No singular elements!
      91     6653952 :       libmesh_assert(dxdxi[0][p]);
      92     6653952 :       libmesh_assert(dxdxi[1][p]);
      93     6653952 :       libmesh_assert(dxdxi[2][p]);
      94             :       // No non-rectilinear or non-axis-aligned elements!
      95             : #ifdef DEBUG
      96     6653952 :       libmesh_assert_less (std::abs(dydxi[p]), TOLERANCE);
      97     6653952 :       libmesh_assert_less (std::abs(dzdeta[p]), TOLERANCE);
      98     6653952 :       libmesh_assert_less (std::abs(dxdzeta[p]), TOLERANCE);
      99     6653952 :       libmesh_assert_less (std::abs(dzdxi[p]), TOLERANCE);
     100     6653952 :       libmesh_assert_less (std::abs(dxdeta[p]), TOLERANCE);
     101     6653952 :       libmesh_assert_less (std::abs(dydzeta[p]), TOLERANCE);
     102             : #endif
     103             :     }
     104    39923712 : }
     105             : 
     106             : 
     107             : 
     108    39923712 : Real hermite_bases_3D (std::vector<unsigned int> & bases1D,
     109             :                        const std::vector<std::vector<Real>> & dxdxi,
     110             :                        const Order & o,
     111             :                        unsigned int i)
     112             : {
     113     3326976 :   bases1D.clear();
     114    39923712 :   bases1D.resize(3,0);
     115     3326976 :   Real coef = 1.0;
     116             : 
     117    39923712 :   unsigned int e = o-2;
     118             : 
     119             :   // Nodes
     120    39923712 :   if (i < 64)
     121             :     {
     122    39923712 :       switch (i / 8)
     123             :         {
     124      415872 :         case 0:
     125      415872 :           break;
     126      831744 :         case 1:
     127     4990464 :           bases1D[0] = 1;
     128     4990464 :           break;
     129      831744 :         case 2:
     130     4990464 :           bases1D[0] = 1;
     131     4990464 :           bases1D[1] = 1;
     132     4990464 :           break;
     133      831744 :         case 3:
     134     4990464 :           bases1D[1] = 1;
     135     4990464 :           break;
     136      831744 :         case 4:
     137     4990464 :           bases1D[2] = 1;
     138     4990464 :           break;
     139      831744 :         case 5:
     140     4990464 :           bases1D[0] = 1;
     141     4990464 :           bases1D[2] = 1;
     142     4990464 :           break;
     143      831744 :         case 6:
     144     4990464 :           bases1D[0] = 1;
     145     4990464 :           bases1D[1] = 1;
     146     4990464 :           bases1D[2] = 1;
     147     4990464 :           break;
     148      831744 :         case 7:
     149     4990464 :           bases1D[1] = 1;
     150     4990464 :           bases1D[2] = 1;
     151     4990464 :           break;
     152           0 :         default:
     153           0 :           libmesh_error_msg("Invalid basis node = " << i/8);
     154             :         }
     155             : 
     156    39923712 :       unsigned int basisnum = i%8;
     157    39923712 :       switch (basisnum) // DoF type
     158             :         {
     159      415872 :         case 0: // DoF = value at node
     160      415872 :           coef = 1.0;
     161      415872 :           break;
     162      831744 :         case 1: // DoF = x derivative at node
     163     4990464 :           coef = dxdxi[0][bases1D[0]];
     164     4990464 :           bases1D[0] += 2; break;
     165      831744 :         case 2: // DoF = y derivative at node
     166     4990464 :           coef = dxdxi[1][bases1D[1]];
     167     4990464 :           bases1D[1] += 2; break;
     168      831744 :         case 3: // DoF = xy derivative at node
     169     5406336 :           coef = dxdxi[0][bases1D[0]] * dxdxi[1][bases1D[1]];
     170     4990464 :           bases1D[0] += 2; bases1D[1] += 2; break;
     171      831744 :         case 4: // DoF = z derivative at node
     172     4990464 :           coef = dxdxi[2][bases1D[2]];
     173     4990464 :           bases1D[2] += 2; break;
     174      831744 :         case 5: // DoF = xz derivative at node
     175     5406336 :           coef = dxdxi[0][bases1D[0]] * dxdxi[2][bases1D[2]];
     176     4990464 :           bases1D[0] += 2; bases1D[2] += 2; break;
     177      831744 :         case 6: // DoF = yz derivative at node
     178     5406336 :           coef = dxdxi[1][bases1D[1]] * dxdxi[2][bases1D[2]];
     179     4990464 :           bases1D[1] += 2; bases1D[2] += 2; break;
     180      831744 :         case 7: // DoF = xyz derivative at node
     181     5822208 :           coef = dxdxi[0][bases1D[0]] * dxdxi[1][bases1D[1]] * dxdxi[2][bases1D[2]];
     182     4990464 :           bases1D[0] += 2; bases1D[1] += 2; bases1D[2] += 2; break;
     183           0 :         default:
     184           0 :           libmesh_error_msg("Invalid basisnum = " << basisnum);
     185             :         }
     186             :     }
     187             :   // Edges
     188           0 :   else if (i < 64 + 12*4*e)
     189             :     {
     190           0 :       unsigned int basisnum = (i - 64) % (4*e);
     191           0 :       switch ((i - 64) / (4*e))
     192             :         {
     193           0 :         case 0:
     194           0 :           bases1D[0] = basisnum / 4 + 4;
     195           0 :           bases1D[1] = basisnum % 4 / 2 * 2;
     196           0 :           bases1D[2] = basisnum % 2 * 2;
     197           0 :           if (basisnum % 4 / 2)
     198           0 :             coef *= dxdxi[1][0];
     199           0 :           if (basisnum % 2)
     200           0 :             coef *= dxdxi[2][0];
     201           0 :           break;
     202           0 :         case 1:
     203           0 :           bases1D[0] = basisnum % 4 / 2 * 2 + 1;
     204           0 :           bases1D[1] = basisnum / 4 + 4;
     205           0 :           bases1D[2] = basisnum % 2 * 2;
     206           0 :           if (basisnum % 4 / 2)
     207           0 :             coef *= dxdxi[0][1];
     208           0 :           if (basisnum % 2)
     209           0 :             coef *= dxdxi[2][0];
     210           0 :           break;
     211           0 :         case 2:
     212           0 :           bases1D[0] = basisnum / 4 + 4;
     213           0 :           bases1D[1] = basisnum % 4 / 2 * 2 + 1;
     214           0 :           bases1D[2] = basisnum % 2 * 2;
     215           0 :           if (basisnum % 4 / 2)
     216           0 :             coef *= dxdxi[1][1];
     217           0 :           if (basisnum % 2)
     218           0 :             coef *= dxdxi[2][0];
     219           0 :           break;
     220           0 :         case 3:
     221           0 :           bases1D[0] = basisnum % 4 / 2 * 2;
     222           0 :           bases1D[1] = basisnum / 4 + 4;
     223           0 :           bases1D[2] = basisnum % 2 * 2;
     224           0 :           if (basisnum % 4 / 2)
     225           0 :             coef *= dxdxi[0][0];
     226           0 :           if (basisnum % 2)
     227           0 :             coef *= dxdxi[2][0];
     228           0 :           break;
     229           0 :         case 4:
     230           0 :           bases1D[0] = basisnum % 4 / 2 * 2;
     231           0 :           bases1D[1] = basisnum % 2 * 2;
     232           0 :           bases1D[2] = basisnum / 4 + 4;
     233           0 :           if (basisnum % 4 / 2)
     234           0 :             coef *= dxdxi[0][0];
     235           0 :           if (basisnum % 2)
     236           0 :             coef *= dxdxi[1][0];
     237           0 :           break;
     238           0 :         case 5:
     239           0 :           bases1D[0] = basisnum % 4 / 2 * 2 + 1;
     240           0 :           bases1D[1] = basisnum % 2 * 2;
     241           0 :           bases1D[2] = basisnum / 4 + 4;
     242           0 :           if (basisnum % 4 / 2)
     243           0 :             coef *= dxdxi[0][1];
     244           0 :           if (basisnum % 2)
     245           0 :             coef *= dxdxi[1][0];
     246           0 :           break;
     247           0 :         case 6:
     248           0 :           bases1D[0] = basisnum % 4 / 2 * 2 + 1;
     249           0 :           bases1D[1] = basisnum % 2 * 2 + 1;
     250           0 :           bases1D[2] = basisnum / 4 + 4;
     251           0 :           if (basisnum % 4 / 2)
     252           0 :             coef *= dxdxi[0][1];
     253           0 :           if (basisnum % 2)
     254           0 :             coef *= dxdxi[1][1];
     255           0 :           break;
     256           0 :         case 7:
     257           0 :           bases1D[0] = basisnum % 4 / 2 * 2;
     258           0 :           bases1D[1] = basisnum % 2 * 2 + 1;
     259           0 :           bases1D[2] = basisnum / 4 + 4;
     260           0 :           if (basisnum % 4 / 2)
     261           0 :             coef *= dxdxi[0][0];
     262           0 :           if (basisnum % 2)
     263           0 :             coef *= dxdxi[1][1];
     264           0 :           break;
     265           0 :         case 8:
     266           0 :           bases1D[0] = basisnum / 4 + 4;
     267           0 :           bases1D[1] = basisnum % 4 / 2 * 2;
     268           0 :           bases1D[2] = basisnum % 2 * 2 + 1;
     269           0 :           if (basisnum % 4 / 2)
     270           0 :             coef *= dxdxi[1][0];
     271           0 :           if (basisnum % 2)
     272           0 :             coef *= dxdxi[2][1];
     273           0 :           break;
     274           0 :         case 9:
     275           0 :           bases1D[0] = basisnum % 4 / 2 * 2 + 1;
     276           0 :           bases1D[1] = basisnum / 4 + 4;
     277           0 :           bases1D[2] = basisnum % 2 * 2;
     278           0 :           if (basisnum % 4 / 2)
     279           0 :             coef *= dxdxi[0][1];
     280           0 :           if (basisnum % 2)
     281           0 :             coef *= dxdxi[2][1];
     282           0 :           break;
     283           0 :         case 10:
     284           0 :           bases1D[0] = basisnum / 4 + 4;
     285           0 :           bases1D[1] = basisnum % 4 / 2 * 2 + 1;
     286           0 :           bases1D[2] = basisnum % 2 * 2 + 1;
     287           0 :           if (basisnum % 4 / 2)
     288           0 :             coef *= dxdxi[1][1];
     289           0 :           if (basisnum % 2)
     290           0 :             coef *= dxdxi[2][1];
     291           0 :           break;
     292           0 :         case 11:
     293           0 :           bases1D[0] = basisnum % 4 / 2 * 2;
     294           0 :           bases1D[1] = basisnum / 4 + 4;
     295           0 :           bases1D[2] = basisnum % 2 * 2 + 1;
     296           0 :           if (basisnum % 4 / 2)
     297           0 :             coef *= dxdxi[0][0];
     298           0 :           if (basisnum % 2)
     299           0 :             coef *= dxdxi[2][1];
     300           0 :           break;
     301           0 :         default:
     302           0 :           libmesh_error_msg("Invalid basis node = " << (i - 64) / (4*e));
     303             :         }
     304             :     }
     305             :   // Faces
     306           0 :   else if (i < 64 + 12*4*e + 6*2*e*e)
     307             :     {
     308           0 :       unsigned int basisnum = (i - 64 - 12*4*e) % (2*e*e);
     309           0 :       switch ((i - 64 - 12*4*e) / (2*e*e))
     310             :         {
     311           0 :         case 0:
     312           0 :           bases1D[0] = square_number_column[basisnum / 2];
     313           0 :           bases1D[1] = square_number_row[basisnum / 2];
     314           0 :           bases1D[2] = basisnum % 2 * 2;
     315           0 :           if (basisnum % 2)
     316           0 :             coef *= dxdxi[2][0];
     317           0 :           break;
     318           0 :         case 1:
     319           0 :           bases1D[0] = square_number_column[basisnum / 2];
     320           0 :           bases1D[1] = basisnum % 2 * 2;
     321           0 :           bases1D[2] = square_number_row[basisnum / 2];
     322           0 :           if (basisnum % 2)
     323           0 :             coef *= dxdxi[1][0];
     324           0 :           break;
     325           0 :         case 2:
     326           0 :           bases1D[0] = basisnum % 2 * 2 + 1;
     327           0 :           bases1D[1] = square_number_column[basisnum / 2];
     328           0 :           bases1D[2] = square_number_row[basisnum / 2];
     329           0 :           if (basisnum % 2)
     330           0 :             coef *= dxdxi[0][1];
     331           0 :           break;
     332           0 :         case 3:
     333           0 :           bases1D[0] = square_number_column[basisnum / 2];
     334           0 :           bases1D[1] = basisnum % 2 * 2 + 1;
     335           0 :           bases1D[2] = square_number_row[basisnum / 2];
     336           0 :           if (basisnum % 2)
     337           0 :             coef *= dxdxi[1][1];
     338           0 :           break;
     339           0 :         case 4:
     340           0 :           bases1D[0] = basisnum % 2 * 2;
     341           0 :           bases1D[1] = square_number_column[basisnum / 2];
     342           0 :           bases1D[2] = square_number_row[basisnum / 2];
     343           0 :           if (basisnum % 2)
     344           0 :             coef *= dxdxi[0][0];
     345           0 :           break;
     346           0 :         case 5:
     347           0 :           bases1D[0] = square_number_column[basisnum / 2];
     348           0 :           bases1D[1] = square_number_row[basisnum / 2];
     349           0 :           bases1D[2] = basisnum % 2 * 2 + 1;
     350           0 :           if (basisnum % 2)
     351           0 :             coef *= dxdxi[2][1];
     352           0 :           break;
     353           0 :         default:
     354           0 :           libmesh_error_msg("Invalid basis node = " << (i - 64 - 12*4*e) / (2*e*e));
     355             :         }
     356             :     }
     357             :   // Interior
     358             :   else
     359             :     {
     360           0 :       unsigned int basisnum = i - 64 - 12*4*e;
     361           0 :       bases1D[0] = cube_number_column[basisnum] + 4;
     362           0 :       bases1D[1] = cube_number_row[basisnum] + 4;
     363           0 :       bases1D[2] = cube_number_page[basisnum] + 4;
     364             :     }
     365             : 
     366             :   // No singular elements
     367     3326976 :   libmesh_assert(coef);
     368    39923712 :   return coef;
     369             : }
     370             : 
     371             : 
     372             : } // end anonymous namespace
     373             : 
     374             : 
     375             : namespace libMesh
     376             : {
     377             : 
     378             : 
     379    15490068 : LIBMESH_DEFAULT_VECTORIZED_FE(3,HERMITE)
     380             : 
     381             : 
     382             : template <>
     383     4036608 : Real FE<3,HERMITE>::shape(const Elem * elem,
     384             :                           const Order order,
     385             :                           const unsigned int i,
     386             :                           const Point & p,
     387             :                           const bool add_p_level)
     388             : {
     389      336384 :   libmesh_assert(elem);
     390             : 
     391     5045760 :   std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
     392             : 
     393             : #ifdef DEBUG
     394     1345536 :   std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
     395     1345536 :   std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
     396             : #endif //DEBUG
     397             : 
     398     4036608 :   hermite_compute_coefs(elem, dxdxi
     399             : #ifdef DEBUG
     400             :                         , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
     401             : #endif
     402             :                         );
     403             : 
     404     4036608 :   const ElemType type = elem->type();
     405             : 
     406             :   const Order totalorder =
     407     4372992 :     order + add_p_level*elem->p_level();
     408             : 
     409     4036608 :   switch (totalorder)
     410             :     {
     411             :       // 3rd-order tricubic Hermite functions
     412     4036608 :     case THIRD:
     413             :       {
     414     4036608 :         switch (type)
     415             :           {
     416      336384 :           case HEX8:
     417             :           case HEX20:
     418             :           case HEX27:
     419             :             {
     420      336384 :               libmesh_assert_less (i, 64);
     421             : 
     422      336384 :               std::vector<unsigned int> bases1D;
     423             : 
     424     4036608 :               Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
     425             : 
     426     4036608 :               return coef *
     427     4036608 :                 FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
     428     4036608 :                 FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
     429     8073216 :                 FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
     430             :             }
     431           0 :           default:
     432           0 :             libmesh_error_msg("ERROR: Unsupported element type " << Utility::enum_to_string(type));
     433             :           }
     434             :       }
     435             :       // by default throw an error
     436           0 :     default:
     437           0 :       libmesh_error_msg("ERROR: Unsupported polynomial order " << totalorder);
     438             :     }
     439     3363840 : }
     440             : 
     441             : 
     442             : template <>
     443           0 : Real FE<3,HERMITE>::shape(const ElemType,
     444             :                           const Order,
     445             :                           const unsigned int,
     446             :                           const Point &)
     447             : {
     448           0 :   libmesh_error_msg("Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
     449             :   return 0.;
     450             : }
     451             : 
     452             : template <>
     453           0 : Real FE<3,HERMITE>::shape(const FEType fet,
     454             :                           const Elem * elem,
     455             :                           const unsigned int i,
     456             :                           const Point & p,
     457             :                           const bool add_p_level)
     458             : {
     459           0 :   return FE<3,HERMITE>::shape(elem, fet.order, i, p, add_p_level);
     460             : }
     461             : 
     462             : 
     463             : 
     464             : template <>
     465    11962368 : Real FE<3,HERMITE>::shape_deriv(const Elem * elem,
     466             :                                 const Order order,
     467             :                                 const unsigned int i,
     468             :                                 const unsigned int j,
     469             :                                 const Point & p,
     470             :                                 const bool add_p_level)
     471             : {
     472      996864 :   libmesh_assert(elem);
     473      996864 :   libmesh_assert (j == 0 || j == 1 || j == 2);
     474             : 
     475    14952960 :   std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
     476             : 
     477             : #ifdef DEBUG
     478     3987456 :   std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
     479     3987456 :   std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
     480             : #endif //DEBUG
     481             : 
     482    11962368 :   hermite_compute_coefs(elem, dxdxi
     483             : #ifdef DEBUG
     484             :                         , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
     485             : #endif
     486             :                         );
     487             : 
     488    11962368 :   const ElemType type = elem->type();
     489             : 
     490             :   const Order totalorder =
     491    12959232 :     order + add_p_level*elem->p_level();
     492             : 
     493    11962368 :   switch (totalorder)
     494             :     {
     495             :       // 3rd-order tricubic Hermite functions
     496    11962368 :     case THIRD:
     497             :       {
     498    11962368 :         switch (type)
     499             :           {
     500      996864 :           case HEX8:
     501             :           case HEX20:
     502             :           case HEX27:
     503             :             {
     504      996864 :               libmesh_assert_less (i, 64);
     505             : 
     506     1993728 :               std::vector<unsigned int> bases1D;
     507             : 
     508    11962368 :               Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
     509             : 
     510    11962368 :               switch (j) // Derivative type
     511             :                 {
     512     3987456 :                 case 0:
     513     3987456 :                   return coef *
     514     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[0],p(0)) *
     515     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
     516     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
     517             :                   break;
     518     3987456 :                 case 1:
     519     3987456 :                   return coef *
     520     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
     521     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[1],p(1)) *
     522     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
     523             :                   break;
     524     3987456 :                 case 2:
     525     3987456 :                   return coef *
     526     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
     527     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
     528     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[2],p(2));
     529             :                   break;
     530           0 :                 default:
     531           0 :                   libmesh_error_msg("Invalid shape function derivative j = " << j);
     532             :                 }
     533             : 
     534             :             }
     535           0 :           default:
     536           0 :             libmesh_error_msg("ERROR: Unsupported element type " << Utility::enum_to_string(type));
     537             :           }
     538             :       }
     539             :       // by default throw an error
     540           0 :     default:
     541           0 :       libmesh_error_msg("ERROR: Unsupported polynomial order " << totalorder);
     542             :     }
     543     9968640 : }
     544             : 
     545             : 
     546             : template <>
     547           0 : Real FE<3,HERMITE>::shape_deriv(const ElemType,
     548             :                                 const Order,
     549             :                                 const unsigned int,
     550             :                                 const unsigned int,
     551             :                                 const Point &)
     552             : {
     553           0 :   libmesh_error_msg("Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
     554             :   return 0.;
     555             : }
     556             : 
     557             : 
     558             : template <>
     559           0 : Real FE<3,HERMITE>::shape_deriv(const FEType fet,
     560             :                                 const Elem * elem,
     561             :                                 const unsigned int i,
     562             :                                 const unsigned int j,
     563             :                                 const Point & p,
     564             :                                 const bool add_p_level)
     565             : {
     566           0 :   return FE<3,HERMITE>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
     567             : }
     568             : 
     569             : 
     570             : 
     571             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     572             : 
     573             : 
     574             : template <>
     575    23924736 : Real FE<3,HERMITE>::shape_second_deriv(const Elem * elem,
     576             :                                        const Order order,
     577             :                                        const unsigned int i,
     578             :                                        const unsigned int j,
     579             :                                        const Point & p,
     580             :                                        const bool add_p_level)
     581             : {
     582     1993728 :   libmesh_assert(elem);
     583             : 
     584    29905920 :   std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
     585             : 
     586             : #ifdef DEBUG
     587     7974912 :   std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
     588     7974912 :   std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
     589             : #endif //DEBUG
     590             : 
     591    23924736 :   hermite_compute_coefs(elem, dxdxi
     592             : #ifdef DEBUG
     593             :                         , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
     594             : #endif
     595             :                         );
     596             : 
     597    23924736 :   const ElemType type = elem->type();
     598             : 
     599             :   const Order totalorder =
     600    25918464 :     order + add_p_level*elem->p_level();
     601             : 
     602    23924736 :   switch (totalorder)
     603             :     {
     604             :       // 3rd-order tricubic Hermite functions
     605    23924736 :     case THIRD:
     606             :       {
     607    23924736 :         switch (type)
     608             :           {
     609     1993728 :           case HEX8:
     610             :           case HEX20:
     611             :           case HEX27:
     612             :             {
     613     1993728 :               libmesh_assert_less (i, 64);
     614             : 
     615     3987456 :               std::vector<unsigned int> bases1D;
     616             : 
     617    23924736 :               Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
     618             : 
     619    23924736 :               switch (j) // Derivative type
     620             :                 {
     621     3987456 :                 case 0:
     622     3987456 :                   return coef *
     623     3987456 :                     FEHermite<1>::hermite_raw_shape_second_deriv(bases1D[0],p(0)) *
     624     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
     625     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
     626             :                   break;
     627     3987456 :                 case 1:
     628     3987456 :                   return coef *
     629     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[0],p(0)) *
     630     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[1],p(1)) *
     631     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
     632             :                   break;
     633     3987456 :                 case 2:
     634     3987456 :                   return coef *
     635     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
     636     3987456 :                     FEHermite<1>::hermite_raw_shape_second_deriv(bases1D[1],p(1)) *
     637     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
     638             :                   break;
     639     3987456 :                 case 3:
     640     3987456 :                   return coef *
     641     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[0],p(0)) *
     642     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
     643     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[2],p(2));
     644             :                   break;
     645     3987456 :                 case 4:
     646     3987456 :                   return coef *
     647     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
     648     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[1],p(1)) *
     649     3987456 :                     FEHermite<1>::hermite_raw_shape_deriv(bases1D[2],p(2));
     650             :                   break;
     651     3987456 :                 case 5:
     652     3987456 :                   return coef *
     653     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
     654     3987456 :                     FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
     655     3987456 :                     FEHermite<1>::hermite_raw_shape_second_deriv(bases1D[2],p(2));
     656             :                   break;
     657           0 :                 default:
     658           0 :                   libmesh_error_msg("Invalid shape function derivative j = " << j);
     659             :                 }
     660             : 
     661             :             }
     662           0 :           default:
     663           0 :             libmesh_error_msg("ERROR: Unsupported element type " << Utility::enum_to_string(type));
     664             :           }
     665             :       }
     666             :       // by default throw an error
     667           0 :     default:
     668           0 :       libmesh_error_msg("ERROR: Unsupported polynomial order " << totalorder);
     669             :     }
     670    19937280 : }
     671             : 
     672             : 
     673             : template <>
     674           0 : Real FE<3,HERMITE>::shape_second_deriv(const ElemType,
     675             :                                        const Order,
     676             :                                        const unsigned int,
     677             :                                        const unsigned int,
     678             :                                        const Point &)
     679             : {
     680           0 :   libmesh_error_msg("Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
     681             :   return 0.;
     682             : }
     683             : 
     684             : template <>
     685           0 : Real FE<3,HERMITE>::shape_second_deriv(const FEType fet,
     686             :                                        const Elem * elem,
     687             :                                        const unsigned int i,
     688             :                                        const unsigned int j,
     689             :                                        const Point & p,
     690             :                                        const bool add_p_level)
     691             : {
     692           0 :   return FE<3,HERMITE>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
     693             : }
     694             : 
     695             : #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
     696             : 
     697             : } // namespace libMesh

Generated by: LCOV version 1.14