MakeRandomVectorInMagnitudeRange.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cmath>
7 #include <random>
8 
9 #include "DataStructures/DataVector.hpp" // IWYU pragma: keep
11 #include "DataStructures/Tensor/Tensor.hpp" // IWYU pragma: keep
14 #include "Helpers/DataStructures/RandomUnitNormal.hpp"
15 #include "PointwiseFunctions/GeneralRelativity/IndexManipulation.hpp"
17 #include "Utilities/Gsl.hpp"
18 
19 /// \ingroup TestingFrameworkGroup
20 /// \brief Construct a spatial vector in a given magnitude range
21 ///
22 /// The magnitude is computed with respect to the given metric, where the metric
23 /// is assumed to have positive signature.
24 template <typename DataType, size_t Dim, UpLo Ul, typename Fr = Frame::Inertial,
25  Requires<(Ul == UpLo::Up)> = nullptr>
26 tnsr::I<DataType, Dim, Fr> make_random_vector_in_magnitude_range(
27  const gsl::not_null<std::mt19937*> nn_generator,
28  const tnsr::ii<DataType, Dim, Fr>& metric, const double min_magnitude,
29  const double max_magnitude) noexcept {
30  if (min_magnitude < 0) {
31  ERROR("min_magnitude < 0. Magnitude must be non-negative");
32  }
33  if (max_magnitude < 0) {
34  ERROR("max_magnitude < 0. Magnitude must be non-negative");
35  }
36 
37  // generate distribution
38  std::uniform_real_distribution<> dist_magnitude(min_magnitude, max_magnitude);
39  const auto magnitude = make_with_random_values<Scalar<DataType>>(
40  nn_generator, make_not_null(&dist_magnitude), metric);
41 
42  // construct vector
43  tnsr::I<DataType, Dim, Fr> x_up = random_unit_normal(nn_generator, metric);
44 
45  for (size_t i = 0; i < Dim; i++) {
46  x_up.get(i) *= magnitude.get();
47  }
48 
49  return x_up;
50 }
51 
52 template <typename DataType, size_t Dim, UpLo Ul, typename Fr = Frame::Inertial,
53  Requires<(Ul == UpLo::Lo)> = nullptr>
54 tnsr::i<DataType, Dim, Fr> make_random_vector_in_magnitude_range(
55  const gsl::not_null<std::mt19937*> nn_generator,
56  const tnsr::ii<DataType, Dim, Fr>& metric, const double min_magnitude,
57  const double max_magnitude) noexcept {
58  const tnsr::I<DataType, Dim, Fr> x_up =
59  make_random_vector_in_magnitude_range<DataType, Dim, UpLo::Up, Fr>(
60  nn_generator, metric, min_magnitude, max_magnitude);
61 
62  return raise_or_lower_index(x_up, metric);
63 }
64 
65 /// \ingroup TestingFrameworkGroup
66 /// \brief Construct a spatial vector in a given magnitude range
67 ///
68 /// The magnitude is computed with respect to the flat space Euclidian metric.
69 template <typename DataType, size_t Dim, UpLo Ul, typename Fr = Frame::Inertial,
70  typename T>
71 Tensor<DataType, Symmetry<1>, index_list<SpatialIndex<Dim, Ul, Fr>>>
73  const gsl::not_null<std::mt19937*> nn_generator, const T& used_for_size,
74  const double min_magnitude, const double max_magnitude) noexcept {
75  // construct flat spatial metric
76  tnsr::ii<DataType, Dim, Fr> metric =
77  make_with_value<tnsr::ii<DataType, Dim, Fr>>(used_for_size, 0.0);
78  for (size_t i = 0; i < Dim; i++) {
79  metric.get(i, i) = 1.0;
80  }
81 
82  return make_random_vector_in_magnitude_range<DataType, Dim, Ul, Fr>(
83  nn_generator, metric, min_magnitude, max_magnitude);
84 }
Frame::Inertial
Definition: IndexType.hpp:44
UpLo
UpLo
Definition: IndexType.hpp:20
IndexType.hpp
make_random_vector_in_magnitude_range
tnsr::I< DataType, Dim, Fr > make_random_vector_in_magnitude_range(const gsl::not_null< std::mt19937 * > nn_generator, const tnsr::ii< DataType, Dim, Fr > &metric, const double min_magnitude, const double max_magnitude) noexcept
Construct a spatial vector in a given magnitude range.
Definition: MakeRandomVectorInMagnitudeRange.hpp:26
random
MakeWithRandomValues.hpp
cmath
std::uniform_real_distribution
make_random_vector_in_magnitude_range_flat
Tensor< DataType, Symmetry< 1 >, index_list< SpatialIndex< Dim, Ul, Fr > > > make_random_vector_in_magnitude_range_flat(const gsl::not_null< std::mt19937 * > nn_generator, const T &used_for_size, const double min_magnitude, const double max_magnitude) noexcept
Construct a spatial vector in a given magnitude range.
Definition: MakeRandomVectorInMagnitudeRange.hpp:72
UpLo::Lo
@ Lo
Covariant, or Lower index.
ERROR
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:36
raise_or_lower_index
void raise_or_lower_index(gsl::not_null< Tensor< DataType, Symmetry< 1 >, index_list< change_index_up_lo< Index0 >>> * > result, const Tensor< DataType, Symmetry< 1 >, index_list< Index0 >> &tensor, const Tensor< DataType, Symmetry< 1, 1 >, index_list< change_index_up_lo< Index0 >, change_index_up_lo< Index0 >>> &metric) noexcept
Raises or lowers the index of a rank 1 tensor.
ConstantExpressions.hpp
Gsl.hpp
TypeAliases.hpp
Tensor.hpp
random_unit_normal
tnsr::I< DataType, 1 > random_unit_normal(gsl::not_null< std::mt19937 * > generator, const tnsr::ii< DataType, 1 > &spatial_metric) noexcept
Make a random unit normal vector at each element of DataType.
magnitude
Scalar< DataType > magnitude(const Tensor< DataType, Symmetry< 1 >, index_list< Index >> &vector) noexcept
Compute the Euclidean magnitude of a rank-1 tensor.
Definition: Magnitude.hpp:28
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
Requires
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t
Definition: Requires.hpp:67
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183
UpLo::Up
@ Up
Contravariant, or Upper index.