LCOV - code coverage report
Current view: top level - include/utils - EigenADReal.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 22 23 95.7 %
Date: 2025-07-17 01:28:37 Functions: 6 15 40.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 "ADReal.h"
      13             : #include "metaphysicl/raw_type.h"
      14             : 
      15             : namespace Eigen
      16             : {
      17             : namespace internal
      18             : {
      19             : template <typename V, typename D, bool asd>
      20             : inline bool
      21         168 : isinf_impl(const MetaPhysicL::DualNumber<V, D, asd> & a)
      22             : {
      23         168 :   return std::isinf(a);
      24             : }
      25             : 
      26             : template <typename V, typename D, bool asd>
      27             : inline bool
      28         168 : isnan_impl(const MetaPhysicL::DualNumber<V, D, asd> & a)
      29             : {
      30         168 :   return std::isnan(a);
      31             : }
      32             : 
      33             : template <typename V, typename D, bool asd>
      34             : inline MetaPhysicL::DualNumber<V, D, asd>
      35             : sqrt(const MetaPhysicL::DualNumber<V, D, asd> & a)
      36             : {
      37             :   return std::sqrt(a);
      38             : }
      39             : 
      40             : template <typename V, typename D, bool asd>
      41             : inline MetaPhysicL::DualNumber<V, D, asd>
      42             : abs(const MetaPhysicL::DualNumber<V, D, asd> & a)
      43             : {
      44             :   return std::abs(a);
      45             : }
      46             : }
      47             : } // namespace Eigen
      48             : 
      49             : // this include _must_ come after the Eigen::internal overloads above. We also ignore a warning
      50             : // about an Eigen internal use of a potentially uninitialized variable
      51             : #include "libmesh/ignore_warnings.h"
      52             : #include <Eigen/Core>
      53             : #include "libmesh/restore_warnings.h"
      54             : 
      55             : // Eigen needs this
      56             : namespace MetaPhysicL
      57             : {
      58             : // raw_value AD->non-AD conversion for ADReal valued Eigen::Matrix objects
      59             : template <typename T, int M, int N, int O, int M2, int N2>
      60             : struct RawType<Eigen::Matrix<T, M, N, O, M2, N2>>
      61             : {
      62             :   typedef Eigen::Matrix<typename RawType<T>::value_type, M, N, O, M2, N2> value_type;
      63             : 
      64           1 :   static value_type value(const Eigen::Matrix<T, M, N, O, M2, N2> & in)
      65             :   {
      66          11 :     return value_type::NullaryExpr([&in](Eigen::Index i) { return raw_value(in(i)); });
      67             :   }
      68             : };
      69             : 
      70             : // raw_value overload for Map type objects that forces evaluation
      71             : template <typename T>
      72             : auto
      73             : raw_value(const Eigen::Map<T> & in)
      74             : {
      75             :   return raw_value(in.eval());
      76             : }
      77             : } // namespace MetaPhysicL
      78             : 
      79             : namespace Eigen
      80             : {
      81             : // libEigen support for dual number types
      82             : template <typename V, typename D, bool asd>
      83             : struct NumTraits<MetaPhysicL::DualNumber<V, D, asd>>
      84             :   : NumTraits<V> // permits to get the epsilon, dummy_precision, lowest, highest functions
      85             : {
      86             :   typedef MetaPhysicL::DualNumber<V, D, asd> Real;
      87             :   typedef MetaPhysicL::DualNumber<V, D, asd> NonInteger;
      88             :   typedef MetaPhysicL::DualNumber<V, D, asd> Nested;
      89             : 
      90             :   enum
      91             :   {
      92             :     IsComplex = 0,
      93             :     IsInteger = 0,
      94             :     IsSigned = 1,
      95             :     RequireInitialization = 1,
      96             :     ReadCost = HugeCost,
      97             :     AddCost = HugeCost,
      98             :     MulCost = HugeCost
      99             :   };
     100             : };
     101             : 
     102             : template <typename BinaryOp, typename V, typename D, bool asd>
     103             : struct ScalarBinaryOpTraits<Real, MetaPhysicL::DualNumber<V, D, asd>, BinaryOp>
     104             : {
     105             :   typedef MetaPhysicL::DualNumber<V, D, asd> ReturnType;
     106             : };
     107             : template <typename BinaryOp, typename V, typename D, bool asd>
     108             : struct ScalarBinaryOpTraits<MetaPhysicL::DualNumber<V, D, asd>, Real, BinaryOp>
     109             : {
     110             :   typedef MetaPhysicL::DualNumber<V, D, asd> ReturnType;
     111             : };
     112             : } // namespace Eigen
     113             : 
     114             : namespace Moose
     115             : {
     116             : template <typename T>
     117             : struct ADType;
     118             : 
     119             : template <typename T, int M, int N, int O, int M2, int N2>
     120             : struct ADType<Eigen::Matrix<T, M, N, O, M2, N2>>
     121             : {
     122             :   typedef typename Eigen::Matrix<typename ADType<T>::type, M, N, O, M2, N2> type;
     123             : };
     124             : }
     125             : 
     126             : namespace Eigen::internal
     127             : {
     128             : 
     129             : template <>
     130             : inline long double
     131             : cast<ADReal, long double>(const ADReal & x)
     132             : {
     133             :   return MetaPhysicL::raw_value(x);
     134             : }
     135             : 
     136             : template <>
     137             : inline double
     138             : cast<ADReal, double>(const ADReal & x)
     139             : {
     140             :   return MetaPhysicL::raw_value(x);
     141             : }
     142             : 
     143             : template <>
     144             : inline long
     145             : cast<ADReal, long>(const ADReal & x)
     146             : {
     147             :   return MetaPhysicL::raw_value(x);
     148             : }
     149             : 
     150             : template <>
     151             : inline int
     152             : cast<ADReal, int>(const ADReal & x)
     153             : {
     154             :   return MetaPhysicL::raw_value(x);
     155             : }
     156             : 
     157             : /**
     158             :  * Override number traits for the ADReal type used in libEigen calculations.
     159             :  * nr and mr are used to determine block matrix (panel) sizes. We keep them
     160             :  * as small as possible to avoid panel sizes that exceed the allowable stack
     161             :  * size. Those numbers could be made a function of the Eigen stack limit and
     162             :  * the number of derivative entries.
     163             :  */
     164             : template <>
     165             : class gebp_traits<ADReal, ADReal, false, false>
     166             : {
     167             : public:
     168             :   typedef ADReal ResScalar;
     169             :   enum
     170             :   {
     171             :     Vectorizable = false,
     172             :     LhsPacketSize = 1,
     173             :     RhsPacketSize = 1,
     174             :     ResPacketSize = 1,
     175             :     NumberOfRegisters = 1,
     176             :     nr = 1,
     177             :     mr = 1,
     178             :     LhsProgress = 1,
     179             :     RhsProgress = 1
     180             :   };
     181             :   typedef ResScalar LhsPacket;
     182             :   typedef ResScalar RhsPacket;
     183             :   typedef ResScalar ResPacket;
     184             :   typedef ResScalar AccPacket;
     185             :   typedef ResScalar LhsPacket4Packing;
     186             : };
     187             : 
     188             : template <typename Index, typename DataMapper, bool ConjugateLhs, bool ConjugateRhs>
     189             : struct gebp_kernel<ADReal, ADReal, Index, DataMapper, 1, 1, ConjugateLhs, ConjugateRhs>
     190             : {
     191             :   EIGEN_DONT_INLINE
     192          27 :   void operator()(const DataMapper & res,
     193             :                   const ADReal * blockA,
     194             :                   const ADReal * blockB,
     195             :                   Index rows,
     196             :                   Index depth,
     197             :                   Index cols,
     198             :                   const ADReal & alpha,
     199             :                   Index strideA = -1,
     200             :                   Index strideB = -1,
     201             :                   Index offsetA = 0,
     202             :                   Index offsetB = 0)
     203             :   {
     204          27 :     if (rows == 0 || cols == 0 || depth == 0)
     205           0 :       return;
     206             : 
     207          27 :     ADReal acc1;
     208             : 
     209          27 :     if (strideA == -1)
     210           1 :       strideA = depth;
     211          27 :     if (strideB == -1)
     212           1 :       strideB = depth;
     213             : 
     214         234 :     for (Index i = 0; i < rows; ++i)
     215         420 :       for (Index j = 0; j < cols; ++j)
     216             :       {
     217         213 :         const ADReal * A = blockA + i * strideA + offsetA;
     218         213 :         const ADReal * B = blockB + j * strideB + offsetB;
     219             : 
     220         213 :         acc1 = 0;
     221        1050 :         for (Index k = 0; k < depth; k++)
     222         837 :           acc1 += A[k] * B[k];
     223         417 :         res(i, j) += acc1 * alpha;
     224             :       }
     225          27 :   }
     226             : };
     227             : 
     228             : }

Generated by: LCOV version 1.14