LCOV - code coverage report
Current view: top level - include/kokkos/materials - KokkosMaterial.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 6f668f Lines: 119 123 96.7 %
Date: 2025-09-22 20:01:15 Functions: 105 280 37.5 %
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             : // initQpStatefulProperties() and computeQpProperties() are intentionally hidden
      13             : // but some compilers generate ugly warnings
      14             : 
      15             : #if defined(__clang__)
      16             : #pragma clang diagnostic push
      17             : #pragma clang diagnostic ignored "-Woverloaded-virtual"
      18             : #elif defined(__GNUC__) || defined(__GNUG__)
      19             : #pragma GCC diagnostic push
      20             : #pragma GCC diagnostic ignored "-Woverloaded-virtual"
      21             : #endif
      22             : 
      23             : #include "KokkosMaterialBase.h"
      24             : #include "KokkosDatum.h"
      25             : 
      26             : #include "Coupleable.h"
      27             : #include "MaterialPropertyInterface.h"
      28             : 
      29             : namespace Moose
      30             : {
      31             : namespace Kokkos
      32             : {
      33             : 
      34             : /**
      35             :  * The base class for a user to derive their own Kokkos materials.
      36             :  *
      37             :  * The polymorphic design of the original MOOSE is reproduced statically by leveraging the Curiously
      38             :  * Recurring Template Pattern (CRTP), a programming idiom that involves a class template inheriting
      39             :  * from a template instantiation of itself. When the user derives their Kokkos object from this
      40             :  * class, the inheritance structure will look like:
      41             :  *
      42             :  * class UserMaterial final : public Moose::Kokkos::Material<UserMaterial>
      43             :  *
      44             :  * It is important to note that the template argument should point to the last derived class.
      45             :  * Therefore, if the user wants to define a derived class that can be further inherited, the derived
      46             :  * class should be a class template as well. Otherwise, it is recommended to mark the derived class
      47             :  * as final to prevent its inheritence by mistake.
      48             :  *
      49             :  * The user is expected to define initQpStatefulProperties() and computeQpProperties() as inlined
      50             :  * public methods in their derived class (not virtual override). The signature of
      51             :  * computeQpProperties() expected to be defined in the derived class is as follows:
      52             :  *
      53             :  * @param qp The local quadrature point index
      54             :  * @param datum The Datum object of the current thread
      55             :  *
      56             :  * KOKKOS_FUNCTION void computeQpProperties(const unsigned int qp, Datum & datum) const;
      57             :  *
      58             :  * The signature of initQpStatefulProperties() can be found in the code below, and its definition in
      59             :  * the derived class is optional. If it is defined in the derived class, it will hide the default
      60             :  * definition in the base class.
      61             :  */
      62             : template <typename Derived>
      63             : class Material : public MaterialBase, public Coupleable, public MaterialPropertyInterface
      64             : {
      65             : public:
      66             :   static InputParameters validParams();
      67             : 
      68             :   /**
      69             :    * Constructor
      70             :    */
      71             :   Material(const InputParameters & parameters);
      72             : 
      73             :   /**
      74             :    * Copy constructor for parallel dispatch
      75             :    */
      76             :   Material(const Material & object);
      77             : 
      78             :   /**
      79             :    * Dispatch stateful material property initialization
      80             :    */
      81             :   virtual void initStatefulProperties(unsigned int) override;
      82             :   /**
      83             :    * Dispatch material property evaluation
      84             :    */
      85             :   virtual void computeProperties() override;
      86             : 
      87             :   /**
      88             :    * Default methods to prevent compile errors even when these methods were not defined in the
      89             :    * derived class
      90             :    */
      91             :   ///@{
      92             :   /**
      93             :    * Initialize stateful material properties on a quadrature point
      94             :    * @param qp The local quadrature point index
      95             :    * @param datum The Datum object of the current thread
      96             :    */
      97           0 :   KOKKOS_FUNCTION void initQpStatefulProperties(const unsigned int /* qp */,
      98             :                                                 Datum & /* datum */) const
      99             :   {
     100           0 :   }
     101             :   ///@}
     102             : 
     103             :   /**
     104             :    * The parallel computation entry functions called by Kokkos
     105             :    */
     106             :   ///@{
     107             :   KOKKOS_FUNCTION void operator()(ElementInit, const ThreadID tid) const;
     108             :   KOKKOS_FUNCTION void operator()(SideInit, const ThreadID tid) const;
     109             :   KOKKOS_FUNCTION void operator()(NeighborInit, const ThreadID tid) const;
     110             :   KOKKOS_FUNCTION void operator()(ElementCompute, const ThreadID tid) const;
     111             :   KOKKOS_FUNCTION void operator()(SideCompute, const ThreadID tid) const;
     112             :   KOKKOS_FUNCTION void operator()(NeighborCompute, const ThreadID tid) const;
     113             :   ///@}
     114             : 
     115             : protected:
     116             :   /**
     117             :    * Get a material property by property name for any state
     118             :    * @tparam T The property data type
     119             :    * @tparam dimension The property dimension
     120             :    * @tparam state The property state
     121             :    * @param prop_name_in The property name
     122             :    * @returns The material property
     123             :    */
     124             :   template <typename T, unsigned int dimension = 0, unsigned int state = 0>
     125             :   MaterialProperty<T, dimension> getKokkosMaterialPropertyByName(const std::string & prop_name_in);
     126             :   /**
     127             :    * Get an old material property by property name
     128             :    * @tparam T The property data type
     129             :    * @tparam dimension The property dimension
     130             :    * @param prop_name The property name
     131             :    * @returns The material property
     132             :    */
     133             :   template <typename T, unsigned int dimension = 0>
     134             :   MaterialProperty<T, dimension> getKokkosMaterialPropertyOldByName(const std::string & prop_name)
     135             :   {
     136             :     return getKokkosMaterialPropertyByName<T, dimension, 1>(prop_name);
     137             :   }
     138             :   /**
     139             :    * Get an older material property by property name
     140             :    * @tparam T The property data type
     141             :    * @tparam dimension The property dimension
     142             :    * @param prop_name The property name
     143             :    * @returns The material property
     144             :    */
     145             :   template <typename T, unsigned int dimension = 0>
     146             :   MaterialProperty<T, dimension> getKokkosMaterialPropertyOlderByName(const std::string & prop_name)
     147             :   {
     148             :     return getKokkosMaterialPropertyByName<T, dimension, 2>(prop_name);
     149             :   }
     150             :   /**
     151             :    * Get a material property for any state
     152             :    * @tparam T The property data type
     153             :    * @tparam dimension The property dimension
     154             :    * @tparam state The property state
     155             :    * @param name The property name or the parameter name containing the property name
     156             :    * @returns The material property
     157             :    */
     158             :   template <typename T, unsigned int dimension = 0, unsigned int state = 0>
     159         123 :   MaterialProperty<T, dimension> getKokkosMaterialProperty(const std::string & name)
     160             :   {
     161         123 :     return getKokkosMaterialPropertyByName<T, dimension, state>(getMaterialPropertyName(name));
     162             :   }
     163             :   /**
     164             :    * Get an old material property
     165             :    * @tparam T The property data type
     166             :    * @tparam dimension The property dimension
     167             :    * @param name The property name or the parameter name containing the property name
     168             :    * @returns The material property
     169             :    */
     170             :   template <typename T, unsigned int dimension = 0>
     171         544 :   MaterialProperty<T, dimension> getKokkosMaterialPropertyOld(const std::string & name)
     172             :   {
     173         544 :     return getKokkosMaterialPropertyByName<T, dimension, 1>(getMaterialPropertyName(name));
     174             :   }
     175             :   /**
     176             :    * Get an older material property
     177             :    * @tparam T The property data type
     178             :    * @tparam dimension The property dimension
     179             :    * @param name The property name or the parameter name containing the property name
     180             :    * @returns The material property
     181             :    */
     182             :   template <typename T, unsigned int dimension = 0>
     183         204 :   MaterialProperty<T, dimension> getKokkosMaterialPropertyOlder(const std::string & name)
     184             :   {
     185         204 :     return getKokkosMaterialPropertyByName<T, dimension, 2>(getMaterialPropertyName(name));
     186             :   }
     187             : 
     188         871 :   virtual void checkMaterialProperty(const std::string & name, const unsigned int state) override
     189             :   {
     190             :     // Avoid performing duplicate checks for triple block/face/neighbor materials
     191         871 :     if (boundaryRestricted() || !_bnd)
     192         299 :       MaterialPropertyInterface::checkMaterialProperty(name, state);
     193         871 :   }
     194             : 
     195        1027 :   virtual bool isBoundaryMaterial() const override { return _bnd; }
     196             : 
     197       13318 :   virtual const std::unordered_set<unsigned int> & getMatPropDependencies() const override
     198             :   {
     199       13318 :     return MaterialPropertyInterface::getMatPropDependencies();
     200             :   }
     201             : 
     202        1064 :   virtual const MaterialData & materialData() const override { return _material_data; }
     203        2048 :   virtual MaterialData & materialData() override { return _material_data; }
     204         838 :   virtual MaterialDataType materialDataType() override { return _material_data_type; }
     205             : 
     206             :   /**
     207             :    * Flag whether the material is on faces
     208             :    */
     209             :   const bool _bnd;
     210             :   /**
     211             :    * Flag whether the material is on neighbor faces
     212             :    */
     213             :   const bool _neighbor;
     214             : 
     215             : private:
     216             :   /**
     217             :    * Flag whether initQpStatefulProperties() was not defined in the derived class
     218             :    */
     219             :   const bool _default_init;
     220             : 
     221             :   /**
     222             :    * Dummy members unused for Kokkos materials
     223             :    */
     224             :   ///@{
     225             :   const QBase * const & _qrule;
     226           0 :   virtual const QBase & qRule() const override { return *_qrule; }
     227             :   ///@}
     228             : };
     229             : 
     230             : template <typename Derived>
     231             : InputParameters
     232      128754 : Material<Derived>::validParams()
     233             : {
     234      128754 :   InputParameters params = MaterialBase::validParams();
     235      128754 :   params += MaterialPropertyInterface::validParams();
     236      386262 :   params.addParamNamesToGroup("use_displaced_mesh", "Advanced");
     237      128754 :   return params;
     238           0 : }
     239             : 
     240             : template <typename Derived>
     241         952 : Material<Derived>::Material(const InputParameters & parameters)
     242             :   : MaterialBase(parameters),
     243             :     Coupleable(this, false),
     244             :     MaterialPropertyInterface(this, blockIDs(), boundaryIDs()),
     245         766 :     _bnd(_material_data_type != Moose::BLOCK_MATERIAL_DATA),
     246         766 :     _neighbor(_material_data_type == Moose::NEIGHBOR_MATERIAL_DATA),
     247         766 :     _default_init(&Derived::initQpStatefulProperties == &Material::initQpStatefulProperties),
     248         770 :     _qrule(_bnd ? (_neighbor ? _subproblem.assembly(_tid, 0).qRuleNeighbor()
     249         260 :                              : _subproblem.assembly(_tid, 0).qRuleFace())
     250         766 :                 : _subproblem.assembly(_tid, 0).qRule())
     251             : {
     252        1108 :   for (auto coupled_var : getCoupledMooseVars())
     253         156 :     addMooseVariableDependency(coupled_var);
     254         952 : }
     255             : 
     256             : template <typename Derived>
     257       36803 : Material<Derived>::Material(const Material & object)
     258             :   : MaterialBase(object),
     259             :     Coupleable(object, {}),
     260             :     MaterialPropertyInterface(object, {}),
     261       29790 :     _bnd(object._bnd),
     262       29790 :     _neighbor(object._neighbor),
     263       29790 :     _default_init(object._default_init),
     264       29790 :     _qrule(object._qrule)
     265             : {
     266       36803 : }
     267             : 
     268             : template <typename Derived>
     269             : void
     270         656 : Material<Derived>::initStatefulProperties(unsigned int)
     271             : {
     272         656 :   if (_default_init)
     273         142 :     return;
     274             : 
     275         514 :   if (!_bnd && !_neighbor)
     276         168 :     ::Kokkos::parallel_for(
     277         264 :         ::Kokkos::RangePolicy<ElementInit, ExecSpace, ::Kokkos::IndexType<ThreadID>>(
     278             :             0, numKokkosElements()),
     279             :         *static_cast<Derived *>(this));
     280         346 :   else if (_bnd && !_neighbor)
     281         178 :     ::Kokkos::parallel_for(
     282         280 :         ::Kokkos::RangePolicy<SideInit, ExecSpace, ::Kokkos::IndexType<ThreadID>>(
     283             :             0, numKokkosElementSides()),
     284             :         *static_cast<Derived *>(this));
     285             :   else
     286         168 :     ::Kokkos::parallel_for(
     287         264 :         ::Kokkos::RangePolicy<NeighborInit, ExecSpace, ::Kokkos::IndexType<ThreadID>>(
     288             :             0, numKokkosElementSides()),
     289             :         *static_cast<Derived *>(this));
     290             : 
     291        1028 :   ::Kokkos::fence();
     292             : }
     293             : 
     294             : template <typename Derived>
     295             : void
     296       36289 : Material<Derived>::computeProperties()
     297             : {
     298       36289 :   if (!_bnd && !_neighbor)
     299       11806 :     ::Kokkos::parallel_for(
     300       19110 :         ::Kokkos::RangePolicy<ElementCompute, ExecSpace, ::Kokkos::IndexType<ThreadID>>(
     301             :             0, numKokkosElements()),
     302             :         *static_cast<Derived *>(this));
     303       24483 :   else if (_bnd && !_neighbor)
     304       12677 :     ::Kokkos::parallel_for(
     305       20552 :         ::Kokkos::RangePolicy<SideCompute, ExecSpace, ::Kokkos::IndexType<ThreadID>>(
     306             :             0, numKokkosElementSides()),
     307             :         *static_cast<Derived *>(this));
     308             :   else
     309       11806 :     ::Kokkos::parallel_for(
     310       19110 :         ::Kokkos::RangePolicy<NeighborCompute, ExecSpace, ::Kokkos::IndexType<ThreadID>>(
     311             :             0, numKokkosElementSides()),
     312             :         *static_cast<Derived *>(this));
     313             : 
     314       36289 :   ::Kokkos::fence();
     315       36289 : }
     316             : 
     317             : template <typename Derived>
     318             : KOKKOS_FUNCTION void
     319        9352 : Material<Derived>::operator()(ElementInit, const ThreadID tid) const
     320             : {
     321        9352 :   auto material = static_cast<const Derived *>(this);
     322        9352 :   auto elem = kokkosElementID(tid);
     323             : 
     324        9352 :   Datum datum(elem, kokkosAssembly(), kokkosSystems());
     325             : 
     326       51368 :   for (unsigned int qp = 0; qp < datum.n_qps(); qp++)
     327             :   {
     328       42016 :     datum.reinit();
     329       42016 :     material->initQpStatefulProperties(qp, datum);
     330             :   }
     331        9352 : }
     332             : 
     333             : template <typename Derived>
     334             : KOKKOS_FUNCTION void
     335         230 : Material<Derived>::operator()(SideInit, const ThreadID tid) const
     336             : {
     337         230 :   auto material = static_cast<const Derived *>(this);
     338         230 :   auto [elem, side] = kokkosElementSideID(tid);
     339             : 
     340         230 :   Datum datum(elem, side, kokkosAssembly(), kokkosSystems());
     341             : 
     342         690 :   for (unsigned int qp = 0; qp < datum.n_qps(); qp++)
     343             :   {
     344         460 :     datum.reinit();
     345         460 :     material->initQpStatefulProperties(qp, datum);
     346             :   }
     347         230 : }
     348             : 
     349             : template <typename Derived>
     350             : KOKKOS_FUNCTION void
     351         170 : Material<Derived>::operator()(NeighborInit, const ThreadID tid) const
     352             : {
     353         170 :   auto material = static_cast<const Derived *>(this);
     354         170 :   auto [elem, side] = kokkosElementSideID(tid);
     355             : 
     356         170 :   Datum datum(elem, side, kokkosAssembly(), kokkosSystems());
     357             : 
     358         510 :   for (unsigned int qp = 0; qp < datum.n_qps(); qp++)
     359             :   {
     360         340 :     datum.reinit();
     361         340 :     material->initQpStatefulProperties(qp, datum);
     362             :   }
     363         170 : }
     364             : 
     365             : template <typename Derived>
     366             : KOKKOS_FUNCTION void
     367      653476 : Material<Derived>::operator()(ElementCompute, const ThreadID tid) const
     368             : {
     369      653476 :   auto material = static_cast<const Derived *>(this);
     370      653476 :   auto elem = kokkosElementID(tid);
     371             : 
     372      653476 :   Datum datum(elem, kokkosAssembly(), kokkosSystems());
     373             : 
     374     3576884 :   for (unsigned int qp = 0; qp < datum.n_qps(); qp++)
     375             :   {
     376     2923408 :     datum.reinit();
     377     2923408 :     material->computeQpProperties(qp, datum);
     378             :   }
     379      653476 : }
     380             : 
     381             : template <typename Derived>
     382             : KOKKOS_FUNCTION void
     383       27110 : Material<Derived>::operator()(SideCompute, const ThreadID tid) const
     384             : {
     385       27110 :   auto material = static_cast<const Derived *>(this);
     386       27110 :   auto [elem, side] = kokkosElementSideID(tid);
     387             : 
     388       27110 :   Datum datum(elem, side, kokkosAssembly(), kokkosSystems());
     389             : 
     390       81330 :   for (unsigned int qp = 0; qp < datum.n_qps(); qp++)
     391             :   {
     392       54220 :     datum.reinit();
     393       54220 :     material->computeQpProperties(qp, datum);
     394             :   }
     395       27110 : }
     396             : 
     397             : template <typename Derived>
     398             : KOKKOS_FUNCTION void
     399       21930 : Material<Derived>::operator()(NeighborCompute, const ThreadID tid) const
     400             : {
     401       21930 :   auto material = static_cast<const Derived *>(this);
     402       21930 :   auto [elem, side] = kokkosElementSideID(tid);
     403             : 
     404       21930 :   Datum datum(elem, side, kokkosAssembly(), kokkosSystems());
     405             : 
     406       65790 :   for (unsigned int qp = 0; qp < datum.n_qps(); qp++)
     407             :   {
     408       43860 :     datum.reinit();
     409       43860 :     material->computeQpProperties(qp, datum);
     410             :   }
     411       21930 : }
     412             : 
     413             : template <typename Derived>
     414             : template <typename T, unsigned int dimension, unsigned int state>
     415             : MaterialProperty<T, dimension>
     416         871 : Material<Derived>::getKokkosMaterialPropertyByName(const std::string & prop_name_in)
     417             : {
     418         871 :   MaterialBase::checkExecutionStage();
     419             : 
     420        1565 :   const auto prop_name =
     421         694 :       _get_suffix.empty()
     422         694 :           ? prop_name_in
     423         694 :           : MooseUtils::join(std::vector<std::string>({prop_name_in, _get_suffix}), "_");
     424             : 
     425             :   if constexpr (state == 0)
     426         123 :     _requested_props.insert(prop_name);
     427             : 
     428         871 :   auto prop =
     429             :       MaterialPropertyInterface::getKokkosMaterialPropertyByName<T, dimension, state>(prop_name);
     430             : 
     431         871 :   registerPropName(prop_name, true, state);
     432             : 
     433        1742 :   return prop;
     434         871 : }
     435             : 
     436             : } // namespace Kokkos
     437             : } // namespace Moose

Generated by: LCOV version 1.14