LCOV - code coverage report
Current view: top level - include/kokkos/base - KokkosAssembly.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 329044 Lines: 123 131 93.9 %
Date: 2026-08-03 21:12:22 Functions: 28 30 93.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://www.mooseframework.org
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "KokkosTypes.h"
      13             : 
      14             : #include "MooseMesh.h"
      15             : 
      16             : #include "libmesh/elem_range.h"
      17             : #include "libmesh/fe_base.h"
      18             : #include "libmesh/fe_type.h"
      19             : 
      20             : class FEProblemBase;
      21             : 
      22             : namespace Moose::Kokkos
      23             : {
      24             : 
      25             : /**
      26             :  * The Kokkos assembly class
      27             :  */
      28             : class Assembly : public MeshHolder
      29             : {
      30             : public:
      31             :   /**
      32             :    * Constructor
      33             :    * @param problem The MOOSE problem
      34             :    */
      35             :   Assembly(FEProblemBase & problem);
      36             :   /**
      37             :    * Initialize assembly
      38             :    */
      39             :   void init();
      40             : 
      41             : #ifdef MOOSE_KOKKOS_SCOPE
      42             :   /**
      43             :    * Get the FE type ID
      44             :    * @param type The libMesh FEType object
      45             :    * @returns The FE type ID
      46             :    */
      47        4324 :   unsigned int getFETypeID(FEType type) const { return libmesh_map_find(_fe_type_map, type); }
      48             :   /**
      49             :    * Get the mesh dimension
      50             :    * @returns The mesh dimension
      51             :    */
      52     8028345 :   KOKKOS_FUNCTION unsigned int getDimension() const { return _dimension; }
      53             :   /**
      54             :    * Get the maximum number of quadrature points per element in the current partition
      55             :    * @returns The maximum number of quadrature points per element
      56             :    */
      57      144746 :   KOKKOS_FUNCTION unsigned int getMaxQpsPerElem() const { return _max_qps_per_elem; }
      58             :   /**
      59             :    * Get the total number of elemental quadrature points in a subdomain
      60             :    * @param subdomain The contiguous subdomain ID
      61             :    * @returns The number of quadrature points
      62             :    */
      63       16505 :   KOKKOS_FUNCTION dof_id_type getNumQps(ContiguousSubdomainID subdomain) const
      64             :   {
      65       16505 :     return _n_subdomain_qps[subdomain];
      66             :   }
      67             :   /**
      68             :    * Get the number of quadrature points of an element
      69             :    * @param info The element information object
      70             :    * @returns The number of quadrature points
      71             :    */
      72    79270524 :   KOKKOS_FUNCTION unsigned int getNumQps(ElementInfo info) const { return _n_qps[info.id]; }
      73             :   /**
      74             :    * Get the total number of facial quadrature points in a subdomain
      75             :    * NOTE: This number does not represent the real number of facial quadrature points but only
      76             :    * the facial quadrature points that need global caching, such as face material properties
      77             :    * @param subdomain The contiguous subdomain ID
      78             :    * @returns The number of quadrature points
      79             :    */
      80        3091 :   KOKKOS_FUNCTION dof_id_type getNumFaceQps(ContiguousSubdomainID subdomain) const
      81             :   {
      82        3091 :     return _n_subdomain_qps_face[subdomain];
      83             :   }
      84             :   /**
      85             :    * Get the number of quadrature points of a side of an element
      86             :    * @param info The element information object
      87             :    * @param side The side index
      88             :    * @returns The number of quadrature points
      89             :    */
      90      224910 :   KOKKOS_FUNCTION unsigned int getNumFaceQps(ElementInfo info, unsigned int side) const
      91             :   {
      92      224910 :     return _n_qps_face(side, info.id);
      93             :   }
      94             :   /**
      95             :    * Get the starting offset of quadrature points of an element into the global quadrature point
      96             :    * index
      97             :    * @param info The element information object
      98             :    * @returns The starting offset
      99             :    */
     100   280569189 :   KOKKOS_FUNCTION dof_id_type getQpOffset(ElementInfo info) const { return _qp_offset[info.id]; }
     101             :   /**
     102             :    * Get the starting offset of quadrature points of a side of an element into the global quadrature
     103             :    * point index
     104             :    * @param info The element information object
     105             :    * @param side The side index
     106             :    * @returns The starting offset
     107             :    */
     108      224910 :   KOKKOS_FUNCTION dof_id_type getQpFaceOffset(ElementInfo info, unsigned int side) const
     109             :   {
     110      224910 :     return _qp_offset_face(side, info.id);
     111             :   }
     112             :   /**
     113             :    * Get the index of a side of an element into the element-constant face material property data
     114             :    * @param info The element information object
     115             :    * @param side The side index
     116             :    * @returns The index
     117             :    */
     118      224910 :   KOKKOS_FUNCTION dof_id_type getElemFacePropertyIndex(ElementInfo info, unsigned int side) const
     119             :   {
     120      224910 :     return _elem_face_property_idx(side, info.id);
     121             :   }
     122             :   /**
     123             :    * Get the size of element-constant face material property data storage of a subdomain
     124             :    * @param subdomain The contiguous subdomain ID
     125             :    * @returns The storage size
     126             :    */
     127         170 :   KOKKOS_FUNCTION dof_id_type getElemFacePropertySize(ContiguousSubdomainID subdomain) const
     128             :   {
     129         170 :     return _n_elem_face_properties[subdomain];
     130             :   }
     131             :   /**
     132             :    * Get the number of DOFs of a FE type for an element type
     133             :    * @param elem_type The element type ID
     134             :    * @param fe_type The FE type ID
     135             :    * @returns The number of DOFs
     136             :    */
     137    87332529 :   KOKKOS_FUNCTION unsigned int getNumDofs(unsigned int elem_type, unsigned int fe_type) const
     138             :   {
     139    87332529 :     return _n_dofs(elem_type, fe_type);
     140             :   }
     141             :   /**
     142             :    * Get the shape functions of a FE type for an element type and subdomain
     143             :    * @param subdomain The contiguous subdomain ID
     144             :    * @param elem_type The element type ID
     145             :    * @param fe_type The FE type ID
     146             :    * @returns The shape functions at quadrature points
     147             :    */
     148             :   KOKKOS_FUNCTION const auto &
     149   188328414 :   getPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
     150             :   {
     151   188328414 :     return _phi(subdomain, elem_type, fe_type);
     152             :   }
     153             :   /**
     154             :    * Get the face shape functions of a FE type for an element type and subdomain
     155             :    * @param subdomain The contiguous subdomain ID
     156             :    * @param elem_type The element type ID
     157             :    * @param fe_type The FE type ID
     158             :    * @returns The shape functions of all sides at quadrature points
     159             :    */
     160             :   KOKKOS_FUNCTION const auto &
     161     1343406 :   getPhiFace(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
     162             :   {
     163     1343406 :     return _phi_face(subdomain, elem_type, fe_type);
     164             :   }
     165             :   /**
     166             :    * Get the gradient of shape functions of a FE type for an element type and subdomain
     167             :    * @param subdomain The contiguous subdomain ID
     168             :    * @param elem_type The element type ID
     169             :    * @param fe_type The FE type ID
     170             :    * @returns The gradient of shape functions at quadrature points
     171             :    */
     172             :   KOKKOS_FUNCTION const auto &
     173   168366322 :   getGradPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
     174             :   {
     175   168366322 :     return _grad_phi(subdomain, elem_type, fe_type);
     176             :   }
     177             :   /**
     178             :    * Get the gradient of face shape functions of a FE type for an element type and subdomain
     179             :    * @param subdomain The contiguous subdomain ID
     180             :    * @param elem_type The element type ID
     181             :    * @param fe_type The FE type ID
     182             :    * @returns The gradient of shape functions of all sides at quadrature points
     183             :    */
     184           0 :   KOKKOS_FUNCTION const auto & getGradPhiFace(ContiguousSubdomainID subdomain,
     185             :                                               unsigned int elem_type,
     186             :                                               unsigned int fe_type) const
     187             :   {
     188           0 :     return _grad_phi_face(subdomain, elem_type, fe_type);
     189             :   }
     190             :   /**
     191             :    * Get the vector shape functions of a FE type for an element type and subdomain
     192             :    * @param subdomain The contiguous subdomain ID
     193             :    * @param elem_type The element type ID
     194             :    * @param fe_type The FE type ID
     195             :    * @returns The vector shape functions at quadrature points
     196             :    */
     197             :   KOKKOS_FUNCTION const auto &
     198    33043389 :   getVectorPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
     199             :   {
     200    33043389 :     return _vector_phi(subdomain, elem_type, fe_type);
     201             :   }
     202             :   /**
     203             :    * Get the face vector shape functions of a FE type for an element type and subdomain
     204             :    * @param subdomain The contiguous subdomain ID
     205             :    * @param elem_type The element type ID
     206             :    * @param fe_type The FE type ID
     207             :    * @returns The vector shape functions of all sides at quadrature points
     208             :    */
     209      599040 :   KOKKOS_FUNCTION const auto & getVectorPhiFace(ContiguousSubdomainID subdomain,
     210             :                                                 unsigned int elem_type,
     211             :                                                 unsigned int fe_type) const
     212             :   {
     213      599040 :     return _vector_phi_face(subdomain, elem_type, fe_type);
     214             :   }
     215             :   /**
     216             :    * Get the gradient of vector shape functions of a FE type for an element type and subdomain
     217             :    * @param subdomain The contiguous subdomain ID
     218             :    * @param elem_type The element type ID
     219             :    * @param fe_type The FE type ID
     220             :    * @returns The gradient of vector shape functions at quadrature points
     221             :    */
     222    47191941 :   KOKKOS_FUNCTION const auto & getVectorGradPhi(ContiguousSubdomainID subdomain,
     223             :                                                 unsigned int elem_type,
     224             :                                                 unsigned int fe_type) const
     225             :   {
     226    47191941 :     return _vector_grad_phi(subdomain, elem_type, fe_type);
     227             :   }
     228             :   /**
     229             :    * Get the gradient of face vector shape functions of a FE type for an element type and subdomain
     230             :    * @param subdomain The contiguous subdomain ID
     231             :    * @param elem_type The element type ID
     232             :    * @param fe_type The FE type ID
     233             :    * @returns The gradient of vector shape functions of all sides at quadrature points
     234             :    */
     235           0 :   KOKKOS_FUNCTION const auto & getVectorGradPhiFace(ContiguousSubdomainID subdomain,
     236             :                                                     unsigned int elem_type,
     237             :                                                     unsigned int fe_type) const
     238             :   {
     239           0 :     return _vector_grad_phi_face(subdomain, elem_type, fe_type);
     240             :   }
     241             :   /**
     242             :    * Get whether a cached FE type is vector-valued
     243             :    * @param fe_type The FE type ID
     244             :    * @returns Whether the FE type is vector-valued
     245             :    */
     246             :   KOKKOS_FUNCTION bool isVectorFEType(unsigned int fe_type) const
     247             :   {
     248             :     return _is_vector_fe_type[fe_type];
     249             :   }
     250             :   /**
     251             :    * Get the inverse of Jacobian matrix of an element quadrature point
     252             :    * @param info The element information object
     253             :    * @param qp The local quadrature point index
     254             :    * @returns The inverse of Jacobian matrix
     255             :    */
     256   114430047 :   KOKKOS_FUNCTION Real33 getJacobian(ElementInfo info, unsigned int qp) const
     257             :   {
     258   114430047 :     return _jacobian[info.subdomain][getQpOffset(info) + qp];
     259             :   }
     260             :   /**
     261             :    * Get the transformed Jacobian weight of an element quadrature point
     262             :    * @param info The element information object
     263             :    * @param qp The local quadrature point index
     264             :    * @returns The inverse of Jacobian matrix
     265             :    */
     266    43767516 :   KOKKOS_FUNCTION Real getJxW(ElementInfo info, unsigned int qp) const
     267             :   {
     268    43767516 :     return _jxw[info.subdomain][getQpOffset(info) + qp];
     269             :   }
     270             :   /**
     271             :    * Get the coordinate of an element quadrature point
     272             :    * @param info The element information object
     273             :    * @param qp The local quadrature point index
     274             :    * @returns The inverse of Jacobian matrix
     275             :    */
     276    43767516 :   KOKKOS_FUNCTION Real3 getQPoint(ElementInfo info, unsigned int qp) const
     277             :   {
     278    43767516 :     return _xyz[info.subdomain][getQpOffset(info) + qp];
     279             :   }
     280             : 
     281             :   /**
     282             :    * Get the coordinate transform factor for a point in a subdomain
     283             :    * @param subdomain The contiguous subdomain ID
     284             :    * @param point The point coordinate
     285             :    * @returns The coordinate transform factor
     286             :    */
     287             :   KOKKOS_FUNCTION Real coordTransformFactor(const ContiguousSubdomainID subdomain,
     288             :                                             const Real3 point) const;
     289             :   /**
     290             :    * Compute physical transformation data for an element
     291             :    * @param info The element information object
     292             :    * @param qp The local quadrature point index
     293             :    * @param jacobian The pointer to store the inverse of Jacobian matrix
     294             :    * @param JxW The pointer to store transformed Jacobian weight
     295             :    * @param q_points The pointer to store physical quadrature point coordinate
     296             :    */
     297             :   KOKKOS_FUNCTION void computePhysicalMap(const ElementInfo info,
     298             :                                           const unsigned int qp,
     299             :                                           Real33 * const jacobian,
     300             :                                           Real * const JxW,
     301             :                                           Real3 * const q_points) const;
     302             :   /**
     303             :    * Compute physical transformation data for a side
     304             :    * @param info The element information object
     305             :    * @param side The side index
     306             :    * @param qp The local quadrature point index
     307             :    * @param jacobian The pointer to store the inverse of Jacobian matrix
     308             :    * @param JxW The pointer to store transformed Jacobian weight
     309             :    * @param q_points The pointer to store physical quadrature point coordinate
     310             :    * @param normal The pointer to store normal vector
     311             :    */
     312             :   KOKKOS_FUNCTION void computePhysicalMap(const ElementInfo info,
     313             :                                           const unsigned int side,
     314             :                                           const unsigned int qp,
     315             :                                           Real33 * const jacobian,
     316             :                                           Real * const JxW,
     317             :                                           Real3 * const q_points,
     318             :                                           Real3 * const normal) const;
     319             : 
     320             :   /**
     321             :    * Kokkos function for caching physical maps on element quadrature points
     322             :    */
     323             :   KOKKOS_FUNCTION void operator()(const ThreadID tid) const;
     324             : 
     325             :   /**
     326             :    * Get the list of boundaries to cache face material properties
     327             :    * @returns The list of boundaries
     328             :    */
     329        1767 :   const auto & getMaterialBoundaries() const { return _material_boundaries; }
     330             : #endif
     331             : 
     332             : private:
     333             :   /**
     334             :    * Initialize quadrature data
     335             :    */
     336             :   void initQuadrature();
     337             :   /**
     338             :    * Initialize shape data
     339             :    */
     340             :   void initShape();
     341             :   /**
     342             :    * Cache physical maps on element quadrature points
     343             :    */
     344             :   void cachePhysicalMap();
     345             : 
     346             :   /**
     347             :    * Reference of the MOOSE problem
     348             :    */
     349             :   FEProblemBase & _problem;
     350             :   /**
     351             :    * Reference of the MOOSE mesh
     352             :    */
     353             :   MooseMesh & _mesh;
     354             :   /**
     355             :    * FE type ID map
     356             :    */
     357             :   std::map<FEType, unsigned int> _fe_type_map;
     358             : 
     359             :   /**
     360             :    * Mesh dimension
     361             :    */
     362             :   const unsigned int _dimension;
     363             :   /**
     364             :    * Coordinate system type of each subdomain
     365             :    */
     366             :   Array<Moose::CoordinateSystemType> _coord_type;
     367             :   /**
     368             :    * Radial coordinate index in cylindrical coordinate system
     369             :    */
     370             :   unsigned int _rz_radial_coord = libMesh::invalid_uint;
     371             :   /**
     372             :    * General axisymmetric axis of each subdomain in cylindrical coordinate system
     373             :    */
     374             :   Array<Pair<Real3, Real3>> _rz_axis;
     375             : 
     376             :   /**
     377             :    * Starting offset into the global quadrature point index
     378             :    * NOTE: The global quadrature point index is subdomain-wise
     379             :    */
     380             :   ///@{
     381             :   Array<dof_id_type> _qp_offset;
     382             :   Array2D<dof_id_type> _qp_offset_face;
     383             :   ///@}
     384             :   /**
     385             :    * Number of quadrature points
     386             :    */
     387             :   ///@{
     388             :   Array<unsigned int> _n_qps;
     389             :   Array2D<unsigned int> _n_qps_face;
     390             : 
     391             :   unsigned int _max_qps_per_elem = 0;
     392             : 
     393             :   Array<dof_id_type> _n_subdomain_qps;
     394             :   Array<dof_id_type> _n_subdomain_qps_face;
     395             :   ///@}
     396             :   /**
     397             :    * Index into the element-constant face material property data
     398             :    */
     399             :   ///@{
     400             :   Array2D<dof_id_type> _elem_face_property_idx;
     401             :   Array<dof_id_type> _n_elem_face_properties;
     402             :   ///@}
     403             :   /**
     404             :    * Quadrature points and weights for reference elements
     405             :    */
     406             :   ///@{
     407             :   Array2D<Array<Real3>> _q_points;
     408             :   Array2D<Array<Array<Real3>>> _q_points_face;
     409             :   Array2D<Array<Real>> _weights;
     410             :   Array2D<Array<Array<Real>>> _weights_face;
     411             :   ///@}
     412             :   /**
     413             :    * Shape functions for reference elements
     414             :    */
     415             :   ///@{
     416             :   Array3D<Array2D<Real>> _phi;
     417             :   Array3D<Array<Array2D<Real>>> _phi_face;
     418             :   Array3D<Array2D<Real3>> _grad_phi;
     419             :   Array3D<Array<Array2D<Real3>>> _grad_phi_face;
     420             :   Array3D<Array2D<Real3>> _vector_phi;
     421             :   Array3D<Array<Array2D<Real3>>> _vector_phi_face;
     422             :   Array3D<Array2D<Real33>> _vector_grad_phi;
     423             :   Array3D<Array<Array2D<Real33>>> _vector_grad_phi_face;
     424             :   Array<bool> _is_vector_fe_type;
     425             :   Array2D<unsigned int> _n_dofs;
     426             :   ///@}
     427             :   /**
     428             :    * Shape functions for computing reference-to-physical maps
     429             :    */
     430             :   ///@{
     431             :   Array2D<Array2D<Real>> _map_phi;
     432             :   Array2D<Array<Array2D<Real>>> _map_phi_face;
     433             :   Array2D<Array<Array2D<Real>>> _map_psi_face;
     434             :   Array2D<Array2D<Real3>> _map_grad_phi;
     435             :   Array2D<Array<Array2D<Real3>>> _map_grad_phi_face;
     436             :   Array2D<Array<Array2D<Real3>>> _map_grad_psi_face;
     437             :   ///@}
     438             :   /**
     439             :    * Shape functions for computing normal vectors
     440             :    */
     441             :   ///@{
     442             :   Array2D<Array<Array2D<Real>>> _normal_dx_dxi;
     443             :   Array2D<Array<Array2D<Real>>> _normal_dx_deta;
     444             :   ///@}
     445             :   /**
     446             :    * Cached physical maps on element quadrature points
     447             :    */
     448             :   ///@{
     449             :   Array<Array<Real33>> _jacobian;
     450             :   Array<Array<Real>> _jxw;
     451             :   Array<Array<Real3>> _xyz;
     452             :   ///@}
     453             : 
     454             :   /**
     455             :    * Boundaries to cache face material properties
     456             :    */
     457             :   std::set<BoundaryID> _material_boundaries;
     458             : };
     459             : 
     460             : #ifdef MOOSE_KOKKOS_SCOPE
     461             : KOKKOS_FUNCTION inline Real
     462     1024346 : Assembly::coordTransformFactor(const ContiguousSubdomainID subdomain, const Real3 point) const
     463             : {
     464     1024346 :   switch (_coord_type[subdomain])
     465             :   {
     466     1020902 :     case Moose::COORD_XYZ:
     467     1020902 :       return 1;
     468        3052 :     case Moose::COORD_RZ:
     469        3052 :       if (_rz_radial_coord == libMesh::invalid_uint)
     470           0 :         return 2 * M_PI *
     471           0 :                (point - _rz_axis[subdomain].first).cross_product(_rz_axis[subdomain].second).norm();
     472             :       else
     473        3052 :         return 2 * M_PI * point(_rz_radial_coord);
     474         392 :     case Moose::COORD_RSPHERICAL:
     475         392 :       return 4 * M_PI * point(0) * point(0);
     476           0 :     default:
     477           0 :       return 0;
     478             :   }
     479             : }
     480             : 
     481             : KOKKOS_FUNCTION inline void
     482      666414 : Assembly::computePhysicalMap(const ElementInfo info,
     483             :                              const unsigned int qp,
     484             :                              Real33 * const jacobian,
     485             :                              Real * const JxW,
     486             :                              Real3 * const q_points) const
     487             : {
     488      666414 :   auto sid = info.subdomain;
     489      666414 :   auto eid = info.id;
     490      666414 :   auto elem_type = info.type;
     491      666414 :   auto num_nodes = kokkosMesh().getNumNodes(elem_type);
     492             : 
     493      666414 :   auto & phi = _map_phi(sid, elem_type);
     494      666414 :   auto & grad_phi = _map_grad_phi(sid, elem_type);
     495             : 
     496      666414 :   Real33 J;
     497      666414 :   Real3 xyz;
     498             : 
     499     3660318 :   for (unsigned int node = 0; node < num_nodes; ++node)
     500             :   {
     501     2993904 :     auto points = kokkosMesh().getNodePoint(kokkosMesh().getContiguousNodeID(eid, node));
     502             : 
     503     2993904 :     if (jacobian || JxW)
     504     2993904 :       J += grad_phi(node, qp).cartesian_product(points);
     505             : 
     506     2993904 :     xyz += phi(node, qp) * points;
     507             :   }
     508             : 
     509      666414 :   if (jacobian)
     510      666414 :     *jacobian = J.inverse(_dimension);
     511             : 
     512      666414 :   if (JxW)
     513      666414 :     *JxW =
     514      666414 :         J.determinant(_dimension) * _weights(sid, elem_type)[qp] * coordTransformFactor(sid, xyz);
     515             : 
     516      666414 :   if (q_points)
     517      666414 :     *q_points = xyz;
     518      666414 : }
     519             : 
     520             : KOKKOS_FUNCTION inline void
     521      357932 : Assembly::computePhysicalMap(const ElementInfo info,
     522             :                              const unsigned int side,
     523             :                              const unsigned int qp,
     524             :                              Real33 * const jacobian,
     525             :                              Real * const JxW,
     526             :                              Real3 * const q_points,
     527             :                              Real3 * const normal) const
     528             : {
     529      357932 :   auto sid = info.subdomain;
     530      357932 :   auto eid = info.id;
     531      357932 :   auto elem_type = info.type;
     532      357932 :   auto num_nodes = kokkosMesh().getNumNodes(elem_type);
     533      357932 :   auto num_side_nodes = kokkosMesh().getNumNodes(elem_type, side);
     534             : 
     535      357932 :   auto & phi = _map_phi_face(sid, elem_type)(side);
     536      357932 :   auto & grad_phi = _map_grad_phi_face(sid, elem_type)(side);
     537             : 
     538      357932 :   auto & normal_dx_dxi = _normal_dx_dxi(sid, elem_type)(side);
     539      357932 :   auto & normal_dx_deta = _normal_dx_deta(sid, elem_type)(side);
     540             : 
     541      357932 :   Real33 J;
     542      357932 :   Real3 xyz;
     543             : 
     544      357932 :   Real3 dxyz_dxi;
     545      357932 :   Real3 dxyz_deta;
     546             : 
     547     1984620 :   for (unsigned int node = 0; node < num_nodes; ++node)
     548             :   {
     549     1626688 :     auto points = kokkosMesh().getNodePoint(kokkosMesh().getContiguousNodeID(eid, node));
     550             : 
     551     1626688 :     if (jacobian)
     552     1626688 :       J += grad_phi(node, qp).cartesian_product(points);
     553             : 
     554     1626688 :     if (JxW || q_points)
     555     1626688 :       xyz += phi(node, qp) * points;
     556             : 
     557     1626688 :     if (normal)
     558             :     {
     559     1626688 :       if (_dimension < 3)
     560     1607104 :         dxyz_dxi += normal_dx_dxi(node, qp) * points;
     561     1626688 :       if (_dimension == 2)
     562     1605072 :         dxyz_deta += normal_dx_deta(node, qp) * points;
     563             :     }
     564             :   }
     565             : 
     566      357932 :   if (jacobian)
     567      357932 :     *jacobian = J.inverse(_dimension);
     568             : 
     569      357932 :   if (q_points)
     570      357932 :     *q_points = xyz;
     571             : 
     572      357932 :   if (JxW || (normal && _dimension > 1))
     573             :   {
     574      357932 :     J = 0;
     575             : 
     576      357932 :     auto & grad_psi = _map_grad_psi_face(sid, elem_type)(side);
     577             : 
     578     1115116 :     for (unsigned int node = 0; node < num_side_nodes; ++node)
     579             :     {
     580      757184 :       auto points = kokkosMesh().getNodePoint(kokkosMesh().getContiguousNodeID(info, side, node));
     581             : 
     582      757184 :       J += grad_psi(node, qp).cartesian_product(points);
     583             :     }
     584             :   }
     585             : 
     586      357932 :   if (JxW)
     587      357932 :     *JxW = ::Kokkos::sqrt((J * J.transpose()).determinant(_dimension - 1)) *
     588      357932 :            _weights_face(sid, elem_type)[side][qp] * coordTransformFactor(sid, xyz);
     589             : 
     590      357932 :   if (normal)
     591             :   {
     592      357932 :     if (_dimension == 3)
     593        2448 :       *normal = J.row(0).cross_product(J.row(1));
     594      355484 :     else if (_dimension == 2)
     595      354468 :       *normal = J.row(0).cross_product(dxyz_dxi.cross_product(dxyz_deta));
     596             :     else
     597        1016 :       *normal = side ? dxyz_dxi : -dxyz_dxi;
     598             : 
     599      357932 :     *normal *= 1.0 / normal->norm();
     600             :   }
     601      357932 : }
     602             : #endif
     603             : 
     604             : /**
     605             :  * The Kokkos interface that holds the host reference of the Kokkos assembly and copies it to device
     606             :  * during parallel dispatch.
     607             :  * Maintains synchronization between host and device Kokkos assemblies and provides access to the
     608             :  * appropriate Kokkos assembly depending on the architecture.
     609             :  */
     610             : class AssemblyHolder
     611             : {
     612             : public:
     613             :   /**
     614             :    * Constructor
     615             :    * @param assembly The Kokkos assembly
     616             :    */
     617       16253 :   AssemblyHolder(const Assembly & assembly) : _assembly_host(assembly), _assembly_device(assembly)
     618             :   {
     619       16253 :   }
     620             :   /**
     621             :    * Copy constructor
     622             :    */
     623      680650 :   AssemblyHolder(const AssemblyHolder & holder)
     624      392154 :     : _assembly_host(holder._assembly_host), _assembly_device(holder._assembly_host)
     625             :   {
     626      680650 :   }
     627             : 
     628             : #ifdef MOOSE_KOKKOS_SCOPE
     629             :   /**
     630             :    * Get the const reference of the Kokkos assembly
     631             :    * @returns The const reference of the Kokkos assembly depending on the architecture this function
     632             :    * is being called on
     633             :    */
     634   447207193 :   KOKKOS_FUNCTION const Assembly & kokkosAssembly() const
     635             :   {
     636   447207193 :     KOKKOS_IF_ON_HOST(return _assembly_host;)
     637             : 
     638   447041007 :     return _assembly_device;
     639             :   }
     640             : #endif
     641             : 
     642             : private:
     643             :   /**
     644             :    * Host reference of the Kokkos assembly
     645             :    */
     646             :   const Assembly & _assembly_host;
     647             :   /**
     648             :    * Device copy of the Kokkos assembly
     649             :    */
     650             :   const Assembly _assembly_device;
     651             : };
     652             : 
     653             : } // namespace Moose::Kokkos

Generated by: LCOV version 1.14