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 "NumericalAlgorithms/DiscontinuousGalerkin/NumericalFluxes/NumericalFluxHelpers.hpp"
25 #include "NumericalAlgorithms/DiscontinuousGalerkin/SimpleBoundaryData.hpp"
26 #include "Utilities/Gsl.hpp"
27 #include "Utilities/TMPL.hpp"
28 
29 namespace TestHelpers {
30 namespace NumericalFluxes {
31 
32 namespace Tags {
34  using type = Scalar<DataVector>;
35 };
36 
37 template <size_t Dim>
39  using type = tnsr::I<DataVector, Dim>;
40 };
41 
42 template <size_t Dim>
44  using type = tnsr::i<DataVector, Dim>;
45 };
46 
47 template <size_t Dim>
49  using type = tnsr::Ij<DataVector, Dim>;
50 };
51 
52 template <size_t Dim>
54  using type = std::array<DataVector, (Dim + 1) * (Dim + 1)>;
55 };
56 
57 } // namespace Tags
58 
59 template <size_t Dim>
60 std::array<DataVector, (Dim + 1) * (Dim + 1)> characteristic_speeds(
61  const Scalar<DataVector>& var_1, const tnsr::I<DataVector, Dim>& var_2,
62  const tnsr::i<DataVector, Dim>& var_3) noexcept {
63  std::array<DataVector, (Dim + 1) * (Dim + 1)> result;
64  // Any expression for the characteristic speeds is fine.
65  for (size_t i = 0; i < result.size(); ++i) {
66  gsl::at(result, i) =
67  cos(static_cast<double>(i)) * get(var_1) -
68  (1.0 - sin(static_cast<double>(i))) * get(dot_product(var_2, var_3));
69  }
70  return result;
71 }
72 
73 template <size_t Dim>
74 struct System {
75  static constexpr size_t volume_dim = Dim;
76  using variables_tag =
80 };
81 
82 template <typename Var>
84 
85 template <size_t Dim>
86 using n_dot_f_tags =
87  tmpl::list<n_dot_f<Tags::Variable1>, n_dot_f<Tags::Variable2<Dim>>,
89 
90 template <typename FluxType, typename... Args>
91 auto get_packaged_data(const FluxType& flux_computer,
92  const DataVector& used_for_size,
93  const Args&... args) noexcept {
94  dg::SimpleBoundaryData<typename FluxType::package_field_tags,
95  typename FluxType::package_extra_tags>
96  packaged_data{used_for_size.size()};
97  dg::NumericalFluxes::package_data(make_not_null(&packaged_data),
98  flux_computer, args...);
99  return packaged_data;
100 }
101 
102 namespace detail {
103 template <size_t Dim, typename FluxType, typename... VariablesTags>
104 void test_conservation(const FluxType& flux_computer,
105  const DataVector& used_for_size,
106  const tmpl::list<VariablesTags...> /*meta*/) noexcept {
107  MAKE_GENERATOR(gen);
108  std::uniform_real_distribution<> dist(0.0, 1.0);
109  const size_t num_points = used_for_size.size();
110 
111  const auto variables_interior =
112  make_with_random_values<Variables<tmpl::list<VariablesTags...>>>(
113  make_not_null(&gen), make_not_null(&dist), used_for_size);
114  const auto variables_exterior =
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_interior =
118  make_with_random_values<Variables<tmpl::list<VariablesTags...>>>(
119  make_not_null(&gen), make_not_null(&dist), used_for_size);
120  const auto n_dot_f_exterior =
121  make_with_random_values<Variables<tmpl::list<VariablesTags...>>>(
122  make_not_null(&gen), make_not_null(&dist), used_for_size);
123 
124  auto packaged_data_interior = get_packaged_data(
125  flux_computer, used_for_size, 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  auto packaged_data_exterior = get_packaged_data(
132  flux_computer, used_for_size, get<VariablesTags>(n_dot_f_exterior)...,
133  get<VariablesTags>(variables_exterior)...,
134  TestHelpers::NumericalFluxes::characteristic_speeds(
135  get<Tags::Variable1>(variables_exterior),
136  get<Tags::Variable2<Dim>>(variables_exterior),
137  get<Tags::Variable3<Dim>>(variables_exterior)));
138 
139  Variables<tmpl::list<VariablesTags...>> n_dot_num_flux_interior(
141  dg::NumericalFluxes::normal_dot_numerical_fluxes(
142  make_not_null(&n_dot_num_flux_interior), flux_computer,
143  packaged_data_interior, packaged_data_exterior);
144 
145  Variables<tmpl::list<VariablesTags...>> n_dot_num_flux_exterior(
147  dg::NumericalFluxes::normal_dot_numerical_fluxes(
148  make_not_null(&n_dot_num_flux_exterior), flux_computer,
149  packaged_data_exterior, packaged_data_interior);
150 
151  CHECK_VARIABLES_APPROX(n_dot_num_flux_interior, -n_dot_num_flux_exterior);
152 }
153 } // namespace detail
154 
155 template <size_t Dim, typename FluxType>
156 void test_conservation(const FluxType& flux_computer,
157  const DataVector& used_for_size) noexcept {
158  detail::test_conservation<Dim>(
159  flux_computer, used_for_size,
160  typename System<Dim>::variables_tag::tags_list{});
161 }
162 
163 } // namespace NumericalFluxes
164 } // namespace TestHelpers
gsl::at
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:125
TestHelpers::NumericalFluxes::Tags::Variable1
Definition: TestHelpers.hpp:33
utility
get
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:639
TestingFramework.hpp
TestHelpers::NumericalFluxes::Tags::CharacteristicSpeeds
Definition: TestHelpers.hpp:53
TestHelpers::NumericalFluxes::System
Definition: TestHelpers.hpp:74
random
Tags::Variables
Definition: VariablesTag.hpp:21
MakeWithRandomValues.hpp
db::SimpleTag
Tags for the DataBox inherit from this type.
Definition: Tag.hpp:23
Tags::NormalDotFlux
Prefix indicating a boundary unit normal vector dotted into the flux.
Definition: Prefixes.hpp:96
cmath
std::uniform_real_distribution
TestHelpers.hpp
dot_product
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
DotProduct.hpp
TestHelpers::NumericalFluxes::Tags::Variable4
Definition: TestHelpers.hpp:48
dg::SimpleBoundaryData
Distinguishes between field data, which can be projected to a mortar, and extra data,...
Definition: SimpleBoundaryData.hpp:35
cstddef
array
DataVector
Stores a collection of function values.
Definition: DataVector.hpp:42
TestHelpers::NumericalFluxes::Tags::Variable3
Definition: TestHelpers.hpp:43
MAKE_GENERATOR
#define MAKE_GENERATOR(...)
MAKE_GENERATOR(NAME [, SEED]) declares a variable of name NAME containing a generator of type std::mt...
Definition: TestHelpers.hpp:417
Variables.hpp
Scalar
Tensor< T, Symmetry<>, index_list<> > Scalar
Definition: TypeAliases.hpp:21
make_with_random_values
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
limits
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
TestHelpers::NumericalFluxes::Tags::Variable2
Definition: TestHelpers.hpp:38
Prefixes.hpp
std::numeric_limits
TMPL.hpp
CHECK_VARIABLES_APPROX
#define CHECK_VARIABLES_APPROX(a, b)
A wrapper around Catch's CHECK macro that checks approximate equality of each entry in each tag withi...
Definition: TestHelpers.hpp:434
string