ComputeRhsTensorIndexRank3TestHelpers.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 
10 #include "Utilities/GenerateInstantiations.hpp"
11 #include "Utilities/TMPL.hpp"
12 
13 namespace TestHelpers::TensorExpressions {
14 
15 /// \ingroup TestingFrameworkGroup
16 /// \brief Test that the computed tensor multi-index of a rank 3 RHS Tensor is
17 /// equivalent to the given LHS tensor multi-index, according to the order of
18 /// their generic indices
19 ///
20 /// \details `TensorIndexA`, `TensorIndexB`, and `TensorIndexC` can be any type
21 /// of TensorIndex and are not necessarily `ti_a_t`, `ti_b_t`, and `ti_c_t`. The
22 /// "A", "B", and "C" suffixes just denote the ordering of the generic indices
23 /// of the RHS tensor expression. In the RHS tensor expression, it means
24 /// `TensorIndexA` is the first index used, `TensorIndexB` is the second index
25 /// used, and `TensorIndexC` is the third index used.
26 ///
27 /// If we consider the RHS tensor's generic indices to be (a, b, c), the
28 /// possible orderings of the LHS tensor's generic indices are: (a, b, c),
29 /// (a, c, b), (b, a, c), (b, c, a), (c, a, b), and (c, b, a). For each of these
30 /// cases, this test checks that for each LHS component's tensor multi-index,
31 /// the equivalent RHS tensor multi-index is correctly computed.
32 ///
33 /// \tparam DataType the type of data being stored in the Tensors
34 /// \tparam RhsSymmetry the ::Symmetry of the RHS Tensor
35 /// \tparam RhsTensorIndexTypeList the RHS Tensor's typelist of
36 /// \ref SpacetimeIndex "TensorIndexType"s
37 /// \param tensorindex_a the first TensorIndex used on the RHS of the
38 /// TensorExpression, e.g. `ti_a`
39 /// \param tensorindex_b the second TensorIndex used on the RHS of the
40 /// TensorExpression, e.g. `ti_B`
41 /// \param tensorindex_c the third TensorIndex used on the RHS of the
42 /// TensorExpression, e.g. `ti_c`
43 template <typename DataType, typename RhsSymmetry,
44  typename RhsTensorIndexTypeList, typename TensorIndexA,
45  typename TensorIndexB, typename TensorIndexC>
47  const TensorIndexA& tensorindex_a, const TensorIndexB& tensorindex_b,
48  const TensorIndexC& tensorindex_c) noexcept {
49  const Tensor<DataType, RhsSymmetry, RhsTensorIndexTypeList> rhs_tensor(5_st);
50  // Get TensorExpression from RHS tensor
51  const auto R_abc = rhs_tensor(tensorindex_a, tensorindex_b, tensorindex_c);
52 
53  const std::array<size_t, 3> index_order_abc = {
54  TensorIndexA::value, TensorIndexB::value, TensorIndexC::value};
55  const std::array<size_t, 3> index_order_acb = {
56  TensorIndexA::value, TensorIndexC::value, TensorIndexB::value};
57  const std::array<size_t, 3> index_order_bac = {
58  TensorIndexB::value, TensorIndexA::value, TensorIndexC::value};
59  const std::array<size_t, 3> index_order_bca = {
60  TensorIndexB::value, TensorIndexC::value, TensorIndexA::value};
61  const std::array<size_t, 3> index_order_cab = {
62  TensorIndexC::value, TensorIndexA::value, TensorIndexB::value};
63  const std::array<size_t, 3> index_order_cba = {
64  TensorIndexC::value, TensorIndexB::value, TensorIndexA::value};
65 
66  const size_t dim_a = tmpl::at_c<RhsTensorIndexTypeList, 0>::dim;
67  const size_t dim_b = tmpl::at_c<RhsTensorIndexTypeList, 1>::dim;
68  const size_t dim_c = tmpl::at_c<RhsTensorIndexTypeList, 2>::dim;
69 
70  for (size_t i = 0; i < dim_a; i++) {
71  for (size_t j = 0; j < dim_b; j++) {
72  for (size_t k = 0; k < dim_c; k++) {
73  const std::array<size_t, 3> ijk = {i, j, k};
74  const std::array<size_t, 3> ikj = {i, k, j};
75  const std::array<size_t, 3> jik = {j, i, k};
76  const std::array<size_t, 3> jki = {j, k, i};
77  const std::array<size_t, 3> kij = {k, i, j};
78  const std::array<size_t, 3> kji = {k, j, i};
79 
80  // For L_{abc} = R_{abc}, check that L_{ijk} == R_{ijk}
81  CHECK(R_abc.compute_rhs_tensor_index(index_order_abc, index_order_abc,
82  ijk) == ijk);
83  // For L_{acb} = R_{abc}, check that L_{ijk} == R_{ikj}
84  CHECK(R_abc.compute_rhs_tensor_index(index_order_acb, index_order_abc,
85  ijk) == ikj);
86  // For L_{bac} = R_{abc}, check that L_{ijk} == R_{jik}
87  CHECK(R_abc.compute_rhs_tensor_index(index_order_bac, index_order_abc,
88  ijk) == jik);
89  // For L_{bca} = R_{abc}, check that L_{ijk} == R_{kij}
90  CHECK(R_abc.compute_rhs_tensor_index(index_order_bca, index_order_abc,
91  ijk) == kij);
92  // For L_{cab} = R_{abc}, check that L_{ijk} == R_{jki}
93  CHECK(R_abc.compute_rhs_tensor_index(index_order_cab, index_order_abc,
94  ijk) == jki);
95  // For L_{cba} = R_{abc}, check that L_{ijk} == R_{kji}
96  CHECK(R_abc.compute_rhs_tensor_index(index_order_cba, index_order_abc,
97  ijk) == kji);
98  }
99  }
100  }
101 }
102 
103 /// \ingroup TestingFrameworkGroup
104 /// \brief Iterate testing of computing the RHS tensor multi-index equivalent of
105 /// the LHS tensor multi-index with rank 3 Tensors on multiple Frame types and
106 /// dimension combinations for nonsymmetric indices
107 ///
108 /// We test various different symmetries across several functions to ensure that
109 /// the code works correctly with symmetries. This function tests one of the
110 /// following symmetries:
111 /// - <3, 2, 1> (`test_compute_rhs_tensor_index_rank_3_no_symmetry`)
112 /// - <2, 2, 1> (`test_compute_rhs_tensor_index_rank_3_ab_symmetry`)
113 /// - <2, 1, 2> (`test_compute_rhs_tensor_index_rank_3_ac_symmetry`)
114 /// - <2, 1, 1> (`test_compute_rhs_tensor_index_rank_3_bc_symmetry`)
115 /// - <1, 1, 1> (`test_compute_rhs_tensor_index_rank_3_abc_symmetry`)
116 ///
117 /// \details `TensorIndexA`, `TensorIndexB`, and `TensorIndexC` can be any type
118 /// of TensorIndex and are not necessarily `ti_a_t`, `ti_b_t`, and `ti_c_t`. The
119 /// "A", "B", and "C" suffixes just denote the ordering of the generic indices
120 /// of the RHS tensor expression. In the RHS tensor expression, it means
121 /// `TensorIndexA` is the first index used, `TensorIndexB` is the second index
122 /// used, and `TensorIndexC` is the third index used.
123 ///
124 /// Note: the functions dealing with symmetric indices have fewer template
125 /// parameters due to the indices having a shared \ref SpacetimeIndex
126 /// "TensorIndexType" and valence
127 ///
128 /// \tparam DataType the type of data being stored in the Tensors
129 /// \tparam TensorIndexTypeA the \ref SpacetimeIndex "TensorIndexType" of the
130 /// first index of the RHS Tensor
131 /// \tparam TensorIndexTypeB the \ref SpacetimeIndex "TensorIndexType" of the
132 /// second index of the RHS Tensor
133 /// \tparam TensorIndexTypeC the \ref SpacetimeIndex "TensorIndexType" of the
134 /// third index of the RHS Tensor
135 /// \tparam ValenceA the valence of the first index used on the RHS of the
136 /// TensorExpression
137 /// \tparam ValenceB the valence of the second index used on the RHS of the
138 /// TensorExpression
139 /// \tparam ValenceC the valence of the third index used on the RHS of the
140 /// TensorExpression
141 /// \param tensorindex_a the first TensorIndex used on the RHS of the
142 /// TensorExpression, e.g. `ti_a`
143 /// \param tensorindex_b the second TensorIndex used on the RHS of the
144 /// TensorExpression, e.g. `ti_B`
145 /// \param tensorindex_c the third TensorIndex used on the RHS of the
146 /// TensorExpression, e.g. `ti_c`
147 template <typename DataType,
148  template <size_t, UpLo, typename> class TensorIndexTypeA,
149  template <size_t, UpLo, typename> class TensorIndexTypeB,
150  template <size_t, UpLo, typename> class TensorIndexTypeC,
151  UpLo ValenceA, UpLo ValenceB, UpLo ValenceC, typename TensorIndexA,
152  typename TensorIndexB, typename TensorIndexC>
154  const TensorIndexA& tensorindex_a, const TensorIndexB& tensorindex_b,
155  const TensorIndexC& tensorindex_c) noexcept {
156 #define DIM_A(data) BOOST_PP_TUPLE_ELEM(0, data)
157 #define DIM_B(data) BOOST_PP_TUPLE_ELEM(1, data)
158 #define DIM_C(data) BOOST_PP_TUPLE_ELEM(2, data)
159 #define FRAME(data) BOOST_PP_TUPLE_ELEM(3, data)
160 
161 #define CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL(_, data) \
162  test_compute_rhs_tensor_index_rank_3_impl< \
163  DataType, Symmetry<3, 2, 1>, \
164  index_list<TensorIndexTypeA<DIM_A(data), ValenceA, FRAME(data)>, \
165  TensorIndexTypeB<DIM_B(data), ValenceB, FRAME(data)>, \
166  TensorIndexTypeC<DIM_C(data), ValenceC, FRAME(data)>>>( \
167  tensorindex_a, tensorindex_b, tensorindex_c);
168 
169  GENERATE_INSTANTIATIONS(CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL,
170  (1, 2, 3), (1, 2, 3), (1, 2, 3),
172 
173 #undef CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL
174 #undef FRAME
175 #undef DIM_C
176 #undef DIM_B
177 #undef DIM_A
178 }
179 
180 /// \ingroup TestingFrameworkGroup
181 /// \copydoc test_compute_rhs_tensor_index_rank_3_no_symmetry()
182 template <typename DataType,
183  template <size_t, UpLo, typename> class TensorIndexTypeAB,
184  template <size_t, UpLo, typename> class TensorIndexTypeC,
185  UpLo ValenceAB, UpLo ValenceC, typename TensorIndexA,
186  typename TensorIndexB, typename TensorIndexC>
188  const TensorIndexA& tensorindex_a, const TensorIndexB& tensorindex_b,
189  const TensorIndexC& tensorindex_c) noexcept {
190 #define DIM_AB(data) BOOST_PP_TUPLE_ELEM(0, data)
191 #define DIM_C(data) BOOST_PP_TUPLE_ELEM(1, data)
192 #define FRAME(data) BOOST_PP_TUPLE_ELEM(2, data)
193 
194 #define CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL(_, data) \
195  test_compute_rhs_tensor_index_rank_3_impl< \
196  DataType, Symmetry<2, 2, 1>, \
197  index_list<TensorIndexTypeAB<DIM_AB(data), ValenceAB, FRAME(data)>, \
198  TensorIndexTypeAB<DIM_AB(data), ValenceAB, FRAME(data)>, \
199  TensorIndexTypeC<DIM_C(data), ValenceC, FRAME(data)>>>( \
200  tensorindex_a, tensorindex_b, tensorindex_c);
201 
202  GENERATE_INSTANTIATIONS(CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL,
203  (1, 2, 3), (1, 2, 3), (Frame::Grid, Frame::Inertial))
204 
205 #undef CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL
206 #undef FRAME
207 #undef DIM_C
208 #undef DIM_AB
209 }
210 
211 /// \ingroup TestingFrameworkGroup
212 /// \copydoc test_compute_rhs_tensor_index_rank_3_no_symmetry()
213 template <typename DataType,
214  template <size_t, UpLo, typename> class TensorIndexTypeAC,
215  template <size_t, UpLo, typename> class TensorIndexTypeB,
216  UpLo ValenceAC, UpLo ValenceB, typename TensorIndexA,
217  typename TensorIndexB, typename TensorIndexC>
219  const TensorIndexA& tensorindex_a, const TensorIndexB& tensorindex_b,
220  const TensorIndexC& tensorindex_c) noexcept {
221 #define DIM_AC(data) BOOST_PP_TUPLE_ELEM(0, data)
222 #define DIM_B(data) BOOST_PP_TUPLE_ELEM(1, data)
223 #define FRAME(data) BOOST_PP_TUPLE_ELEM(2, data)
224 
225 #define CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL(_, data) \
226  test_compute_rhs_tensor_index_rank_3_impl< \
227  DataType, Symmetry<2, 1, 2>, \
228  index_list<TensorIndexTypeAC<DIM_AC(data), ValenceAC, FRAME(data)>, \
229  TensorIndexTypeB<DIM_B(data), ValenceB, FRAME(data)>, \
230  TensorIndexTypeAC<DIM_AC(data), ValenceAC, FRAME(data)>>>( \
231  tensorindex_a, tensorindex_b, tensorindex_c);
232 
233  GENERATE_INSTANTIATIONS(CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL,
234  (1, 2, 3), (1, 2, 3), (Frame::Grid, Frame::Inertial))
235 
236 #undef CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL
237 #undef FRAME
238 #undef DIM_B
239 #undef DIM_AC
240 }
241 
242 /// \ingroup TestingFrameworkGroup
243 /// \copydoc test_compute_rhs_tensor_index_rank_3_no_symmetry()
244 template <typename DataType,
245  template <size_t, UpLo, typename> class TensorIndexTypeA,
246  template <size_t, UpLo, typename> class TensorIndexTypeBC,
247  UpLo ValenceA, UpLo ValenceBC, typename TensorIndexA,
248  typename TensorIndexB, typename TensorIndexC>
250  const TensorIndexA& tensorindex_a, const TensorIndexB& tensorindex_b,
251  const TensorIndexC& tensorindex_c) noexcept {
252 #define DIM_A(data) BOOST_PP_TUPLE_ELEM(0, data)
253 #define DIM_BC(data) BOOST_PP_TUPLE_ELEM(1, data)
254 #define FRAME(data) BOOST_PP_TUPLE_ELEM(2, data)
255 
256 #define CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL(_, data) \
257  test_compute_rhs_tensor_index_rank_3_impl< \
258  DataType, Symmetry<2, 1, 1>, \
259  index_list<TensorIndexTypeA<DIM_A(data), ValenceA, FRAME(data)>, \
260  TensorIndexTypeBC<DIM_BC(data), ValenceBC, FRAME(data)>, \
261  TensorIndexTypeBC<DIM_BC(data), ValenceBC, FRAME(data)>>>( \
262  tensorindex_a, tensorindex_b, tensorindex_c);
263 
264  GENERATE_INSTANTIATIONS(CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL,
265  (1, 2, 3), (1, 2, 3), (Frame::Grid, Frame::Inertial))
266 
267 #undef CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL
268 #undef FRAME
269 #undef DIM_BC
270 #undef DIM_A
271 }
272 
273 /// \ingroup TestingFrameworkGroup
274 /// \copydoc test_compute_rhs_tensor_index_rank_3_no_symmetry()
275 template <typename DataType,
276  template <size_t, UpLo, typename> class TensorIndexType, UpLo Valence,
277  typename TensorIndexA, typename TensorIndexB, typename TensorIndexC>
279  const TensorIndexA& tensorindex_a, const TensorIndexB& tensorindex_b,
280  const TensorIndexC& tensorindex_c) noexcept {
281 #define DIM(data) BOOST_PP_TUPLE_ELEM(0, data)
282 #define FRAME(data) BOOST_PP_TUPLE_ELEM(1, data)
283 
284 #define CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL(_, data) \
285  test_compute_rhs_tensor_index_rank_3_impl< \
286  DataType, Symmetry<1, 1, 1>, \
287  index_list<TensorIndexType<DIM(data), Valence, FRAME(data)>, \
288  TensorIndexType<DIM(data), Valence, FRAME(data)>, \
289  TensorIndexType<DIM(data), Valence, FRAME(data)>>>( \
290  tensorindex_a, tensorindex_b, tensorindex_c);
291 
292  GENERATE_INSTANTIATIONS(CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL,
293  (1, 2, 3), (Frame::Grid, Frame::Inertial))
294 
295 #undef CALL_TEST_COMPUTE_RHS_TENSOR_INDEX_RANK_3_IMPL
296 #undef FRAME
297 #undef DIM
298 }
299 
300 } // namespace TestHelpers::TensorExpressions
TestHelpers::TensorExpressions::test_compute_rhs_tensor_index_rank_3_impl
void test_compute_rhs_tensor_index_rank_3_impl(const TensorIndexA &tensorindex_a, const TensorIndexB &tensorindex_b, const TensorIndexC &tensorindex_c) noexcept
Test that the computed tensor multi-index of a rank 3 RHS Tensor is equivalent to the given LHS tenso...
Definition: ComputeRhsTensorIndexRank3TestHelpers.hpp:46
TestHelpers::TensorExpressions::test_compute_rhs_tensor_index_rank_3_abc_symmetry
void test_compute_rhs_tensor_index_rank_3_abc_symmetry(const TensorIndexA &tensorindex_a, const TensorIndexB &tensorindex_b, const TensorIndexC &tensorindex_c) noexcept
Iterate testing of computing the RHS tensor multi-index equivalent of the LHS tensor multi-index with...
Definition: ComputeRhsTensorIndexRank3TestHelpers.hpp:278
Frame::Inertial
Definition: IndexType.hpp:44
TensorExpression.hpp
UpLo
UpLo
Definition: IndexType.hpp:20
Frame::Grid
Definition: IndexType.hpp:43
TestHelpers::TensorExpressions::test_compute_rhs_tensor_index_rank_3_ab_symmetry
void test_compute_rhs_tensor_index_rank_3_ab_symmetry(const TensorIndexA &tensorindex_a, const TensorIndexB &tensorindex_b, const TensorIndexC &tensorindex_c) noexcept
Iterate testing of computing the RHS tensor multi-index equivalent of the LHS tensor multi-index with...
Definition: ComputeRhsTensorIndexRank3TestHelpers.hpp:187
TestHelpers::TensorExpressions::test_compute_rhs_tensor_index_rank_3_no_symmetry
void test_compute_rhs_tensor_index_rank_3_no_symmetry(const TensorIndexA &tensorindex_a, const TensorIndexB &tensorindex_b, const TensorIndexC &tensorindex_c) noexcept
Iterate testing of computing the RHS tensor multi-index equivalent of the LHS tensor multi-index with...
Definition: ComputeRhsTensorIndexRank3TestHelpers.hpp:153
cstddef
TestHelpers::TensorExpressions::test_compute_rhs_tensor_index_rank_3_ac_symmetry
void test_compute_rhs_tensor_index_rank_3_ac_symmetry(const TensorIndexA &tensorindex_a, const TensorIndexB &tensorindex_b, const TensorIndexC &tensorindex_c) noexcept
Iterate testing of computing the RHS tensor multi-index equivalent of the LHS tensor multi-index with...
Definition: ComputeRhsTensorIndexRank3TestHelpers.hpp:218
std::array< size_t, 3 >
Tensor.hpp
GENERATE_INSTANTIATIONS
#define GENERATE_INSTANTIATIONS(INSTANTIATION_MACRO,...)
Macro useful for generating many explicit instantiations of function or class templates.
Definition: GenerateInstantiations.hpp:160
TMPL.hpp
TestHelpers::TensorExpressions::test_compute_rhs_tensor_index_rank_3_bc_symmetry
void test_compute_rhs_tensor_index_rank_3_bc_symmetry(const TensorIndexA &tensorindex_a, const TensorIndexB &tensorindex_b, const TensorIndexC &tensorindex_c) noexcept
Iterate testing of computing the RHS tensor multi-index equivalent of the LHS tensor multi-index with...
Definition: ComputeRhsTensorIndexRank3TestHelpers.hpp:249