LCOV - code coverage report
Current view: top level - include/kokkos/base - KokkosVariableValue.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 329044 Lines: 190 219 86.8 %
Date: 2026-08-03 21:12:22 Functions: 47 48 97.9 %
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 "KokkosDatum.h"
      13             : 
      14             : #include "MooseError.h"
      15             : #include "MooseVariableFieldBase.h"
      16             : #include "SystemBase.h"
      17             : 
      18             : namespace Moose::Kokkos
      19             : {
      20             : 
      21             : inline void
      22       17750 : checkVariable(const Variable & var, bool expect_vector, const std::string & wrapper_name)
      23             : {
      24       17750 :   if (!var.initialized())
      25           0 :     mooseError("Attempted to construct Kokkos ", wrapper_name, " with an uninitialized variable.");
      26             : 
      27       17750 :   if (var.vector() != expect_vector)
      28           0 :     mooseError("Kokkos ",
      29             :                wrapper_name,
      30             :                " cannot be constructed with ",
      31           0 :                var.vector() ? "vector" : "scalar",
      32             :                " variables.");
      33       17750 : }
      34             : 
      35             : /**
      36             :  * The Kokkos wrapper classes for MOOSE-like shape function access
      37             :  */
      38             : ///@{
      39             : template <bool is_test>
      40             : class VariableShapeValue
      41             : {
      42             : public:
      43             :   /**
      44             :    * Get the current shape function
      45             :    * @param datum The AssemblyDatum object of the current thread
      46             :    * @param i The element-local DOF index
      47             :    * @param qp The local quadrature point index
      48             :    * @returns The shape function
      49             :    */
      50   119035616 :   KOKKOS_FUNCTION Real operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
      51             :   {
      52   119035616 :     auto & elem = datum.elem();
      53   119035616 :     auto side = datum.side();
      54   119035616 :     auto fe = is_test ? datum.ife() : datum.jfe();
      55             : 
      56           0 :     return side == libMesh::invalid_uint
      57   119035616 :                ? datum.assembly().getPhi(elem.subdomain, elem.type, fe)(i, qp)
      58   119035616 :                : datum.assembly().getPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
      59             :   }
      60             : };
      61             : 
      62             : template <bool is_test>
      63             : class VariableShapeGradient
      64             : {
      65             : public:
      66             :   /**
      67             :    * Get the gradient of the current shape function in reference space
      68             :    * @param datum The AssemblyDatum object of the current thread
      69             :    * @param i The element-local DOF index
      70             :    * @param qp The local quadrature point index
      71             :    * @returns The reference-space gradient of the shape function
      72             :    */
      73             :   KOKKOS_FUNCTION const Real3 &
      74             :   reference(AssemblyDatum & datum, unsigned int i, unsigned int qp) const;
      75             : 
      76             :   /**
      77             :    * Get the gradient of the current shape function
      78             :    * @param datum The AssemblyDatum object of the current thread
      79             :    * @param i The element-local DOF index
      80             :    * @param qp The local quadrature point index
      81             :    * @returns The gradient of the shape function
      82             :    */
      83    98124900 :   KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
      84             :   {
      85    98124900 :     return datum.J(qp) * reference(datum, i, qp);
      86             :   }
      87             : };
      88             : 
      89             : template <bool is_test>
      90             : KOKKOS_FUNCTION const Real3 &
      91    98127972 : VariableShapeGradient<is_test>::reference(AssemblyDatum & datum,
      92             :                                           unsigned int i,
      93             :                                           unsigned int qp) const
      94             : {
      95    98127972 :   auto & elem = datum.elem();
      96    98127972 :   auto side = datum.side();
      97    98127972 :   auto fe = is_test ? datum.ife() : datum.jfe();
      98             : 
      99           0 :   return side == libMesh::invalid_uint
     100    98127972 :              ? datum.assembly().getGradPhi(elem.subdomain, elem.type, fe)(i, qp)
     101   196255944 :              : datum.assembly().getGradPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
     102             : }
     103             : 
     104             : using VariablePhiValue = VariableShapeValue<false>;
     105             : using VariablePhiGradient = VariableShapeGradient<false>;
     106             : using VariableTestValue = VariableShapeValue<true>;
     107             : using VariableTestGradient = VariableShapeGradient<true>;
     108             : using ADVariablePhiValue = VariablePhiValue;
     109             : using ADVariablePhiGradient = VariablePhiGradient;
     110             : using ADVariableTestValue = VariableTestValue;
     111             : using ADVariableTestGradient = VariableTestGradient;
     112             : 
     113             : template <bool is_test>
     114             : class VectorVariableShapeValue
     115             : {
     116             : public:
     117             :   /**
     118             :    * Get the current vector shape function
     119             :    * @param datum The AssemblyDatum object of the current thread
     120             :    * @param i The element-local DOF index
     121             :    * @param qp The local quadrature point index
     122             :    * @returns The vector shape function
     123             :    */
     124    31071704 :   KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
     125             :   {
     126    31071704 :     auto & elem = datum.elem();
     127    31071704 :     auto side = datum.side();
     128    31071704 :     auto fe = is_test ? datum.ife() : datum.jfe();
     129             : 
     130           0 :     return side == libMesh::invalid_uint
     131    31071704 :                ? datum.assembly().getVectorPhi(elem.subdomain, elem.type, fe)(i, qp)
     132    31071704 :                : datum.assembly().getVectorPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
     133             :   }
     134             : };
     135             : 
     136             : template <bool is_test>
     137             : class VectorVariableShapeGradient
     138             : {
     139             : public:
     140             :   /**
     141             :    * Get the gradient of the current vector shape function in reference space
     142             :    * @param datum The AssemblyDatum object of the current thread
     143             :    * @param i The element-local DOF index
     144             :    * @param qp The local quadrature point index
     145             :    * @returns The reference-space gradient of the vector shape function
     146             :    */
     147             :   KOKKOS_FUNCTION const Real33 &
     148             :   reference(AssemblyDatum & datum, unsigned int i, unsigned int qp) const;
     149             : 
     150             :   /**
     151             :    * Get the gradient of the current vector shape function
     152             :    * @param datum The AssemblyDatum object of the current thread
     153             :    * @param i The element-local DOF index
     154             :    * @param qp The local quadrature point index
     155             :    * @returns The gradient of the vector shape function
     156             :    */
     157     4205016 :   KOKKOS_FUNCTION Real33 operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
     158             :   {
     159     4205016 :     return reference(datum, i, qp) * datum.J(qp).transpose();
     160             :   }
     161             : };
     162             : 
     163             : template <bool is_test>
     164             : KOKKOS_FUNCTION const Real33 &
     165    39218080 : VectorVariableShapeGradient<is_test>::reference(AssemblyDatum & datum,
     166             :                                                 unsigned int i,
     167             :                                                 unsigned int qp) const
     168             : {
     169    39218080 :   auto & elem = datum.elem();
     170    39218080 :   auto side = datum.side();
     171    39218080 :   auto fe = is_test ? datum.ife() : datum.jfe();
     172             : 
     173           0 :   return side == libMesh::invalid_uint
     174    39218080 :              ? datum.assembly().getVectorGradPhi(elem.subdomain, elem.type, fe)(i, qp)
     175    78436160 :              : datum.assembly().getVectorGradPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
     176             : }
     177             : 
     178             : template <bool is_test>
     179             : class VectorVariableShapeCurl
     180             : {
     181             : public:
     182             :   /**
     183             :    * Get the curl of the current vector shape function
     184             :    * @param datum The AssemblyDatum object of the current thread
     185             :    * @param i The element-local DOF index
     186             :    * @param qp The local quadrature point index
     187             :    * @returns The curl of the vector shape function
     188             :    */
     189     5456896 :   KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
     190             :   {
     191     5456896 :     auto & elem = datum.elem();
     192     5456896 :     auto side = datum.side();
     193     5456896 :     auto fe = is_test ? datum.ife() : datum.jfe();
     194             : 
     195     5456896 :     auto grad =
     196             :         side == libMesh::invalid_uint
     197     5456896 :             ? datum.assembly().getVectorGradPhi(elem.subdomain, elem.type, fe)(i, qp)
     198           0 :             : datum.assembly().getVectorGradPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
     199             : 
     200    10913792 :     return curlFromVectorGradient(grad * datum.J(qp).transpose(), datum.assembly().getDimension());
     201             :   }
     202             : };
     203             : 
     204             : using VectorVariablePhiValue = VectorVariableShapeValue<false>;
     205             : using VectorVariablePhiGradient = VectorVariableShapeGradient<false>;
     206             : using VectorVariablePhiCurl = VectorVariableShapeCurl<false>;
     207             : using VectorVariableTestValue = VectorVariableShapeValue<true>;
     208             : using VectorVariableTestGradient = VectorVariableShapeGradient<true>;
     209             : using VectorVariableTestCurl = VectorVariableShapeCurl<true>;
     210             : ///@}
     211             : 
     212             : /**
     213             :  * The Kokkos wrapper classes for MOOSE-like variable value access
     214             :  */
     215             : ///@{
     216             : template <bool is_ad>
     217             : class VariableValueTempl
     218             : {
     219             :   using real_type = std::conditional_t<is_ad, ADReal, Real>;
     220             : 
     221             : public:
     222             :   /**
     223             :    * Default constructor
     224             :    */
     225        8867 :   VariableValueTempl() = default;
     226             :   /**
     227             :    * Constructor
     228             :    * @param var The Kokkos variable
     229             :    * @param dof Whether to get DOF values
     230             :    */
     231        2898 :   VariableValueTempl(Variable var, bool dof = false) : _var(var), _dof(dof)
     232             :   {
     233        2898 :     checkVariable(_var, false, is_ad ? "ADVariableValue" : "VariableValue");
     234        2898 :   }
     235             :   /**
     236             :    * Constructor
     237             :    * @param var The MOOSE variable
     238             :    * @param tag The vector tag name
     239             :    * @param dof Whether to get DOF values
     240             :    */
     241        9232 :   VariableValueTempl(const MooseVariableFieldBase & var,
     242             :                      const TagName & tag = Moose::SOLUTION_TAG,
     243        4214 :                      bool dof = false)
     244        5018 :     : _var(var, tag), _dof(dof)
     245             :   {
     246        9232 :     checkVariable(_var, false, is_ad ? "ADVariableValue" : "VariableValue");
     247        9232 :   }
     248             :   /**
     249             :    * Constructor
     250             :    * @param vars The MOOSE variables
     251             :    * @param tag The vector tag name
     252             :    * @param dof Whether to get DOF values
     253             :    */
     254             :   ///@{
     255             :   VariableValueTempl(const std::vector<const MooseVariableFieldBase *> & vars,
     256             :                      const TagName & tag = Moose::SOLUTION_TAG,
     257             :                      bool dof = false)
     258             :     : _var(vars, tag), _dof(dof)
     259             :   {
     260             :     checkVariable(_var, false, is_ad ? "ADVariableValue" : "VariableValue");
     261             :   }
     262             :   VariableValueTempl(const std::vector<MooseVariableFieldBase *> & vars,
     263             :                      const TagName & tag = Moose::SOLUTION_TAG,
     264             :                      bool dof = false)
     265             :     : _var(vars, tag), _dof(dof)
     266             :   {
     267             :     checkVariable(_var, false, is_ad ? "ADVariableValue" : "VariableValue");
     268             :   }
     269             :   ///@}
     270             : 
     271             :   /**
     272             :    * Copy constructor for parallel dispatch
     273             :    */
     274             :   VariableValueTempl(const VariableValueTempl<is_ad> & object);
     275             :   /**
     276             :    * Copy assignment operator
     277             :    */
     278             :   VariableValueTempl<is_ad> & operator=(const VariableValueTempl<is_ad> & object);
     279             : 
     280             :   /**
     281             :    * Get whether the variable was coupled
     282             :    * @returns Whether the variable was coupled
     283             :    */
     284       28032 :   KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
     285             : 
     286             :   /**
     287             :    * Get the current variable value
     288             :    * @param datum The Datum object of the current thread
     289             :    * @param idx The local quadrature point or DOF index
     290             :    * @param comp The variable component
     291             :    * @returns The variable value
     292             :    */
     293     2592739 :   KOKKOS_FUNCTION auto operator()(Datum & datum, unsigned int idx, unsigned int comp = 0) const
     294             :   {
     295     2592739 :     return get(datum, idx, comp);
     296             :   }
     297             : 
     298             :   /**
     299             :    * Get the current variable value
     300             :    * @param datum The AssemblyDatum object of the current thread
     301             :    * @param idx The local quadrature point or DOF index
     302             :    * @param comp The variable component
     303             :    * @returns The variable value
     304             :    */
     305             :   KOKKOS_FUNCTION auto
     306             :   operator()(AssemblyDatum & datum, unsigned int idx, unsigned int comp = 0) const;
     307             : 
     308             :   /**
     309             :    * Get the Kokkos variable
     310             :    * @returns The Kokkos variable
     311             :    */
     312      460146 :   KOKKOS_FUNCTION const Variable & variable() const { return _var; }
     313             : 
     314             : private:
     315             :   /**
     316             :    * Get the current variable value
     317             :    * @param datum The Datum object of the current thread
     318             :    * @param idx The local quadrature point or DOF index
     319             :    * @param comp The variable component
     320             :    * @param seed The derivative seed (only meaningful for AD)
     321             :    * @returns The variable value
     322             :    */
     323             :   KOKKOS_FUNCTION auto
     324             :   get(Datum & datum, unsigned int idx, unsigned int comp = 0, Real seed = 0) const;
     325             : 
     326             :   /**
     327             :    * Coupled Kokkos variable
     328             :    */
     329             :   Variable _var;
     330             :   /**
     331             :    * Derivative seed of each component for AD
     332             :    */
     333             :   Array<Real> _seed;
     334             :   /**
     335             :    * Flag whether DOF values are requested
     336             :    */
     337             :   bool _dof = false;
     338             : };
     339             : 
     340             : template <bool is_ad>
     341      594137 : VariableValueTempl<is_ad>::VariableValueTempl(const VariableValueTempl<is_ad> & object)
     342      338540 :   : _var(object._var), _seed(object._seed), _dof(object._dof)
     343             : {
     344             :   if constexpr (is_ad)
     345       59361 :     if (_var.coupled())
     346             :     {
     347       57477 :       if (!_seed.isAlloc())
     348       57477 :         _seed.create(_var.components());
     349             : 
     350      114954 :       for (unsigned int comp = 0; comp < _var.components(); ++comp)
     351       57477 :         _seed[comp] =
     352       29002 :             _var.dot() ? _var.mooseVar(comp)->sys().duDotDu(_var.var(comp)) : (_var.old() ? 0 : 1);
     353             : 
     354       57477 :       _seed.copyToDevice();
     355             :     }
     356      594137 : }
     357             : 
     358             : template <bool is_ad>
     359             : VariableValueTempl<is_ad> &
     360        8867 : VariableValueTempl<is_ad>::operator=(const VariableValueTempl<is_ad> & object)
     361             : {
     362        8867 :   _var = object._var;
     363        8867 :   _dof = object._dof;
     364             : 
     365        8867 :   return *this;
     366             : }
     367             : 
     368             : template <bool is_ad>
     369             : KOKKOS_FUNCTION auto
     370    16042115 : VariableValueTempl<is_ad>::operator()(AssemblyDatum & datum,
     371             :                                       unsigned int idx,
     372             :                                       unsigned int comp) const
     373             : {
     374             :   if constexpr (is_ad)
     375             :   {
     376     2369536 :     Real seed =
     377     2369536 :         datum.do_derivatives() && _var.coupled() && _var.sys(comp) == datum.sys() ? _seed[comp] : 0;
     378             : 
     379     2369536 :     return get(datum, idx, comp, seed);
     380             :   }
     381             :   else
     382    13672579 :     return get(datum, idx, comp);
     383             : }
     384             : 
     385             : template <bool is_ad>
     386             : KOKKOS_FUNCTION auto
     387    18634854 : VariableValueTempl<is_ad>::get(Datum & datum,
     388             :                                unsigned int idx,
     389             :                                unsigned int comp,
     390             :                                [[maybe_unused]] Real seed) const
     391             : {
     392             :   KOKKOS_ASSERT(_var.initialized());
     393             : 
     394     2369536 :   real_type value;
     395             : 
     396    18634854 :   if (_var.coupled())
     397             :   {
     398    18615652 :     auto & sys = datum.system(_var.sys(comp));
     399    18615652 :     auto var = _var.var(comp);
     400    18615652 :     auto tag = _var.tag();
     401             : 
     402    18615652 :     if (_dof)
     403             :     {
     404             :       unsigned int dof;
     405             : 
     406     4361422 :       if (datum.isNodal())
     407             :       {
     408     4360782 :         auto node = datum.node();
     409     4360782 :         dof = sys.getNodeLocalDofIndex(node, 0, var);
     410             :       }
     411             :       else
     412             :       {
     413         640 :         auto elem = datum.elem().id;
     414         640 :         dof = sys.getElemLocalDofIndex(elem, idx, var);
     415             :       }
     416             : 
     417             :       if constexpr (is_ad)
     418       68840 :         value = sys.getVectorDofADValue(dof, tag, seed);
     419             :       else
     420     4292582 :         value = sys.getVectorDofValue(dof, tag);
     421             :     }
     422             :     else
     423             :     {
     424    14254230 :       auto & elem = datum.elem();
     425    14254230 :       auto side = datum.side();
     426             : 
     427             :       if constexpr (is_ad)
     428     2285548 :         value = side == libMesh::invalid_uint
     429     4571096 :                     ? sys.getVectorQpADValue(elem, datum.qpOffset(), idx, var, tag, seed)
     430             :                     : sys.getVectorQpADValueFace(elem, side, idx, var, tag, seed);
     431             :       else
     432    11968682 :         value = side == libMesh::invalid_uint
     433    11968682 :                     ? sys.getVectorQpValue(elem, datum.qpOffset() + idx, var, tag)
     434      221890 :                     : sys.getVectorQpValueFace(elem, side, idx, var, tag);
     435             :     }
     436             :   }
     437             :   else
     438       19202 :     value = _var.value(comp);
     439             : 
     440    18634854 :   return value;
     441           0 : }
     442             : 
     443             : template <bool is_ad>
     444             : class VariableGradientTempl
     445             : {
     446             :   using real3_type = std::conditional_t<is_ad, ADReal3, Real3>;
     447             : 
     448             : public:
     449             :   /**
     450             :    * Default constructor
     451             :    */
     452             :   VariableGradientTempl() = default;
     453             :   /**
     454             :    * Constructor
     455             :    * @param var The Kokkos variable
     456             :    */
     457         680 :   VariableGradientTempl(Variable var) : _var(var)
     458             :   {
     459         680 :     checkVariable(_var, false, is_ad ? "ADVariableGradient" : "VariableGradient");
     460         680 :   }
     461             :   /**
     462             :    * Constructor
     463             :    * @param var The MOOSE variable
     464             :    * @param tag The vector tag name
     465             :    */
     466        3949 :   VariableGradientTempl(const MooseVariableFieldBase & var,
     467        1775 :                         const TagName & tag = Moose::SOLUTION_TAG)
     468        2174 :     : _var(var, tag)
     469             :   {
     470        3949 :     checkVariable(_var, false, is_ad ? "ADVariableGradient" : "VariableGradient");
     471        3949 :   }
     472             :   /**
     473             :    * Constructor
     474             :    * @param vars The MOOSE variables
     475             :    * @param tag The vector tag name
     476             :    */
     477             :   ///@{
     478             :   VariableGradientTempl(const std::vector<const MooseVariableFieldBase *> & vars,
     479             :                         const TagName & tag = Moose::SOLUTION_TAG)
     480             :     : _var(vars, tag)
     481             :   {
     482             :     checkVariable(_var, false, is_ad ? "ADVariableGradient" : "VariableGradient");
     483             :   }
     484             :   VariableGradientTempl(const std::vector<MooseVariableFieldBase *> & vars,
     485             :                         const TagName & tag = Moose::SOLUTION_TAG)
     486             :     : _var(vars, tag)
     487             :   {
     488             :     checkVariable(_var, false, is_ad ? "ADVariableGradient" : "VariableGradient");
     489             :   }
     490             :   ///@}
     491             : 
     492             :   /**
     493             :    * Copy constructor for parallel dispatch
     494             :    */
     495             :   VariableGradientTempl(const VariableGradientTempl<is_ad> & object);
     496             :   /**
     497             :    * Copy assignment operator
     498             :    */
     499             :   VariableGradientTempl<is_ad> & operator=(const VariableGradientTempl<is_ad> & object);
     500             : 
     501             :   /**
     502             :    * Get whether the variable was coupled
     503             :    * @returns Whether the variable was coupled
     504             :    */
     505             :   KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
     506             : 
     507             :   /**
     508             :    * Get the current variable gradient
     509             :    * @param datum The Datum object of the current thread
     510             :    * @param qp The local quadrature point index
     511             :    * @param comp The variable component
     512             :    * @returns The variable gradient
     513             :    */
     514             :   KOKKOS_FUNCTION auto operator()(Datum & datum, unsigned int qp, unsigned int comp = 0) const
     515             :   {
     516             :     return get(datum, qp, comp);
     517             :   }
     518             : 
     519             :   /**
     520             :    * Get the current variable gradient
     521             :    * @param datum The AssemblyDatum object of the current thread
     522             :    * @param qp The local quadrature point index
     523             :    * @param comp The variable component
     524             :    * @returns The variable gradient
     525             :    */
     526             :   KOKKOS_FUNCTION auto
     527             :   operator()(AssemblyDatum & datum, unsigned int qp, unsigned int comp = 0) const;
     528             : 
     529             :   /**
     530             :    * Get the Kokkos variable
     531             :    * @returns The Kokkos variable
     532             :    */
     533             :   KOKKOS_FUNCTION const Variable & variable() const { return _var; }
     534             : 
     535             : private:
     536             :   /**
     537             :    * Get the current variable gradient
     538             :    * @param datum The Datum object of the current thread
     539             :    * @param qp The local quadrature point index
     540             :    * @param comp The variable component
     541             :    * @param seed The derivative seed (only meaningful for AD)
     542             :    * @returns The variable gradient
     543             :    */
     544             :   KOKKOS_FUNCTION auto
     545             :   get(Datum & datum, unsigned int qp, unsigned int comp = 0, Real seed = 0) const;
     546             : 
     547             :   /**
     548             :    * Coupled Kokkos variable
     549             :    */
     550             :   Variable _var;
     551             :   /**
     552             :    * Derivative seed of each component for AD
     553             :    */
     554             :   Array<Real> _seed;
     555             : };
     556             : 
     557             : template <bool is_ad>
     558      190477 : VariableGradientTempl<is_ad>::VariableGradientTempl(const VariableGradientTempl<is_ad> & object)
     559      112839 :   : _var(object._var), _seed(object._seed)
     560             : {
     561             :   if constexpr (is_ad)
     562       17907 :     if (_var.coupled())
     563             :     {
     564       17907 :       if (!_seed.isAlloc())
     565       17907 :         _seed.create(_var.components());
     566             : 
     567       35814 :       for (unsigned int comp = 0; comp < _var.components(); ++comp)
     568       17907 :         _seed[comp] =
     569        9044 :             _var.dot() ? _var.mooseVar(comp)->sys().duDotDu(_var.var(comp)) : (_var.old() ? 0 : 1);
     570             : 
     571       17907 :       _seed.copyToDevice();
     572             :     }
     573      190477 : }
     574             : 
     575             : template <bool is_ad>
     576             : VariableGradientTempl<is_ad> &
     577             : VariableGradientTempl<is_ad>::operator=(const VariableGradientTempl<is_ad> & object)
     578             : {
     579             :   _var = object._var;
     580             : 
     581             :   return *this;
     582             : }
     583             : 
     584             : template <bool is_ad>
     585             : KOKKOS_FUNCTION auto
     586    43240260 : VariableGradientTempl<is_ad>::operator()(AssemblyDatum & datum,
     587             :                                          unsigned int qp,
     588             :                                          unsigned int comp) const
     589             : {
     590             :   if constexpr (is_ad)
     591             :   {
     592     2368704 :     Real seed =
     593     2368704 :         datum.do_derivatives() && _var.coupled() && _var.sys(comp) == datum.sys() ? _seed[comp] : 0;
     594             : 
     595     2368704 :     return get(datum, qp, comp, seed);
     596             :   }
     597             :   else
     598    40871556 :     return get(datum, qp, comp);
     599             : }
     600             : 
     601             : template <bool is_ad>
     602             : KOKKOS_FUNCTION auto
     603    43240260 : VariableGradientTempl<is_ad>::get(Datum & datum,
     604             :                                   unsigned int qp,
     605             :                                   unsigned int comp,
     606             :                                   [[maybe_unused]] Real seed) const
     607             : {
     608             :   KOKKOS_ASSERT(_var.initialized());
     609             : 
     610    43240260 :   real3_type grad;
     611             : 
     612    43240260 :   if (_var.coupled())
     613             :   {
     614             :     KOKKOS_ASSERT(!datum.isNodal());
     615             : 
     616    43240260 :     auto & elem = datum.elem();
     617    43240260 :     auto side = datum.side();
     618             : 
     619             :     if constexpr (is_ad)
     620     2368704 :       grad =
     621             :           side == libMesh::invalid_uint
     622     4737408 :               ? datum.system(_var.sys(comp))
     623             :                     .getVectorQpADGrad(
     624     2368704 :                         elem, datum.J(qp), datum.qpOffset(), qp, _var.var(comp), _var.tag(), seed)
     625           0 :               : datum.system(_var.sys(comp))
     626             :                     .getVectorQpADGradFace(
     627           0 :                         elem, side, datum.J(qp), qp, _var.var(comp), _var.tag(), seed);
     628             :     else
     629    40871556 :       grad =
     630             :           side == libMesh::invalid_uint
     631    81743112 :               ? datum.system(_var.sys(comp))
     632    40871556 :                     .getVectorQpGrad(elem, datum.qpOffset() + qp, _var.var(comp), _var.tag())
     633           0 :               : datum.system(_var.sys(comp))
     634           0 :                     .getVectorQpGradFace(elem, side, datum.J(qp), qp, _var.var(comp), _var.tag());
     635             :   }
     636             : 
     637    43240260 :   return grad;
     638           0 : }
     639             : 
     640             : using VariableValue = VariableValueTempl<false>;
     641             : using ADVariableValue = VariableValueTempl<true>;
     642             : using VariableGradient = VariableGradientTempl<false>;
     643             : using ADVariableGradient = VariableGradientTempl<true>;
     644             : 
     645             : class VectorVariableValue
     646             : {
     647             : public:
     648             :   /**
     649             :    * Default constructor
     650             :    */
     651             :   VectorVariableValue() = default;
     652             :   /**
     653             :    * Constructor
     654             :    * @param var The Kokkos variable
     655             :    * @param dof Whether to get DOF values
     656             :    */
     657          70 :   VectorVariableValue(Variable var, bool dof = false) : _var(var), _dof(dof)
     658             :   {
     659          70 :     checkVariable(_var, true, "VectorVariableValue");
     660          70 :   }
     661             :   /**
     662             :    * Constructor
     663             :    * @param var The MOOSE variable
     664             :    * @param tag The vector tag name
     665             :    * @param dof Whether to get DOF values
     666             :    */
     667         526 :   VectorVariableValue(const MooseVariableFieldBase & var,
     668             :                       const TagName & tag = Moose::SOLUTION_TAG,
     669         250 :                       bool dof = false)
     670         276 :     : _var(var, tag), _dof(dof)
     671             :   {
     672         526 :     checkVariable(_var, true, "VectorVariableValue");
     673         526 :   }
     674             : 
     675             :   /**
     676             :    * Get whether the variable was coupled
     677             :    * @returns Whether the variable was coupled
     678             :    */
     679             :   KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
     680             : 
     681             :   /**
     682             :    * Get the current vector variable value
     683             :    * @param datum The AssemblyDatum object of the current thread
     684             :    * @param idx The local quadrature point index or DOF index
     685             :    * @returns The vector variable value
     686             :    */
     687             :   KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum,
     688             :                                    unsigned int idx,
     689             :                                    unsigned int comp = 0) const;
     690             : 
     691             :   /**
     692             :    * Get the Kokkos variable
     693             :    * @returns The Kokkos variable
     694             :    */
     695             :   KOKKOS_FUNCTION const Variable & variable() const { return _var; }
     696             : 
     697             : private:
     698             :   /**
     699             :    * Coupled Kokkos variable
     700             :    */
     701             :   Variable _var;
     702             :   /**
     703             :    * Flag whether DOF values are requested
     704             :    */
     705             :   bool _dof = false;
     706             : };
     707             : 
     708             : class VectorVariableGradient
     709             : {
     710             : public:
     711             :   /**
     712             :    * Default constructor
     713             :    */
     714             :   VectorVariableGradient() = default;
     715             :   /**
     716             :    * Constructor
     717             :    * @param var The Kokkos variable
     718             :    */
     719          51 :   VectorVariableGradient(Variable var) : _var(var)
     720             :   {
     721          51 :     checkVariable(_var, true, "VectorVariableGradient");
     722          51 :   }
     723             :   /**
     724             :    * Constructor
     725             :    * @param var The MOOSE variable
     726             :    * @param tag The vector tag name
     727             :    */
     728         315 :   VectorVariableGradient(const MooseVariableFieldBase & var,
     729         150 :                          const TagName & tag = Moose::SOLUTION_TAG)
     730         165 :     : _var(var, tag)
     731             :   {
     732         315 :     checkVariable(_var, true, "VectorVariableGradient");
     733         315 :   }
     734             : 
     735             :   /**
     736             :    * Get whether the variable was coupled
     737             :    * @returns Whether the variable was coupled
     738             :    */
     739             :   KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
     740             : 
     741             :   /**
     742             :    * Get the current vector variable gradient
     743             :    * @param datum The AssemblyDatum object of the current thread
     744             :    * @param qp The local quadrature point index
     745             :    * @returns The vector variable gradient
     746             :    */
     747             :   KOKKOS_FUNCTION Real33 operator()(AssemblyDatum & datum,
     748             :                                     unsigned int qp,
     749             :                                     unsigned int comp = 0) const;
     750             : 
     751             :   /**
     752             :    * Get the Kokkos variable
     753             :    * @returns The Kokkos variable
     754             :    */
     755             :   KOKKOS_FUNCTION const Variable & variable() const { return _var; }
     756             : 
     757             : private:
     758             :   /**
     759             :    * Coupled Kokkos variable
     760             :    */
     761             :   Variable _var;
     762             : };
     763             : 
     764             : class VectorVariableCurl
     765             : {
     766             : public:
     767             :   /**
     768             :    * Default constructor
     769             :    */
     770             :   VectorVariableCurl() = default;
     771             :   /**
     772             :    * Constructor
     773             :    * @param var The Kokkos variable
     774             :    */
     775             :   VectorVariableCurl(Variable var) : _var(var) { checkVariable(_var, true, "VectorVariableCurl"); }
     776             :   /**
     777             :    * Constructor
     778             :    * @param var The MOOSE variable
     779             :    * @param tag The vector tag name
     780             :    */
     781          29 :   VectorVariableCurl(const MooseVariableFieldBase & var, const TagName & tag = Moose::SOLUTION_TAG)
     782          15 :     : _var(var, tag)
     783             :   {
     784          29 :     checkVariable(_var, true, "VectorVariableCurl");
     785          29 :   }
     786             : 
     787             :   /**
     788             :    * Get whether the variable was coupled
     789             :    * @returns Whether the variable was coupled
     790             :    */
     791             :   KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
     792             : 
     793             :   /**
     794             :    * Get the current vector variable curl
     795             :    * @param datum The AssemblyDatum object of the current thread
     796             :    * @param qp The local quadrature point index
     797             :    * @returns The vector variable curl
     798             :    */
     799             :   KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum,
     800             :                                    unsigned int qp,
     801             :                                    unsigned int comp = 0) const;
     802             : 
     803             :   /**
     804             :    * Get the Kokkos variable
     805             :    * @returns The Kokkos variable
     806             :    */
     807             :   KOKKOS_FUNCTION const Variable & variable() const { return _var; }
     808             : 
     809             : private:
     810             :   /**
     811             :    * Coupled Kokkos variable
     812             :    */
     813             :   Variable _var;
     814             : };
     815             : 
     816             : KOKKOS_FUNCTION inline Real3
     817     1869208 : VectorVariableValue::operator()(AssemblyDatum & datum, unsigned int idx, unsigned int comp) const
     818             : {
     819             :   KOKKOS_ASSERT(_var.initialized());
     820             : 
     821     1869208 :   Real3 value = 0;
     822             : 
     823     1869208 :   if (_var.coupled())
     824             :   {
     825     1759384 :     auto & sys = datum.system(_var.sys(comp));
     826     1759384 :     auto var = _var.var(comp);
     827     1759384 :     auto tag = _var.tag();
     828             : 
     829     1759384 :     if (_dof)
     830             :     {
     831       54120 :       auto dimension = datum.assembly().getDimension();
     832             : 
     833       54120 :       if (datum.isNodal())
     834             :       {
     835       54120 :         auto node = datum.node();
     836             : 
     837      162236 :         for (unsigned int c = 0; c < dimension; ++c)
     838      108116 :           value(c) = sys.getVectorDofValue(sys.getNodeLocalDofIndex(node, c, var), tag);
     839             :       }
     840             :       else
     841             :       {
     842           0 :         auto elem = datum.elem().id;
     843           0 :         auto offset = idx * dimension;
     844             : 
     845           0 :         for (unsigned int c = 0; c < dimension; ++c)
     846           0 :           value(c) = sys.getVectorDofValue(sys.getElemLocalDofIndex(elem, offset + c, var), tag);
     847             :       }
     848             :     }
     849             :     else
     850             :     {
     851             :       KOKKOS_ASSERT(!datum.isNodal());
     852             : 
     853     1705264 :       auto & elem = datum.elem();
     854     1705264 :       auto side = datum.side();
     855             : 
     856     1705264 :       if (side == libMesh::invalid_uint)
     857     1651504 :         value = sys.getVectorQpVectorValue(elem, datum.qpOffset() + idx, var, tag);
     858             :       else
     859       53760 :         value = sys.getVectorQpVectorValueFace(elem, side, idx, var, tag);
     860             :     }
     861             :   }
     862             :   else
     863      109824 :     value = _var.vectorValue(comp);
     864             : 
     865     1869208 :   return value;
     866             : }
     867             : 
     868             : KOKKOS_FUNCTION inline Real33
     869     1666857 : VectorVariableGradient::operator()(AssemblyDatum & datum, unsigned int qp, unsigned int comp) const
     870             : {
     871             :   KOKKOS_ASSERT(_var.initialized());
     872             : 
     873     1666857 :   Real33 grad = 0;
     874             : 
     875     1666857 :   if (_var.coupled())
     876             :   {
     877             :     KOKKOS_ASSERT(!datum.isNodal());
     878             : 
     879     1666857 :     auto & elem = datum.elem();
     880     1666857 :     auto side = datum.side();
     881     1666857 :     auto & sys = datum.system(_var.sys(comp));
     882     1666857 :     auto var = _var.var(comp);
     883     1666857 :     auto tag = _var.tag();
     884             : 
     885     1666857 :     if (side == libMesh::invalid_uint)
     886     1666857 :       grad = sys.getVectorQpVectorGrad(elem, datum.qpOffset() + qp, var, tag);
     887             :     else
     888           0 :       grad = sys.getVectorQpVectorGradFace(elem, side, datum.J(qp), qp, var, tag);
     889             :   }
     890             : 
     891     1666857 :   return grad;
     892             : }
     893             : 
     894             : KOKKOS_FUNCTION inline Real3
     895      539648 : VectorVariableCurl::operator()(AssemblyDatum & datum, unsigned int qp, unsigned int comp) const
     896             : {
     897             :   KOKKOS_ASSERT(_var.initialized());
     898             : 
     899      539648 :   Real3 curl = 0;
     900             : 
     901      539648 :   if (_var.coupled())
     902             :   {
     903             :     KOKKOS_ASSERT(!datum.isNodal());
     904             : 
     905      539648 :     auto & elem = datum.elem();
     906      539648 :     auto side = datum.side();
     907      539648 :     auto & sys = datum.system(_var.sys(comp));
     908      539648 :     auto var = _var.var(comp);
     909      539648 :     auto tag = _var.tag();
     910             : 
     911      539648 :     if (side == libMesh::invalid_uint)
     912      539648 :       curl = sys.getVectorQpVectorCurl(elem, datum.qpOffset() + qp, var, tag);
     913             :     else
     914             :     {
     915           0 :       auto fe = sys.getFETypeID(var);
     916           0 :       auto n_dofs = datum.assembly().getNumDofs(elem.type, fe);
     917           0 :       auto & grad_phi = datum.assembly().getVectorGradPhiFace(elem.subdomain, elem.type, fe)(side);
     918           0 :       auto jacobian = datum.J(qp);
     919           0 :       auto jacobian_transpose = jacobian.transpose();
     920           0 :       Real33 grad = 0;
     921             : 
     922           0 :       for (unsigned int i = 0; i < n_dofs; ++i)
     923           0 :         grad += sys.getVectorDofValue(sys.getElemLocalDofIndex(elem.id, i, var), tag) *
     924           0 :                 (grad_phi(i, qp) * jacobian_transpose);
     925             : 
     926           0 :       curl = curlFromVectorGradient(grad, datum.assembly().getDimension());
     927             :     }
     928             :   }
     929             : 
     930      539648 :   return curl;
     931             : }
     932             : 
     933             : template <>
     934             : struct ArrayDeepCopy<ADVariableValue>
     935             : {
     936             :   static constexpr bool value = true;
     937             : };
     938             : 
     939             : template <>
     940             : struct ArrayDeepCopy<ADVariableGradient>
     941             : {
     942             :   static constexpr bool value = true;
     943             : };
     944             : ///@}
     945             : 
     946             : } // namespace Moose::Kokkos

Generated by: LCOV version 1.14