TensorAsExpressionRank2TestHelpers.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <iterator>
8 #include <numeric>
9 
13 
14 namespace TestHelpers::TensorExpressions {
15 /// \ingroup TestingFrameworkGroup
16 /// \brief Test that the transformation between LHS and RHS multi-indices and
17 /// the subsequent computed RHS multi-index of a rank 2 tensor is correctly
18 /// computed by the functions of TensorAsExpression, according to the orders of
19 /// the LHS and RHS generic indices
20 ///
21 /// \details The functions tested are:
22 /// - `TensorAsExpression::compute_index_transformation`
23 /// - `TensorAsExpression::compute_rhs_multi_index`
24 ///
25 /// If we consider the RHS tensor's generic indices to be (a, b), the possible
26 /// orderings of the LHS tensor's generic indices are: (a, b) and (b, a). For
27 /// each of these cases, this test checks that for each LHS component's
28 /// multi-index, the equivalent RHS multi-index is correctly computed.
29 ///
30 /// \param tensorindex_a the first TensorIndex used on the RHS of the
31 /// TensorExpression, e.g. `ti_a`
32 /// \param tensorindex_b the second TensorIndex used on the RHS of the
33 /// TensorExpression, e.g. `ti_B`
34 template <typename TensorIndexA, typename TensorIndexB>
36  const TensorIndexA& tensorindex_a,
37  const TensorIndexB& tensorindex_b) noexcept {
38  const size_t dim_a = 3;
39  const size_t dim_b = 4;
40 
41  const IndexType indextype_a =
42  TensorIndexA::is_spacetime ? IndexType::Spacetime : IndexType::Spatial;
43  const IndexType indextype_b =
44  TensorIndexB::is_spacetime ? IndexType::Spacetime : IndexType::Spatial;
45 
46  Tensor<
47  double, Symmetry<2, 1>,
48  index_list<Tensor_detail::TensorIndexType<dim_a, TensorIndexA::valence,
49  Frame::Inertial, indextype_a>,
50  Tensor_detail::TensorIndexType<dim_b, TensorIndexB::valence,
51  Frame::Inertial, indextype_b>>>
52  rhs_tensor{};
53  std::iota(rhs_tensor.begin(), rhs_tensor.end(), 0.0);
54  // Get TensorExpression from RHS tensor
55  const auto R_ab_expr = rhs_tensor(tensorindex_a, tensorindex_b);
56 
57  const std::array<size_t, 2> index_order_ab = {TensorIndexA::value,
58  TensorIndexB::value};
59  const std::array<size_t, 2> index_order_ba = {TensorIndexB::value,
60  TensorIndexA::value};
61 
62  const std::array<size_t, 2> actual_ab_to_ab_transformation =
63  R_ab_expr.compute_index_transformation(index_order_ab);
64  const std::array<size_t, 2> expected_ab_to_ab_transformation = {0, 1};
65  const std::array<size_t, 2> actual_ba_to_ab_transformation =
66  R_ab_expr.compute_index_transformation(index_order_ba);
67  const std::array<size_t, 2> expected_ba_to_ab_transformation = {1, 0};
68 
69  CHECK(actual_ab_to_ab_transformation == expected_ab_to_ab_transformation);
70  CHECK(actual_ba_to_ab_transformation == expected_ba_to_ab_transformation);
71 
72  for (size_t i = 0; i < dim_a; i++) {
73  for (size_t j = 0; j < dim_b; j++) {
74  const std::array<size_t, 2> ij = {i, j};
75  const std::array<size_t, 2> ji = {j, i};
76 
77  // For L_{ab} = R_{ab}, check that L_{ij} == R_{ij}
78  CHECK(R_ab_expr.compute_rhs_multi_index(
79  ij, expected_ab_to_ab_transformation) == ij);
80  // For L_{ba} = R_{ab}, check that L_{ij} == R_{ji}
81  CHECK(R_ab_expr.compute_rhs_multi_index(
82  ij, expected_ba_to_ab_transformation) == ji);
83  }
84  }
85 }
86 } // namespace TestHelpers::TensorExpressions
TestHelpers::TensorExpressions::test_tensor_as_expression_rank_2
void test_tensor_as_expression_rank_2(const TensorIndexA &tensorindex_a, const TensorIndexB &tensorindex_b) noexcept
Test that the transformation between LHS and RHS multi-indices and the subsequent computed RHS multi-...
Definition: TensorAsExpressionRank2TestHelpers.hpp:35
Frame::Inertial
Definition: IndexType.hpp:44
TensorExpression.hpp
IndexType.hpp
iterator
IndexType::Spatial
@ Spatial
The TensorIndexType is purely spatial.
IndexType::Spacetime
@ Spacetime
The TensorIndexType is a spacetime index.
cstddef
std::array< size_t, 2 >
Symmetry
typename detail::SymmetryImpl< std::make_index_sequence< sizeof...(T)>, tmpl::integral_list< std::int32_t, T... > >::type Symmetry
Computes the canonical symmetry from the integers T
Definition: Symmetry.hpp:81
IndexType
IndexType
Definition: IndexType.hpp:134
Tensor.hpp
numeric
cpp2b::iota
constexpr void iota(ForwardIterator first, ForwardIterator last, T value)
Definition: Numeric.hpp:20