ComputeRhsTensorIndexRank4TestHelpers.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 
7 #include <cstddef>
8 
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 4 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`, `TensorIndexC`, and `TensorIndexD`
21 /// can be any type of TensorIndex and are not necessarily `ti_a_t`, `ti_b_t`,
22 /// `ti_c_t`, and `ti_d_t`. The "A", "B", "C", and "D" suffixes just denote the
23 /// ordering of the generic indices of the RHS tensor expression. In the RHS
24 /// tensor expression, it means `TensorIndexA` is the first index used,
25 /// `TensorIndexB` is the second index used, `TensorIndexC` is the third index
26 /// used, and `TensorIndexD` is the fourth index used.
27 ///
28 /// If we consider the RHS tensor's generic indices to be (a, b, c, d), there
29 /// are 24 permutations that are possible orderings of the LHS tensor's generic
30 /// indices, such as: (a, b, c, d), e.g. (a, b, d, c), (a, c, b, d), etc. For
31 /// each of these cases, this test checks that for each LHS component's tensor
32 /// multi-index, the equivalent RHS tensor multi-index is correctly computed.
33 ///
34 /// \tparam DataType the type of data being stored in the Tensors
35 /// \tparam RhsSymmetry the ::Symmetry of the RHS Tensor
36 /// \tparam RhsTensorIndexTypeList the RHS Tensor's typelist of
37 /// \ref SpacetimeIndex "TensorIndexType"s
38 /// \param tensorindex_a the first TensorIndex used on the RHS of the
39 /// TensorExpression, e.g. `ti_a`
40 /// \param tensorindex_b the second TensorIndex used on the RHS of the
41 /// TensorExpression, e.g. `ti_B`
42 /// \param tensorindex_c the third TensorIndex used on the RHS of the
43 /// TensorExpression, e.g. `ti_c`
44 /// \param tensorindex_d the fourth TensorIndex used on the RHS of the
45 /// TensorExpression, e.g. `ti_D`
46 template <typename DataType, typename RhsSymmetry,
47  typename RhsTensorIndexTypeList, typename TensorIndexA,
48  typename TensorIndexB, typename TensorIndexC, typename TensorIndexD>
50  const TensorIndexA& tensorindex_a, const TensorIndexB& tensorindex_b,
51  const TensorIndexC& tensorindex_c,
52  const TensorIndexD& tensorindex_d) noexcept {
53  const Tensor<DataType, RhsSymmetry, RhsTensorIndexTypeList> rhs_tensor(5_st);
54  // Get TensorExpression from RHS tensor
55  const auto R_abcd =
56  rhs_tensor(tensorindex_a, tensorindex_b, tensorindex_c, tensorindex_d);
57 
58  const std::array<size_t, 4> index_order_abcd = {
59  TensorIndexA::value, TensorIndexB::value, TensorIndexC::value,
60  TensorIndexD::value};
61  const std::array<size_t, 4> index_order_abdc = {
62  TensorIndexA::value, TensorIndexB::value, TensorIndexD::value,
63  TensorIndexC::value};
64  const std::array<size_t, 4> index_order_acbd = {
65  TensorIndexA::value, TensorIndexC::value, TensorIndexB::value,
66  TensorIndexD::value};
67  const std::array<size_t, 4> index_order_acdb = {
68  TensorIndexA::value, TensorIndexC::value, TensorIndexD::value,
69  TensorIndexB::value};
70  const std::array<size_t, 4> index_order_adbc = {
71  TensorIndexA::value, TensorIndexD::value, TensorIndexB::value,
72  TensorIndexC::value};
73  const std::array<size_t, 4> index_order_adcb = {
74  TensorIndexA::value, TensorIndexD::value, TensorIndexC::value,
75  TensorIndexB::value};
76 
77  const std::array<size_t, 4> index_order_bacd = {
78  TensorIndexB::value, TensorIndexA::value, TensorIndexC::value,
79  TensorIndexD::value};
80  const std::array<size_t, 4> index_order_badc = {
81  TensorIndexB::value, TensorIndexA::value, TensorIndexD::value,
82  TensorIndexC::value};
83  const std::array<size_t, 4> index_order_bcad = {
84  TensorIndexB::value, TensorIndexC::value, TensorIndexA::value,
85  TensorIndexD::value};
86  const std::array<size_t, 4> index_order_bcda = {
87  TensorIndexB::value, TensorIndexC::value, TensorIndexD::value,
88  TensorIndexA::value};
89  const std::array<size_t, 4> index_order_bdac = {
90  TensorIndexB::value, TensorIndexD::value, TensorIndexA::value,
91  TensorIndexC::value};
92  const std::array<size_t, 4> index_order_bdca = {
93  TensorIndexB::value, TensorIndexD::value, TensorIndexC::value,
94  TensorIndexA::value};
95 
96  const std::array<size_t, 4> index_order_cabd = {
97  TensorIndexC::value, TensorIndexA::value, TensorIndexB::value,
98  TensorIndexD::value};
99  const std::array<size_t, 4> index_order_cadb = {
100  TensorIndexC::value, TensorIndexA::value, TensorIndexD::value,
101  TensorIndexB::value};
102  const std::array<size_t, 4> index_order_cbad = {
103  TensorIndexC::value, TensorIndexB::value, TensorIndexA::value,
104  TensorIndexD::value};
105  const std::array<size_t, 4> index_order_cbda = {
106  TensorIndexC::value, TensorIndexB::value, TensorIndexD::value,
107  TensorIndexA::value};
108  const std::array<size_t, 4> index_order_cdab = {
109  TensorIndexC::value, TensorIndexD::value, TensorIndexA::value,
110  TensorIndexB::value};
111  const std::array<size_t, 4> index_order_cdba = {
112  TensorIndexC::value, TensorIndexD::value, TensorIndexB::value,
113  TensorIndexA::value};
114 
115  const std::array<size_t, 4> index_order_dabc = {
116  TensorIndexD::value, TensorIndexA::value, TensorIndexB::value,
117  TensorIndexC::value};
118  const std::array<size_t, 4> index_order_dacb = {
119  TensorIndexD::value, TensorIndexA::value, TensorIndexC::value,
120  TensorIndexB::value};
121  const std::array<size_t, 4> index_order_dbac = {
122  TensorIndexD::value, TensorIndexB::value, TensorIndexA::value,
123  TensorIndexC::value};
124  const std::array<size_t, 4> index_order_dbca = {
125  TensorIndexD::value, TensorIndexB::value, TensorIndexC::value,
126  TensorIndexA::value};
127  const std::array<size_t, 4> index_order_dcab = {
128  TensorIndexD::value, TensorIndexC::value, TensorIndexA::value,
129  TensorIndexB::value};
130  const std::array<size_t, 4> index_order_dcba = {
131  TensorIndexD::value, TensorIndexC::value, TensorIndexB::value,
132  TensorIndexA::value};
133 
134  const size_t dim_a = tmpl::at_c<RhsTensorIndexTypeList, 0>::dim;
135  const size_t dim_b = tmpl::at_c<RhsTensorIndexTypeList, 1>::dim;
136  const size_t dim_c = tmpl::at_c<RhsTensorIndexTypeList, 2>::dim;
137  const size_t dim_d = tmpl::at_c<RhsTensorIndexTypeList, 3>::dim;
138 
139  for (size_t i = 0; i < dim_a; i++) {
140  for (size_t j = 0; j < dim_b; j++) {
141  for (size_t k = 0; k < dim_c; k++) {
142  for (size_t l = 0; l < dim_d; l++) {
143  const std::array<size_t, 4> ijkl = {i, j, k, l};
144  const std::array<size_t, 4> ijlk = {i, j, l, k};
145  const std::array<size_t, 4> ikjl = {i, k, j, l};
146  const std::array<size_t, 4> iklj = {i, k, l, j};
147  const std::array<size_t, 4> iljk = {i, l, j, k};
148  const std::array<size_t, 4> ilkj = {i, l, k, j};
149 
150  const std::array<size_t, 4> jikl = {j, i, k, l};
151  const std::array<size_t, 4> jilk = {j, i, l, k};
152  const std::array<size_t, 4> jkil = {j, k, i, l};
153  const std::array<size_t, 4> jkli = {j, k, l, i};
154  const std::array<size_t, 4> jlik = {j, l, i, k};
155  const std::array<size_t, 4> jlki = {j, l, k, i};
156 
157  const std::array<size_t, 4> kijl = {k, i, j, l};
158  const std::array<size_t, 4> kilj = {k, i, l, j};
159  const std::array<size_t, 4> kjil = {k, j, i, l};
160  const std::array<size_t, 4> kjli = {k, j, l, i};
161  const std::array<size_t, 4> klij = {k, l, i, j};
162  const std::array<size_t, 4> klji = {k, l, j, i};
163 
164  const std::array<size_t, 4> lijk = {l, i, j, k};
165  const std::array<size_t, 4> likj = {l, i, k, j};
166  const std::array<size_t, 4> ljik = {l, j, i, k};
167  const std::array<size_t, 4> ljki = {l, j, k, i};
168  const std::array<size_t, 4> lkij = {l, k, i, j};
169  const std::array<size_t, 4> lkji = {l, k, j, i};
170 
171  // For L_{abcd} = R_{abcd}, check that L_{ijkl} == R_{ijkl}
172  CHECK(R_abcd.compute_rhs_tensor_index(
173  index_order_abcd, index_order_abcd, ijkl) == ijkl);
174  // For L_{abdc} = R_{abcd}, check that L_{ijkl} == R_{ijlk}
175  CHECK(R_abcd.compute_rhs_tensor_index(
176  index_order_abdc, index_order_abcd, ijkl) == ijlk);
177  // For L_{acbd} = R_{abcd}, check that L_{ijkl} == R_{ikjl}
178  CHECK(R_abcd.compute_rhs_tensor_index(
179  index_order_acbd, index_order_abcd, ijkl) == ikjl);
180  // For L_{acdb} = R_{abcd}, check that L_{ijkl} == R_{iklj}
181  CHECK(R_abcd.compute_rhs_tensor_index(
182  index_order_acdb, index_order_abcd, ijkl) == iljk);
183  // For L_{adbc} = R_{abcd}, check that L_{ijkl} == R_{iklj}
184  CHECK(R_abcd.compute_rhs_tensor_index(
185  index_order_adbc, index_order_abcd, ijkl) == iklj);
186  // For L_{adcb} = R_{abcd}, check that L_{ijkl} == R_{ilkj}
187  CHECK(R_abcd.compute_rhs_tensor_index(
188  index_order_adcb, index_order_abcd, ijkl) == ilkj);
189 
190  // For L_{bacd} = R_{abcd}, check that L_{ijkl} == R_{jikl}
191  CHECK(R_abcd.compute_rhs_tensor_index(
192  index_order_bacd, index_order_abcd, ijkl) == jikl);
193  // For L_{badc} = R_{abcd}, check that L_{ijkl} == R_{jilk}
194  CHECK(R_abcd.compute_rhs_tensor_index(
195  index_order_badc, index_order_abcd, ijkl) == jilk);
196  // For L_{bcad} = R_{abcd}, check that L_{ijkl} == R_{kijl}
197  CHECK(R_abcd.compute_rhs_tensor_index(
198  index_order_bcad, index_order_abcd, ijkl) == kijl);
199  // For L_{bcda} = R_{abcd}, check that L_{ijkl} == R_{lijk}
200  CHECK(R_abcd.compute_rhs_tensor_index(
201  index_order_bcda, index_order_abcd, ijkl) == lijk);
202  // For L_{bdac} = R_{abcd}, check that L_{ijkl} == R_{kilj}
203  CHECK(R_abcd.compute_rhs_tensor_index(
204  index_order_bdac, index_order_abcd, ijkl) == kilj);
205  // For L_{bdca} = R_{abcd}, check that L_{ijkl} == R_{likj}
206  CHECK(R_abcd.compute_rhs_tensor_index(
207  index_order_bdca, index_order_abcd, ijkl) == likj);
208 
209  // For L_{cabd} = R_{abcd}, check that L_{ijkl} == R_{jkil}
210  CHECK(R_abcd.compute_rhs_tensor_index(
211  index_order_cabd, index_order_abcd, ijkl) == jkil);
212  // For L_{cadb} = R_{abcd}, check that L_{ijkl} == R_{jlik}
213  CHECK(R_abcd.compute_rhs_tensor_index(
214  index_order_cadb, index_order_abcd, ijkl) == jlik);
215  // For L_{cbad} = R_{abcd}, check that L_{ijkl} == R_{kjil}
216  CHECK(R_abcd.compute_rhs_tensor_index(
217  index_order_cbad, index_order_abcd, ijkl) == kjil);
218  // For L_{cbda} = R_{abcd}, check that L_{ijkl} == R_{ljik}
219  CHECK(R_abcd.compute_rhs_tensor_index(
220  index_order_cbda, index_order_abcd, ijkl) == ljik);
221  // For L_{cdab} = R_{abcd}, check that L_{ijkl} == R_{klij}
222  CHECK(R_abcd.compute_rhs_tensor_index(
223  index_order_cdab, index_order_abcd, ijkl) == klij);
224  // For L_{cdba} = R_{abcd}, check that L_{ijkl} == R_{lkij}
225  CHECK(R_abcd.compute_rhs_tensor_index(
226  index_order_cdba, index_order_abcd, ijkl) == lkij);
227 
228  // For L_{dabc} = R_{abcd}, check that L_{ijkl} == R_{jkli}
229  CHECK(R_abcd.compute_rhs_tensor_index(
230  index_order_dabc, index_order_abcd, ijkl) == jkli);
231  // For L_{dacb} = R_{abcd}, check that L_{ijkl} == R_{jlki}
232  CHECK(R_abcd.compute_rhs_tensor_index(
233  index_order_dacb, index_order_abcd, ijkl) == jlki);
234  // For L_{dbac} = R_{abcd}, check that L_{ijkl} == R_{kjli}
235  CHECK(R_abcd.compute_rhs_tensor_index(
236  index_order_dbac, index_order_abcd, ijkl) == kjli);
237  // For L_{dbca} = R_{abcd}, check that L_{ijkl} == R_{ljki}
238  CHECK(R_abcd.compute_rhs_tensor_index(
239  index_order_dbca, index_order_abcd, ijkl) == ljki);
240  // For L_{dcab} = R_{abcd}, check that L_{ijkl} == R_{klji}
241  CHECK(R_abcd.compute_rhs_tensor_index(
242  index_order_dcab, index_order_abcd, ijkl) == klji);
243  // For L_{dcba} = R_{abcd}, check that L_{ijkl} == R_{lkji}
244  CHECK(R_abcd.compute_rhs_tensor_index(
245  index_order_dcba, index_order_abcd, ijkl) == lkji);
246  }
247  }
248  }
249  }
250 }
251 
252 } // namespace TestHelpers::TensorExpressions
TensorExpression.hpp
cstddef
std::array
Tensor.hpp
TMPL.hpp
TestHelpers::TensorExpressions::test_compute_rhs_tensor_index_rank_4
void test_compute_rhs_tensor_index_rank_4(const TensorIndexA &tensorindex_a, const TensorIndexB &tensorindex_b, const TensorIndexC &tensorindex_c, const TensorIndexD &tensorindex_d) noexcept
Test that the computed tensor multi-index of a rank 4 RHS Tensor is equivalent to the given LHS tenso...
Definition: ComputeRhsTensorIndexRank4TestHelpers.hpp:49