LCOV - code coverage report
Current view: top level - include/kokkos/linearfvkernels - KokkosLinearFVFluxKernel.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33416 (b10b36) with base 9fbd27 Lines: 43 60 71.7 %
Date: 2026-07-23 16:15:30 Functions: 17 30 56.7 %
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 "KokkosLinearFVKernel.h"
      13             : #include "KokkosLinearFVBoundaryCondition.h"
      14             : #include "KokkosDatum.h"
      15             : 
      16             : namespace Moose::Kokkos
      17             : {
      18             : 
      19             : /**
      20             :  * Base class for Kokkos linear finite volume kernels that contribute on faces (flux terms). On
      21             :  * boundary faces the contribution comes from the boundary face data populated by the boundary
      22             :  * conditions acting on this kernel's variable.
      23             :  */
      24             : class LinearFVFluxKernel : public LinearFVKernel
      25             : {
      26             : public:
      27             :   static InputParameters validParams();
      28             : 
      29             :   LinearFVFluxKernel(const InputParameters & parameters);
      30             :   LinearFVFluxKernel(const LinearFVFluxKernel & object);
      31             : 
      32             :   virtual void computeRightHandSide() override;
      33             :   virtual void computeMatrix() override;
      34             :   virtual void initialSetup() override;
      35             : 
      36             :   /// Whether this kernel needs boundary value data from its boundary conditions
      37         312 :   virtual bool needsBoundaryValueData() const { return false; }
      38             :   /// Whether this kernel needs boundary normal gradient data from its boundary conditions
      39          28 :   virtual bool needsBoundaryNormalGradientData() const { return false; }
      40             :   /// Whether this kernel has nonzero internal-face RHS contributions
      41           0 :   virtual bool hasInternalRightHandSideContribution() const { return true; }
      42             : 
      43             :   /// Tag dispatch type for internal-face right-hand side computation
      44             :   struct InternalRightHandSideLoop
      45             :   {
      46             :   };
      47             :   /// Tag dispatch type for boundary-face right-hand side computation
      48             :   struct BoundaryRightHandSideLoop
      49             :   {
      50             :   };
      51             :   /// Tag dispatch type for internal-face matrix computation
      52             :   struct InternalMatrixLoop
      53             :   {
      54             :   };
      55             :   /// Tag dispatch type for boundary-face matrix computation
      56             :   struct BoundaryMatrixLoop
      57             :   {
      58             :   };
      59             : 
      60             :   template <typename Derived>
      61             :   KOKKOS_FUNCTION void
      62             :   operator()(InternalRightHandSideLoop, const ThreadID tid, const Derived & kernel) const;
      63             : 
      64             :   template <typename Derived>
      65             :   KOKKOS_FUNCTION void
      66             :   operator()(BoundaryRightHandSideLoop, const ThreadID tid, const Derived & kernel) const;
      67             : 
      68             :   template <typename Derived>
      69             :   KOKKOS_FUNCTION void
      70             :   operator()(InternalMatrixLoop, const ThreadID tid, const Derived & kernel) const;
      71             : 
      72             :   template <typename Derived>
      73             :   KOKKOS_FUNCTION void
      74             :   operator()(BoundaryMatrixLoop, const ThreadID tid, const Derived & kernel) const;
      75             : 
      76             :   /**
      77             :    * Default methods to prevent compile errors when matrix/RHS contributions are not defined in the
      78             :    * derived class.
      79             :    */
      80             :   ///@{
      81             :   template <typename Derived>
      82             :   KOKKOS_FUNCTION Real computeInternalMatrixContribution(const FVDatum & datum) const;
      83             :   template <typename Derived>
      84             :   KOKKOS_FUNCTION Real computeInternalNeighborMatrixContribution(const FVDatum & datum) const;
      85             :   template <typename Derived>
      86             :   KOKKOS_FUNCTION Real computeBoundaryMatrixContribution(
      87             :       const FVDatum & datum, const int bc_index, const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const;
      88             :   template <typename Derived>
      89             :   KOKKOS_FUNCTION Real computeInternalRightHandSideContribution(const FVDatum & datum) const;
      90             :   template <typename Derived>
      91             :   KOKKOS_FUNCTION Real computeBoundaryRightHandSideContribution(
      92             :       const FVDatum & datum, const int bc_index, const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const;
      93             :   ///@}
      94             : 
      95             :   /**
      96             :    * Functions used to check if users have overriden the matrix hook methods, whose calculations can
      97             :    * be skipped when not overriden.
      98             :    * @returns The function pointer of the default hook method
      99             :    */
     100             :   ///@{
     101             :   template <typename Derived>
     102       82208 :   static auto defaultInternalMatrixContribution()
     103             :   {
     104       82208 :     return &LinearFVFluxKernel::computeInternalMatrixContribution<Derived>;
     105             :   }
     106             : 
     107             :   template <typename Derived>
     108           0 :   static auto defaultInternalNeighborMatrixContribution()
     109             :   {
     110           0 :     return &LinearFVFluxKernel::computeInternalNeighborMatrixContribution<Derived>;
     111             :   }
     112             : 
     113             :   template <typename Derived>
     114       82208 :   static auto defaultBoundaryMatrixContribution()
     115             :   {
     116       82208 :     return &LinearFVFluxKernel::computeBoundaryMatrixContribution<Derived>;
     117             :   }
     118             :   ///@}
     119             : 
     120             : protected:
     121             :   /// Directed element side operated on by this flux kernel
     122             :   using FaceID = Pair<ContiguousElementID, unsigned int>;
     123             :   /// Directed boundary side and its compact boundary condition and BC-local face indices
     124             :   struct BoundaryFaceID
     125             :   {
     126             :     ContiguousElementID elem;
     127             :     unsigned int side;
     128             :     int bc_index;
     129             :     MOOSE_KOKKOS_INDEX_TYPE bc_face_index;
     130             : 
     131       15913 :     bool operator<(const BoundaryFaceID & other) const
     132             :     {
     133       15913 :       if (bc_index != other.bc_index)
     134        3606 :         return bc_index < other.bc_index;
     135       12307 :       if (elem != other.elem)
     136       12191 :         return elem < other.elem;
     137         116 :       return side < other.side;
     138             :     }
     139             :   };
     140             : 
     141             : #ifndef NDEBUG
     142             :   /**
     143             :    * Whether this face has a mesh neighbor on a subdomain where this kernel's variable is active.
     144             :    * A mesh-internal face is treated as a boundary for a block-restricted variable when the adjacent
     145             :    * element is outside the variable's block restriction.
     146             :    */
     147             :   KOKKOS_FUNCTION bool hasFaceNeighbor(const FVDatum & datum) const;
     148             : 
     149             :   /// Whether this boundary face has a boundary condition data provider
     150             :   KOKKOS_FUNCTION bool hasBoundaryData(const FVDatum & datum, const int bc_index) const;
     151             : #endif
     152             : 
     153             :   /// Boundary value coefficient for this boundary face
     154             :   KOKKOS_FUNCTION Real boundaryValueCoefficient(const int bc_index,
     155             :                                                 const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const;
     156             :   /// Boundary value source for this boundary face
     157             :   KOKKOS_FUNCTION Real boundaryValueSource(const int bc_index,
     158             :                                            const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const;
     159             :   /// Boundary normal gradient coefficient for this boundary face
     160             :   KOKKOS_FUNCTION Real boundaryNormalGradientCoefficient(
     161             :       const int bc_index, const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const;
     162             :   /// Boundary normal gradient source for this boundary face
     163             :   KOKKOS_FUNCTION Real boundaryNormalGradientSource(
     164             :       const int bc_index, const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const;
     165             : 
     166             :   /// Boundary condition data handles indexed by compact boundary condition index
     167             :   Array<LinearFVBoundaryCondition::BoundaryData> _bc_data;
     168             :   /// Setup/debug map from (side, element) to compact boundary condition index
     169             :   Array2D<int> _bc_index;
     170             :   /// Directed internal element sides with an active variable on the neighbor element
     171             :   Array<FaceID> _internal_face_ids;
     172             :   /// Directed boundary element sides with active Kokkos boundary data
     173             :   Array<BoundaryFaceID> _boundary_face_ids;
     174             : 
     175             :   std::unique_ptr<DispatcherBase> _internal_rhs_dispatcher;
     176             :   std::unique_ptr<DispatcherBase> _boundary_rhs_dispatcher;
     177             :   std::unique_ptr<DispatcherBase> _internal_matrix_dispatcher;
     178             :   std::unique_ptr<DispatcherBase> _boundary_matrix_dispatcher;
     179             : };
     180             : 
     181             : #ifndef NDEBUG
     182             : KOKKOS_FUNCTION inline bool
     183             : LinearFVFluxKernel::hasFaceNeighbor(const FVDatum & datum) const
     184             : {
     185             :   if (!datum.hasNeighbor())
     186             :     return false;
     187             : 
     188             :   const auto & sys = kokkosSystem(_var.sys());
     189             :   return sys.isVariableActive(_var.var(), datum.neighborSubdomain());
     190             : }
     191             : 
     192             : KOKKOS_FUNCTION inline bool
     193             : LinearFVFluxKernel::hasBoundaryData(const FVDatum & datum, const int bc_index) const
     194             : {
     195             :   return bc_index >= 0 && _bc_index.isAlloc() &&
     196             :          _bc_index(datum.side(), datum.elemID()) == bc_index;
     197             : }
     198             : #endif
     199             : 
     200             : KOKKOS_FUNCTION inline Real
     201          28 : LinearFVFluxKernel::boundaryValueCoefficient(const int bc_index,
     202             :                                              const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const
     203             : {
     204             :   KOKKOS_ASSERT(bc_index >= 0);
     205          28 :   return _bc_data[bc_index].value.coefficient[bc_face_index];
     206             : }
     207             : 
     208             : KOKKOS_FUNCTION inline Real
     209          28 : LinearFVFluxKernel::boundaryValueSource(const int bc_index,
     210             :                                         const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const
     211             : {
     212             :   KOKKOS_ASSERT(bc_index >= 0);
     213          28 :   return _bc_data[bc_index].value.source[bc_face_index];
     214             : }
     215             : 
     216             : KOKKOS_FUNCTION inline Real
     217        1570 : LinearFVFluxKernel::boundaryNormalGradientCoefficient(
     218             :     const int bc_index, const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const
     219             : {
     220             :   KOKKOS_ASSERT(bc_index >= 0);
     221        1570 :   return _bc_data[bc_index].normal_gradient.coefficient[bc_face_index];
     222             : }
     223             : 
     224             : KOKKOS_FUNCTION inline Real
     225        1570 : LinearFVFluxKernel::boundaryNormalGradientSource(const int bc_index,
     226             :                                                  const MOOSE_KOKKOS_INDEX_TYPE bc_face_index) const
     227             : {
     228             :   KOKKOS_ASSERT(bc_index >= 0);
     229        1570 :   return _bc_data[bc_index].normal_gradient.source[bc_face_index];
     230             : }
     231             : 
     232             : template <typename Derived>
     233             : KOKKOS_FUNCTION Real
     234           0 : LinearFVFluxKernel::computeInternalMatrixContribution(const FVDatum &) const
     235             : {
     236           0 :   ::Kokkos::abort("Default computeInternalMatrixContribution() should never be called. Make sure "
     237             :                   "you properly redefined this method in your class without typos.");
     238             : 
     239             :   return 0;
     240             : }
     241             : 
     242             : template <typename Derived>
     243             : KOKKOS_FUNCTION Real
     244           0 : LinearFVFluxKernel::computeInternalNeighborMatrixContribution(const FVDatum &) const
     245             : {
     246           0 :   ::Kokkos::abort("Default computeInternalNeighborMatrixContribution() should never be called. "
     247             :                   "Make sure you properly redefined this method in your class without typos.");
     248             : 
     249             :   return 0;
     250             : }
     251             : 
     252             : template <typename Derived>
     253             : KOKKOS_FUNCTION Real
     254           0 : LinearFVFluxKernel::computeBoundaryMatrixContribution(const FVDatum &,
     255             :                                                       const int,
     256             :                                                       const MOOSE_KOKKOS_INDEX_TYPE) const
     257             : {
     258           0 :   ::Kokkos::abort("Default computeBoundaryMatrixContribution() should never be called. Make sure "
     259             :                   "you properly redefined this method in your class without typos.");
     260             : 
     261             :   return 0;
     262             : }
     263             : 
     264             : template <typename Derived>
     265             : KOKKOS_FUNCTION Real
     266           0 : LinearFVFluxKernel::computeInternalRightHandSideContribution(const FVDatum &) const
     267             : {
     268           0 :   ::Kokkos::abort("Default computeInternalRightHandSideContribution() should never be called. Make "
     269             :                   "sure you properly redefined this method in your class without typos.");
     270             : 
     271             :   return 0;
     272             : }
     273             : 
     274             : template <typename Derived>
     275             : KOKKOS_FUNCTION Real
     276             : LinearFVFluxKernel::computeBoundaryRightHandSideContribution(const FVDatum &,
     277             :                                                              const int,
     278             :                                                              const MOOSE_KOKKOS_INDEX_TYPE) const
     279             : {
     280             :   ::Kokkos::abort("Default computeBoundaryRightHandSideContribution() should never be called. Make "
     281             :                   "sure you properly redefined this method in your class without typos.");
     282             : 
     283             :   return 0;
     284             : }
     285             : 
     286             : template <typename Derived>
     287             : KOKKOS_FUNCTION void
     288           0 : LinearFVFluxKernel::operator()(InternalRightHandSideLoop,
     289             :                                const ThreadID tid,
     290             :                                const Derived & kernel) const
     291             : {
     292           0 :   const auto [elem, side] = _internal_face_ids[tid];
     293           0 :   FVDatum datum(elem, side, kokkosMesh());
     294             :   KOKKOS_ASSERT(hasFaceNeighbor(datum));
     295             : 
     296             :   KOKKOS_ASSERT(_var.components() == 1);
     297           0 :   const auto & sys = kokkosSystem(_var.sys());
     298           0 :   kernel.accumulateTaggedVector(
     299             :       kernel.template computeInternalRightHandSideContribution<Derived>(datum),
     300             :       sys.getElemLocalDofIndex(elem, 0, _var.var()));
     301           0 : }
     302             : 
     303             : template <typename Derived>
     304             : KOKKOS_FUNCTION void
     305        1598 : LinearFVFluxKernel::operator()(BoundaryRightHandSideLoop,
     306             :                                const ThreadID tid,
     307             :                                const Derived & kernel) const
     308             : {
     309        1598 :   const auto [elem, side, bc_index, bc_face_index] = _boundary_face_ids[tid];
     310        1598 :   FVDatum datum(elem, side, kokkosMesh());
     311             :   KOKKOS_ASSERT(hasBoundaryData(datum, bc_index));
     312             : 
     313             :   KOKKOS_ASSERT(_var.components() == 1);
     314        1598 :   const auto & sys = kokkosSystem(_var.sys());
     315        1598 :   kernel.accumulateTaggedVector(kernel.template computeBoundaryRightHandSideContribution<Derived>(
     316             :                                     datum, bc_index, bc_face_index),
     317             :                                 sys.getElemLocalDofIndex(elem, 0, _var.var()));
     318        1598 : }
     319             : 
     320             : template <typename Derived>
     321             : KOKKOS_FUNCTION void
     322       39858 : LinearFVFluxKernel::operator()(InternalMatrixLoop, const ThreadID tid, const Derived & kernel) const
     323             : {
     324       39858 :   const auto [elem, side] = _internal_face_ids[tid];
     325       39858 :   FVDatum datum(elem, side, kokkosMesh());
     326             :   KOKKOS_ASSERT(hasFaceNeighbor(datum));
     327             : 
     328             :   KOKKOS_ASSERT(_var.components() == 1);
     329       39858 :   const auto var_num = _var.var();
     330       39858 :   const auto & sys = kokkosSystem(_var.sys());
     331       39858 :   const auto row = sys.getElemLocalDofIndex(elem, 0, var_num);
     332       39858 :   kernel.accumulateTaggedMatrix(kernel.template computeInternalMatrixContribution<Derived>(datum),
     333             :                                 row,
     334             :                                 sys.getElemGlobalDofIndex(elem, 0, var_num));
     335       39858 :   kernel.accumulateTaggedMatrix(
     336             :       kernel.template computeInternalNeighborMatrixContribution<Derived>(datum),
     337             :       row,
     338             :       sys.getElemGlobalDofIndex(datum.neighborID(), 0, var_num));
     339       39858 : }
     340             : 
     341             : template <typename Derived>
     342             : KOKKOS_FUNCTION void
     343        1598 : LinearFVFluxKernel::operator()(BoundaryMatrixLoop, const ThreadID tid, const Derived & kernel) const
     344             : {
     345        1598 :   const auto [elem, side, bc_index, bc_face_index] = _boundary_face_ids[tid];
     346        1598 :   FVDatum datum(elem, side, kokkosMesh());
     347             :   KOKKOS_ASSERT(hasBoundaryData(datum, bc_index));
     348             : 
     349             :   KOKKOS_ASSERT(_var.components() == 1);
     350        1598 :   const auto var_num = _var.var();
     351        1598 :   const auto & sys = kokkosSystem(_var.sys());
     352        1598 :   const auto row = sys.getElemLocalDofIndex(elem, 0, var_num);
     353        1598 :   kernel.accumulateTaggedMatrix(
     354             :       kernel.template computeBoundaryMatrixContribution<Derived>(datum, bc_index, bc_face_index),
     355             :       row,
     356             :       sys.getElemGlobalDofIndex(elem, 0, var_num));
     357        1598 : }
     358             : 
     359             : } // namespace Moose::Kokkos

Generated by: LCOV version 1.14