LCOV - code coverage report
Current view: top level - include/kokkos/base - KokkosDatum.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 100 103 97.1 %
Date: 2026-05-29 20:35:17 Functions: 35 35 100.0 %
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             : #include "KokkosAssembly.h"
      14             : #include "KokkosSystem.h"
      15             : #include "KokkosVariable.h"
      16             : 
      17             : namespace Moose::Kokkos
      18             : {
      19             : 
      20             : /**
      21             :  * The Kokkos object that holds thread-private data in the parallel operations of any Kokkos object
      22             :  */
      23             : class Datum
      24             : {
      25             : public:
      26             :   /**
      27             :    * Constructor for element and side data
      28             :    * @param elem The contiguous element ID of the current thread
      29             :    * @param side The side index of the current thread
      30             :    * @param assembly The Kokkos assembly
      31             :    * @param systems The Kokkos systems
      32             :    */
      33             :   KOKKOS_FUNCTION
      34    22753706 :   Datum(const ContiguousElementID elem,
      35             :         const unsigned int side,
      36             :         const Assembly & assembly,
      37             :         const Array<System> & systems)
      38    22753706 :     : _assembly(assembly),
      39    22753706 :       _systems(systems),
      40    22753706 :       _mesh(assembly.kokkosMesh()),
      41    22753706 :       _elem(_mesh.getElementInfo(elem)),
      42    22753706 :       _side(side),
      43    22753706 :       _neighbor(!isSide() ? libMesh::DofObject::invalid_id : _mesh.getNeighbor(_elem.id, side)),
      44    22753706 :       _n_qps(!isSide() ? assembly.getNumQps(_elem) : assembly.getNumFaceQps(_elem, side)),
      45    22753706 :       _qp_offset(!isSide() ? assembly.getQpOffset(_elem) : assembly.getQpFaceOffset(_elem, side)),
      46    22753706 :       _elem_property_idx(!isSide()
      47    22753706 :                              ? _elem.id - _mesh.getStartingContiguousElementID(_elem.subdomain)
      48    45507412 :                              : assembly.getElemFacePropertyIndex(_elem, _side))
      49             :   {
      50    22753706 :   }
      51             :   /**
      52             :    * Constructor for node data
      53             :    * @param node The contiguous node ID of the current thread
      54             :    * @param assembly The Kokkos assembly
      55             :    * @param systems The Kokkos systems
      56             :    */
      57             :   KOKKOS_FUNCTION
      58     3442344 :   Datum(const ContiguousNodeID node, const Assembly & assembly, const Array<System> & systems)
      59     3442344 :     : _assembly(assembly), _systems(systems), _mesh(assembly.kokkosMesh()), _node(node)
      60             :   {
      61     3442344 :   }
      62             : 
      63             :   /**
      64             :    * Get the Kokkos assembly
      65             :    * @returns The Kokkos assembly
      66             :    */
      67   211708800 :   KOKKOS_FUNCTION const Assembly & assembly() const { return _assembly; }
      68             :   /**
      69             :    * Get the Kokkos system
      70             :    * @param sys The system number
      71             :    * @returns The Kokkos system
      72             :    */
      73    83442670 :   KOKKOS_FUNCTION const System & system(unsigned int sys) const { return _systems[sys]; }
      74             :   /**
      75             :    * Get the Kokkos mesh
      76             :    * @returns The Kokkos mesh
      77             :    */
      78             :   KOKKOS_FUNCTION const Mesh & mesh() const { return _mesh; }
      79             : 
      80             :   /**
      81             :    * Get the element information object
      82             :    * @returns The element information object
      83             :    */
      84   320179901 :   KOKKOS_FUNCTION const ElementInfo & elem() const { return _elem; }
      85             :   /**
      86             :    * Get the contiguous element ID
      87             :    * @returns The contiguous element ID
      88             :    */
      89      307272 :   KOKKOS_FUNCTION ContiguousElementID elemID() const { return _elem.id; }
      90             :   /**
      91             :    * Get the extra element ID
      92             :    * @param index The extra element ID index
      93             :    * @returns The extra element ID
      94             :    */
      95         500 :   KOKKOS_FUNCTION dof_id_type extraElemID(unsigned int index) const
      96             :   {
      97         500 :     return isNodal() ? libMesh::DofObject::invalid_id : _mesh.getExtraElementID(_elem.id, index);
      98             :   }
      99             :   /**
     100             :    * Get the contiguous subdomain ID
     101             :    * @returns The contiguous subdomain ID
     102             :    */
     103    80934610 :   KOKKOS_FUNCTION ContiguousSubdomainID subdomain() const { return _elem.subdomain; }
     104             :   /**
     105             :    * Get the side index
     106             :    * @returns The side index
     107             :    */
     108   290796160 :   KOKKOS_FUNCTION unsigned int side() const { return _side; }
     109             :   /**
     110             :    * Get the contiguous node ID
     111             :    * @returns The contiguous node ID
     112             :    */
     113     5718882 :   KOKKOS_FUNCTION ContiguousNodeID node() const { return _node; }
     114             :   /**
     115             :    * Get the number of local quadrature points
     116             :    * @returns The number of local quadrature points
     117             :    */
     118   112741497 :   KOKKOS_FUNCTION unsigned int n_qps() const { return _n_qps; }
     119             :   /**
     120             :    * Get the starting offset into the global quadrature point index
     121             :    * @returns The starting offset
     122             :    */
     123    78806948 :   KOKKOS_FUNCTION dof_id_type qpOffset() const { return _qp_offset; }
     124             :   /**
     125             :    * Get the index into the property data storage
     126             :    * @param constant_option The property constant option
     127             :    * @param qp The local quadrature point index
     128             :    * @returns The index
     129             :    */
     130             :   KOKKOS_FUNCTION dof_id_type propertyIdx(const PropertyConstantOption constant_option,
     131             :                                           const unsigned int qp) const;
     132             :   /**
     133             :    * Get whether the current side has a neighbor
     134             :    * @returns Whether the current side has a neighbor
     135             :    */
     136             :   KOKKOS_FUNCTION bool hasNeighbor() const { return _neighbor != libMesh::DofObject::invalid_id; }
     137             :   /**
     138             :    * Get whether the current datum is on a side
     139             :    * @returns Whether the current datum is on a side
     140             :    */
     141   181293272 :   KOKKOS_FUNCTION bool isSide() const { return _side != libMesh::invalid_uint; }
     142             :   /**
     143             :    * Get whether the current datum is on a node
     144             :    * @returns Whether the current datum is on a node
     145             :    */
     146   235987810 :   KOKKOS_FUNCTION bool isNodal() const { return _node != libMesh::DofObject::invalid_id; }
     147             :   /**
     148             :    * Get whether the a variable is defined on the current node
     149             :    * @param var The variable
     150             :    * @returns Whether the variable is defined on the current node
     151             :    */
     152             :   KOKKOS_FUNCTION bool isNodalDefined(const Variable & var) const;
     153             : 
     154             :   /**
     155             :    * Get the inverse of Jacobian matrix
     156             :    * | dxi/dx deta/dx dzeta/dx |
     157             :    * | dxi/dy deta/dy dzeta/dy |
     158             :    * | dxi/dz deta/dz dzeta/dz |
     159             :    * @param qp The local quadrature point index
     160             :    * @returns The Jacobian matrix
     161             :    */
     162             :   KOKKOS_FUNCTION const Real33 & J(const unsigned int qp);
     163             :   /**
     164             :    * Get the transformed Jacobian weight
     165             :    * @param qp The local quadrature point index
     166             :    * @returns The transformed Jacobian weights
     167             :    */
     168             :   KOKKOS_FUNCTION Real JxW(const unsigned int qp);
     169             :   /**
     170             :    * Get the physical quadrature point coordinate
     171             :    * @param qp The local quadrature point index
     172             :    * @returns The physical quadrature point coordinate
     173             :    */
     174             :   KOKKOS_FUNCTION Real3 q_point(const unsigned int qp);
     175             :   /**
     176             :    * Get the normal vector on surface
     177             :    * @param qp The local quadrature point index
     178             :    * @returns The normal vector
     179             :    */
     180             :   KOKKOS_FUNCTION Real3 normals(const unsigned int qp);
     181             : 
     182             :   /**
     183             :    * Set local parallelization option
     184             :    * @param local_thread_id The current local thread ID
     185             :    * @param num_local_threads The number of local threads
     186             :    */
     187    20773492 :   KOKKOS_FUNCTION void set_local_parallel(const unsigned int local_thread_id,
     188             :                                           const unsigned int num_local_threads)
     189             :   {
     190    20773492 :     _local_thread_id = local_thread_id;
     191    20773492 :     _num_local_threads = num_local_threads;
     192    20773492 :   }
     193             :   /**
     194             :    * Get the current local thread ID
     195             :    * @returns The current local thread ID
     196             :    */
     197    20773492 :   KOKKOS_FUNCTION unsigned int local_thread_id() const { return _local_thread_id; }
     198             :   /**
     199             :    * Get the number of local threads
     200             :    * @returns The number of local threads
     201             :    */
     202    54302784 :   KOKKOS_FUNCTION unsigned int num_local_threads() const { return _num_local_threads; }
     203             : 
     204             : protected:
     205             :   /**
     206             :    * Reference of the Kokkos assembly
     207             :    */
     208             :   const Assembly & _assembly;
     209             :   /**
     210             :    * Reference of the Kokkos systems
     211             :    */
     212             :   const Array<System> & _systems;
     213             :   /**
     214             :    * Reference of the Kokkos mesh
     215             :    */
     216             :   const Mesh & _mesh;
     217             :   /**
     218             :    * Current element information object
     219             :    */
     220             :   const ElementInfo _elem;
     221             :   /**
     222             :    * Current side index
     223             :    */
     224             :   const unsigned int _side = libMesh::invalid_uint;
     225             :   /**
     226             :    * Current contiguous node ID
     227             :    */
     228             :   const ContiguousNodeID _node = libMesh::DofObject::invalid_id;
     229             :   /**
     230             :    * Current contiguous element ID of neighbor
     231             :    */
     232             :   const ContiguousElementID _neighbor = libMesh::DofObject::invalid_id;
     233             :   /**
     234             :    * Number of local quadrature points
     235             :    */
     236             :   const unsigned int _n_qps = 1;
     237             :   /**
     238             :    * Starting offset into the global quadrature point index
     239             :    */
     240             :   const dof_id_type _qp_offset = libMesh::DofObject::invalid_id;
     241             :   /**
     242             :    * Index for element-constant material properties
     243             :    */
     244             :   const dof_id_type _elem_property_idx = libMesh::DofObject::invalid_id;
     245             : 
     246             : private:
     247             :   /**
     248             :    * Compute and cache the physical transformation data
     249             :    * @param qp The local quadrature point index
     250             :    */
     251             :   KOKKOS_FUNCTION void reinitTransform(const unsigned int qp);
     252             : 
     253             :   /**
     254             :    * Cached quadrature point index for checking whether the physical transformation data should be
     255             :    * recomputed
     256             :    */
     257             :   unsigned int _cached_qp = libMesh::invalid_uint;
     258             :   /**
     259             :    * Cached physical transformation data
     260             :    */
     261             :   ///@{
     262             :   Real33 _J;
     263             :   Real _JxW;
     264             :   Real3 _xyz;
     265             :   Real3 _normal;
     266             :   ///@}
     267             :   /**
     268             :    * Thread ID for local parallelization
     269             :    */
     270             :   unsigned int _local_thread_id = 0;
     271             :   /**
     272             :    * Number of threads for local parallelization
     273             :    */
     274             :   unsigned int _num_local_threads = 1;
     275             : };
     276             : 
     277             : KOKKOS_FUNCTION inline dof_id_type
     278    40059305 : Datum::propertyIdx(const PropertyConstantOption constant_option, const unsigned int qp) const
     279             : {
     280    40059305 :   dof_id_type idx = 0;
     281             : 
     282    40059305 :   if (constant_option == PropertyConstantOption::NONE)
     283    39491900 :     idx = _qp_offset + qp;
     284      567405 :   else if (constant_option == PropertyConstantOption::ELEMENT)
     285      263250 :     idx = _elem_property_idx;
     286             : 
     287    40059305 :   return idx;
     288             : }
     289             : 
     290             : KOKKOS_FUNCTION inline bool
     291      152946 : Datum::isNodalDefined(const Variable & var) const
     292             : {
     293      152946 :   if (!isNodal() || !var.nodal())
     294           0 :     return false;
     295             : 
     296      152946 :   return _systems[var.sys()].isNodalDefined(_node, var.var());
     297             : }
     298             : 
     299             : KOKKOS_FUNCTION inline const Real33 &
     300    95970496 : Datum::J(const unsigned int qp)
     301             : {
     302    95970496 :   if (!isNodal())
     303    95970496 :     reinitTransform(qp);
     304             :   else
     305           0 :     _J.identity(_assembly.getDimension());
     306             : 
     307    95970496 :   return _J;
     308             : }
     309             : 
     310             : KOKKOS_FUNCTION inline Real
     311   117907320 : Datum::JxW(const unsigned int qp)
     312             : {
     313   117907320 :   if (!isNodal())
     314   117907320 :     reinitTransform(qp);
     315             :   else
     316           0 :     _JxW = 1;
     317             : 
     318   117907320 :   return _JxW;
     319             : }
     320             : 
     321             : KOKKOS_FUNCTION inline Real3
     322    17601190 : Datum::q_point(const unsigned int qp)
     323             : {
     324    17601190 :   if (!isNodal())
     325    17160824 :     reinitTransform(qp);
     326             :   else
     327      440366 :     _xyz = _assembly.kokkosMesh().getNodePoint(_node);
     328             : 
     329    17601190 :   return _xyz;
     330             : }
     331             : 
     332             : KOKKOS_FUNCTION inline Real3
     333        8416 : Datum::normals(const unsigned int qp)
     334             : {
     335             :   KOKKOS_ASSERT(isSide());
     336             : 
     337        8416 :   if (isSide())
     338        8416 :     reinitTransform(qp);
     339             : 
     340        8416 :   return _normal;
     341             : }
     342             : 
     343             : KOKKOS_FUNCTION inline void
     344   231047056 : Datum::reinitTransform(const unsigned int qp)
     345             : {
     346   231047056 :   if (_cached_qp == qp)
     347   140777024 :     return;
     348             : 
     349    90270032 :   if (!isSide())
     350             :   {
     351    89206752 :     _J = _assembly.getJacobian(_elem, qp);
     352    89206752 :     _JxW = _assembly.getJxW(_elem, qp);
     353    89206752 :     _xyz = _assembly.getQPoint(_elem, qp);
     354             :   }
     355             :   else
     356     1063280 :     _assembly.computePhysicalMap(_elem, _side, qp, &_J, &_JxW, &_xyz, &_normal);
     357             : 
     358    90270032 :   _cached_qp = qp;
     359             : }
     360             : 
     361             : /**
     362             :  * The Kokkos object that holds thread-private data in the parallel operations of Kokkos kernels
     363             :  */
     364             : class AssemblyDatum : public Datum
     365             : {
     366             : public:
     367             :   /**
     368             :    * Constructor for element and side data
     369             :    * @param elem The contiguous element ID of the current thread
     370             :    * @param side The side index of the current thread
     371             :    * @param assembly The Kokkos assembly
     372             :    * @param systems The Kokkos systems
     373             :    * @param ivar The Kokkos variable
     374             :    * @param jvar The coupled variable number
     375             :    * @param comp The variable component
     376             :    */
     377             :   KOKKOS_FUNCTION
     378    21007292 :   AssemblyDatum(const ContiguousElementID elem,
     379             :                 const unsigned int side,
     380             :                 const Assembly & assembly,
     381             :                 const Array<System> & systems,
     382             :                 const Variable & ivar,
     383             :                 const unsigned int jvar,
     384             :                 const unsigned int comp = 0)
     385    21007292 :     : Datum(elem, side, assembly, systems),
     386    21007292 :       _tag(ivar.tag()),
     387    21007292 :       _sys(ivar.sys(comp)),
     388    21007292 :       _ivar(ivar.var(comp)),
     389    21007292 :       _jvar(jvar),
     390    21007292 :       _ife(systems[ivar.sys(comp)].getFETypeID(_ivar)),
     391    21007292 :       _jfe(systems[ivar.sys(comp)].getFETypeID(_jvar)),
     392    21007292 :       _n_idofs(assembly.getNumDofs(_elem.type, _ife)),
     393    42014584 :       _n_jdofs(assembly.getNumDofs(_elem.type, _jfe))
     394             :   {
     395    21007292 :   }
     396             :   /**
     397             :    * Constructor for node data
     398             :    * @param elem The contiguous element ID of the current thread
     399             :    * @param assembly The Kokkos assembly
     400             :    * @param systems The Kokkos systems
     401             :    * @param ivar The Kokkos variable
     402             :    * @param jvar The coupled variable number
     403             :    * @param comp The variable component
     404             :    */
     405             :   KOKKOS_FUNCTION
     406     3288576 :   AssemblyDatum(const ContiguousNodeID node,
     407             :                 const Assembly & assembly,
     408             :                 const Array<System> & systems,
     409             :                 const Variable & ivar,
     410             :                 const unsigned int jvar,
     411             :                 const unsigned int comp = 0)
     412     3288576 :     : Datum(node, assembly, systems),
     413     3288576 :       _tag(ivar.tag()),
     414     3288576 :       _sys(ivar.sys(comp)),
     415     3288576 :       _ivar(ivar.var(comp)),
     416     3288576 :       _jvar(jvar),
     417     3288576 :       _ife(systems[ivar.sys(comp)].getFETypeID(_ivar)),
     418     6577152 :       _jfe(systems[ivar.sys(comp)].getFETypeID(_jvar))
     419             :   {
     420     3288576 :   }
     421             : 
     422             :   /**
     423             :    * Get the number of local DOFs
     424             :    * @returns The number of local DOFs
     425             :    */
     426   177059260 :   KOKKOS_FUNCTION unsigned int n_dofs() const { return _n_idofs; }
     427             :   /**
     428             :    * Get the number of local DOFs
     429             :    * @returns The number of local DOFs
     430             :    */
     431     7374972 :   KOKKOS_FUNCTION unsigned int n_idofs() const { return _n_idofs; }
     432             :   /**
     433             :    * Get the number of local DOFs for the coupled variable
     434             :    * @returns The number of local DOFs
     435             :    */
     436     5121848 :   KOKKOS_FUNCTION unsigned int n_jdofs() const { return _n_jdofs; }
     437             :   /**
     438             :    * Get the system number of variable
     439             :    * @returns The system number of variable
     440             :    */
     441     4381978 :   KOKKOS_FUNCTION unsigned int sys() const { return _sys; }
     442             :   /**
     443             :    * Get the variable number
     444             :    * @returns The variable number
     445             :    */
     446             :   KOKKOS_FUNCTION unsigned int var() const { return _ivar; }
     447             :   /**
     448             :    * Get the variable number
     449             :    * @returns The variable number
     450             :    */
     451             :   KOKKOS_FUNCTION unsigned int ivar() const { return _ivar; }
     452             :   /**
     453             :    * Get the coupled variable number
     454             :    * @returns The variable number
     455             :    */
     456    10015672 :   KOKKOS_FUNCTION unsigned int jvar() const { return _jvar; }
     457             :   /**
     458             :    * Get the variable FE type ID
     459             :    * @returns The variable FE type ID
     460             :    */
     461             :   KOKKOS_FUNCTION unsigned int fe() const { return _ife; }
     462             :   /**
     463             :    * Get the variable FE type ID
     464             :    * @returns The variable FE type ID
     465             :    */
     466   181415928 :   KOKKOS_FUNCTION unsigned int ife() const { return _ife; }
     467             :   /**
     468             :    * Get the coupled variable FE type ID
     469             :    * @returns The variable FE type ID
     470             :    */
     471    30292872 :   KOKKOS_FUNCTION unsigned int jfe() const { return _jfe; }
     472             :   /**
     473             :    * Set whether to compute derivatives for automatic differentiation (AD)
     474             :    * @param flag Whether to compute derivatives
     475             :    */
     476     1292796 :   KOKKOS_FUNCTION void do_derivatives(const bool flag) { _do_derivatives = flag; }
     477             :   /**
     478             :    * Get whether to compute derivatives for automatic differentiation (AD)
     479             :    * @returns Whether to compute derivatives
     480             :    */
     481     4738908 :   KOKKOS_FUNCTION bool do_derivatives() const { return _do_derivatives; }
     482             : 
     483             : protected:
     484             :   /**
     485             :    * Solution tag ID
     486             :    */
     487             :   const TagID _tag;
     488             :   /**
     489             :    * System number
     490             :    */
     491             :   const unsigned int _sys;
     492             :   /**
     493             :    * Variable numbers
     494             :    */
     495             :   const unsigned int _ivar, _jvar;
     496             :   /**
     497             :    * FE type IDs of variables
     498             :    */
     499             :   const unsigned int _ife, _jfe;
     500             :   /**
     501             :    * Number of local DOFs
     502             :    */
     503             :   const unsigned int _n_idofs = 1, _n_jdofs = 1;
     504             :   /**
     505             :    * Whether to compute derivatives for automatic differentiation (AD)
     506             :    */
     507             :   bool _do_derivatives = true;
     508             : };
     509             : 
     510             : } // namespace Moose::Kokkos
     511             : 
     512             : using Datum = Moose::Kokkos::Datum;
     513             : using AssemblyDatum = Moose::Kokkos::AssemblyDatum;

Generated by: LCOV version 1.14