TestHelpers.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
7 
8 #include <array>
9 #include <cmath>
10 #include <cstddef>
11 #include <limits>
12 #include <random>
13 #include <string>
14 #include <utility>
15 
17 #include "DataStructures/DataBox/Tag.hpp"
18 #include "DataStructures/DataVector.hpp"
24 #include "Utilities/Gsl.hpp"
25 #include "Utilities/TMPL.hpp"
26 
27 namespace TestHelpers {
28 namespace NumericalFluxes {
29 
30 namespace Tags {
32  using type = Scalar<DataVector>;
33 };
34 
35 template <size_t Dim>
37  using type = tnsr::I<DataVector, Dim>;
38 };
39 
40 template <size_t Dim>
42  using type = tnsr::i<DataVector, Dim>;
43 };
44 
45 template <size_t Dim>
47  using type = tnsr::Ij<DataVector, Dim>;
48 };
49 
50 template <size_t Dim>
53 };
54 
55 } // namespace Tags
56 
57 template <size_t Dim>
59  const Scalar<DataVector>& var_1, const tnsr::I<DataVector, Dim>& var_2,
60  const tnsr::i<DataVector, Dim>& var_3) noexcept {
62  // Any expression for the characteristic speeds is fine.
63  for (size_t i = 0; i < result.size(); ++i) {
64  gsl::at(result, i) =
65  cos(static_cast<double>(i)) * get(var_1) -
66  (1.0 - sin(static_cast<double>(i))) * get(dot_product(var_2, var_3));
67  }
68  return result;
69 }
70 
71 template <size_t Dim>
72 struct System {
73  static constexpr size_t volume_dim = Dim;
74  using variables_tag =
78 };
79 
80 template <typename Var>
82 
83 template <size_t Dim>
84 using n_dot_f_tags =
85  tmpl::list<n_dot_f<Tags::Variable1>, n_dot_f<Tags::Variable2<Dim>>,
87 
88 template <class... PackageDataTags, class FluxType,
89  class... NormalDotNumericalFluxTypes>
90 void apply_numerical_flux(
91  const FluxType& flux,
92  const Variables<tmpl::list<PackageDataTags...>>& packaged_data_int,
93  const Variables<tmpl::list<PackageDataTags...>>& packaged_data_ext,
94  NormalDotNumericalFluxTypes&&... normal_dot_numerical_flux) noexcept {
95  flux(std::forward<NormalDotNumericalFluxTypes>(normal_dot_numerical_flux)...,
96  get<PackageDataTags>(packaged_data_int)...,
97  get<PackageDataTags>(packaged_data_ext)...);
98 }
99 
100 namespace detail {
101 template <size_t Dim, typename FluxType, typename... VariablesTags>
102 void test_conservation(const FluxType& flux_computer,
103  const DataVector& used_for_size,
104  const tmpl::list<VariablesTags...> /*meta*/) noexcept {
105  MAKE_GENERATOR(gen);
106  std::uniform_real_distribution<> dist(0.0, 1.0);
107 
108  const auto variables_interior =
109  make_with_random_values<Variables<tmpl::list<VariablesTags...>>>(
110  make_not_null(&gen), make_not_null(&dist), used_for_size);
111  const auto variables_exterior =
112  make_with_random_values<Variables<tmpl::list<VariablesTags...>>>(
113  make_not_null(&gen), make_not_null(&dist), used_for_size);
114  const auto n_dot_f_interior =
115  make_with_random_values<Variables<tmpl::list<VariablesTags...>>>(
116  make_not_null(&gen), make_not_null(&dist), used_for_size);
117  const auto n_dot_f_exterior =
118  make_with_random_values<Variables<tmpl::list<VariablesTags...>>>(
119  make_not_null(&gen), make_not_null(&dist), used_for_size);
120 
121  Variables<typename FluxType::package_tags> packaged_data_interior(
122  used_for_size.size(), std::numeric_limits<double>::signaling_NaN());
123  flux_computer.package_data(
124  make_not_null(&packaged_data_interior),
125  get<VariablesTags>(n_dot_f_interior)...,
126  get<VariablesTags>(variables_interior)...,
127  TestHelpers::NumericalFluxes::characteristic_speeds(
128  get<Tags::Variable1>(variables_interior),
129  get<Tags::Variable2<Dim>>(variables_interior),
130  get<Tags::Variable3<Dim>>(variables_interior)));
131 
132  Variables<typename FluxType::package_tags> packaged_data_exterior(
133  used_for_size.size(), std::numeric_limits<double>::signaling_NaN());
134  flux_computer.package_data(
135  make_not_null(&packaged_data_exterior),
136  get<VariablesTags>(n_dot_f_exterior)...,
137  get<VariablesTags>(variables_exterior)...,
138  TestHelpers::NumericalFluxes::characteristic_speeds(
139  get<Tags::Variable1>(variables_exterior),
140  get<Tags::Variable2<Dim>>(variables_exterior),
141  get<Tags::Variable3<Dim>>(variables_exterior)));
142 
143  Variables<tmpl::list<VariablesTags...>> n_dot_num_flux_interior(
144  used_for_size.size(), std::numeric_limits<double>::signaling_NaN());
145  apply_numerical_flux(flux_computer, packaged_data_interior,
146  packaged_data_exterior,
147  &get<VariablesTags>(n_dot_num_flux_interior)...);
148 
149  Variables<tmpl::list<VariablesTags...>> n_dot_num_flux_exterior(
150  used_for_size.size(), std::numeric_limits<double>::signaling_NaN());
151  apply_numerical_flux(flux_computer, packaged_data_exterior,
152  packaged_data_interior,
153  &get<VariablesTags>(n_dot_num_flux_exterior)...);
154 
155  auto check = [](const auto& int_flux, const auto& ext_flux) noexcept {
156  for (size_t i = 0; i < int_flux.size(); ++i) {
157  CHECK_ITERABLE_APPROX(int_flux[i], -ext_flux[i]);
158  }
159  return nullptr;
160  };
161 
162  expand_pack(check(get<VariablesTags>(n_dot_num_flux_interior),
163  get<VariablesTags>(n_dot_num_flux_exterior))...);
164 }
165 } // namespace detail
166 
167 template <size_t Dim, typename FluxType>
168 void test_conservation(const FluxType& flux_computer,
169  const DataVector& used_for_size) noexcept {
170  detail::test_conservation<Dim>(
171  flux_computer, used_for_size,
172  typename System<Dim>::variables_tag::tags_list{});
173 }
174 
175 } // namespace NumericalFluxes
176 } // namespace TestHelpers
Prefix indicating a boundary unit normal vector dotted into the flux.
Definition: Prefixes.hpp:124
Definition: TestCreation.hpp:14
Definition: VariablesTag.hpp:21
Definition: TestHelpers.hpp:36
T signaling_NaN(T... args)
ReturnType make_with_random_values(const gsl::not_null< UniformRandomBitGenerator *> generator, const gsl::not_null< RandomNumberDistribution *> distribution, const T &used_for_size) noexcept
Make a data structure and fill it with random values.
Definition: MakeWithRandomValues.hpp:164
Commonly used routines, functions and definitions shared amongst unit tests.
Helper functions for data structures used in unit tests.
Define prefixes for DataBox tags.
Defines functions euclidean dot_product and dot_product with a metric.
Tags for the DataBox inherit from this type.
Definition: Tag.hpp:23
Definition: TestHelpers.hpp:31
#define MAKE_GENERATOR(...)
MAKE_GENERATOR(NAME [, SEED]) declares a variable of name NAME containing a generator of type std::mt...
Definition: TestHelpers.hpp:417
Definition: Determinant.hpp:11
Definition: TestHelpers.hpp:72
Defines class Variables.
Definition: DataBoxTag.hpp:27
Definition: TestHelpers.hpp:46
void check(EosType in_eos, const std::string &python_function_prefix, const T &used_for_size, const MemberArgs &... member_args) noexcept
Test an equation of state by comparing to python functions.
Definition: TestHelpers.hpp:210
Defines classes for Tensor.
#define CHECK_ITERABLE_APPROX(a, b)
A wrapper around Catch&#39;s CHECK macro that checks approximate equality of entries in iterable containe...
Definition: TestingFramework.hpp:139
Stores a collection of function values.
Definition: DataVector.hpp:42
Wraps the template metaprogramming library used (brigand)
Defines functions and classes from the GSL.
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, but it may be necessary to perform the conversion explicitly when type deduction is desired.
Definition: Gsl.hpp:879
Code to wrap or improve the Catch testing framework used for unit tests.
void dot_product(const gsl::not_null< Scalar< DataType > *> dot_product, const Tensor< DataType, Symmetry< 1 >, index_list< Index >> &vector_a, const Tensor< DataType, Symmetry< 1 >, index_list< Index >> &vector_b) noexcept
Compute the Euclidean dot product of two vectors or one forms.
Definition: DotProduct.hpp:24
Definition: TestHelpers.hpp:41
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
constexpr void expand_pack(Ts &&...) noexcept
Allows zero-cost unordered expansion of a parameter.
Definition: TMPL.hpp:546
constexpr T & at(std::array< T, N > &arr, Size index)
Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid...
Definition: Gsl.hpp:124