LCOV - code coverage report
Current view: top level - src/fe - fe_xyz_shape_2D.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 231 307 75.2 %
Date: 2025-08-19 19:27:09 Functions: 5 13 38.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             : // C++ includes
      20             : 
      21             : // Local includes
      22             : #include "libmesh/fe.h"
      23             : 
      24             : #include "libmesh/elem.h"
      25             : #include "libmesh/int_range.h"
      26             : 
      27             : 
      28             : namespace libMesh
      29             : {
      30             : 
      31             : 
      32        2580 : LIBMESH_DEFAULT_VECTORIZED_FE(2,XYZ)
      33             : 
      34             : 
      35             : template <>
      36     4531510 : Real FE<2,XYZ>::shape(const Elem * elem,
      37             :                       const Order libmesh_dbg_var(order),
      38             :                       const unsigned int i,
      39             :                       const Point & point_in,
      40             :                       const bool libmesh_dbg_var(add_p_level))
      41             : {
      42             : #if LIBMESH_DIM > 1
      43             : 
      44      380576 :   libmesh_assert(elem);
      45             : 
      46     4531510 :   Point avg = elem->vertex_average();
      47      380576 :   Point max_distance = Point(0.,0.,0.);
      48    33061278 :   for (const Point & p : elem->node_ref_range())
      49    85589304 :     for (unsigned int d = 0; d < 2; d++)
      50             :       {
      51    61851804 :         const Real distance = std::abs(avg(d) - p(d));
      52    57059536 :         max_distance(d) = std::max(distance, max_distance(d));
      53             :       }
      54             : 
      55     4531510 :   const Real x  = point_in(0);
      56     4531510 :   const Real y  = point_in(1);
      57     4531510 :   const Real xc = avg(0);
      58     4531510 :   const Real yc = avg(1);
      59     4531510 :   const Real distx = max_distance(0);
      60     4531510 :   const Real disty = max_distance(1);
      61     4531510 :   const Real dx = (x - xc)/distx;
      62     4531510 :   const Real dy = (y - yc)/disty;
      63             : 
      64             : #ifndef NDEBUG
      65             :   // totalorder is only used in the assertion below, so
      66             :   // we avoid declaring it when asserts are not active.
      67      380576 :   const unsigned int totalorder = order + add_p_level * elem->p_level();
      68             : #endif
      69      380576 :   libmesh_assert_less (i, (totalorder+1)*(totalorder+2)/2);
      70             : 
      71             : 
      72             :   // monomials. since they are hierarchic we only need one case block.
      73     4531510 :   switch (i)
      74             :     {
      75             :       // constant
      76       82122 :     case 0:
      77       82122 :       return 1.;
      78             : 
      79             :       // linear
      80      981298 :     case 1:
      81      981298 :       return dx;
      82             : 
      83      981298 :     case 2:
      84      981298 :       return dy;
      85             : 
      86             :       // quadratics
      87      372172 :     case 3:
      88      372172 :       return dx*dx;
      89             : 
      90      372172 :     case 4:
      91      372172 :       return dx*dy;
      92             : 
      93      372172 :     case 5:
      94      372172 :       return dy*dy;
      95             : 
      96             :       // cubics
      97       69760 :     case 6:
      98       69760 :       return dx*dx*dx;
      99             : 
     100       69760 :     case 7:
     101       69760 :       return dx*dx*dy;
     102             : 
     103       69760 :     case 8:
     104       69760 :       return dx*dy*dy;
     105             : 
     106       69760 :     case 9:
     107       69760 :       return dy*dy*dy;
     108             : 
     109             :       // quartics
     110       38412 :     case 10:
     111       38412 :       return dx*dx*dx*dx;
     112             : 
     113       38412 :     case 11:
     114       38412 :       return dx*dx*dx*dy;
     115             : 
     116       38412 :     case 12:
     117       38412 :       return dx*dx*dy*dy;
     118             : 
     119       38412 :     case 13:
     120       38412 :       return dx*dy*dy*dy;
     121             : 
     122       38412 :     case 14:
     123       38412 :       return dy*dy*dy*dy;
     124             : 
     125           0 :     default:
     126           0 :       unsigned int o = 0;
     127           0 :       for (; i >= (o+1)*(o+2)/2; o++) { }
     128           0 :       unsigned int i2 = i - (o*(o+1)/2);
     129           0 :       Real val = 1.;
     130           0 :       for (unsigned int index=i2; index != o; index++)
     131           0 :         val *= dx;
     132           0 :       for (unsigned int index=0; index != i2; index++)
     133           0 :         val *= dy;
     134           0 :       return val;
     135             :     }
     136             : 
     137             : #else // LIBMESH_DIM <= 1
     138             :   libmesh_assert(true || order || add_p_level);
     139             :   libmesh_ignore(elem, i, point_in);
     140             :   libmesh_not_implemented();
     141             : #endif
     142             : }
     143             : 
     144             : 
     145             : 
     146             : 
     147             : template <>
     148           0 : Real FE<2,XYZ>::shape(const ElemType,
     149             :                       const Order,
     150             :                       const unsigned int,
     151             :                       const Point &)
     152             : {
     153           0 :   libmesh_error_msg("XYZ polynomials require the element.");
     154             :   return 0.;
     155             : }
     156             : 
     157             : 
     158             : 
     159             : template <>
     160           0 : Real FE<2,XYZ>::shape(const FEType fet,
     161             :                       const Elem * elem,
     162             :                       const unsigned int i,
     163             :                       const Point & p,
     164             :                       const bool add_p_level)
     165             : {
     166           0 :   return FE<2,XYZ>::shape(elem, fet.order, i, p, add_p_level);
     167             : }
     168             : 
     169             : 
     170             : 
     171             : 
     172             : 
     173             : template <>
     174     7724084 : Real FE<2,XYZ>::shape_deriv(const Elem * elem,
     175             :                             const Order libmesh_dbg_var(order),
     176             :                             const unsigned int i,
     177             :                             const unsigned int j,
     178             :                             const Point & point_in,
     179             :                             const bool libmesh_dbg_var(add_p_level))
     180             : {
     181             : #if LIBMESH_DIM > 1
     182             : 
     183             : 
     184      649272 :   libmesh_assert_less (j, 2);
     185      649272 :   libmesh_assert(elem);
     186             : 
     187     7724084 :   Point avg = elem->vertex_average();
     188      649272 :   Point max_distance = Point(0.,0.,0.);
     189    55892208 :   for (const Point & p : elem->node_ref_range())
     190   144504372 :     for (unsigned int d = 0; d < 2; d++)
     191             :       {
     192   104434984 :         const Real distance = std::abs(avg(d) - p(d));
     193    96336248 :         max_distance(d) = std::max(distance, max_distance(d));
     194             :       }
     195             : 
     196     7724084 :   const Real x  = point_in(0);
     197     7724084 :   const Real y  = point_in(1);
     198     7724084 :   const Real xc = avg(0);
     199     7724084 :   const Real yc = avg(1);
     200     7724084 :   const Real distx = max_distance(0);
     201     7724084 :   const Real disty = max_distance(1);
     202     7724084 :   const Real dx = (x - xc)/distx;
     203     7724084 :   const Real dy = (y - yc)/disty;
     204             : 
     205             : #ifndef NDEBUG
     206             :   // totalorder is only used in the assertion below, so
     207             :   // we avoid declaring it when asserts are not active.
     208      649272 :   const unsigned int totalorder = order + add_p_level * elem->p_level();
     209             : #endif
     210      649272 :   libmesh_assert_less (i, (totalorder+1)*(totalorder+2)/2);
     211             : 
     212             :   // monomials. since they are hierarchic we only need one case block.
     213             : 
     214     7724084 :   switch (j)
     215             :     {
     216             :       // d()/dx
     217     3862042 :     case 0:
     218             :       {
     219     3862042 :         switch (i)
     220             :           {
     221             :             // constants
     222       73752 :           case 0:
     223       73752 :             return 0.;
     224             : 
     225             :             // linears
     226      881018 :           case 1:
     227      881018 :             return 1./distx;
     228             : 
     229       73752 :           case 2:
     230       73752 :             return 0.;
     231             : 
     232             :             // quadratics
     233      307164 :           case 3:
     234      307164 :             return 2.*dx/distx;
     235             : 
     236      307164 :           case 4:
     237      307164 :             return dy/distx;
     238             : 
     239       25856 :           case 5:
     240       25856 :             return 0.;
     241             : 
     242             :             // cubics
     243       45164 :           case 6:
     244       45164 :             return 3.*dx*dx/distx;
     245             : 
     246       45164 :           case 7:
     247       45164 :             return 2.*dx*dy/distx;
     248             : 
     249       45164 :           case 8:
     250       45164 :             return dy*dy/distx;
     251             : 
     252        3918 :           case 9:
     253        3918 :             return 0.;
     254             : 
     255             :             // quartics
     256       23368 :           case 10:
     257       23368 :             return 4.*dx*dx*dx/distx;
     258             : 
     259       23368 :           case 11:
     260       23368 :             return 3.*dx*dx*dy/distx;
     261             : 
     262       23368 :           case 12:
     263       23368 :             return 2.*dx*dy*dy/distx;
     264             : 
     265       23368 :           case 13:
     266       23368 :             return dy*dy*dy/distx;
     267             : 
     268        2028 :           case 14:
     269        2028 :             return 0.;
     270             : 
     271           0 :           default:
     272           0 :             unsigned int o = 0;
     273           0 :             for (; i >= (o+1)*(o+2)/2; o++) { }
     274           0 :             unsigned int i2 = i - (o*(o+1)/2);
     275           0 :             Real val = o - i2;
     276           0 :             for (unsigned int index=i2+1; index < o; index++)
     277           0 :               val *= dx;
     278           0 :             for (unsigned int index=0; index != i2; index++)
     279           0 :               val *= dy;
     280           0 :             return val/distx;
     281             :           }
     282             :       }
     283             : 
     284             : 
     285             :       // d()/dy
     286     3862042 :     case 1:
     287             :       {
     288     3862042 :         switch (i)
     289             :           {
     290             :             // constants
     291       73752 :           case 0:
     292       73752 :             return 0.;
     293             : 
     294             :             // linears
     295       73752 :           case 1:
     296       73752 :             return 0.;
     297             : 
     298      881018 :           case 2:
     299      881018 :             return 1./disty;
     300             : 
     301             :             // quadratics
     302       25856 :           case 3:
     303       25856 :             return 0.;
     304             : 
     305      307164 :           case 4:
     306      307164 :             return dx/disty;
     307             : 
     308      307164 :           case 5:
     309      307164 :             return 2.*dy/disty;
     310             : 
     311             :             // cubics
     312        3918 :           case 6:
     313        3918 :             return 0.;
     314             : 
     315       45164 :           case 7:
     316       45164 :             return dx*dx/disty;
     317             : 
     318       45164 :           case 8:
     319       45164 :             return 2.*dx*dy/disty;
     320             : 
     321       45164 :           case 9:
     322       45164 :             return 3.*dy*dy/disty;
     323             : 
     324             :             // quartics
     325        2028 :           case 10:
     326        2028 :             return 0.;
     327             : 
     328       23368 :           case 11:
     329       23368 :             return dx*dx*dx/disty;
     330             : 
     331       23368 :           case 12:
     332       23368 :             return 2.*dx*dx*dy/disty;
     333             : 
     334       23368 :           case 13:
     335       23368 :             return 3.*dx*dy*dy/disty;
     336             : 
     337       23368 :           case 14:
     338       23368 :             return 4.*dy*dy*dy/disty;
     339             : 
     340           0 :           default:
     341           0 :             unsigned int o = 0;
     342           0 :             for (; i >= (o+1)*(o+2)/2; o++) { }
     343           0 :             unsigned int i2 = i - (o*(o+1)/2);
     344           0 :             Real val = i2;
     345           0 :             for (unsigned int index=i2; index != o; index++)
     346           0 :               val *= dx;
     347           0 :             for (unsigned int index=1; index <= i2; index++)
     348           0 :               val *= dy;
     349           0 :             return val/disty;
     350             :           }
     351             :       }
     352             : 
     353             : 
     354           0 :     default:
     355           0 :       libmesh_error_msg("Invalid j = " << j);
     356             :     }
     357             : 
     358             : #else // LIBMESH_DIM <= 1
     359             :   libmesh_assert(true || order || add_p_level);
     360             :   libmesh_ignore(elem, i, j, point_in);
     361             :   libmesh_not_implemented();
     362             : #endif
     363             : }
     364             : 
     365             : 
     366             : template <>
     367           0 : Real FE<2,XYZ>::shape_deriv(const ElemType,
     368             :                             const Order,
     369             :                             const unsigned int,
     370             :                             const unsigned int,
     371             :                             const Point &)
     372             : {
     373           0 :   libmesh_error_msg("XYZ polynomials require the element.");
     374             :   return 0.;
     375             : }
     376             : 
     377             : 
     378             : template <>
     379           0 : Real FE<2,XYZ>::shape_deriv(const FEType fet,
     380             :                             const Elem * elem,
     381             :                             const unsigned int i,
     382             :                             const unsigned int j,
     383             :                             const Point & p,
     384             :                             const bool add_p_level)
     385             : {
     386           0 :   return FE<2,XYZ>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
     387             : }
     388             : 
     389             : 
     390             : 
     391             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     392             : 
     393             : template <>
     394     5192094 : Real FE<2,XYZ>::shape_second_deriv(const Elem * elem,
     395             :                                    const Order libmesh_dbg_var(order),
     396             :                                    const unsigned int i,
     397             :                                    const unsigned int j,
     398             :                                    const Point & point_in,
     399             :                                    const bool libmesh_dbg_var(add_p_level))
     400             : {
     401             : #if LIBMESH_DIM > 1
     402             : 
     403      440856 :   libmesh_assert_less_equal (j, 2);
     404      440856 :   libmesh_assert(elem);
     405             : 
     406     5192094 :   Point avg = elem->vertex_average();
     407      440856 :   Point max_distance = Point(0.,0.,0.);
     408    39080088 :   for (auto p : make_range(elem->n_nodes()))
     409   101663982 :     for (unsigned int d = 0; d < 2; d++)
     410             :       {
     411    79278948 :         const Real distance = std::abs(avg(d) - elem->point(p)(d));
     412    67775988 :         max_distance(d) = std::max(distance, max_distance(d));
     413             :       }
     414             : 
     415     5192094 :   const Real x  = point_in(0);
     416     5192094 :   const Real y  = point_in(1);
     417     5192094 :   const Real xc = avg(0);
     418     5192094 :   const Real yc = avg(1);
     419     5192094 :   const Real distx = max_distance(0);
     420     5192094 :   const Real disty = max_distance(1);
     421     5192094 :   const Real dx = (x - xc)/distx;
     422     5192094 :   const Real dy = (y - yc)/disty;
     423     5192094 :   const Real dist2x = pow(distx,2.);
     424     5192094 :   const Real dist2y = pow(disty,2.);
     425     5192094 :   const Real distxy = distx * disty;
     426             : 
     427             : #ifndef NDEBUG
     428             :   // totalorder is only used in the assertion below, so
     429             :   // we avoid declaring it when asserts are not active.
     430      440856 :   const unsigned int totalorder = order + add_p_level * elem->p_level();
     431             : #endif
     432      440856 :   libmesh_assert_less (i, (totalorder+1)*(totalorder+2)/2);
     433             : 
     434             :   // monomials. since they are hierarchic we only need one case block.
     435             : 
     436     5192094 :   switch (j)
     437             :     {
     438             :       // d^2()/dx^2
     439     1730698 :     case 0:
     440             :       {
     441     1730698 :         switch (i)
     442             :           {
     443             :             // constants
     444       70572 :           case 0:
     445             :             // linears
     446             :           case 1:
     447             :           case 2:
     448       70572 :             return 0.;
     449             : 
     450             :             // quadratics
     451      199164 :           case 3:
     452      199164 :             return 2./dist2x;
     453             : 
     454       33712 :           case 4:
     455             :           case 5:
     456       33712 :             return 0.;
     457             : 
     458             :             // cubics
     459       45164 :           case 6:
     460       45164 :             return 6.*dx/dist2x;
     461             : 
     462       45164 :           case 7:
     463       45164 :             return 2.*dy/dist2x;
     464             : 
     465        7836 :           case 8:
     466             :           case 9:
     467        7836 :             return 0.;
     468             : 
     469             :             // quartics
     470       23368 :           case 10:
     471       23368 :             return 12.*dx*dx/dist2x;
     472             : 
     473       23368 :           case 11:
     474       23368 :             return 6.*dx*dy/dist2x;
     475             : 
     476       23368 :           case 12:
     477       23368 :             return 2.*dy*dy/dist2x;
     478             : 
     479        4056 :           case 13:
     480             :           case 14:
     481        4056 :             return 0.;
     482             : 
     483           0 :           default:
     484           0 :             unsigned int o = 0;
     485           0 :             for (; i >= (o+1)*(o+2)/2; o++) { }
     486           0 :             unsigned int i2 = i - (o*(o+1)/2);
     487           0 :             Real val = (o - i2) * (o - i2 - 1);
     488           0 :             for (unsigned int index=i2+2; index < o; index++)
     489           0 :               val *= dx;
     490           0 :             for (unsigned int index=0; index != i2; index++)
     491           0 :               val *= dy;
     492           0 :             return val/dist2x;
     493             :           }
     494             :       }
     495             : 
     496             :       // d^2()/dxdy
     497     1730698 :     case 1:
     498             :       {
     499     1730698 :         switch (i)
     500             :           {
     501             :             // constants
     502       70572 :           case 0:
     503             : 
     504             :             // linears
     505             :           case 1:
     506             :           case 2:
     507       70572 :             return 0.;
     508             : 
     509             :             // quadratics
     510       16856 :           case 3:
     511       16856 :             return 0.;
     512             : 
     513      199164 :           case 4:
     514      199164 :             return 1./distxy;
     515             : 
     516       16856 :           case 5:
     517       16856 :             return 0.;
     518             : 
     519             :             // cubics
     520        3918 :           case 6:
     521        3918 :             return 0.;
     522       45164 :           case 7:
     523       45164 :             return 2.*dx/distxy;
     524             : 
     525       45164 :           case 8:
     526       45164 :             return 2.*dy/distxy;
     527             : 
     528        3918 :           case 9:
     529        3918 :             return 0.;
     530             : 
     531             :             // quartics
     532        2028 :           case 10:
     533        2028 :             return 0.;
     534             : 
     535       23368 :           case 11:
     536       23368 :             return 3.*dx*dx/distxy;
     537             : 
     538       23368 :           case 12:
     539       23368 :             return 4.*dx*dy/distxy;
     540             : 
     541       23368 :           case 13:
     542       23368 :             return 3.*dy*dy/distxy;
     543             : 
     544        2028 :           case 14:
     545        2028 :             return 0.;
     546             : 
     547           0 :           default:
     548           0 :             unsigned int o = 0;
     549           0 :             for (; i >= (o+1)*(o+2)/2; o++) { }
     550           0 :             unsigned int i2 = i - (o*(o+1)/2);
     551           0 :             Real val = (o - i2) * i2;
     552           0 :             for (unsigned int index=i2+1; index < o; index++)
     553           0 :               val *= dx;
     554           0 :             for (unsigned int index=1; index < i2; index++)
     555           0 :               val *= dy;
     556           0 :             return val/distxy;
     557             :           }
     558             :       }
     559             : 
     560             :       // d^2()/dy^2
     561     1730698 :     case 2:
     562             :       {
     563     1730698 :         switch (i)
     564             :           {
     565             :             // constants
     566       70572 :           case 0:
     567             : 
     568             :             // linears
     569             :           case 1:
     570             :           case 2:
     571       70572 :             return 0.;
     572             : 
     573             :             // quadratics
     574       33712 :           case 3:
     575             :           case 4:
     576       33712 :             return 0.;
     577             : 
     578      199164 :           case 5:
     579      199164 :             return 2./dist2y;
     580             : 
     581             :             // cubics
     582        3918 :           case 6:
     583        3918 :             return 0.;
     584             : 
     585        3918 :           case 7:
     586        3918 :             return 0.;
     587             : 
     588       45164 :           case 8:
     589       45164 :             return 2.*dx/dist2y;
     590             : 
     591       45164 :           case 9:
     592       45164 :             return 6.*dy/dist2y;
     593             : 
     594             :             // quartics
     595        4056 :           case 10:
     596             :           case 11:
     597        4056 :             return 0.;
     598             : 
     599       23368 :           case 12:
     600       23368 :             return 2.*dx*dx/dist2y;
     601             : 
     602       23368 :           case 13:
     603       23368 :             return 6.*dx*dy/dist2y;
     604             : 
     605       23368 :           case 14:
     606       23368 :             return 12.*dy*dy/dist2y;
     607             : 
     608           0 :           default:
     609           0 :             unsigned int o = 0;
     610           0 :             for (; i >= (o+1)*(o+2)/2; o++) { }
     611           0 :             unsigned int i2 = i - (o*(o+1)/2);
     612           0 :             Real val = i2 * (i2 - 1);
     613           0 :             for (unsigned int index=i2; index != o; index++)
     614           0 :               val *= dx;
     615           0 :             for (unsigned int index=2; index < i2; index++)
     616           0 :               val *= dy;
     617           0 :             return val/dist2y;
     618             :           }
     619             :       }
     620             : 
     621           0 :     default:
     622           0 :       libmesh_error_msg("Invalid shape function derivative j = " << j);
     623             :     }
     624             : 
     625             : #else // LIBMESH_DIM <= 1
     626             :   libmesh_assert(true || order || add_p_level);
     627             :   libmesh_ignore(elem, i, j, point_in);
     628             :   libmesh_not_implemented();
     629             : #endif
     630             : }
     631             : 
     632             : 
     633             : template <>
     634           0 : Real FE<2,XYZ>::shape_second_deriv(const ElemType,
     635             :                                    const Order,
     636             :                                    const unsigned int,
     637             :                                    const unsigned int,
     638             :                                    const Point &)
     639             : {
     640           0 :   libmesh_error_msg("XYZ polynomials require the element.");
     641             :   return 0.;
     642             : }
     643             : 
     644             : 
     645             : 
     646             : template <>
     647           0 : Real FE<2,XYZ>::shape_second_deriv(const FEType fet,
     648             :                                    const Elem * elem,
     649             :                                    const unsigned int i,
     650             :                                    const unsigned int j,
     651             :                                    const Point & p,
     652             :                                    const bool add_p_level)
     653             : {
     654           0 :   return FE<2,XYZ>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
     655             : }
     656             : 
     657             : 
     658             : #endif
     659             : 
     660             : } // namespace libMesh

Generated by: LCOV version 1.14