Characteristics.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 
8 #include "DataStructures/DataBox/Tag.hpp"
9 #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
12 #include "Domain/FaceNormal.hpp"
14 #include "Evolution/Systems/CurvedScalarWave/TagsDeclarations.hpp"
15 #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
16 #include "Utilities/TMPL.hpp"
17 
18 namespace CurvedScalarWave {
19 // @{
20 /*!
21  * \ingroup CurvedScalarWave
22  * \brief Compute the characteristic speeds for the scalar wave system in curved
23  * spacetime.
24  *
25  * Computes the speeds as described in "Optimal constraint projection for
26  * hyperbolic evolution systems" by Holst et. al \cite Holst2004wt
27  * [see text following Eq. (32)]. The characteristic fields' names used here
28  * are similar to the paper:
29  *
30  * \f{align*}
31  * \mathrm{SpECTRE} && \mathrm{Holst} \\
32  * v^{\hat \psi} && Z^1 \\
33  * v^{\hat 0}_{i} && Z^{2}_{i} \\
34  * v^{\hat \pm} && u^{1\pm}
35  * \f}
36  *
37  * The corresponding characteristic speeds \f$\lambda\f$ are given in the text
38  * following Eq. (38) of \cite Holst2004wt :
39  *
40  * \f{align*}
41  * \lambda_{\hat \psi} =& -(1 + \gamma_1) n_k N^k \\
42  * \lambda_{\hat 0} =& -n_k N^k \\
43  * \lambda_{\hat \pm} =& -n_k N^k \pm N
44  * \f}
45  *
46  * where \f$n_k\f$ is the unit normal to the surface.
47  */
48 template <size_t SpatialDim>
49 std::array<DataVector, 4> characteristic_speeds(
50  const Scalar<DataVector>& gamma_1, const Scalar<DataVector>& lapse,
51  const tnsr::I<DataVector, SpatialDim, Frame::Inertial>& shift,
52  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
53  unit_normal_one_form) noexcept;
54 
55 template <size_t SpatialDim>
56 void characteristic_speeds(
58  const Scalar<DataVector>& gamma_1, const Scalar<DataVector>& lapse,
59  const tnsr::I<DataVector, SpatialDim, Frame::Inertial>& shift,
60  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
61  unit_normal_one_form) noexcept;
62 
63 template <size_t SpatialDim>
67  using return_type = typename base::type;
68  using argument_tags = tmpl::list<
72 
73  static constexpr void function(
74  gsl::not_null<return_type*> result, const Scalar<DataVector>& gamma_1,
76  const tnsr::I<DataVector, SpatialDim, Frame::Inertial>& shift,
77  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
78  unit_normal_one_form) noexcept {
79  characteristic_speeds<SpatialDim>(result, gamma_1, lapse, shift,
81  }
82 };
83 // @}
84 
85 // @{
86 /*!
87  * \ingroup CurvedScalarWave
88  * \brief Computes characteristic fields from evolved fields
89  *
90  * \ref CharacteristicFieldsCompute and
91  * \ref EvolvedFieldsFromCharacteristicFieldsCompute convert between
92  * characteristic and evolved fields for the scalar-wave system in curved
93  * spacetime.
94  *
95  * \ref CharacteristicFieldsCompute computes
96  * characteristic fields as described in "Optimal constraint projection for
97  * hyperbolic evolution systems" by Holst et. al \cite Holst2004wt .
98  * Their names used here differ from this paper:
99  *
100  * \f{align*}
101  * \mathrm{SpECTRE} && \mathrm{Holst} \\
102  * v^{\hat \psi} && Z^1 \\
103  * v^{\hat 0}_{i} && Z^{2}_{i} \\
104  * v^{\hat \pm} && u^{1\pm}
105  * \f}
106  *
107  * The characteristic fields \f$u\f$ are given in terms of the evolved fields by
108  * Eq. (33) - (35) of \cite Holst2004wt, respectively:
109  *
110  * \f{align*}
111  * v^{\hat \psi} =& \psi \\
112  * v^{\hat 0}_{i} =& (\delta^k_i - n_i n^k) \Phi_{k} := P^k_i \Phi_{k} \\
113  * v^{\hat \pm} =& \Pi \pm n^i \Phi_{i} - \gamma_2\psi
114  * \f}
115  *
116  * where \f$\psi\f$ is the scalar field, \f$\Pi\f$ and \f$\Phi_{i}\f$ are
117  * evolved fields introduced by first derivatives of \f$\psi\f$, \f$\gamma_2\f$
118  * is a constraint damping parameter, and \f$n_k\f$ is the unit normal to the
119  * surface.
120  *
121  * \ref EvolvedFieldsFromCharacteristicFieldsCompute computes evolved fields
122  * \f$w\f$ in terms of the characteristic fields. This uses the inverse of
123  * above relations (c.f. Eq. (36) - (38) of \cite Holst2004wt ):
124  *
125  * \f{align*}
126  * \psi =& v^{\hat \psi}, \\
127  * \Pi =& \frac{1}{2}(v^{\hat +} + v^{\hat -}) + \gamma_2 v^{\hat \psi}, \\
128  * \Phi_{i} =& \frac{1}{2}(v^{\hat +} - v^{\hat -}) n_i + v^{\hat 0}_{i}.
129  * \f}
130  *
131  * The corresponding characteristic speeds \f$\lambda\f$ are computed by
132  * \ref CharacteristicSpeedsCompute .
133  */
134 template <size_t SpatialDim>
135 Variables<
136  tmpl::list<Tags::VPsi, Tags::VZero<SpatialDim>, Tags::VPlus, Tags::VMinus>>
137 characteristic_fields(
138  const Scalar<DataVector>& gamma_2,
139  const tnsr::II<DataVector, SpatialDim, Frame::Inertial>&
140  inverse_spatial_metric,
141  const Scalar<DataVector>& psi, const Scalar<DataVector>& pi,
142  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>& phi,
143  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
144  unit_normal_one_form) noexcept;
145 
146 template <size_t SpatialDim>
147 void characteristic_fields(
148  gsl::not_null<Variables<tmpl::list<Tags::VPsi, Tags::VZero<SpatialDim>,
149  Tags::VPlus, Tags::VMinus>>*>
150  char_fields,
151  const Scalar<DataVector>& gamma_2,
152  const tnsr::II<DataVector, SpatialDim, Frame::Inertial>&
153  inverse_spatial_metric,
154  const Scalar<DataVector>& psi, const Scalar<DataVector>& pi,
155  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>& phi,
156  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
157  unit_normal_one_form) noexcept;
158 
159 template <size_t SpatialDim>
163  using return_type = typename base::type;
164  using argument_tags = tmpl::list<
169 
170  static constexpr void function(
171  gsl::not_null<return_type*> result, const Scalar<DataVector>& gamma_2,
172  const tnsr::II<DataVector, SpatialDim, Frame::Inertial>&
173  inverse_spatial_metric,
174  const Scalar<DataVector>& psi, const Scalar<DataVector>& pi,
175  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>& phi,
176  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
177  unit_normal_one_form) noexcept {
178  characteristic_fields<SpatialDim>(result, gamma_2, inverse_spatial_metric,
179  psi, pi, phi, unit_normal_one_form);
180  }
181 };
182 // @}
183 
184 // @{
185 /*!
186  * \ingroup CurvedScalarWave
187  * \brief For expressions used here to compute evolved fields from
188  * characteristic ones, see \ref CharacteristicFieldsCompute.
189  */
190 template <size_t SpatialDim>
191 Variables<tmpl::list<Psi, Pi, Phi<SpatialDim>>>
192 evolved_fields_from_characteristic_fields(
193  const Scalar<DataVector>& gamma_2, const Scalar<DataVector>& v_psi,
194  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>& v_zero,
195  const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
196  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
197  unit_normal_one_form) noexcept;
198 
199 template <size_t SpatialDim>
200 void evolved_fields_from_characteristic_fields(
201  gsl::not_null<Variables<tmpl::list<Psi, Pi, Phi<SpatialDim>>>*>
202  evolved_fields,
203  const Scalar<DataVector>& gamma_2, const Scalar<DataVector>& v_psi,
204  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>& v_zero,
205  const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
206  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
207  unit_normal_one_form) noexcept;
208 
209 template <size_t SpatialDim>
214  using return_type = typename base::type;
215  using argument_tags = tmpl::list<
217  Tags::VMinus,
219 
220  static constexpr void function(
221  gsl::not_null<return_type*> result, const Scalar<DataVector>& gamma_2,
222  const Scalar<DataVector>& v_psi,
223  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>& v_zero,
224  const Scalar<DataVector>& v_plus, const Scalar<DataVector>& v_minus,
225  const tnsr::i<DataVector, SpatialDim, Frame::Inertial>&
226  unit_normal_one_form) noexcept {
227  evolved_fields_from_characteristic_fields<SpatialDim>(
228  result, gamma_2, v_psi, v_zero, v_plus, v_minus, unit_normal_one_form);
229  }
230 };
231 // @}
232 
233 /*!
234  * \ingroup CurvedScalarWave
235  * \brief Computes the largest magnitude of the characteristic speeds.
236  */
237 template <size_t SpatialDim>
239  using argument_tags = tmpl::list<Tags::CharacteristicSpeeds<SpatialDim>>;
240  static double apply(const std::array<DataVector, 4>& char_speeds) noexcept;
241 };
242 } // namespace CurvedScalarWave
Definition: Characteristics.hpp:64
void phi(gsl::not_null< 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&#39;s equations...
Defines functions to calculate the scalar wave constraints in curved spacetime.
The normalized (co)vector represented by Tag.
Definition: Magnitude.hpp:121
void unit_normal_one_form(gsl::not_null< tnsr::i< DataVector, 3, Frame > *> result, const tnsr::i< DataVector, 3, Frame > &normal_one_form, const DataVector &one_over_one_form_magnitude) noexcept
Computes normalized unit normal one-form to a Strahlkorper.
Tags corresponding to the characteristic fields of the scalar-wave system in curved spacetime...
Definition: Tags.hpp:74
Marks a DataBoxTag as being a compute item that executes a function.
Definition: Tag.hpp:109
Definition: Tags.hpp:27
Definition: Characteristics.hpp:160
Definition: Tags.hpp:52
Inverse of the spatial metric.
Definition: Tags.hpp:33
Definition: Tags.hpp:78
Definition: Tags.hpp:84
Definition: Tags.hpp:81
Scalar< DataType > lapse(const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::aa< DataType, SpatialDim, Frame > &spacetime_metric) noexcept
Compute lapse from shift and spacetime metric.
Definition: Tags.hpp:32
Defines class Variables.
Definition: Tags.hpp:48
void pi(gsl::not_null< tnsr::aa< DataType, SpatialDim, Frame > *> pi, const Scalar< DataType > &lapse, const Scalar< DataType > &dt_lapse, const tnsr::I< DataType, SpatialDim, Frame > &shift, const tnsr::I< DataType, SpatialDim, Frame > &dt_shift, const tnsr::ii< DataType, SpatialDim, Frame > &spatial_metric, const tnsr::ii< DataType, SpatialDim, Frame > &dt_spatial_metric, const tnsr::iaa< DataType, SpatialDim, Frame > &phi) noexcept
Computes the conjugate momentum of the spacetime metric .
Defines classes for Tensor.
Declares function unnormalized_face_normal.
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args) noexcept
Apply the invokable f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1444
tnsr::I< DataType, SpatialDim, Frame > shift(const tnsr::aa< DataType, SpatialDim, Frame > &spacetime_metric, const tnsr::II< DataType, SpatialDim, Frame > &inverse_spatial_metric) noexcept
Compute shift from spacetime metric and inverse spatial metric.
Definition: Tags.hpp:23
Wraps the template metaprogramming library used (brigand)
Items related to evolving a scalar wave on a curved background.
Definition: Characteristics.cpp:18
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182
Computes the largest magnitude of the characteristic speeds.
Definition: Characteristics.hpp:238