LCOV - code coverage report
Current view: top level - src/fe - fe_l2_hierarchic.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 59 89 66.3 %
Date: 2025-08-19 19:27:09 Functions: 29 58 50.0 %
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/elem.h"
      22             : #include "libmesh/enum_to_string.h"
      23             : #include "libmesh/fe.h"
      24             : #include "libmesh/fe_interface.h"
      25             : #include "libmesh/fe_macro.h"
      26             : 
      27             : namespace libMesh
      28             : {
      29             : 
      30             : // ------------------------------------------------------------
      31             : // Hierarchic-specific implementations
      32             : 
      33             : // Anonymous namespace for local helper functions
      34             : namespace {
      35             : 
      36      113899 : void l2_hierarchic_nodal_soln(const Elem * elem,
      37             :                               const Order order,
      38             :                               const std::vector<Number> & elem_soln,
      39             :                               std::vector<Number> & nodal_soln,
      40             :                               const bool add_p_level)
      41             : {
      42      113899 :   const unsigned int n_nodes = elem->n_nodes();
      43             : 
      44      113899 :   const ElemType elem_type = elem->type();
      45             : 
      46      113899 :   nodal_soln.resize(n_nodes);
      47             : 
      48      123463 :   const Order totalorder = order + add_p_level*elem->p_level();
      49             : 
      50             :   // FEType object to be passed to various FEInterface functions below.
      51        9564 :   FEType fe_type(order, L2_HIERARCHIC);
      52             : 
      53      113899 :   switch (totalorder)
      54             :     {
      55             :       // Constant shape functions
      56           0 :     case CONSTANT:
      57             :       {
      58           0 :         libmesh_assert_equal_to (elem_soln.size(), 1);
      59             : 
      60           0 :         std::fill(nodal_soln.begin(), nodal_soln.end(), elem_soln[0]);
      61             : 
      62           0 :         return;
      63             :       }
      64             : 
      65             : 
      66             :       // For other orders do interpolation at the nodes
      67             :       // explicitly.
      68      113899 :     default:
      69             :       {
      70             :         const unsigned int n_sf =
      71      113899 :           FEInterface::n_shape_functions(fe_type, elem);
      72             : 
      73       19128 :         std::vector<Point> refspace_nodes;
      74      113899 :         FEBase::get_refspace_nodes(elem_type,refspace_nodes);
      75        9564 :         libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
      76        9564 :         libmesh_assert_equal_to (elem_soln.size(), n_sf);
      77             : 
      78             :         // Zero before summation
      79        9564 :         std::fill(nodal_soln.begin(), nodal_soln.end(), 0);
      80             : 
      81     1143675 :         for (unsigned int n=0; n<n_nodes; n++)
      82             :           // u_i = Sum (alpha_i phi_i)
      83     8122216 :           for (unsigned int i=0; i<n_sf; i++)
      84     7720554 :             nodal_soln[n] += elem_soln[i] *
      85     7720554 :               FEInterface::shape(fe_type, elem, i, refspace_nodes[n]);
      86             : 
      87        9564 :         return;
      88             :       }
      89             :     }
      90             : } // l2_hierarchic_nodal_soln()
      91             : 
      92             : 
      93             : 
      94    10966709 : unsigned int l2_hierarchic_n_dofs(const ElemType t, const Order o)
      95             : {
      96     1129554 :   libmesh_assert_greater (o, 0);
      97    10966709 :   switch (t)
      98             :     {
      99           0 :     case NODEELEM:
     100           0 :       return 1;
     101         825 :     case EDGE2:
     102             :     case EDGE3:
     103        7425 :       return (o+1);
     104       26173 :     case QUAD4:
     105             :     case QUADSHELL4:
     106             :     case QUAD8:
     107             :     case QUADSHELL8:
     108             :     case QUAD9:
     109             :     case QUADSHELL9:
     110      209573 :       return ((o+1)*(o+1));
     111       67057 :     case HEX8:
     112             :     case HEX20:
     113             :     case HEX27:
     114      680272 :       return ((o+1)*(o+1)*(o+1));
     115       31824 :     case PRISM6:
     116             :     case PRISM15:
     117             :     case PRISM18:
     118             :     case PRISM20:
     119             :     case PRISM21:
     120      380070 :       return ((o+1)*(o+1)*(o+2)/2);
     121      509764 :     case TRI3:
     122             :     case TRI6:
     123             :     case TRI7:
     124     4722240 :       return ((o+1)*(o+2)/2);
     125      493911 :     case TET4:
     126             :     case TET10:
     127             :     case TET14:
     128     5398712 :       return ((o+1)*(o+2)*(o+3)/6);
     129           0 :     case INVALID_ELEM:
     130           0 :       return 0;
     131           0 :     default:
     132           0 :       libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for L2_HIERARCHIC FE family!");
     133             :     }
     134             : } // l2_hierarchic_n_dofs()
     135             : 
     136             : 
     137             : 
     138    10075921 : unsigned int l2_hierarchic_n_dofs(const Elem * e, const Order o)
     139             : {
     140     1129554 :   libmesh_assert(e);
     141    10966709 :   return l2_hierarchic_n_dofs(e->type(), o);
     142             : }
     143             : 
     144             : 
     145             : } // anonymous namespace
     146             : 
     147             : 
     148             : // Instantiate (side_) nodal_soln() function for every dimension
     149      113899 : LIBMESH_FE_NODAL_SOLN(L2_HIERARCHIC, l2_hierarchic_nodal_soln)
     150           0 : LIBMESH_FE_SIDE_NODAL_SOLN(L2_HIERARCHIC)
     151             : 
     152             : 
     153             : // Full specialization of n_dofs() function for every dimension
     154           0 : template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
     155           0 : template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
     156           0 : template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
     157           0 : template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
     158             : 
     159           0 : template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs(const Elem * e, const Order o) { return l2_hierarchic_n_dofs(e, o); }
     160        4140 : template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs(const Elem * e, const Order o) { return l2_hierarchic_n_dofs(e, o); }
     161     3636948 : template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs(const Elem * e, const Order o) { return l2_hierarchic_n_dofs(e, o); }
     162     4911494 : template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs(const Elem * e, const Order o) { return l2_hierarchic_n_dofs(e, o); }
     163             : 
     164             : // Full specialization of n_dofs_at_node() function for every dimension.
     165             : // Discontinuous L2 elements only have interior nodes
     166           0 : template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     167        5382 : template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     168     7553360 : template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     169    11655668 : template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     170             : 
     171           0 : template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     172        3969 : template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     173     1293155 : template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     174     2845415 : template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     175             : 
     176             : // Full specialization of n_dofs_per_elem() function for every dimension.
     177           0 : template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
     178           0 : template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
     179           0 : template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
     180           0 : template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
     181             : 
     182           0 : template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_hierarchic_n_dofs(&e, o); }
     183        3285 : template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_hierarchic_n_dofs(&e, o); }
     184     1294865 : template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_hierarchic_n_dofs(&e, o); }
     185     1115977 : template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_hierarchic_n_dofs(&e, o); }
     186             : 
     187             : // L2 Hierarchic FEMs are C^0 continuous
     188           0 : template <> FEContinuity FE<0,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; }
     189       16575 : template <> FEContinuity FE<1,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; }
     190       44039 : template <> FEContinuity FE<2,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; }
     191       82596 : template <> FEContinuity FE<3,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; }
     192             : 
     193             : // L2 Hierarchic FEMs are hierarchic (duh!)
     194           0 : template <> bool FE<0,L2_HIERARCHIC>::is_hierarchic() const { return true; }
     195          60 : template <> bool FE<1,L2_HIERARCHIC>::is_hierarchic() const { return true; }
     196         236 : template <> bool FE<2,L2_HIERARCHIC>::is_hierarchic() const { return true; }
     197         594 : template <> bool FE<3,L2_HIERARCHIC>::is_hierarchic() const { return true; }
     198             : 
     199             : #ifdef LIBMESH_ENABLE_AMR
     200             : // compute_constraints() is a NOOP for DISCONTINUOUS FE's
     201             : template <>
     202           0 : void FE<2,L2_HIERARCHIC>::compute_constraints (DofConstraints &,
     203             :                                                DofMap &,
     204             :                                                const unsigned int,
     205             :                                                const Elem *)
     206           0 : { }
     207             : 
     208             : template <>
     209           0 : void FE<3,L2_HIERARCHIC>::compute_constraints (DofConstraints &,
     210             :                                                DofMap &,
     211             :                                                const unsigned int,
     212             :                                                const Elem *)
     213           0 : { }
     214             : #endif // #ifdef LIBMESH_ENABLE_AMR
     215             : 
     216             : // L2-Hierarchic FEM shapes need reinit
     217           0 : template <> bool FE<0,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
     218         720 : template <> bool FE<1,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
     219     2205512 : template <> bool FE<2,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
     220     2353698 : template <> bool FE<3,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
     221             : 
     222             : } // namespace libMesh

Generated by: LCOV version 1.14