EvaluateRank1TestHelpers.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 #include <type_traits>
10 
11 #include "DataStructures/Tags/TempTensor.hpp"
16 #include "Utilities/GenerateInstantiations.hpp"
17 #include "Utilities/Gsl.hpp"
18 #include "Utilities/TMPL.hpp"
19 
20 namespace TestHelpers::TensorExpressions {
21 
22 /// \ingroup TestingFrameworkGroup
23 /// \brief Test that evaluating a right hand side tensor expression containing a
24 /// single rank 1 tensor correctly assigns the data to the evaluated left hand
25 /// side tensor
26 ///
27 /// \tparam DataType the type of data being stored in the Tensors
28 /// \tparam TensorIndexTypeList the Tensors' typelist containing their
29 /// \ref SpacetimeIndex "TensorIndexType"
30 /// \tparam TensorIndex the TensorIndex used in the the TensorExpression,
31 /// e.g. `ti_a`
32 template <typename DataType, typename TensorIndexTypeList, auto& TensorIndex>
33 void test_evaluate_rank_1_impl() noexcept {
34  const size_t used_for_size = 5;
35  using tensor_type = Tensor<DataType, Symmetry<1>, TensorIndexTypeList>;
36  tensor_type R_a(used_for_size);
37  std::iota(R_a.begin(), R_a.end(), 0.0);
38 
39  // L_a = R_a
40  // Use explicit type (vs auto) so the compiler checks return type of
41  // `evaluate`
42  const tensor_type L_a_returned =
43  ::TensorExpressions::evaluate<TensorIndex>(R_a(TensorIndex));
44  tensor_type L_a_filled{};
45  ::TensorExpressions::evaluate<TensorIndex>(make_not_null(&L_a_filled),
46  R_a(TensorIndex));
47 
48  const size_t dim = tmpl::at_c<TensorIndexTypeList, 0>::dim;
49 
50  // For L_a = R_a, check that L_i == R_i
51  for (size_t i = 0; i < dim; ++i) {
52  CHECK(L_a_returned.get(i) == R_a.get(i));
53  CHECK(L_a_filled.get(i) == R_a.get(i));
54  }
55 
56  // Test with TempTensor for LHS tensor
57  if constexpr (not std::is_same_v<DataType, double>) {
58  // L_a = R_a
59  Variables<tmpl::list<::Tags::TempTensor<1, tensor_type>>> L_a_var{
60  used_for_size};
61  tensor_type& L_a_temp = get<::Tags::TempTensor<1, tensor_type>>(L_a_var);
62  ::TensorExpressions::evaluate<TensorIndex>(make_not_null(&L_a_temp),
63  R_a(TensorIndex));
64 
65  // For L_a = R_a, check that L_i == R_i
66  for (size_t i = 0; i < dim; ++i) {
67  CHECK(L_a_temp.get(i) == R_a.get(i));
68  }
69  }
70 }
71 
72 /// \ingroup TestingFrameworkGroup
73 /// \brief Iterate testing of evaluating single rank 1 Tensors on multiple Frame
74 /// types and dimensions
75 ///
76 /// \tparam DataType the type of data being stored in the Tensors
77 /// \tparam TensorIndexType the Tensors' \ref SpacetimeIndex "TensorIndexType"
78 /// \tparam Valence the valence of the Tensors' index
79 /// \tparam TensorIndex the TensorIndex used in the the TensorExpression,
80 /// e.g. `ti_a`
81 template <typename DataType,
82  template <size_t, UpLo, typename> class TensorIndexType, UpLo Valence,
83  auto& TensorIndex>
84 void test_evaluate_rank_1() noexcept {
85 #define DIM(data) BOOST_PP_TUPLE_ELEM(0, data)
86 #define FRAME(data) BOOST_PP_TUPLE_ELEM(1, data)
87 
88 #define CALL_TEST_EVALUATE_RANK_1_IMPL(_, data) \
89  test_evaluate_rank_1_impl< \
90  DataType, index_list<TensorIndexType<DIM(data), Valence, FRAME(data)>>, \
91  TensorIndex>();
92 
93  GENERATE_INSTANTIATIONS(CALL_TEST_EVALUATE_RANK_1_IMPL, (1, 2, 3),
95 
96 #undef CALL_TEST_EVALUATE_RANK_1_IMPL
97 #undef FRAME
98 #undef DIM
99 }
100 
101 } // namespace TestHelpers::TensorExpressions
Frame::Inertial
Definition: IndexType.hpp:44
UpLo
UpLo
Definition: IndexType.hpp:20
IndexType.hpp
Frame::Grid
Definition: IndexType.hpp:43
Symmetry.hpp
TensorIndex
Represents the geeric indices in a TensorExpression.
Definition: TensorIndex.hpp:69
iterator
TestHelpers::TensorExpressions::test_evaluate_rank_1_impl
void test_evaluate_rank_1_impl() noexcept
Test that evaluating a right hand side tensor expression containing a single rank 1 tensor correctly ...
Definition: EvaluateRank1TestHelpers.hpp:33
cstddef
TestHelpers::TensorExpressions::test_evaluate_rank_1
void test_evaluate_rank_1() noexcept
Iterate testing of evaluating single rank 1 Tensors on multiple Frame types and dimensions.
Definition: EvaluateRank1TestHelpers.hpp:84
Variables.hpp
Gsl.hpp
Tensor.hpp
make_not_null
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion,...
Definition: Gsl.hpp:880
numeric
type_traits
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
cpp2b::iota
constexpr void iota(ForwardIterator first, ForwardIterator last, T value)
Definition: Numeric.hpp:20