17 #include "DataStructures/DataVector.hpp" 23 #include "Domain/OrientationMap.hpp" 25 #include "tests/Unit/Domain/DomainTestHelpers.hpp" 34 template <
typename Map>
37 Map::dim>& map_base) {
38 const auto* map_derived =
dynamic_cast<const Map*
>(&map_base);
39 return map_derived ==
nullptr ? false : (*map_derived == map);
45 template <
typename SourceFrame,
typename TargetFrame,
size_t VolumeDim>
52 for (
size_t n = 0; n < 10; ++n) {
53 tnsr::I<double, VolumeDim, SourceFrame> source_point{};
54 for (
size_t d = 0; d < VolumeDim; ++d) {
55 source_point.get(d) = real_dis(gen);
69 template <
typename Map>
73 make_coordinate_map<Frame::Inertial, Frame::Grid>(IdentityMap{}),
74 make_coordinate_map<Frame::Inertial, Frame::Grid>(map));
75 CHECK(map.is_identity());
83 template <
typename Map>
87 Approx local_approx = Approx::custom().epsilon(1e-10).scale(1.0);
88 const double dx = 1e-4;
89 const auto jacobian = map.jacobian(test_point);
90 for (
size_t i = 0; i < Map::dim; ++i) {
92 for (
size_t j = 0; j < Map::dim; ++j) {
93 INFO(
"i: " << i <<
" j: " << j);
94 CHECK(jacobian.get(j, i) == local_approx(
gsl::at(numerical_deriv_i, j)));
104 template <
typename Map>
107 const auto jacobian = map.jacobian(test_point);
108 const auto inv_jacobian = map.inv_jacobian(test_point);
110 const auto expected_identity = [&jacobian, &inv_jacobian]() {
112 for (
size_t i = 0; i < Map::dim; ++i) {
113 for (
size_t j = 0; j < Map::dim; ++j) {
115 for (
size_t k = 0; k < Map::dim; ++k) {
117 jacobian.get(i, k) * inv_jacobian.get(k, j);
124 for (
size_t i = 0; i < Map::dim; ++i) {
125 for (
size_t j = 0; j < Map::dim; ++j) {
127 approx(i == j ? 1. : 0.));
137 template <
typename Map,
typename... Args>
139 const auto coord_map = make_coordinate_map<Frame::Logical, Frame::Grid>(map);
143 const auto test_point = [&gen, &real_dis] {
145 for (
size_t i = 0; i < Map::dim; ++i) {
151 for (
size_t i = 0; i < Map::dim; ++i) {
155 const auto test_point_tensor = [&test_point]() {
156 tnsr::I<double, Map::dim, Frame::Logical> point_as_tensor{};
157 for (
size_t i = 0; i < Map::dim; ++i) {
158 point_as_tensor.get(i) =
gsl::at(test_point, i);
160 return point_as_tensor;
163 for (
size_t i = 0; i < Map::dim; ++i) {
164 CHECK(coord_map(test_point_tensor).
get(i) ==
165 approx(
gsl::at(map(test_point), i)));
166 for (
size_t j = 0; j < Map::dim; ++j) {
167 CHECK(coord_map.jacobian(test_point_tensor).get(i, j) ==
168 map.jacobian(test_point).get(i, j));
169 CHECK(coord_map.inv_jacobian(test_point_tensor).get(i, j) ==
170 map.inv_jacobian(test_point).get(i, j));
180 template <
typename Map,
typename... Args>
183 const Args&... args) {
184 const auto make_array_data_vector = [](
const auto& double_array) noexcept {
186 std::transform(double_array.begin(), double_array.end(), result.begin(),
187 [](
const double x) noexcept {
192 const auto add_reference_wrapper = [](
const auto& unwrapped_array) noexcept {
194 return make_array<std::reference_wrapper<const typename Arg::value_type>,
195 Map::dim>(unwrapped_array);
199 const auto mapped_point = map(test_point, args...);
203 make_array_data_vector(mapped_point));
205 map(add_reference_wrapper(make_array_data_vector(test_point)), args...),
206 make_array_data_vector(mapped_point));
212 const auto check_jac =
213 [](
const auto& make_arr_data_vec,
const auto& add_ref_wrap,
215 const auto&... time_args) noexcept {
216 const auto make_tensor_data_vector = [](
const auto& double_tensor) {
218 Tensor<DataVector, typename Arg::symmetry, typename Arg::index_list>
220 std::transform(double_tensor.begin(), double_tensor.end(), result.begin(),
228 const auto expected = the_map.jacobian(point, time_args...);
232 the_map.jacobian(make_arr_data_vec(point), time_args...),
233 make_tensor_data_vector(expected));
235 the_map.jacobian(add_ref_wrap(make_arr_data_vec(point)),
237 make_tensor_data_vector(expected));
240 const auto expected = the_map.inv_jacobian(point, time_args...);
242 the_map.inv_jacobian(add_ref_wrap(point), time_args...), expected);
244 the_map.inv_jacobian(make_arr_data_vec(point), time_args...),
245 make_tensor_data_vector(expected));
247 the_map.inv_jacobian(add_ref_wrap(make_arr_data_vec(point)),
249 make_tensor_data_vector(expected));
258 [&check_jac](
const auto& make_array_data_vec,
const auto& add_ref_wrapper,
262 const Args&... ) noexcept {
263 check_jac(make_array_data_vec, add_ref_wrapper, this_map, this_point);
266 [&check_jac](
const auto& make_array_data_vec,
const auto& add_ref_wrapper,
270 const Args&... the_args) noexcept {
271 check_jac(make_array_data_vec, add_ref_wrapper, this_map, this_point,
277 make_array_data_vector, add_reference_wrapper, map, test_point,
278 CoordinateMap_detail::is_jacobian_time_dependent_t<decltype(map),
287 template <
typename Map,
typename T>
300 template <
typename Map>
308 for (
size_t i = 0; i < Map::dim; i++) {
310 gsl::at(random_point, i) = real_dis(gen);
313 const auto test_helper =
314 [&origin, &random_point ](
const auto& map_to_test) noexcept {
316 CHECK_FALSE(map_to_test != map_to_test);
336 make_coordinate_map<Frame::Logical, Frame::Grid>(map),
337 make_coordinate_map<Frame::Logical, Frame::Grid>(map2));
351 template <
typename Map>
353 const bool include_origin =
true,
354 const double radius_of_sphere = 1.0) {
355 static_assert(Map::dim == 3,
"Works only for a 3d map");
364 const double inner_bdry = include_origin ? 0.0 : 5.e-3;
370 const double theta = theta_dis(gen);
372 const double phi = phi_dis(gen);
374 const double radius = radius_dis(gen);
378 radius * sin(theta) * sin(phi),
379 radius * cos(theta)}};
382 {radius_of_sphere * sin(theta) * cos(phi),
383 radius_of_sphere * sin(theta) * sin(phi),
384 radius_of_sphere * cos(theta)}};
389 {inner_bdry * sin(theta) * cos(phi),
390 inner_bdry * sin(theta) * sin(phi),
391 inner_bdry * cos(theta)}};
393 const auto test_helper =
394 [&random_bdry_point, &random_inner_bdry_point_or_origin,
395 &random_point ](
const auto& map_to_test) noexcept {
397 CHECK_FALSE(map_to_test != map_to_test);
400 random_inner_bdry_point_or_origin);
401 test_jacobian(map_to_test, random_inner_bdry_point_or_origin);
417 make_coordinate_map<Frame::Logical, Frame::Grid>(map),
418 make_coordinate_map<Frame::Logical, Frame::Grid>(map2));
427 template <
size_t VolumeDim>
431 std::iota(dims_.begin(), dims_.end(), 0);
434 void operator++() noexcept {
442 explicit operator bool()
const noexcept {
return not_at_end_; }
443 const OrientationMap<VolumeDim>& operator()()
const noexcept {
return map_; }
444 const OrientationMap<VolumeDim>& operator*()
const noexcept {
return map_; }
445 void set_map() noexcept {
446 for (
size_t i = 0; i < VolumeDim; i++) {
450 map_ = OrientationMap<VolumeDim>{directions_};
454 bool not_at_end_ =
true;
458 OrientationMap<VolumeDim> map_ = OrientationMap<VolumeDim>{};
467 const OrientationMap<3> upper_zeta_rotation{};
483 return {{upper_zeta_rotation, lower_zeta_rotation, upper_eta_rotation,
484 lower_eta_rotation, upper_xi_rotation, lower_xi_rotation}};
Defines class template Direction.
void test_jacobian(const Map &map, const std::array< double, Map::dim > &test_point)
Given a Map map, checks that the jacobian gives expected results when compared to the numerical deriv...
Definition: TestMapHelpers.hpp:84
void test_inverse_map(const Map &map, const std::array< T, Map::dim > &test_point)
Given a Map map, checks that the inverse map gives expected results.
Definition: TestMapHelpers.hpp:288
constexpr void iota(ForwardIterator first, ForwardIterator last, T value)
Definition: Numeric.hpp:20
Defines DomainHelper functions.
void test_inv_jacobian(const Map &map, const std::array< double, Map::dim > &test_point)
Given a Map map, checks that the inverse jacobian and jacobian multiply together to produce the ident...
Definition: TestMapHelpers.hpp:105
void test_coordinate_map_argument_types(const Map &map, const std::array< double, Map::dim > &test_point, const Args &... args)
Checks that the CoordinateMap map functions as expected when used with different argument types...
Definition: TestMapHelpers.hpp:181
bool are_maps_equal(const Map &map, const CoordinateMapBase< Frame::Logical, Frame::Inertial, Map::dim > &map_base)
Given a Map and a CoordinateMapBase, checks that the maps are equal by downcasting map_base and then ...
Definition: TestMapHelpers.hpp:35
Iterates over the corners of a VolumeDim-dimensional cube.
Definition: DomainHelpers.hpp:240
Overloader< Fs... > make_overloader(Fs... fs)
Create Overloader<Fs...>, see Overloader for details.
Definition: Overloader.hpp:109
void test_coordinate_map_implementation(const Map &map)
Checks that the CoordinateMap map functions as expected when used as the template parameter to the Co...
Definition: TestMapHelpers.hpp:138
Identity map from .
Definition: Identity.hpp:25
Abstract base class for CoordinateMap.
Definition: CoordinateMap.hpp:49
#define CAPTURE_PRECISE(variable)
Alternative to Catch's CAPTURE that prints more digits.
Definition: TestingFramework.hpp:46
constexpr bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp)
Definition: Algorithm.hpp:93
std::array< double, VolumeDim > numerical_derivative(const Invocable &map, const std::array< double, VolumeDim > &x, const size_t direction, const double delta)
Calculates the derivative of an Invocable at a point x - represented by an array of doubles - in the ...
Definition: TestHelpers.hpp:257
std::array< OrientationMap< 3 >, 6 > all_wedge_directions()
Wedge OrientationMap in each of the six directions used in the Shell and Sphere domain creators...
Definition: TestMapHelpers.hpp:466
#define MAKE_GENERATOR(...)
MAKE_GENERATOR(NAME [, SEED]) declares a variable of name NAME containing a generator of type std::mt...
Definition: TestHelpers.hpp:387
virtual InverseJacobian< double, Dim, SourceFrame, TargetFrame > inv_jacobian(tnsr::I< double, Dim, SourceFrame > source_point, double time=std::numeric_limits< double >::signaling_NaN(), const std::unordered_map< std::string, FunctionOfTime &> &f_of_t_list=std::unordered_map< std::string, FunctionOfTime &>{}) const noexcept=0
Compute the inverse Jacobian of the Maps at the point(s) source_point
A particular Side along a particular coordinate Axis.
Definition: Direction.hpp:23
void check_if_maps_are_equal(const CoordinateMapBase< SourceFrame, TargetFrame, VolumeDim > &map_one, const CoordinateMapBase< SourceFrame, TargetFrame, VolumeDim > &map_two)
Given two coordinate maps (but not their types), check that the maps are equal by evaluating them at ...
Definition: TestMapHelpers.hpp:46
tnsr::iaa< DataType, SpatialDim, Frame > phi(const Scalar< DataType > &lapse, const tnsr::i< DataType, SpatialDim, Frame > &deriv_lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::iJ< DataType, SpatialDim, Frame > &deriv_shift, const tnsr::ii< DataType, SpatialDim, Frame > &spatial_metric, const tnsr::ijj< DataType, SpatialDim, Frame > &deriv_spatial_metric) noexcept
Computes the auxiliary variable used by the generalized harmonic formulation of Einstein's equations...
Definition: ComputeGhQuantities.cpp:22
void test_serialization(const T &t)
Tests the serialization of comparable types.
Definition: TestHelpers.hpp:55
Definition: IndexType.hpp:42
Defines class CoordinateMap.
Defines classes for Tensor.
An iterator for looping through all possible orientations of the n-dim cube.
Definition: TestMapHelpers.hpp:428
#define CHECK_ITERABLE_APPROX(a, b)
A wrapper around Catch's CHECK macro that checks approximate equality of entries in iterable containe...
Definition: TestingFramework.hpp:110
void test_suite_for_map_on_unit_cube(const Map &map)
Given a Map map, tests the map functions, including map inverse, jacobian, and inverse jacobian...
Definition: TestMapHelpers.hpp:301
Stores a collection of function values.
Definition: DataVector.hpp:46
Commonly used routines, functions and definitions shared amongst unit tests.
Code to wrap or improve the Catch testing framework used for unit tests.
T serialize_and_deserialize(const T &t)
Serializes and deserializes an object t of type T
Definition: TestHelpers.hpp:42
Definition: IndexType.hpp:44
tnsr::Ij< DataType, Dim, Frame::NoFrame > identity(const DataType &used_for_type) noexcept
returns the Identity matrix
Definition: Identity.hpp:14
virtual Jacobian< double, Dim, SourceFrame, TargetFrame > jacobian(tnsr::I< double, Dim, SourceFrame > source_point, double time=std::numeric_limits< double >::signaling_NaN(), const std::unordered_map< std::string, FunctionOfTime &> &f_of_t_list=std::unordered_map< std::string, FunctionOfTime &>{}) const noexcept=0
Compute the Jacobian of the Maps at the point(s) source_point
Defines type traits, some of which are future STL type_traits header.
void check_if_map_is_identity(const Map &map)
Given a coordinate map, check that this map is equal to the identity by evaluating the map at a rando...
Definition: TestMapHelpers.hpp:70
void test_suite_for_map_on_sphere(const Map &map, const bool include_origin=true, const double radius_of_sphere=1.0)
Given a Map map, tests the map functions, including map inverse, jacobian, and inverse jacobian...
Definition: TestMapHelpers.hpp:352
static Direction< VolumeDim > lower_xi() noexcept
Helper functions for creating specific Directions. These are labeled by the logical-coordinate names ...
Definition: Direction.hpp:108
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
Defines the class Identity.