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/ScalarWave/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 : namespace ScalarWave {
29 : /// @{
30 : /*!
31 : * \brief Compute the characteristic speeds for the scalar wave system.
32 : *
33 : * Computes the speeds as described in "Optimal constraint projection for
34 : * hyperbolic evolution systems" by Holst et al. \cite Holst2004wt
35 : * [see text following Eq.(32)]. The characteristic fields' names used here
36 : * differ from this paper:
37 : *
38 : * \f{align*}
39 : * \mathrm{SpECTRE} && \mathrm{Holst} \\
40 : * v^{\hat \psi} && Z^1 \\
41 : * v^{\hat 0}_{i} && Z^{2}_{i} \\
42 : * v^{\hat \pm} && u^{1\pm}
43 : * \f}
44 : *
45 : * The corresponding characteristic speeds \f$\lambda_{\hat \alpha}\f$ are given
46 : * in the text following Eq.(38) of \cite Holst2004wt :
47 : *
48 : * \f{align*}
49 : * \lambda_{\hat \psi} =& 0 \\
50 : * \lambda_{\hat 0} =& 0 \\
51 : * \lambda_{\hat \pm} =& \pm 1.
52 : * \f}
53 : */
54 : template <size_t Dim>
55 1 : std::array<DataVector, 4> characteristic_speeds(
56 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
57 :
58 : template <size_t Dim>
59 1 : void characteristic_speeds(
60 : gsl::not_null<std::array<DataVector, 4>*> char_speeds,
61 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
62 :
63 1 : namespace Tags {
64 : template <size_t Dim>
65 0 : struct CharacteristicSpeedsCompute : Tags::CharacteristicSpeeds<Dim>,
66 : db::ComputeTag {
67 0 : using base = Tags::CharacteristicSpeeds<Dim>;
68 0 : using return_type = typename base::type;
69 0 : using argument_tags =
70 : tmpl::list<::Tags::Normalized<domain::Tags::UnnormalizedFaceNormal<Dim>>>;
71 :
72 0 : static void function(
73 : gsl::not_null<return_type*> char_speeds,
74 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form) {
75 : characteristic_speeds(char_speeds, unit_normal_one_form);
76 : }
77 : };
78 : } // namespace Tags
79 : /// @}
80 :
81 : /// @{
82 : /*!
83 : * \brief Computes characteristic fields from evolved fields
84 : *
85 : * \ref Tags::CharacteristicFieldsCompute and
86 : * \ref Tags::EvolvedFieldsFromCharacteristicFieldsCompute convert between
87 : * characteristic and evolved fields for the scalar-wave system.
88 : *
89 : * \ref Tags::CharacteristicFieldsCompute computes
90 : * characteristic fields as described in "Optimal constraint projection for
91 : * hyperbolic evolution systems" by Holst et al. \cite Holst2004wt .
92 : * Their names used here differ from this paper:
93 : *
94 : * \f{align*}
95 : * \mathrm{SpECTRE} && \mathrm{Holst} \\
96 : * v^{\hat \psi} && Z^1 \\
97 : * v^{\hat 0}_{i} && Z^{2}_{i} \\
98 : * v^{\hat \pm} && u^{1\pm}
99 : * \f}
100 : *
101 : * The characteristic fields \f${v}^{\hat \alpha}\f$ are given in terms of
102 : * the evolved fields by Eq.(33) - (35) of \cite Holst2004wt, respectively:
103 : *
104 : * \f{align*}
105 : * v^{\hat \psi} =& \psi \\
106 : * v^{\hat 0}_{i} =& (\delta^k_i - n_i n^k) \Phi_{k} := P^k_i \Phi_{k} \\
107 : * v^{\hat \pm} =& \Pi \pm n^i \Phi_{i} - \gamma_2\psi
108 : * \f}
109 : *
110 : * where \f$\psi\f$ is the scalar field, \f$\Phi_{i}=\partial_i \psi\f$ is an
111 : * auxiliary variable, \f$\Pi\f$ is a conjugate momentum, \f$\gamma_2\f$
112 : * is a constraint damping parameter, and \f$n_k\f$ is the unit normal to the
113 : * surface along which the characteristic fields are defined.
114 : *
115 : * \ref Tags::EvolvedFieldsFromCharacteristicFieldsCompute computes evolved
116 : * fields \f$u_\alpha\f$ in terms of the characteristic fields. This uses the
117 : * inverse of above relations:
118 : *
119 : * \f{align*}
120 : * \psi =& v^{\hat \psi}, \\
121 : * \Pi =& \frac{1}{2}(v^{\hat +} + v^{\hat -}) + \gamma_2 v^{\hat \psi}, \\
122 : * \Phi_{i} =& \frac{1}{2}(v^{\hat +} - v^{\hat -}) n_i + v^{\hat 0}_{i}.
123 : * \f}
124 : *
125 : * The corresponding characteristic speeds \f$\lambda_{\hat \alpha}\f$
126 : * are computed by \ref Tags::CharacteristicSpeedsCompute .
127 : */
128 : template <size_t Dim>
129 : Variables<tmpl::list<Tags::VPsi, Tags::VZero<Dim>, Tags::VPlus, Tags::VMinus>>
130 1 : characteristic_fields(
131 : const Scalar<DataVector>& gamma_2, const Scalar<DataVector>& psi,
132 : const Scalar<DataVector>& pi,
133 : const tnsr::i<DataVector, Dim, Frame::Inertial>& phi,
134 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
135 :
136 : template <size_t Dim>
137 1 : void characteristic_fields(
138 : gsl::not_null<Variables<
139 : tmpl::list<Tags::VPsi, Tags::VZero<Dim>, Tags::VPlus, Tags::VMinus>>*>
140 : char_fields,
141 : const Scalar<DataVector>& gamma_2, const Scalar<DataVector>& psi,
142 : const Scalar<DataVector>& pi,
143 : const tnsr::i<DataVector, Dim, Frame::Inertial>& phi,
144 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
145 :
146 : namespace Tags {
147 : template <size_t Dim>
148 0 : struct CharacteristicFieldsCompute : Tags::CharacteristicFields<Dim>,
149 : db::ComputeTag {
150 0 : using base = Tags::CharacteristicFields<Dim>;
151 0 : using return_type = typename base::type;
152 0 : using argument_tags =
153 : tmpl::list<Tags::ConstraintGamma2, Psi, Pi, Phi<Dim>,
154 : ::Tags::Normalized<domain::Tags::UnnormalizedFaceNormal<Dim>>>;
155 :
156 0 : static void function(
157 : const gsl::not_null<return_type*> char_fields,
158 : const Scalar<DataVector>& gamma_2, const Scalar<DataVector>& psi,
159 : const Scalar<DataVector>& pi,
160 : const tnsr::i<DataVector, Dim, Frame::Inertial>& phi,
161 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form) {
162 : characteristic_fields(char_fields, gamma_2, psi, pi, phi,
163 : unit_normal_one_form);
164 : };
165 : };
166 : } // namespace Tags
167 : /// @}
168 :
169 : /// @{
170 : /*!
171 : * \brief Compute evolved fields from characteristic fields.
172 : *
173 : * For expressions used here to compute evolved fields from characteristic ones,
174 : * see \ref Tags::CharacteristicFieldsCompute.
175 : */
176 : template <size_t Dim>
177 : Variables<tmpl::list<Tags::Psi, Tags::Pi, Tags::Phi<Dim>>>
178 1 : evolved_fields_from_characteristic_fields(
179 : const Scalar<DataVector>& gamma_2, const Scalar<DataVector>& v_psi,
180 : const tnsr::i<DataVector, Dim, Frame::Inertial>& v_zero,
181 : const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
182 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
183 :
184 : template <size_t Dim>
185 1 : void evolved_fields_from_characteristic_fields(
186 : gsl::not_null<Variables<tmpl::list<Tags::Psi, Tags::Pi, Tags::Phi<Dim>>>*>
187 : evolved_fields,
188 : const Scalar<DataVector>& gamma_2, const Scalar<DataVector>& v_psi,
189 : const tnsr::i<DataVector, Dim, Frame::Inertial>& v_zero,
190 : const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
191 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form);
192 :
193 : namespace Tags {
194 : template <size_t Dim>
195 0 : struct EvolvedFieldsFromCharacteristicFieldsCompute
196 : : Tags::EvolvedFieldsFromCharacteristicFields<Dim>,
197 : db::ComputeTag {
198 0 : using base = Tags::EvolvedFieldsFromCharacteristicFields<Dim>;
199 0 : using return_type = typename base::type;
200 0 : using argument_tags =
201 : tmpl::list<Tags::ConstraintGamma2, Tags::VPsi, Tags::VZero<Dim>,
202 : Tags::VPlus, Tags::VMinus,
203 : ::Tags::Normalized<domain::Tags::UnnormalizedFaceNormal<Dim>>>;
204 :
205 0 : static void function(
206 : const gsl::not_null<return_type*> evolved_fields,
207 : const Scalar<DataVector>& gamma_2, const Scalar<DataVector>& v_psi,
208 : const tnsr::i<DataVector, Dim, Frame::Inertial>& v_zero,
209 : const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
210 : const tnsr::i<DataVector, Dim, Frame::Inertial>& unit_normal_one_form) {
211 : evolved_fields_from_characteristic_fields(evolved_fields, gamma_2, v_psi,
212 : v_zero, v_plus, v_minus,
213 : unit_normal_one_form);
214 : };
215 : };
216 :
217 0 : struct LargestCharacteristicSpeed : db::SimpleTag {
218 0 : using type = double;
219 : };
220 :
221 : /// Compute the maximum magnitude of the characteristic speeds.
222 1 : struct ComputeLargestCharacteristicSpeed : LargestCharacteristicSpeed,
223 : db::ComputeTag {
224 0 : using argument_tags = tmpl::list<>;
225 0 : using return_type = double;
226 0 : using base = LargestCharacteristicSpeed;
227 0 : SPECTRE_ALWAYS_INLINE static constexpr void function(
228 : const gsl::not_null<double*> speed) {
229 : *speed = 1.0;
230 : }
231 : };
232 : } // namespace Tags
233 : /// @}
234 : } // namespace ScalarWave
|