LCOV - code coverage report
Current view: top level - src/FEM - LagrangeSpace.h (source / functions) Coverage Total Hit
Test: report.info Lines: 100.0 % 5 5
Test Date: 2025-05-21 12:58:26 Functions: 26.7 % 15 4
Branches: 100.0 % 8 8

             Branch data     Line data    Source code
       1                 :             : // Class LagrangeSpace
       2                 :             : //    This is the LagrangeSpace class. It is a class representing a Lagrange space
       3                 :             : //    for finite element methods on a structured grid.
       4                 :             : 
       5                 :             : #ifndef IPPL_LAGRANGESPACE_H
       6                 :             : #define IPPL_LAGRANGESPACE_H
       7                 :             : 
       8                 :             : #include <cmath>
       9                 :             : 
      10                 :             : #include "FEM/FiniteElementSpace.h"
      11                 :             : 
      12                 :             : constexpr unsigned getLagrangeNumElementDOFs(unsigned Dim, unsigned Order) {
      13                 :             :     // needs to be constexpr pow function to work at compile time. Kokkos::pow doesn't work.
      14                 :             :     return static_cast<unsigned>(power(static_cast<int>(Order + 1), static_cast<int>(Dim)));
      15                 :             : }
      16                 :             : 
      17                 :             : namespace ippl {
      18                 :             : 
      19                 :             :     /**
      20                 :             :      * @brief A class representing a Lagrange space for finite element methods on a structured,
      21                 :             :      * rectilinear grid.
      22                 :             :      *
      23                 :             :      * @tparam T The floating point number type of the field values
      24                 :             :      * @tparam Dim The dimension of the mesh
      25                 :             :      * @tparam Order The order of the Lagrange space
      26                 :             :      * @tparam QuadratureType The type of the quadrature rule
      27                 :             :      * @tparam FieldLHS The type of the left hand side field
      28                 :             :      * @tparam FieldRHS The type of the right hand side field
      29                 :             :      */
      30                 :             :     template <typename T, unsigned Dim, unsigned Order, typename ElementType,
      31                 :             :               typename QuadratureType, typename FieldLHS, typename FieldRHS>
      32                 :             :     // requires IsQuadrature<QuadratureType>
      33                 :             :     class LagrangeSpace
      34                 :             :         : public FiniteElementSpace<T, Dim, getLagrangeNumElementDOFs(Dim, Order), ElementType,
      35                 :             :                                     QuadratureType, FieldLHS, FieldRHS> {
      36                 :             :     public:
      37                 :             :         // The number of degrees of freedom per element
      38                 :             :         static constexpr unsigned numElementDOFs = getLagrangeNumElementDOFs(Dim, Order);
      39                 :             : 
      40                 :             :         // The dimension of the mesh
      41                 :             :         static constexpr unsigned dim = FiniteElementSpace<T, Dim, numElementDOFs, ElementType,
      42                 :             :                                                            QuadratureType, FieldLHS, FieldRHS>::dim;
      43                 :             : 
      44                 :             :         // The order of the Lagrange space
      45                 :             :         static constexpr unsigned order = Order;
      46                 :             : 
      47                 :             :         // The number of mesh vertices per element
      48                 :             :         static constexpr unsigned numElementVertices =
      49                 :             :             FiniteElementSpace<T, Dim, numElementDOFs, ElementType, QuadratureType, FieldLHS,
      50                 :             :                                FieldRHS>::numElementVertices;
      51                 :             : 
      52                 :             :         // A vector with the position of the element in the mesh in each dimension
      53                 :             :         typedef typename FiniteElementSpace<T, Dim, numElementDOFs, ElementType, QuadratureType,
      54                 :             :                                             FieldLHS, FieldRHS>::indices_t indices_t;
      55                 :             : 
      56                 :             :         // A point in the global coordinate system
      57                 :             :         typedef typename FiniteElementSpace<T, Dim, numElementDOFs, ElementType, QuadratureType,
      58                 :             :                                             FieldLHS, FieldRHS>::point_t point_t;
      59                 :             : 
      60                 :             :         typedef typename FiniteElementSpace<T, Dim, numElementDOFs, ElementType, QuadratureType,
      61                 :             :                                             FieldLHS, FieldRHS>::vertex_points_t vertex_points_t;
      62                 :             : 
      63                 :             :         // Field layout type for domain decomposition info
      64                 :             :         typedef FieldLayout<Dim> Layout_t;
      65                 :             : 
      66                 :             :         // View types
      67                 :             :         typedef typename detail::ViewType<T, Dim>::view_type ViewType;
      68                 :             :         typedef typename detail::ViewType<T, Dim, Kokkos::MemoryTraits<Kokkos::Atomic>>::view_type
      69                 :             :             AtomicViewType;
      70                 :             : 
      71                 :             :         ///////////////////////////////////////////////////////////////////////
      72                 :             :         // Constructors ///////////////////////////////////////////////////////
      73                 :             :         ///////////////////////////////////////////////////////////////////////
      74                 :             : 
      75                 :             :         /**
      76                 :             :          * @brief Construct a new LagrangeSpace object
      77                 :             :          *
      78                 :             :          * @param mesh Reference to the mesh
      79                 :             :          * @param ref_element Reference to the reference element
      80                 :             :          * @param quadrature Reference to the quadrature rule
      81                 :             :          * @param layout Reference to the field layout
      82                 :             :          */
      83                 :             :         LagrangeSpace(UniformCartesian<T, Dim>& mesh, ElementType& ref_element,
      84                 :             :                       const QuadratureType& quadrature, const Layout_t& layout);
      85                 :             : 
      86                 :             :         /**
      87                 :             :          * @brief Construct a new LagrangeSpace object (without layout)
      88                 :             :          * This constructor is made to work with the default constructor in
      89                 :             :          * FEMPoissonSolver.h such that it is compatible with alpine.
      90                 :             :          *
      91                 :             :          * @param mesh Reference to the mesh
      92                 :             :          * @param ref_element Reference to the reference element
      93                 :             :          * @param quadrature Reference to the quadrature rule
      94                 :             :          */
      95                 :             :         LagrangeSpace(UniformCartesian<T, Dim>& mesh, ElementType& ref_element,
      96                 :             :                       const QuadratureType& quadrature);
      97                 :             : 
      98                 :             :         /**
      99                 :             :          * @brief Initialize a LagrangeSpace object created with the default constructor
     100                 :             :          *
     101                 :             :          * @param mesh Reference to the mesh
     102                 :             :          * @param layout Reference to the field layout
     103                 :             :          */
     104                 :             :         void initialize(UniformCartesian<T, Dim>& mesh, const Layout_t& layout);
     105                 :             : 
     106                 :             :         ///////////////////////////////////////////////////////////////////////
     107                 :             :         /**
     108                 :             :          * @brief Initialize a Kokkos view containing the element indices.
     109                 :             :          * This distributes the elements among MPI ranks.
     110                 :             :          */
     111                 :             :         void initializeElementIndices(const Layout_t& layout);
     112                 :             : 
     113                 :             :         /// Degree of Freedom operations //////////////////////////////////////
     114                 :             :         ///////////////////////////////////////////////////////////////////////
     115                 :             : 
     116                 :             :         /**
     117                 :             :          * @brief Get the number of global degrees of freedom in the space
     118                 :             :          *
     119                 :             :          * @return size_t - unsigned integer number of global degrees of freedom
     120                 :             :          */
     121                 :             :         KOKKOS_FUNCTION size_t numGlobalDOFs() const override;
     122                 :             : 
     123                 :             :         /**
     124                 :             :          * @brief Get the elements local DOF from the element index and global DOF
     125                 :             :          * index
     126                 :             :          *
     127                 :             :          * @param elementIndex size_t - The index of the element
     128                 :             :          * @param globalDOFIndex size_t - The global DOF index
     129                 :             :          *
     130                 :             :          * @return size_t - The local DOF index
     131                 :             :          */
     132                 :             :         KOKKOS_FUNCTION size_t getLocalDOFIndex(const size_t& elementIndex,
     133                 :             :                                  const size_t& globalDOFIndex) const override;
     134                 :             : 
     135                 :             :         /**
     136                 :             :          * @brief Get the global DOF index from the element index and local DOF
     137                 :             :          *
     138                 :             :          * @param elementIndex size_t - The index of the element
     139                 :             :          * @param localDOFIndex size_t - The local DOF index
     140                 :             :          *
     141                 :             :          * @return size_t - The global DOF index
     142                 :             :          */
     143                 :             :         KOKKOS_FUNCTION size_t getGlobalDOFIndex(const size_t& elementIndex,
     144                 :             :                                                  const size_t& localDOFIndex) const override;
     145                 :             : 
     146                 :             :         /**
     147                 :             :          * @brief Get the local DOF indices (vector of local DOF indices)
     148                 :             :          * They are independent of the specific element because it only depends on
     149                 :             :          * the reference element type
     150                 :             :          *
     151                 :             :          * @return Vector<size_t, NumElementDOFs> - The local DOF indices
     152                 :             :          */
     153                 :             :         KOKKOS_FUNCTION Vector<size_t, numElementDOFs> getLocalDOFIndices() const override;
     154                 :             : 
     155                 :             :         /**
     156                 :             :          * @brief Get the global DOF indices (vector of global DOF indices) of an element
     157                 :             :          *
     158                 :             :          * @param elementIndex size_t - The index of the element
     159                 :             :          *
     160                 :             :          * @return Vector<size_t, NumElementDOFs> - The global DOF indices
     161                 :             :          */
     162                 :             :         KOKKOS_FUNCTION Vector<size_t, numElementDOFs> getGlobalDOFIndices(
     163                 :             :             const size_t& element_index) const override;
     164                 :             : 
     165                 :             :         ///////////////////////////////////////////////////////////////////////
     166                 :             :         /// Basis functions and gradients /////////////////////////////////////
     167                 :             :         ///////////////////////////////////////////////////////////////////////
     168                 :             : 
     169                 :             :         /**
     170                 :             :          * @brief Evaluate the shape function of a local degree of freedom at a given point in the
     171                 :             :          * reference element
     172                 :             :          *
     173                 :             :          * @param localDOF size_t - The local degree of freedom index
     174                 :             :          * @param localPoint point_t (Vector<T, Dim>) - The point in the reference element
     175                 :             :          *
     176                 :             :          * @return T - The value of the shape function at the given point
     177                 :             :          */
     178                 :             :         KOKKOS_FUNCTION T evaluateRefElementShapeFunction(const size_t& localDOF,
     179                 :             :                                                           const point_t& localPoint) const override;
     180                 :             : 
     181                 :             :         /**
     182                 :             :          * @brief Evaluate the gradient of the shape function of a local degree of freedom at a
     183                 :             :          * given point in the reference element
     184                 :             :          *
     185                 :             :          * @param localDOF size_t - The local degree of freedom index
     186                 :             :          * @param localPoint point_t (Vector<T, Dim>) - The point in the reference element
     187                 :             :          *
     188                 :             :          * @return point_t (Vector<T, Dim>) - The gradient of the shape function at the given
     189                 :             :          * point
     190                 :             :          */
     191                 :             :         KOKKOS_FUNCTION point_t evaluateRefElementShapeFunctionGradient(
     192                 :             :             const size_t& localDOF, const point_t& localPoint) const override;
     193                 :             : 
     194                 :             :         ///////////////////////////////////////////////////////////////////////
     195                 :             :         /// Assembly operations ///////////////////////////////////////////////
     196                 :             :         ///////////////////////////////////////////////////////////////////////
     197                 :             : 
     198                 :             :         /**
     199                 :             :          * @brief Assemble the left stiffness matrix A of the system Ax = b
     200                 :             :          *
     201                 :             :          * @param field The field to assemble the matrix for
     202                 :             :          * @param evalFunction The lambda telling us the form which A takes
     203                 :             :          *
     204                 :             :          * @return FieldLHS - The LHS field containing A*x
     205                 :             :          */
     206                 :             :         template <typename F>
     207                 :             :         FieldLHS evaluateAx(FieldLHS& field, F& evalFunction) const;
     208                 :             : 
     209                 :             :         /**
     210                 :             :          * @brief Assemble the left stiffness matrix A of the system 
     211                 :             :          * but only for the boundary values, so that they can be 
     212                 :             :          * subtracted from the RHS for treatment of Dirichlet BCs
     213                 :             :          *
     214                 :             :          * @param field The field to assemble the matrix for
     215                 :             :          * @param evalFunction The lambda telling us the form which A takes
     216                 :             :          *
     217                 :             :          * @return FieldLHS - The LHS field containing A*x
     218                 :             :          */
     219                 :             :         template <typename F>
     220                 :             :         FieldLHS evaluateAx_lift(FieldLHS& field, F& evalFunction) const;
     221                 :             : 
     222                 :             :         /**
     223                 :             :          * @brief Assemble the load vector b of the system Ax = b
     224                 :             :          *
     225                 :             :          * @param rhs_field The field to set with the load vector
     226                 :             :          *
     227                 :             :          * @return FieldRHS - The RHS field containing b
     228                 :             :          */
     229                 :             :         void evaluateLoadVector(FieldRHS& field) const override;
     230                 :             : 
     231                 :             :         ///////////////////////////////////////////////////////////////////////
     232                 :             :         /// Error norm computations ///////////////////////////////////////////
     233                 :             :         ///////////////////////////////////////////////////////////////////////
     234                 :             : 
     235                 :             :         /**
     236                 :             :          * @brief Given two fields, compute the L2 norm error
     237                 :             :          *
     238                 :             :          * @param u_h The numerical solution found using FEM
     239                 :             :          * @param u_sol The analytical solution (functor)
     240                 :             :          *
     241                 :             :          * @return error - The error ||u_h - u_sol||_L2
     242                 :             :          */
     243                 :             :         template <typename F>
     244                 :             :         T computeErrorL2(const FieldLHS& u_h, const F& u_sol) const;
     245                 :             : 
     246                 :             :         /**
     247                 :             :          * @brief Given a field, compute the average
     248                 :             :          *
     249                 :             :          * @param u_h The numerical solution found using FEM
     250                 :             :          *
     251                 :             :          * @return avg The average of the field on the domain
     252                 :             :          */
     253                 :             :         T computeAvg(const FieldLHS& u_h) const;
     254                 :             : 
     255                 :             :     private:
     256                 :             :         /**
     257                 :             :          * @brief Check if a DOF is on the boundary of the mesh
     258                 :             :          *
     259                 :             :          * @param ndindex The NDIndex of the global DOF
     260                 :             :          *
     261                 :             :          * @return true - If the DOF is on the boundary
     262                 :             :          * @return false - If the DOF is not on the boundary
     263                 :             :          */
     264                 :         216 :         KOKKOS_FUNCTION bool isDOFOnBoundary(const indices_t& ndindex) const {
     265         [ +  + ]:         388 :             for (size_t d = 0; d < Dim; ++d) {
     266   [ +  +  +  +  :         216 :                 if (ndindex[d] <= 0 || ndindex[d] >= this->nr_m[d] - 1) {
                   +  + ]
     267                 :          44 :                     return true;
     268                 :             :                 }
     269                 :             :             }
     270                 :         172 :             return false;
     271                 :             :         }
     272                 :             : 
     273                 :             :         Kokkos::View<size_t*> elementIndices;
     274                 :             :     };
     275                 :             : 
     276                 :             : }  // namespace ippl
     277                 :             : 
     278                 :             : #include "FEM/LagrangeSpace.hpp"
     279                 :             : 
     280                 :             : #endif
        

Generated by: LCOV version 2.0-1