SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor - Symmetry.hpp Hit Total Coverage
Commit: 211167e84d5366aa6305a94e83962b4ee105745d Lines: 2 2 100.0 %
Date: 2024-04-16 22:08:56
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 metafunctions used to compute the Symmetry<...> for a Tensor
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <type_traits>
      10             : 
      11             : #include "Utilities/Array.hpp"
      12             : #include "Utilities/TMPL.hpp"
      13             : 
      14             : namespace detail {
      15             : template <size_t Size>
      16             : constexpr int find_reduced_index(
      17             :     const cpp20::array<std::pair<int, int>, Size>& t, const int value) {
      18             :   for (size_t i = 0; i < Size; ++i) {
      19             :     if (t[i].first == value) {
      20             :       return t[i].second;
      21             :     }
      22             :   }
      23             :   return 0;
      24             : }
      25             : 
      26             : template <size_t Size>
      27             : constexpr cpp20::array<int, Size> symmetry(
      28             :     const std::array<int, Size>& input_symm) {
      29             :   cpp20::array<int, Size> output_symm{};
      30             :   int next_symm_entry = 1;
      31             :   cpp20::array<std::pair<int, int>, Size> input_to_output_map{};
      32             :   size_t input_to_output_map_size = 0;
      33             :   for (size_t i = Size - 1; i < Size; --i) {
      34             :     // clang-tidy: use gsl::at
      35             :     int found_symm_entry =
      36             :         find_reduced_index(input_to_output_map, input_symm[i]);  // NOLINT
      37             :     if (found_symm_entry == 0) {
      38             :       output_symm[i] = next_symm_entry;  // NOLINT
      39             :       input_to_output_map[input_to_output_map_size].first =
      40             :           input_symm[i];  // NOLINT
      41             :       input_to_output_map[input_to_output_map_size].second = output_symm[i];
      42             :       input_to_output_map_size++;
      43             :       next_symm_entry++;
      44             :     } else {
      45             :       output_symm[i] = found_symm_entry;
      46             :     }
      47             :   }
      48             :   return output_symm;
      49             : }
      50             : 
      51             : template <typename IndexSequence, typename SymmetrySequence>
      52             : struct SymmetryImpl;
      53             : 
      54             : template <size_t... Is, std::int32_t... Ss>
      55             : struct SymmetryImpl<std::index_sequence<Is...>,
      56             :                     tmpl::integral_list<std::int32_t, Ss...>> {
      57             :   static_assert((... and (Ss > 0)),
      58             :                 "Symmetry values must be positive integers.");
      59             :   static constexpr cpp20::array<int, sizeof...(Is)> t =
      60             :       symmetry(std::array<int, sizeof...(Is)>{{Ss...}});
      61             :   using type = tmpl::integral_list<std::int32_t, t[Is]...>;
      62             : };
      63             : }  // namespace detail
      64             : 
      65             : /// \ingroup TensorGroup
      66             : /// \brief Computes the canonical symmetry from the integers `T`
      67             : ///
      68             : /// \details
      69             : /// Compute the canonical symmetry typelist given a set of integers, T. The
      70             : /// resulting typelist is in ascending order of the integers, from right to
      71             : /// left. For example, the result of `Symmetry<1, 2, 1, 3>` is
      72             : /// `integral_list<int32_t, 2, 3, 2, 1>`. Anti-symmetries are not currently
      73             : /// supported.
      74             : ///
      75             : /// \tparam T the integers denoting the symmetry of the Tensor
      76             : template <std::int32_t... T>
      77           1 : using Symmetry = typename detail::SymmetryImpl<
      78             :     std::make_index_sequence<sizeof...(T)>,
      79             :     tmpl::integral_list<std::int32_t, T...>>::type;

Generated by: LCOV version 1.14