SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor/EagerMath - Determinant.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 100.0 % 3 3
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            1 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : /// \file
       5              : /// Defines function for taking the determinant of a rank-2 tensor
       6              : 
       7              : #pragma once
       8              : 
       9              : #include "DataStructures/Tensor/Tensor.hpp"
      10              : #include "Utilities/Gsl.hpp"
      11              : 
      12              : namespace detail {
      13              : template <typename Symm, typename Index, typename = std::nullptr_t>
      14              : struct DeterminantImpl;
      15              : 
      16              : template <typename Symm, typename Index>
      17              : struct DeterminantImpl<Symm, Index, Requires<Index::dim == 1>> {
      18              :   template <typename T>
      19              :   static typename T::type apply(const T& tensor) {
      20              :     return get<0, 0>(tensor);
      21              :   }
      22              : };
      23              : 
      24              : template <typename Symm, typename Index>
      25              : struct DeterminantImpl<Symm, Index, Requires<Index::dim == 2>> {
      26              :   template <typename T>
      27              :   static typename T::type apply(const T& tensor) {
      28              :     const auto& t00 = get<0, 0>(tensor);
      29              :     const auto& t01 = get<0, 1>(tensor);
      30              :     const auto& t10 = get<1, 0>(tensor);
      31              :     const auto& t11 = get<1, 1>(tensor);
      32              :     return t00 * t11 - t01 * t10;
      33              :   }
      34              : };
      35              : 
      36              : template <typename Index>
      37              : struct DeterminantImpl<Symmetry<2, 1>, Index, Requires<Index::dim == 3>> {
      38              :   template <typename T>
      39              :   static typename T::type apply(const T& tensor) {
      40              :     const auto& t00 = get<0, 0>(tensor);
      41              :     const auto& t01 = get<0, 1>(tensor);
      42              :     const auto& t02 = get<0, 2>(tensor);
      43              :     const auto& t10 = get<1, 0>(tensor);
      44              :     const auto& t11 = get<1, 1>(tensor);
      45              :     const auto& t12 = get<1, 2>(tensor);
      46              :     const auto& t20 = get<2, 0>(tensor);
      47              :     const auto& t21 = get<2, 1>(tensor);
      48              :     const auto& t22 = get<2, 2>(tensor);
      49              :     return t00 * (t11 * t22 - t12 * t21) - t01 * (t10 * t22 - t12 * t20) +
      50              :            t02 * (t10 * t21 - t11 * t20);
      51              :   }
      52              : };
      53              : 
      54              : template <typename Index>
      55              : struct DeterminantImpl<Symmetry<1, 1>, Index, Requires<Index::dim == 3>> {
      56              :   template <typename T>
      57              :   static typename T::type apply(const T& tensor) {
      58              :     const auto& t00 = get<0, 0>(tensor);
      59              :     const auto& t01 = get<0, 1>(tensor);
      60              :     const auto& t02 = get<0, 2>(tensor);
      61              :     const auto& t11 = get<1, 1>(tensor);
      62              :     const auto& t12 = get<1, 2>(tensor);
      63              :     const auto& t22 = get<2, 2>(tensor);
      64              :     return t00 * (t11 * t22 - t12 * t12) - t01 * (t01 * t22 - t12 * t02) +
      65              :            t02 * (t01 * t12 - t11 * t02);
      66              :   }
      67              : };
      68              : 
      69              : template <typename Index>
      70              : struct DeterminantImpl<Symmetry<2, 1>, Index, Requires<Index::dim == 4>> {
      71              :   template <typename T>
      72              :   static typename T::type apply(const T& tensor) {
      73              :     const auto& t00 = get<0, 0>(tensor);
      74              :     const auto& t01 = get<0, 1>(tensor);
      75              :     const auto& t02 = get<0, 2>(tensor);
      76              :     const auto& t03 = get<0, 3>(tensor);
      77              :     const auto& t10 = get<1, 0>(tensor);
      78              :     const auto& t11 = get<1, 1>(tensor);
      79              :     const auto& t12 = get<1, 2>(tensor);
      80              :     const auto& t13 = get<1, 3>(tensor);
      81              :     const auto& t20 = get<2, 0>(tensor);
      82              :     const auto& t21 = get<2, 1>(tensor);
      83              :     const auto& t22 = get<2, 2>(tensor);
      84              :     const auto& t23 = get<2, 3>(tensor);
      85              :     const auto& t30 = get<3, 0>(tensor);
      86              :     const auto& t31 = get<3, 1>(tensor);
      87              :     const auto& t32 = get<3, 2>(tensor);
      88              :     const auto& t33 = get<3, 3>(tensor);
      89              :     const auto minor1 = t22 * t33 - t23 * t32;
      90              :     const auto minor2 = t21 * t33 - t23 * t31;
      91              :     const auto minor3 = t20 * t33 - t23 * t30;
      92              :     const auto minor4 = t21 * t32 - t22 * t31;
      93              :     const auto minor5 = t20 * t32 - t22 * t30;
      94              :     const auto minor6 = t20 * t31 - t21 * t30;
      95              :     return t00 * (t11 * minor1 - t12 * minor2 + t13 * minor4) -
      96              :            t01 * (t10 * minor1 - t12 * minor3 + t13 * minor5) +
      97              :            t02 * (t10 * minor2 - t11 * minor3 + t13 * minor6) -
      98              :            t03 * (t10 * minor4 - t11 * minor5 + t12 * minor6);
      99              :   }
     100              : };
     101              : 
     102              : template <typename Index>
     103              : struct DeterminantImpl<Symmetry<1, 1>, Index, Requires<Index::dim == 4>> {
     104              :   template <typename T>
     105              :   static typename T::type apply(const T& tensor) {
     106              :     const auto& t00 = get<0, 0>(tensor);
     107              :     const auto& t01 = get<0, 1>(tensor);
     108              :     const auto& t02 = get<0, 2>(tensor);
     109              :     const auto& t03 = get<0, 3>(tensor);
     110              :     const auto& t11 = get<1, 1>(tensor);
     111              :     const auto& t12 = get<1, 2>(tensor);
     112              :     const auto& t13 = get<1, 3>(tensor);
     113              :     const auto& t22 = get<2, 2>(tensor);
     114              :     const auto& t23 = get<2, 3>(tensor);
     115              :     const auto& t33 = get<3, 3>(tensor);
     116              :     const auto minor1 = t22 * t33 - t23 * t23;
     117              :     const auto minor2 = t12 * t33 - t23 * t13;
     118              :     const auto minor3 = t02 * t33 - t23 * t03;
     119              :     const auto minor4 = t12 * t23 - t22 * t13;
     120              :     const auto minor5 = t02 * t23 - t22 * t03;
     121              :     const auto minor6 = t02 * t13 - t12 * t03;
     122              :     return t00 * (t11 * minor1 - t12 * minor2 + t13 * minor4) -
     123              :            t01 * (t01 * minor1 - t12 * minor3 + t13 * minor5) +
     124              :            t02 * (t01 * minor2 - t11 * minor3 + t13 * minor6) -
     125              :            t03 * (t01 * minor4 - t11 * minor5 + t12 * minor6);
     126              :   }
     127              : };
     128              : }  // namespace detail
     129              : 
     130              : /// @{
     131              : /*!
     132              :  * \ingroup TensorGroup
     133              :  * \brief Computes the determinant of a rank-2 Tensor `tensor`.
     134              :  *
     135              :  * \requires That `tensor` be a rank-2 Tensor, with both indices sharing the
     136              :  *           same dimension and type.
     137              :  */
     138              : template <typename T, typename Symm, typename Index0, typename Index1>
     139            1 : void determinant(const gsl::not_null<Scalar<T>*> det_tensor,
     140              :                  const Tensor<T, Symm, index_list<Index0, Index1>>& tensor) {
     141              :   static_assert(Index0::dim == Index1::dim,
     142              :                 "Cannot take the determinant of a Tensor whose Indices are not "
     143              :                 "of the same dimensionality.");
     144              :   static_assert(Index0::index_type == Index1::index_type,
     145              :                 "Taking the determinant of a mixed Spatial and Spacetime index "
     146              :                 "Tensor is not allowed since it's not clear what that means.");
     147              :   get(*det_tensor) = detail::DeterminantImpl<Symm, Index0>::apply(tensor);
     148              : }
     149              : 
     150              : template <typename T, typename Symm, typename Index0, typename Index1>
     151            1 : Scalar<T> determinant(
     152              :     const Tensor<T, Symm, index_list<Index0, Index1>>& tensor) {
     153              :   Scalar<T> result{};
     154              :   determinant(make_not_null(&result), tensor);
     155              :   return result;
     156              : }
     157              : /// @}
        

Generated by: LCOV version 2.0-1