LCOV - code coverage report
Current view: top level - include/materials - CompileTimeDerivativesMaterial.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 36 37 97.3 %
Date: 2025-07-17 01:28:37 Functions: 85 85 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       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 "Material.h"
      13             : #include "CompileTimeDerivatives.h"
      14             : #include "DerivativeMaterialInterface.h"
      15             : #include "CompileTimeDerivativesMaterialInternal.h"
      16             : 
      17             : /**
      18             :  * @brief Material class to set up an expression and its derivatives built at compile time using the
      19             :  * CompileTimeDerivatives framework.
      20             :  * @tparam N number of coupled variables
      21             :  * @tparam is_ad whether to use forward mode automatic differentiation and to generate Moose AD
      22             :  * material properties
      23             :  * @tparam MaxD maximum derivative order to build
      24             :  */
      25             : template <int N, bool is_ad = false, int MaxD = 3>
      26             : class CompileTimeDerivativesMaterial : public DerivativeMaterialInterface<Material>
      27             : {
      28             : public:
      29             :   CompileTimeDerivativesMaterial(const InputParameters & params,
      30             :                                  const std::array<std::string, N> variables);
      31             :   static InputParameters validParams();
      32             : 
      33             : protected:
      34             :   /**
      35             :    * Entry point for the compile time loop that evaluates all derivatives and assigns them to their
      36             :    * respective  material properties
      37             :    * @arg F the compile time derivative expression object
      38             :    */
      39             :   template <typename T>
      40             :   void evaluate(const T & F);
      41             : 
      42             :   const MaterialPropertyName _F_name;
      43             :   GenericMaterialProperty<Real, is_ad> & _prop_F;
      44             : 
      45             :   /**
      46             :    * The names of the coupled variables
      47             :    */
      48             :   std::array<VariableName, N> _var_name;
      49             : 
      50             :   /**
      51             :    * A serialized list of material properties for all derivatives up to and including order MaxD
      52             :    */
      53             :   std::array<GenericMaterialProperty<Real, is_ad> *,
      54             :              CompileTimeDerivativesMaterialInternal::total_derivatives<MaxD, N>()>
      55             :       _prop_dF;
      56             : 
      57             :   /**
      58             :    * Set up a tuple with one entry per coupled variable (each entry with an increment). The coupled
      59             :    * variables are wrapped in a CTD reference object with a different tag for differentiation. This
      60             :    * makes each reference a different type, so we need to store them in a tuple (as opposed to an
      61             :    * array).
      62             :    */
      63             :   typename decltype(CompileTimeDerivativesMaterialInternal::make_tuple_array<
      64             :                     GenericVariableValue<is_ad>>(std::make_index_sequence<N>{}))::type _refs;
      65             : 
      66             : private:
      67             :   template <std::size_t... Ns>
      68          39 :   auto makeRefsTuple(const std::array<std::string, N> & variables,
      69             :                      const unsigned int & qp,
      70             :                      std::index_sequence<Ns...>)
      71             :   {
      72             :     return std::make_tuple(
      73          78 :         CompileTimeDerivatives::makeRef<Ns>(coupledGenericValue<is_ad>(variables[Ns]), qp)...);
      74             :   }
      75             : 
      76             :   template <std::size_t I>
      77          39 :   constexpr void loopDeclareProperties(std::index_sequence<>)
      78             :   {
      79          39 :   }
      80             :   template <std::size_t I, std::size_t first, std::size_t... tail>
      81        1521 :   constexpr void loopDeclareProperties(std::index_sequence<first, tail...> int_seq)
      82             :   {
      83             :     using namespace CompileTimeDerivativesMaterialInternal;
      84             :     if constexpr (is_sorted(int_seq))
      85             :     {
      86        2496 :       _prop_dF[I] = &declarePropertyDerivative<Real, is_ad>(
      87        1755 :           _F_name, std::vector<VariableName>{_var_name[first], _var_name[tail]...});
      88         741 :       loopDeclareProperties<I + 1>(details::increment<N>(int_seq));
      89             :     }
      90             :     else
      91         780 :       loopDeclareProperties<I>(details::increment<N>(int_seq));
      92        2262 :   }
      93             : 
      94             :   /**
      95             :    * Entry point for the compile time loop that declares all derivative material properties
      96             :    */
      97          39 :   void declareProperties()
      98             :   {
      99             :     using namespace CompileTimeDerivativesMaterialInternal;
     100          39 :     loopDeclareProperties<0>(zeroes<MaxD>());
     101          39 :   }
     102             : 
     103             :   template <std::size_t I, typename T>
     104         512 :   constexpr void loopEvaluate(const T &, std::index_sequence<>)
     105             :   {
     106         512 :   }
     107             :   template <std::size_t I, typename T, std::size_t first, std::size_t... tail>
     108       19968 :   constexpr void loopEvaluate(const T & expression, std::index_sequence<first, tail...> int_seq)
     109             :   {
     110             :     using namespace CompileTimeDerivativesMaterialInternal;
     111             :     if constexpr (is_sorted(int_seq))
     112             :     {
     113        9728 :       (*_prop_dF[I])[_qp] = take_derivatives(expression, int_seq)();
     114        9728 :       loopEvaluate<I + 1>(expression, details::increment<N>(int_seq));
     115             :     }
     116             :     else
     117       10240 :       loopEvaluate<I>(expression, details::increment<N>(int_seq));
     118       19968 :   }
     119             : };
     120             : 
     121             : template <int N, bool is_ad, int MaxD>
     122             : InputParameters
     123       14314 : CompileTimeDerivativesMaterial<N, is_ad, MaxD>::validParams()
     124             : {
     125       14314 :   auto params = DerivativeMaterialInterface<Material>::validParams();
     126       14314 :   params.addRequiredParam<MaterialPropertyName>("property_name",
     127             :                                                 "Name of the parsed material property");
     128       14314 :   return params;
     129           0 : }
     130             : 
     131             : template <int N, bool is_ad, int MaxD>
     132          39 : CompileTimeDerivativesMaterial<N, is_ad, MaxD>::CompileTimeDerivativesMaterial(
     133             :     const InputParameters & params, const std::array<std::string, N> variables)
     134             :   : DerivativeMaterialInterface<Material>(params),
     135          39 :     _F_name(getParam<MaterialPropertyName>("property_name")),
     136          39 :     _prop_F(declareGenericProperty<Real, is_ad>(_F_name)),
     137          78 :     _refs(makeRefsTuple(variables, _qp, std::make_index_sequence<N>{}))
     138             : {
     139             :   // get the names of all coupled variables
     140         156 :   for (const auto i : make_range(N))
     141         117 :     _var_name[i] = coupledName(variables[i]);
     142             : 
     143             :   // declare all material properties
     144          39 :   declareProperties();
     145          39 : }
     146             : 
     147             : template <int N, bool is_ad, int MaxD>
     148             : template <typename T>
     149             : void
     150         512 : CompileTimeDerivativesMaterial<N, is_ad, MaxD>::evaluate(const T & F)
     151             : {
     152         512 :   _prop_F[_qp] = F();
     153             :   using namespace CompileTimeDerivativesMaterialInternal;
     154         512 :   loopEvaluate<0>(F, zeroes<MaxD>());
     155         512 : }

Generated by: LCOV version 1.14