LCOV - code coverage report
Current view: top level - src/fe - fe_monomial.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 98 141 69.5 %
Date: 2025-08-19 19:27:09 Functions: 35 58 60.3 %
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             : 
      20             : // Local includes
      21             : #include "libmesh/fe.h"
      22             : #include "libmesh/elem.h"
      23             : #include "libmesh/enum_to_string.h"
      24             : #include "libmesh/fe_interface.h"
      25             : #include "libmesh/fe_macro.h"
      26             : 
      27             : namespace libMesh
      28             : {
      29             : 
      30    17038542 : unsigned int monomial_n_dofs(const Elem * e, const Order o)
      31             : {
      32     2083160 :   libmesh_assert(e);
      33    17038542 :   return monomial_n_dofs(e->type(), o);
      34             : }
      35             : 
      36             : 
      37    17038542 : unsigned int monomial_n_dofs(const ElemType t, const Order o)
      38             : {
      39    17038542 :   switch (o)
      40             :     {
      41             : 
      42             :       // constant shape functions
      43             :       // no matter what shape there is only one DOF.
      44     8305483 :     case CONSTANT:
      45     8305483 :       return (t != INVALID_ELEM) ? 1 : 0;
      46             : 
      47             : 
      48             :       // Discontinuous linear shape functions
      49             :       // expressed in the monomials.
      50     5377572 :     case FIRST:
      51             :       {
      52     5377572 :         switch (t)
      53             :           {
      54           0 :           case NODEELEM:
      55           0 :             return 1;
      56             : 
      57         623 :           case EDGE2:
      58             :           case EDGE3:
      59             :           case EDGE4:
      60         623 :             return 2;
      61             : 
      62      168292 :           case C0POLYGON:
      63             :           case TRI3:
      64             :           case TRISHELL3:
      65             :           case TRI6:
      66             :           case TRI7:
      67             :           case QUAD4:
      68             :           case QUADSHELL4:
      69             :           case QUAD8:
      70             :           case QUADSHELL8:
      71             :           case QUAD9:
      72             :           case QUADSHELL9:
      73      168292 :             return 3;
      74             : 
      75      861119 :           case TET4:
      76             :           case TET10:
      77             :           case TET14:
      78             :           case HEX8:
      79             :           case HEX20:
      80             :           case HEX27:
      81             :           case PRISM6:
      82             :           case PRISM15:
      83             :           case PRISM18:
      84             :           case PRISM20:
      85             :           case PRISM21:
      86             :           case PYRAMID5:
      87             :           case PYRAMID13:
      88             :           case PYRAMID14:
      89             :           case PYRAMID18:
      90             :           case C0POLYHEDRON:
      91      861119 :             return 4;
      92             : 
      93           0 :           case INVALID_ELEM:
      94           0 :             return 0;
      95             : 
      96           0 :           default:
      97           0 :             libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
      98             :           }
      99             :       }
     100             : 
     101             : 
     102             :       // Discontinuous quadratic shape functions
     103             :       // expressed in the monomials.
     104     1461190 :     case SECOND:
     105             :       {
     106     1461190 :         switch (t)
     107             :           {
     108           0 :           case NODEELEM:
     109           0 :             return 1;
     110             : 
     111         588 :           case EDGE2:
     112             :           case EDGE3:
     113             :           case EDGE4:
     114         588 :             return 3;
     115             : 
     116       52247 :           case C0POLYGON:
     117             :           case TRI3:
     118             :           case TRISHELL3:
     119             :           case TRI6:
     120             :           case TRI7:
     121             :           case QUAD4:
     122             :           case QUADSHELL4:
     123             :           case QUAD8:
     124             :           case QUADSHELL8:
     125             :           case QUAD9:
     126             :           case QUADSHELL9:
     127       52247 :             return 6;
     128             : 
     129      218942 :           case TET4:
     130             :           case TET10:
     131             :           case TET14:
     132             :           case HEX8:
     133             :           case HEX20:
     134             :           case HEX27:
     135             :           case PRISM6:
     136             :           case PRISM15:
     137             :           case PRISM18:
     138             :           case PRISM20:
     139             :           case PRISM21:
     140             :           case PYRAMID5:
     141             :           case PYRAMID13:
     142             :           case PYRAMID14:
     143             :           case PYRAMID18:
     144             :           case C0POLYHEDRON:
     145      218942 :             return 10;
     146             : 
     147           0 :           case INVALID_ELEM:
     148           0 :             return 0;
     149             : 
     150           0 :           default:
     151           0 :             libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
     152             :           }
     153             :       }
     154             : 
     155             : 
     156             :       // Discontinuous cubic shape functions
     157             :       // expressed in the monomials.
     158     1101946 :     case THIRD:
     159             :       {
     160     1101946 :         switch (t)
     161             :           {
     162           0 :           case NODEELEM:
     163           0 :             return 1;
     164             : 
     165         588 :           case EDGE2:
     166             :           case EDGE3:
     167             :           case EDGE4:
     168         588 :             return 4;
     169             : 
     170        9144 :           case C0POLYGON:
     171             :           case TRI3:
     172             :           case TRISHELL3:
     173             :           case TRI6:
     174             :           case TRI7:
     175             :           case QUAD4:
     176             :           case QUADSHELL4:
     177             :           case QUAD8:
     178             :           case QUADSHELL8:
     179             :           case QUAD9:
     180             :           case QUADSHELL9:
     181        9144 :             return 10;
     182             : 
     183      180347 :           case TET4:
     184             :           case TET10:
     185             :           case TET14:
     186             :           case HEX8:
     187             :           case HEX20:
     188             :           case HEX27:
     189             :           case PRISM6:
     190             :           case PRISM15:
     191             :           case PRISM18:
     192             :           case PRISM20:
     193             :           case PRISM21:
     194             :           case PYRAMID5:
     195             :           case PYRAMID13:
     196             :           case PYRAMID14:
     197             :           case PYRAMID18:
     198             :           case C0POLYHEDRON:
     199      180347 :             return 20;
     200             : 
     201           0 :           case INVALID_ELEM:
     202           0 :             return 0;
     203             : 
     204           0 :           default:
     205           0 :             libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
     206             :           }
     207             :       }
     208             : 
     209             : 
     210             :       // Discontinuous quartic shape functions
     211             :       // expressed in the monomials.
     212      528906 :     case FOURTH:
     213             :       {
     214      528906 :         switch (t)
     215             :           {
     216           0 :           case NODEELEM:
     217           0 :             return 1;
     218             : 
     219         588 :           case EDGE2:
     220             :           case EDGE3:
     221         588 :             return 5;
     222             : 
     223       49880 :           case C0POLYGON:
     224             :           case TRI3:
     225             :           case TRISHELL3:
     226             :           case TRI6:
     227             :           case TRI7:
     228             :           case QUAD4:
     229             :           case QUADSHELL4:
     230             :           case QUAD8:
     231             :           case QUADSHELL8:
     232             :           case QUAD9:
     233             :           case QUADSHELL9:
     234       49880 :             return 15;
     235             : 
     236      476056 :           case TET4:
     237             :           case TET10:
     238             :           case TET14:
     239             :           case HEX8:
     240             :           case HEX20:
     241             :           case HEX27:
     242             :           case PRISM6:
     243             :           case PRISM15:
     244             :           case PRISM18:
     245             :           case PRISM20:
     246             :           case PRISM21:
     247             :           case PYRAMID5:
     248             :           case PYRAMID13:
     249             :           case PYRAMID14:
     250             :           case C0POLYHEDRON:
     251      476056 :             return 35;
     252             : 
     253           0 :           case INVALID_ELEM:
     254           0 :             return 0;
     255             : 
     256           0 :           default:
     257           0 :             libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
     258             :           }
     259             :       }
     260             : 
     261             : 
     262      263445 :     default:
     263             :       {
     264      263445 :         const unsigned int order = static_cast<unsigned int>(o);
     265      263445 :         switch (t)
     266             :           {
     267           0 :           case NODEELEM:
     268           0 :             return 1;
     269             : 
     270        1485 :           case EDGE2:
     271             :           case EDGE3:
     272        1485 :             return (order+1);
     273             : 
     274       24922 :           case C0POLYGON:
     275             :           case TRI3:
     276             :           case TRISHELL3:
     277             :           case TRI6:
     278             :           case TRI7:
     279             :           case QUAD4:
     280             :           case QUADSHELL4:
     281             :           case QUAD8:
     282             :           case QUADSHELL8:
     283             :           case QUAD9:
     284             :           case QUADSHELL9:
     285       24922 :             return (order+1)*(order+2)/2;
     286             : 
     287      237038 :           case TET4:
     288             :           case TET10:
     289             :           case TET14:
     290             :           case HEX8:
     291             :           case HEX20:
     292             :           case HEX27:
     293             :           case PRISM6:
     294             :           case PRISM15:
     295             :           case PRISM18:
     296             :           case PRISM20:
     297             :           case PRISM21:
     298             :           case PYRAMID5:
     299             :           case PYRAMID13:
     300             :           case PYRAMID14:
     301             :           case C0POLYHEDRON:
     302      237038 :             return (order+1)*(order+2)*(order+3)/6;
     303             : 
     304           0 :           case INVALID_ELEM:
     305           0 :             return 0;
     306             : 
     307           0 :           default:
     308           0 :             libmesh_error_msg("ERROR: Bad ElemType = " << Utility::enum_to_string(t) << " for " << Utility::enum_to_string(o) << " order approximation!");
     309             :           }
     310             :       }
     311             :     }
     312             : } // monomial_n_dofs()
     313             : 
     314             : 
     315             : // Anonymous namespace for local helper functions
     316             : namespace {
     317             : 
     318     1210595 : void monomial_nodal_soln(const Elem * elem,
     319             :                          const Order order,
     320             :                          const std::vector<Number> & elem_soln,
     321             :                          std::vector<Number> & nodal_soln,
     322             :                          const bool add_p_level)
     323             : {
     324     1210595 :   const unsigned int n_nodes = elem->n_nodes();
     325             : 
     326     1210595 :   const ElemType elem_type = elem->type();
     327             : 
     328     1210595 :   nodal_soln.resize(n_nodes);
     329             : 
     330     1321910 :   const Order totalorder = order + add_p_level*elem->p_level();
     331             : 
     332     1210595 :   switch (totalorder)
     333             :     {
     334             :       // Constant shape functions
     335      211474 :     case CONSTANT:
     336             :       {
     337      105737 :         libmesh_assert_equal_to (elem_soln.size(), 1);
     338             : 
     339      317211 :         std::fill(nodal_soln.begin(), nodal_soln.end(), elem_soln[0]);
     340             : 
     341      105737 :         return;
     342             :       }
     343             : 
     344             : 
     345             :       // For other orders, do interpolation at the nodes
     346             :       // explicitly.
     347        5578 :     default:
     348             :       {
     349             :         // FEType object to be passed to various FEInterface functions below.
     350        5578 :         FEType fe_type(order, MONOMIAL);
     351             : 
     352             :         const unsigned int n_sf =
     353       52769 :           FEInterface::n_shape_functions(fe_type, elem);
     354             : 
     355       11156 :         std::vector<Point> refspace_nodes;
     356       52769 :         FEBase::get_refspace_nodes(elem_type,refspace_nodes);
     357        5578 :         libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
     358        5578 :         libmesh_assert_equal_to (elem_soln.size(), n_sf);
     359             : 
     360             :         // Zero before summation
     361        5578 :         std::fill(nodal_soln.begin(), nodal_soln.end(), 0);
     362             : 
     363      586605 :         for (unsigned int n=0; n<n_nodes; n++)
     364             :           // u_i = Sum (alpha_i phi_i)
     365     2553080 :           for (unsigned int i=0; i<n_sf; i++)
     366     2225293 :             nodal_soln[n] += elem_soln[i] *
     367     2225293 :               FEInterface::shape(fe_type, elem, i, refspace_nodes[n]);
     368             : 
     369        5578 :         return;
     370             :       } // default
     371             :     } // switch
     372             : } // monomial_nodal_soln()
     373             : 
     374             : 
     375             : 
     376             : 
     377             : } // anonymous namespace
     378             : 
     379             : 
     380             : // Instantiate (side_) nodal_soln() function for every dimension
     381     1210595 : LIBMESH_FE_NODAL_SOLN(MONOMIAL, monomial_nodal_soln)
     382           0 : LIBMESH_FE_SIDE_NODAL_SOLN(MONOMIAL)
     383             : 
     384             : 
     385             : // Full specialization of n_dofs() function for every dimension
     386           0 : template <> unsigned int FE<0,MONOMIAL>::n_dofs(const ElemType t, const Order o) { return monomial_n_dofs(t, o); }
     387           0 : template <> unsigned int FE<1,MONOMIAL>::n_dofs(const ElemType t, const Order o) { return monomial_n_dofs(t, o); }
     388           0 : template <> unsigned int FE<2,MONOMIAL>::n_dofs(const ElemType t, const Order o) { return monomial_n_dofs(t, o); }
     389           0 : template <> unsigned int FE<3,MONOMIAL>::n_dofs(const ElemType t, const Order o) { return monomial_n_dofs(t, o); }
     390             : 
     391           2 : template <> unsigned int FE<0,MONOMIAL>::n_dofs(const Elem * e, const Order o) { return monomial_n_dofs(e, o); }
     392        7532 : template <> unsigned int FE<1,MONOMIAL>::n_dofs(const Elem * e, const Order o) { return monomial_n_dofs(e, o); }
     393      524424 : template <> unsigned int FE<2,MONOMIAL>::n_dofs(const Elem * e, const Order o) { return monomial_n_dofs(e, o); }
     394     2653659 : template <> unsigned int FE<3,MONOMIAL>::n_dofs(const Elem * e, const Order o) { return monomial_n_dofs(e, o); }
     395             : 
     396             : // Full specialization of n_dofs_at_node() function for every dimension.
     397             : // Monomials have no dofs at nodes, only element dofs.
     398          31 : template <> unsigned int FE<0,MONOMIAL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     399       70581 : template <> unsigned int FE<1,MONOMIAL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     400     9374058 : template <> unsigned int FE<2,MONOMIAL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     401    84795597 : template <> unsigned int FE<3,MONOMIAL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     402             : 
     403         296 : template <> unsigned int FE<0,MONOMIAL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     404       81342 : template <> unsigned int FE<1,MONOMIAL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     405     2962498 : template <> unsigned int FE<2,MONOMIAL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     406    19704043 : template <> unsigned int FE<3,MONOMIAL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     407             : 
     408             : // Full specialization of n_dofs_per_elem() function for every dimension.
     409           0 : template <> unsigned int FE<0,MONOMIAL>::n_dofs_per_elem(const ElemType t, const Order o) { return monomial_n_dofs(t, o); }
     410           0 : template <> unsigned int FE<1,MONOMIAL>::n_dofs_per_elem(const ElemType t, const Order o) { return monomial_n_dofs(t, o); }
     411           0 : template <> unsigned int FE<2,MONOMIAL>::n_dofs_per_elem(const ElemType t, const Order o) { return monomial_n_dofs(t, o); }
     412           0 : template <> unsigned int FE<3,MONOMIAL>::n_dofs_per_elem(const ElemType t, const Order o) { return monomial_n_dofs(t, o); }
     413             : 
     414         197 : template <> unsigned int FE<0,MONOMIAL>::n_dofs_per_elem(const Elem & e, const Order o) { return monomial_n_dofs(&e, o); }
     415       53558 : template <> unsigned int FE<1,MONOMIAL>::n_dofs_per_elem(const Elem & e, const Order o) { return monomial_n_dofs(&e, o); }
     416     1768353 : template <> unsigned int FE<2,MONOMIAL>::n_dofs_per_elem(const Elem & e, const Order o) { return monomial_n_dofs(&e, o); }
     417     7624503 : template <> unsigned int FE<3,MONOMIAL>::n_dofs_per_elem(const Elem & e, const Order o) { return monomial_n_dofs(&e, o); }
     418             : 
     419             : 
     420             : // Full specialization of get_continuity() function for every dimension.
     421         361 : template <> FEContinuity FE<0,MONOMIAL>::get_continuity() const { return DISCONTINUOUS; }
     422       20819 : template <> FEContinuity FE<1,MONOMIAL>::get_continuity() const { return DISCONTINUOUS; }
     423       90741 : template <> FEContinuity FE<2,MONOMIAL>::get_continuity() const { return DISCONTINUOUS; }
     424      153928 : template <> FEContinuity FE<3,MONOMIAL>::get_continuity() const { return DISCONTINUOUS; }
     425             : 
     426             : // Full specialization of is_hierarchic() function for every dimension.
     427             : // The monomials are hierarchic!
     428           0 : template <> bool FE<0,MONOMIAL>::is_hierarchic() const { return true; }
     429          60 : template <> bool FE<1,MONOMIAL>::is_hierarchic() const { return true; }
     430         318 : template <> bool FE<2,MONOMIAL>::is_hierarchic() const { return true; }
     431         790 : template <> bool FE<3,MONOMIAL>::is_hierarchic() const { return true; }
     432             : 
     433             : #ifdef LIBMESH_ENABLE_AMR
     434             : 
     435             : // Full specialization of compute_constraints() function for 2D and
     436             : // 3D only.  There are no constraints for discontinuous elements, so
     437             : // we do nothing.
     438           0 : template <> void FE<2,MONOMIAL>::compute_constraints (DofConstraints &, DofMap &, const unsigned int, const Elem *) {}
     439           0 : template <> void FE<3,MONOMIAL>::compute_constraints (DofConstraints &, DofMap &, const unsigned int, const Elem *) {}
     440             : 
     441             : #endif // #ifdef LIBMESH_ENABLE_AMR
     442             : 
     443             : // Full specialization of shapes_need_reinit() function for every dimension.
     444           0 : template <> bool FE<0,MONOMIAL>::shapes_need_reinit() const { return false; }
     445        1314 : template <> bool FE<1,MONOMIAL>::shapes_need_reinit() const { return false; }
     446      761897 : template <> bool FE<2,MONOMIAL>::shapes_need_reinit() const { return false; }
     447     2741309 : template <> bool FE<3,MONOMIAL>::shapes_need_reinit() const { return false; }
     448             : 
     449             : } // namespace libMesh

Generated by: LCOV version 1.14