Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <string>
7 :
8 : #include "DataStructures/DataBox/Tag.hpp"
9 : #include "DataStructures/DataBox/TagName.hpp"
10 : #include "DataStructures/DataVector.hpp"
11 : #include "DataStructures/Tensor/EagerMath/DotProduct.hpp"
12 : #include "DataStructures/Tensor/Tensor.hpp"
13 : #include "Utilities/Gsl.hpp"
14 : #include "Utilities/SetNumberOfGridPoints.hpp"
15 : #include "Utilities/TMPL.hpp"
16 :
17 : /// @{
18 : /*!
19 : * \ingroup TensorGroup
20 : * \brief Compute the Euclidean magnitude of a rank-1 tensor
21 : *
22 : * \details
23 : * Computes the square root of the sum of the squares of the components of
24 : * the rank-1 tensor.
25 : */
26 : template <typename DataType, typename Index>
27 1 : Scalar<DataType> magnitude(
28 : const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector) {
29 : return Scalar<DataType>{sqrt(get(dot_product(vector, vector)))};
30 : }
31 :
32 : template <typename DataType, typename Index>
33 1 : void magnitude(const gsl::not_null<Scalar<DataType>*> magnitude,
34 : const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector) {
35 : set_number_of_grid_points(magnitude, vector);
36 : dot_product(magnitude, vector, vector);
37 : get(*magnitude) = sqrt(get(*magnitude));
38 : }
39 : /// @}
40 :
41 : /// @{
42 : /*!
43 : * \ingroup TensorGroup
44 : * \brief Compute the magnitude of a rank-1 tensor
45 : *
46 : * \details
47 : * Returns the square root of the input tensor contracted twice with the given
48 : * metric.
49 : */
50 : template <typename DataType, typename Index>
51 1 : Scalar<DataType> magnitude(
52 : const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector,
53 : const Tensor<DataType, Symmetry<1, 1>,
54 : index_list<change_index_up_lo<Index>,
55 : change_index_up_lo<Index>>>& metric) {
56 : Scalar<DataType> local_magnitude{get_size(get<0>(vector))};
57 : magnitude(make_not_null(&local_magnitude), vector, metric);
58 : return local_magnitude;
59 : }
60 :
61 : template <typename DataType, typename Index>
62 1 : void magnitude(const gsl::not_null<Scalar<DataType>*> magnitude,
63 : const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector,
64 : const Tensor<DataType, Symmetry<1, 1>,
65 : index_list<change_index_up_lo<Index>,
66 : change_index_up_lo<Index>>>& metric) {
67 : dot_product(magnitude, vector, vector, metric);
68 : get(*magnitude) = sqrt(get(*magnitude));
69 : }
70 : /// @}
71 :
72 : namespace Tags {
73 : /// \ingroup DataBoxTagsGroup
74 : /// \ingroup DataStructuresGroup
75 : /// The magnitude of a (co)vector
76 : template <typename Tag>
77 1 : struct Magnitude : db::PrefixTag, db::SimpleTag {
78 0 : using tag = Tag;
79 0 : using type = Scalar<DataVector>;
80 : };
81 :
82 : /// \ingroup DataBoxTagsGroup
83 : /// \ingroup DataStructuresGroup
84 : /// The Euclidean magnitude of a (co)vector
85 : ///
86 : /// This tag inherits from `Tags::Magnitude<Tag>`
87 : template <typename Tag>
88 1 : struct EuclideanMagnitude : Magnitude<Tag>, db::ComputeTag {
89 0 : using base = Magnitude<Tag>;
90 0 : using return_type = typename base::type;
91 0 : static constexpr auto function =
92 : static_cast<void (*)(const gsl::not_null<return_type*>,
93 : const typename Tag::type&)>(&magnitude);
94 0 : using argument_tags = tmpl::list<Tag>;
95 : };
96 :
97 : /// \ingroup DataBoxTagsGroup
98 : /// \ingroup DataStructuresGroup
99 : /// The magnitude of a (co)vector with respect to a specific metric
100 : ///
101 : /// This tag inherits from `Tags::Magnitude<Tag>`
102 : template <typename Tag, typename MetricTag>
103 1 : struct NonEuclideanMagnitude : Magnitude<Tag>, db::ComputeTag {
104 0 : using base = Magnitude<Tag>;
105 0 : using return_type = typename base::type;
106 0 : static constexpr auto function = static_cast<void (*)(
107 : const gsl::not_null<return_type*>, const typename Tag::type&,
108 : const typename MetricTag::type&)>(&magnitude);
109 0 : using argument_tags = tmpl::list<Tag, MetricTag>;
110 : };
111 :
112 : /// \ingroup DataBoxTagsGroup
113 : /// \ingroup DataStructuresGroup
114 : /// The normalized (co)vector represented by Tag
115 : template <typename Tag>
116 1 : struct Normalized : db::PrefixTag, db::SimpleTag {
117 0 : using tag = Tag;
118 0 : using type = typename Tag::type;
119 : };
120 :
121 : /// \ingroup DataBoxTagsGroup
122 : /// \ingroup DataStructuresGroup
123 : /// Normalizes the (co)vector represented by Tag
124 : ///
125 : /// This tag inherits from `Tags::Normalized<Tag>`
126 : template <typename Tag>
127 1 : struct NormalizedCompute : Normalized<Tag>, db::ComputeTag {
128 0 : using base = Normalized<Tag>;
129 0 : using return_type = typename base::type;
130 0 : static void function(const gsl::not_null<return_type*> normalized_vector,
131 : const typename Tag::type& vector_in,
132 : const typename Magnitude<Tag>::type& magnitude) {
133 : *normalized_vector = vector_in;
134 : for (size_t d = 0; d < normalized_vector->index_dim(0); ++d) {
135 : normalized_vector->get(d) /= get(magnitude);
136 : }
137 : }
138 0 : using argument_tags = tmpl::list<Tag, Magnitude<Tag>>;
139 : };
140 :
141 : } // namespace Tags
|