LCOV - code coverage report
Current view: top level - src/fe - fe_raviart_shape_3D.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 85 153 55.6 %
Date: 2025-08-19 19:27:09 Functions: 4 18 22.2 %
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/enum_to_string.h"
      23             : 
      24             : namespace libMesh
      25             : {
      26             : 
      27             : template <>
      28    82028382 : RealGradient FE<3,RAVIART_THOMAS>::shape(const Elem * elem,
      29             :                                          const Order order,
      30             :                                          const unsigned int i,
      31             :                                          const Point & p,
      32             :                                          const bool add_p_level)
      33             : {
      34             : #if LIBMESH_DIM == 3
      35     6836142 :   libmesh_assert(elem);
      36             : 
      37    88864524 :   const Order totalorder = order + add_p_level*elem->p_level();
      38     6836142 :   libmesh_assert_less(i, n_dofs(elem->type(), totalorder));
      39             : 
      40    82028382 :   const char sign = elem->positive_face_orientation(i) ? 1 : -1;
      41             : 
      42    82028382 :   const Real xi   = p(0);
      43    82028382 :   const Real eta  = p(1);
      44    82028382 :   const Real zeta = p(2);
      45             : 
      46    82028382 :   switch (totalorder)
      47             :     {
      48             :       // linear Raviart-Thomas shape functions
      49    82028382 :     case FIRST:
      50             :       {
      51    82028382 :         switch (elem->type())
      52             :           {
      53    46575342 :           case HEX27:
      54             :             {
      55             :               // Even with a loose inverse_map tolerance we ought to
      56             :               // be nearly on the element interior in master
      57             :               // coordinates
      58     3881646 :               libmesh_assert_less_equal ( std::fabs(xi),   1.0+10*TOLERANCE );
      59     3881646 :               libmesh_assert_less_equal ( std::fabs(eta),  1.0+10*TOLERANCE );
      60     3881646 :               libmesh_assert_less_equal ( std::fabs(zeta), 1.0+10*TOLERANCE );
      61             : 
      62    46575342 :               switch(i)
      63             :                 {
      64     7762557 :                 case 0:
      65     7762557 :                   return sign * RealGradient( 0.0, 0.0, 0.125*(zeta-1.0) );
      66     7762557 :                 case 1:
      67     7762557 :                   return sign * RealGradient( 0.0, 0.125*(eta-1.0), 0.0 );
      68     7762557 :                 case 2:
      69     7762557 :                   return sign * RealGradient( 0.125*(xi+1.0), 0.0, 0.0 );
      70     7762557 :                 case 3:
      71     7762557 :                   return sign * RealGradient( 0.0, 0.125*(1.0+eta), 0.0 );
      72     7762557 :                 case 4:
      73     7762557 :                   return sign * RealGradient( 0.125*(xi-1.0), 0.0, 0.0 );
      74     7762557 :                 case 5:
      75     7762557 :                   return sign * RealGradient( 0.0, 0.0, 0.125*(1.0+zeta) );
      76             : 
      77           0 :                 default:
      78           0 :                   libmesh_error_msg("Invalid i = " << i);
      79             :                 }
      80             :             }
      81             : 
      82    35453040 :           case TET14:
      83             :             {
      84    35453040 :               switch(i)
      85             :                 {
      86     8863260 :                 case 0:
      87     8863260 :                   return sign * RealGradient( 2.0*xi, 2.0*eta, 2.0*zeta-2.0 );
      88     8863260 :                 case 1:
      89     8863260 :                   return sign * RealGradient( 2.0*xi, 2.0*eta-2.0, 2.0*zeta );
      90     8863260 :                 case 2:
      91     8863260 :                   return sign * RealGradient( 2.0*xi, 2.0*eta, 2.0*zeta );
      92     8863260 :                 case 3:
      93     8863260 :                   return sign * RealGradient( 2.0*xi-2.0, 2.0*eta, 2.0*zeta );
      94             : 
      95           0 :                 default:
      96           0 :                   libmesh_error_msg("Invalid i = " << i);
      97             :                 }
      98             :             }
      99             : 
     100           0 :           default:
     101           0 :             libmesh_error_msg("ERROR: Unsupported 3D element type!: " << Utility::enum_to_string(elem->type()));
     102             :           }
     103             :       }
     104             : 
     105             :       // unsupported order
     106           0 :     default:
     107           0 :       libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
     108             :     }
     109             : 
     110             : #else // LIBMESH_DIM != 3
     111             :   libmesh_ignore(elem, order, i, p, add_p_level);
     112             :   libmesh_not_implemented();
     113             : #endif
     114             : }
     115             : 
     116             : 
     117             : template <>
     118    10363464 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape(const Elem * elem,
     119             :                                             const Order order,
     120             :                                             const unsigned int i,
     121             :                                             const Point & p,
     122             :                                             const bool add_p_level)
     123             : {
     124    10363464 :   return FE<3,RAVIART_THOMAS>::shape(elem, order, i, p, add_p_level);
     125             : }
     126             : 
     127             : 
     128             : template <>
     129           0 : RealGradient FE<3,RAVIART_THOMAS>::shape(const ElemType,
     130             :                                          const Order,
     131             :                                          const unsigned int,
     132             :                                          const Point &)
     133             : {
     134           0 :   libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
     135             :   return RealGradient();
     136             : }
     137             : 
     138             : 
     139             : template <>
     140           0 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape(const ElemType,
     141             :                                             const Order,
     142             :                                             const unsigned int,
     143             :                                             const Point &)
     144             : {
     145           0 :   libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
     146             :   return RealGradient();
     147             : }
     148             : 
     149             : 
     150             : template <>
     151           0 : RealGradient FE<3,RAVIART_THOMAS>::shape(const FEType fet,
     152             :                                          const Elem * elem,
     153             :                                          const unsigned int i,
     154             :                                          const Point & p,
     155             :                                          const bool add_p_level)
     156             : {
     157           0 :   return FE<3,RAVIART_THOMAS>::shape(elem, fet.order, i, p, add_p_level);
     158             : }
     159             : 
     160             : 
     161             : template <>
     162           0 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape(const FEType fet,
     163             :                                             const Elem * elem,
     164             :                                             const unsigned int i,
     165             :                                             const Point & p,
     166             :                                             const bool add_p_level)
     167             : {
     168           0 :   return FE<3,L2_RAVIART_THOMAS>::shape(elem, fet.order, i, p, add_p_level);
     169             : }
     170             : 
     171             : 
     172             : template <>
     173   126464562 : RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const Elem * elem,
     174             :                                                const Order order,
     175             :                                                const unsigned int i,
     176             :                                                const unsigned int j,
     177             :                                                const Point &,
     178             :                                                const bool add_p_level)
     179             : {
     180             : #if LIBMESH_DIM == 3
     181    10534860 :   libmesh_assert(elem);
     182    10534860 :   libmesh_assert_less (j, 3);
     183             : 
     184   136999422 :   const Order totalorder = order + add_p_level*elem->p_level();
     185    10534860 :   libmesh_assert_less(i, n_dofs(elem->type(), totalorder));
     186             : 
     187   126464562 :   const char sign = elem->positive_face_orientation(i) ? 1 : -1;
     188             : 
     189   126464562 :   switch (totalorder)
     190             :     {
     191             :       // linear Raviart-Thomas shape function first derivatives
     192   126464562 :     case FIRST:
     193             :       {
     194   126464562 :         switch (elem->type())
     195             :           {
     196    74627298 :           case HEX27:
     197             :             {
     198    74627298 :               switch (j)
     199             :                 {
     200             :                   // d()/dxi
     201    24875766 :                 case 0:
     202             :                   {
     203    22804146 :                     switch(i)
     204             :                       {
     205     1381080 :                       case 0:
     206             :                       case 1:
     207             :                       case 3:
     208             :                       case 5:
     209     1381080 :                         return RealGradient();
     210     8291922 :                       case 2:
     211             :                       case 4:
     212      690540 :                         return sign * RealGradient( 0.125, 0.0, 0.0 );
     213             : 
     214           0 :                       default:
     215           0 :                         libmesh_error_msg("Invalid i = " << i);
     216             :                       } // switch(i)
     217             : 
     218             :                   } // j = 0
     219             : 
     220             :                   // d()/deta
     221    24875766 :                 case 1:
     222             :                   {
     223    22804146 :                     switch(i)
     224             :                       {
     225     1381080 :                       case 0:
     226             :                       case 2:
     227             :                       case 4:
     228             :                       case 5:
     229     1381080 :                         return RealGradient();
     230     8291922 :                       case 1:
     231             :                       case 3:
     232      690540 :                         return sign * RealGradient( 0.0, 0.125, 0.0 );
     233             : 
     234           0 :                       default:
     235           0 :                         libmesh_error_msg("Invalid i = " << i);
     236             :                       } // switch(i)
     237             : 
     238             :                   } // j = 1
     239             : 
     240             :                   // d()/dzeta
     241    24875766 :                 case 2:
     242             :                   {
     243    24875766 :                     switch(i)
     244             :                       {
     245     1381080 :                       case 1:
     246             :                       case 2:
     247             :                       case 3:
     248             :                       case 4:
     249     1381080 :                         return RealGradient();
     250     8291922 :                       case 0:
     251             :                       case 5:
     252      690540 :                         return sign * RealGradient( 0.0, 0.0, 0.125 );
     253             : 
     254           0 :                       default:
     255           0 :                         libmesh_error_msg("Invalid i = " << i);
     256             :                       } // switch(i)
     257             : 
     258             :                   } // j = 2
     259             : 
     260           0 :                 default:
     261           0 :                   libmesh_error_msg("Invalid j = " << j);
     262             :                 }
     263             :             }
     264             : 
     265    51837264 :           case TET14:
     266             :             {
     267    51837264 :               switch (j)
     268             :                 {
     269             :                   // d()/dxi
     270    17279088 :                 case 0:
     271             :                   {
     272    17279088 :                     switch(i)
     273             :                     {
     274    17279088 :                     case 0:
     275             :                     case 1:
     276             :                     case 2:
     277             :                     case 3:
     278     1440000 :                       return sign * RealGradient( 2.0, 0.0, 0.0 );
     279             : 
     280           0 :                     default:
     281           0 :                       libmesh_error_msg("Invalid i = " << i);
     282             :                     } // switch(i)
     283             : 
     284             :                   } // j = 0
     285             : 
     286             :                   // d()/deta
     287    17279088 :                 case 1:
     288             :                   {
     289    17279088 :                     switch(i)
     290             :                     {
     291    17279088 :                     case 0:
     292             :                     case 1:
     293             :                     case 2:
     294             :                     case 3:
     295     1440000 :                       return sign * RealGradient( 0.0, 2.0, 0.0 );
     296             : 
     297           0 :                     default:
     298           0 :                       libmesh_error_msg("Invalid i = " << i);
     299             :                     } // switch(i)
     300             : 
     301             :                   } // j = 1
     302             : 
     303             :                   // d()/dzeta
     304    17279088 :                 case 2:
     305             :                   {
     306    17279088 :                     switch(i)
     307             :                     {
     308    17279088 :                     case 0:
     309             :                     case 1:
     310             :                     case 2:
     311             :                     case 3:
     312     1440000 :                       return sign * RealGradient( 0.0, 0.0, 2.0 );
     313             : 
     314           0 :                     default:
     315           0 :                       libmesh_error_msg("Invalid i = " << i);
     316             :                     } // switch(i)
     317             : 
     318             :                   } // j = 2
     319             : 
     320           0 :                 default:
     321           0 :                   libmesh_error_msg("Invalid j = " << j);
     322             :                 }
     323             :             }
     324             : 
     325           0 :           default:
     326           0 :             libmesh_error_msg("ERROR: Unsupported 3D element type!: " << Utility::enum_to_string(elem->type()));
     327             :           }
     328             :       }
     329             :       // unsupported order
     330           0 :     default:
     331           0 :       libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
     332             :     }
     333             : 
     334             : #else // LIBMESH_DIM != 3
     335             :   libmesh_ignore(elem, order, i, j, p, add_p_level);
     336             :   libmesh_not_implemented();
     337             : #endif
     338             : }
     339             : 
     340             : 
     341             : template <>
     342    10333656 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape_deriv(const Elem * elem,
     343             :                                                   const Order order,
     344             :                                                   const unsigned int i,
     345             :                                                   const unsigned int j,
     346             :                                                   const Point & p,
     347             :                                                   const bool add_p_level)
     348             : {
     349    10333656 :   return FE<3,RAVIART_THOMAS>::shape_deriv(elem, order, i, j, p, add_p_level);
     350             : }
     351             : 
     352             : 
     353             : template <>
     354           0 : RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const ElemType,
     355             :                                                const Order,
     356             :                                                const unsigned int,
     357             :                                                const unsigned int,
     358             :                                                const Point &)
     359             : {
     360           0 :   libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
     361             :   return RealGradient();
     362             : }
     363             : 
     364             : 
     365             : template <>
     366           0 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape_deriv(const ElemType,
     367             :                                                   const Order,
     368             :                                                   const unsigned int,
     369             :                                                   const unsigned int,
     370             :                                                   const Point &)
     371             : {
     372           0 :   libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
     373             :   return RealGradient();
     374             : }
     375             : 
     376             : 
     377             : template <>
     378           0 : RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const FEType fet,
     379             :                                                const Elem * elem,
     380             :                                                const unsigned int i,
     381             :                                                const unsigned int j,
     382             :                                                const Point & p,
     383             :                                                const bool add_p_level)
     384             : {
     385           0 :   return FE<3,RAVIART_THOMAS>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
     386             : }
     387             : 
     388             : 
     389             : template <>
     390           0 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape_deriv(const FEType fet,
     391             :                                                   const Elem * elem,
     392             :                                                   const unsigned int i,
     393             :                                                   const unsigned int j,
     394             :                                                   const Point & p,
     395             :                                                   const bool add_p_level)
     396             : {
     397           0 :   return FE<3,L2_RAVIART_THOMAS>::shape_deriv(elem, fet.order, i, j, p, add_p_level);
     398             : }
     399             : 
     400             : 
     401             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     402             : 
     403             : template <>
     404           0 : RealGradient FE<3,RAVIART_THOMAS>::shape_second_deriv(const Elem * elem,
     405             :                                                       const Order order,
     406             :                                                       const unsigned int libmesh_dbg_var(i),
     407             :                                                       const unsigned int libmesh_dbg_var(j),
     408             :                                                       const Point &,
     409             :                                                       const bool add_p_level)
     410             : {
     411             : #if LIBMESH_DIM == 3
     412             : 
     413           0 :   libmesh_assert(elem);
     414             : 
     415             :   // j = 0 ==> d^2 phi / dxi^2
     416             :   // j = 1 ==> d^2 phi / dxi deta
     417             :   // j = 2 ==> d^2 phi / deta^2
     418             :   // j = 3 ==> d^2 phi / dxi dzeta
     419             :   // j = 4 ==> d^2 phi / deta dzeta
     420             :   // j = 5 ==> d^2 phi / dzeta^2
     421           0 :   libmesh_assert_less (j, 6);
     422             : 
     423           0 :   const Order totalorder = order + add_p_level*elem->p_level();
     424           0 :   libmesh_assert_less(i, n_dofs(elem->type(), totalorder));
     425             : 
     426           0 :   switch (totalorder)
     427             :     {
     428             :       // linear Raviart-Thomas shape function second derivatives
     429           0 :     case FIRST:
     430             :       {
     431           0 :         switch (elem->type())
     432             :           {
     433             :             // All second derivatives for linear hexes and tets are zero.
     434           0 :           case HEX27:
     435             :           case TET14:
     436           0 :             return RealGradient();
     437             : 
     438           0 :           default:
     439           0 :             libmesh_error_msg("ERROR: Unsupported 3D element type!: " << Utility::enum_to_string(elem->type()));
     440             : 
     441             :           } //switch(type)
     442             :       }
     443             : 
     444             :       // unsupported order
     445           0 :     default:
     446           0 :       libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
     447             :     }
     448             : 
     449             : #else // LIBMESH_DIM != 3
     450             :   libmesh_assert(true || p(0));
     451             :   libmesh_ignore(elem, order, i, j, add_p_level);
     452             :   libmesh_not_implemented();
     453             : #endif
     454             : }
     455             : 
     456             : 
     457             : template <>
     458           0 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape_second_deriv(const Elem * elem,
     459             :                                                          const Order order,
     460             :                                                          const unsigned int i,
     461             :                                                          const unsigned int j,
     462             :                                                          const Point & p,
     463             :                                                          const bool add_p_level)
     464             : {
     465           0 :   return FE<3,RAVIART_THOMAS>::shape_second_deriv(elem, order, i, j, p, add_p_level);
     466             : }
     467             : 
     468             : 
     469             : template <>
     470           0 : RealGradient FE<3,RAVIART_THOMAS>::shape_second_deriv(const ElemType,
     471             :                                                       const Order,
     472             :                                                       const unsigned int,
     473             :                                                       const unsigned int,
     474             :                                                       const Point &)
     475             : {
     476           0 :   libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
     477             :   return RealGradient();
     478             : }
     479             : 
     480             : 
     481             : template <>
     482           0 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape_second_deriv(const ElemType,
     483             :                                                          const Order,
     484             :                                                          const unsigned int,
     485             :                                                          const unsigned int,
     486             :                                                          const Point &)
     487             : {
     488           0 :   libmesh_error_msg("Raviart-Thomas elements require the element type \nbecause face orientation is needed.");
     489             :   return RealGradient();
     490             : }
     491             : 
     492             : 
     493             : template <>
     494           0 : RealGradient FE<3,RAVIART_THOMAS>::shape_second_deriv(const FEType fet,
     495             :                                                       const Elem * elem,
     496             :                                                       const unsigned int i,
     497             :                                                       const unsigned int j,
     498             :                                                       const Point & p,
     499             :                                                       const bool add_p_level)
     500             : {
     501           0 :   return FE<3,RAVIART_THOMAS>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
     502             : }
     503             : 
     504             : 
     505             : template <>
     506           0 : RealGradient FE<3,L2_RAVIART_THOMAS>::shape_second_deriv(const FEType fet,
     507             :                                                          const Elem * elem,
     508             :                                                          const unsigned int i,
     509             :                                                          const unsigned int j,
     510             :                                                          const Point & p,
     511             :                                                          const bool add_p_level)
     512             : {
     513           0 :   return FE<3,L2_RAVIART_THOMAS>::shape_second_deriv(elem, fet.order, i, j, p, add_p_level);
     514             : }
     515             : 
     516             : #endif
     517             : 
     518             : } // namespace libMesh

Generated by: LCOV version 1.14