LCOV - code coverage report
Current view: top level - src/fe - fe_l2_lagrange_gll.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4583 (689827) with base 9e5b0b Lines: 35 77 45.5 %
Date: 2026-10-16 15:05:09 Functions: 23 58 39.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2026 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_lagrange_gll_shape_1D.h"
      26             : #include "libmesh/fe_macro.h"
      27             : 
      28             : 
      29             : namespace libMesh
      30             : {
      31             : 
      32             : /**
      33             :  * \returns The number of degrees of freedom of the L2_LAGRANGE_GLL basis of order \p o on
      34             :  * an element of type \p t.
      35             :  *
      36             :  * The basis is a tensor product of one-dimensional bases, so it is defined only on tensor
      37             :  * product element types, where it has \f$(p+1)^d\f$ degrees of freedom. All of them belong
      38             :  * to the element, so the count doesn't depend on the number of nodes, and every supported
      39             :  * order works on a first order element.
      40             :  */
      41      648274 : unsigned int l2_lagrange_gll_n_dofs(const ElemType t, const Order o)
      42             : {
      43       56146 :   libmesh_assert_greater (o, 0);
      44             : 
      45      648274 :   const unsigned int n = static_cast<unsigned int>(o) + 1;
      46             : 
      47      648274 :   libmesh_error_msg_if(n > fe_lagrange_gll_max_points_1D,
      48             :                        "The L2_LAGRANGE_GLL basis of order " << o << " needs " << n
      49             :                        << " Gauss-Lobatto points, but QGaussLobatto tabulates at most "
      50             :                        << fe_lagrange_gll_max_points_1D << ".");
      51             : 
      52      648274 :   switch (t)
      53             :     {
      54           0 :     case NODEELEM:
      55           0 :       return 1;
      56             : 
      57       23400 :     case EDGE2:
      58             :     case EDGE3:
      59             :     case EDGE4:
      60       23400 :       return n;
      61             : 
      62       83452 :     case QUAD4:
      63             :     case QUADSHELL4:
      64             :     case QUAD8:
      65             :     case QUADSHELL8:
      66             :     case QUAD9:
      67             :     case QUADSHELL9:
      68       83452 :       return n*n;
      69             : 
      70      541422 :     case HEX8:
      71             :     case HEX20:
      72             :     case HEX27:
      73      541422 :       return n*n*n;
      74             : 
      75           0 :     case INVALID_ELEM:
      76           0 :       return 0;
      77             : 
      78           0 :     default:
      79           0 :       libmesh_error_msg("The L2_LAGRANGE_GLL basis is a tensor product and is not defined on "
      80             :                         << Utility::enum_to_string(t) << ".");
      81             :     }
      82             : }
      83             : 
      84             : 
      85      648274 : unsigned int l2_lagrange_gll_n_dofs(const Elem * e, const Order o)
      86             : {
      87       56146 :   libmesh_assert(e);
      88      648274 :   return l2_lagrange_gll_n_dofs(e->type(), o);
      89             : }
      90             : 
      91             : /**
      92             :  * Evaluates the solution at the nodes of \p elem, for output formats that write nodal
      93             :  * values.
      94             :  *
      95             :  * The interpolation points coincide with the element nodes only at orders one and two, so
      96             :  * the solution is evaluated through the shape functions at every order.
      97             :  */
      98           0 : void l2_lagrange_gll_nodal_soln(const Elem * elem,
      99             :                                 const Order order,
     100             :                                 const std::vector<Number> & elem_soln,
     101             :                                 std::vector<Number> & nodal_soln,
     102             :                                 const bool add_p_level)
     103             : {
     104           0 :   const unsigned int n_nodes = elem->n_nodes();
     105             : 
     106           0 :   nodal_soln.resize(n_nodes);
     107             : 
     108           0 :   const FEType fe_type(order, L2_LAGRANGE_GLL);
     109             : 
     110             :   const unsigned int n_sf =
     111           0 :     FEInterface::n_shape_functions(fe_type, elem, add_p_level);
     112             : 
     113           0 :   std::vector<Point> refspace_nodes;
     114           0 :   FEBase::get_refspace_nodes(elem->type(), refspace_nodes);
     115           0 :   libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
     116           0 :   libmesh_assert_equal_to (elem_soln.size(), n_sf);
     117             : 
     118           0 :   std::fill(nodal_soln.begin(), nodal_soln.end(), 0);
     119             : 
     120           0 :   for (const auto n : make_range(n_nodes))
     121           0 :     for (const auto i : make_range(n_sf))
     122           0 :       nodal_soln[n] += elem_soln[i] *
     123           0 :         FEInterface::shape(fe_type, elem, i, refspace_nodes[n], add_p_level);
     124           0 : }
     125             : 
     126           0 : LIBMESH_FE_NODAL_SOLN(L2_LAGRANGE_GLL, l2_lagrange_gll_nodal_soln)
     127           0 : LIBMESH_FE_SIDE_NODAL_SOLN(L2_LAGRANGE_GLL)
     128             : 
     129             : 
     130             : // Every degree of freedom of this basis belongs to the element
     131           0 : template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
     132           0 : template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
     133           0 : template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
     134           0 : template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
     135             : 
     136           0 : template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_gll_n_dofs(e, o); }
     137       12012 : template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_gll_n_dofs(e, o); }
     138       72064 : template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_gll_n_dofs(e, o); }
     139      530034 : template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs(const Elem * e, const Order o) { return l2_lagrange_gll_n_dofs(e, o); }
     140             : 
     141           0 : template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     142       21528 : template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     143       50232 : template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     144      131560 : template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
     145             : 
     146           0 : template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     147       14820 : template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     148       28860 : template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     149       68484 : template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs_at_node(const Elem &, const Order, const unsigned int) { return 0; }
     150             : 
     151           0 : template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
     152           0 : template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
     153           0 : template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
     154           0 : template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_lagrange_gll_n_dofs(t, o); }
     155             : 
     156           0 : template <> unsigned int FE<0,L2_LAGRANGE_GLL>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_gll_n_dofs(&e, o); }
     157       11388 : template <> unsigned int FE<1,L2_LAGRANGE_GLL>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_gll_n_dofs(&e, o); }
     158       11388 : template <> unsigned int FE<2,L2_LAGRANGE_GLL>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_gll_n_dofs(&e, o); }
     159       11388 : template <> unsigned int FE<3,L2_LAGRANGE_GLL>::n_dofs_per_elem(const Elem & e, const Order o) { return l2_lagrange_gll_n_dofs(&e, o); }
     160             : 
     161             : 
     162           0 : template <> FEContinuity FE<0,L2_LAGRANGE_GLL>::get_continuity() const { return DISCONTINUOUS; }
     163       57396 : template <> FEContinuity FE<1,L2_LAGRANGE_GLL>::get_continuity() const { return DISCONTINUOUS; }
     164       57396 : template <> FEContinuity FE<2,L2_LAGRANGE_GLL>::get_continuity() const { return DISCONTINUOUS; }
     165       57396 : template <> FEContinuity FE<3,L2_LAGRANGE_GLL>::get_continuity() const { return DISCONTINUOUS; }
     166             : 
     167             : // A nodal basis is not hierarchic
     168           0 : template <> bool FE<0,L2_LAGRANGE_GLL>::is_hierarchic() const { return false; }
     169         144 : template <> bool FE<1,L2_LAGRANGE_GLL>::is_hierarchic() const { return false; }
     170         144 : template <> bool FE<2,L2_LAGRANGE_GLL>::is_hierarchic() const { return false; }
     171         144 : template <> bool FE<3,L2_LAGRANGE_GLL>::is_hierarchic() const { return false; }
     172             : 
     173             : // The shape functions are the same on every element of a type
     174           0 : template <> bool FE<0,L2_LAGRANGE_GLL>::shapes_need_reinit() const { return false; }
     175        2460 : template <> bool FE<1,L2_LAGRANGE_GLL>::shapes_need_reinit() const { return false; }
     176        2792 : template <> bool FE<2,L2_LAGRANGE_GLL>::shapes_need_reinit() const { return false; }
     177        3126 : template <> bool FE<3,L2_LAGRANGE_GLL>::shapes_need_reinit() const { return false; }
     178             : 
     179             : // This DISCONTINUOUS basis doesn't need hanging node constraints, so these are empty
     180             : #ifdef LIBMESH_ENABLE_AMR
     181             : template <>
     182           0 : void FE<2,L2_LAGRANGE_GLL>::compute_constraints (DofConstraints &,
     183             :                                                  DofMap &,
     184             :                                                  const unsigned int,
     185             :                                                  const Elem *)
     186           0 : { }
     187             : 
     188             : template <>
     189           0 : void FE<3,L2_LAGRANGE_GLL>::compute_constraints (DofConstraints &,
     190             :                                                  DofMap &,
     191             :                                                  const unsigned int,
     192             :                                                  const Elem *)
     193           0 : { }
     194             : #endif // LIBMESH_ENABLE_AMR
     195             : 
     196             : 
     197             : } // namespace libMesh

Generated by: LCOV version 1.14