Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cstddef>
8 :
9 : #include "DataStructures/DataBox/Tag.hpp"
10 : #include "DataStructures/DataVector.hpp"
11 : #include "DataStructures/Tensor/Tensor.hpp"
12 : #include "Domain/FaceNormal.hpp"
13 : #include "Evolution/Systems/SecondOrderScalarWave/Tags.hpp"
14 : #include "Utilities/Gsl.hpp"
15 : #include "Utilities/MakeWithValue.hpp"
16 : #include "Utilities/TMPL.hpp"
17 :
18 : /// \cond
19 : template <typename>
20 : class Variables;
21 :
22 : namespace Tags {
23 : template <typename Tag>
24 : struct Normalized;
25 : } // namespace Tags
26 : /// \endcond
27 :
28 1 : namespace SecondOrderScalarWave {
29 : /// @{
30 : /*!
31 : * \brief Compute the characteristic speeds for the second-order scalar wave
32 : * system.
33 : *
34 : * The characteristic fields are, in order, \f$v^0_i\f$ (`Tags::VZero`),
35 : * \f$v^+\f$ (`Tags::VPlus`), and \f$v^-\f$ (`Tags::VMinus`). Their
36 : * characteristic speeds are 0, +1, and -1, respectively.
37 : */
38 : template <size_t Dim>
39 1 : std::array<DataVector, 3> characteristic_speeds(
40 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
41 :
42 : template <size_t Dim>
43 1 : void characteristic_speeds(
44 : gsl::not_null<std::array<DataVector, 3>*> char_speeds,
45 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
46 :
47 1 : namespace Tags {
48 : template <size_t Dim>
49 0 : struct CharacteristicSpeedsCompute : Tags::CharacteristicSpeeds<Dim>,
50 : db::ComputeTag {
51 0 : using base = Tags::CharacteristicSpeeds<Dim>;
52 0 : using return_type = typename base::type;
53 0 : using argument_tags =
54 : tmpl::list<::Tags::Normalized<domain::Tags::UnnormalizedFaceNormal<Dim>>>;
55 :
56 0 : static void function(
57 : gsl::not_null<return_type*> char_speeds,
58 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form) {
59 : characteristic_speeds(char_speeds, unit_normal_one_form);
60 : }
61 : };
62 : } // namespace Tags
63 : /// @}
64 :
65 : /// @{
66 : /*!
67 : * \brief Computes characteristic fields from evolved fields for the
68 : * second-order scalar wave system.
69 : *
70 : * The characteristic fields are given in terms of the evolved fields by:
71 : *
72 : * \f{align*}
73 : * v^0_{i} =& (\delta^k_i - n_i n^k) \Phi_{k} \\
74 : * v^{\pm} =& \Pi \pm n^i \Phi_{i}
75 : * \f}
76 : *
77 : * where \f$n_i\f$ is the unit normal along which the characteristic fields
78 : * are defined. Note that, unlike the first-order scalar wave system, there is
79 : * no characteristic field corresponding to \f$\Psi\f$
80 : * (see \cite Gundlach2005ta).
81 : *
82 : * The corresponding characteristic speeds are
83 : * computed by \ref Tags::CharacteristicSpeedsCompute . The inverse
84 : * transform, reconstructing \f$(\Pi, \Phi_i)\f$ from the characteristic fields,
85 : * is computed by
86 : * \ref Tags::FieldsFromInverseCharacteristicTransformCompute .
87 : */
88 : template <size_t Dim>
89 : Variables<tmpl::list<Tags::VZero<Dim>, Tags::VPlus, Tags::VMinus>>
90 1 : characteristic_fields(
91 : const Scalar<DataVector>& pi,
92 : const tnsr::i<DataVector, Dim, Frame::Inertial>& phi,
93 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
94 :
95 : template <size_t Dim>
96 1 : void characteristic_fields(
97 : gsl::not_null<
98 : Variables<tmpl::list<Tags::VZero<Dim>, Tags::VPlus, Tags::VMinus>>*>
99 : char_fields,
100 : const Scalar<DataVector>& pi,
101 : const tnsr::i<DataVector, Dim, Frame::Inertial>& phi,
102 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
103 :
104 : namespace Tags {
105 : template <size_t Dim>
106 0 : struct CharacteristicFieldsCompute : Tags::CharacteristicFields<Dim>,
107 : db::ComputeTag {
108 0 : using base = Tags::CharacteristicFields<Dim>;
109 0 : using return_type = typename base::type;
110 0 : using argument_tags =
111 : tmpl::list<Pi, Phi<Dim>,
112 : ::Tags::Normalized<domain::Tags::UnnormalizedFaceNormal<Dim>>>;
113 :
114 0 : static void function(
115 : const gsl::not_null<return_type*> char_fields,
116 : const Scalar<DataVector>& pi,
117 : const tnsr::i<DataVector, Dim, Frame::Inertial>& phi,
118 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form) {
119 : characteristic_fields(char_fields, pi, phi, unit_normal_one_form);
120 : };
121 : };
122 : } // namespace Tags
123 : /// @}
124 :
125 : /// @{
126 : /*!
127 : * \brief Reconstruct the fields \f$(\Pi, \Phi_i)\f$ from the characteristic
128 : * fields.
129 : *
130 : * This uses the inverse of the relations in
131 : * \ref Tags::CharacteristicFieldsCompute :
132 : *
133 : * \f{align*}
134 : * \Pi =& \frac{1}{2}(v^+ + v^-), \\
135 : * \Phi_{i} =& \frac{1}{2}(v^+ - v^-) n_i + v^0_{i}.
136 : * \f}
137 : *
138 : * The scalar field \f$\Psi\f$ is not reconstructed because it is not part of
139 : * the characteristic decomposition of the second-order scalar wave system.
140 : */
141 : template <size_t Dim>
142 : Variables<tmpl::list<Tags::Pi, Tags::Phi<Dim>>>
143 1 : fields_from_inverse_characteristic_transform(
144 : const tnsr::i<DataVector, Dim, Frame::Inertial>& v_zero,
145 : const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
146 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
147 :
148 : template <size_t Dim>
149 1 : void fields_from_inverse_characteristic_transform(
150 : gsl::not_null<Variables<tmpl::list<Tags::Pi, Tags::Phi<Dim>>>*>
151 : evolved_fields,
152 : const tnsr::i<DataVector, Dim, Frame::Inertial>& v_zero,
153 : const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
154 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
155 :
156 : namespace Tags {
157 : template <size_t Dim>
158 0 : struct FieldsFromInverseCharacteristicTransformCompute
159 : : Tags::FieldsFromInverseCharacteristicTransform<Dim>,
160 : db::ComputeTag {
161 0 : using base = Tags::FieldsFromInverseCharacteristicTransform<Dim>;
162 0 : using return_type = typename base::type;
163 0 : using argument_tags =
164 : tmpl::list<Tags::VZero<Dim>, Tags::VPlus, Tags::VMinus,
165 : ::Tags::Normalized<domain::Tags::UnnormalizedFaceNormal<Dim>>>;
166 :
167 0 : static void function(
168 : const gsl::not_null<return_type*> evolved_fields,
169 : const tnsr::i<DataVector, Dim, Frame::Inertial>& v_zero,
170 : const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
171 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form) {
172 : fields_from_inverse_characteristic_transform(evolved_fields, v_zero, v_plus,
173 : v_minus, unit_normal_one_form);
174 : };
175 : };
176 :
177 0 : struct LargestCharacteristicSpeed : db::SimpleTag {
178 0 : using type = double;
179 : };
180 :
181 : /// Compute the maximum magnitude of the characteristic speeds.
182 1 : struct ComputeLargestCharacteristicSpeed : LargestCharacteristicSpeed,
183 : db::ComputeTag {
184 0 : using argument_tags = tmpl::list<>;
185 0 : using return_type = double;
186 0 : using base = LargestCharacteristicSpeed;
187 0 : SPECTRE_ALWAYS_INLINE static constexpr void function(
188 : const gsl::not_null<double*> speed) {
189 : *speed = 1.0;
190 : }
191 : };
192 : } // namespace Tags
193 : /// @}
194 : } // namespace SecondOrderScalarWave
|