Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <pup.h>
8 :
9 : #include "DataStructures/ComplexDataVector.hpp"
10 : #include "DataStructures/DataVector.hpp"
11 : #include "DataStructures/Tensor/Tensor.hpp"
12 : #include "DataStructures/Variables.hpp"
13 : #include "DataStructures/VariablesTag.hpp"
14 : #include "Domain/Tags.hpp"
15 : #include "Elliptic/Systems/SelfForce/GeneralRelativity/Tags.hpp"
16 : #include "Elliptic/Tags.hpp"
17 : #include "NumericalAlgorithms/DiscontinuousGalerkin/Tags.hpp"
18 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
19 : #include "PointwiseFunctions/InitialDataUtilities/Background.hpp"
20 : #include "Utilities/Gsl.hpp"
21 : #include "Utilities/MakeWithValue.hpp"
22 : #include "Utilities/TMPL.hpp"
23 :
24 : namespace GrSelfForce {
25 :
26 : /// @{
27 : /// We're working with 4D tensors to represent the 10 independent components
28 : /// we're solving for, but we only take 2D spatial derivatives, so we define
29 : /// these mixed-dimension tensors for gradients and fluxes.
30 1 : using GradTensorType =
31 : TensorMetafunctions::prepend_spatial_index<tnsr::aa<ComplexDataVector, 3>,
32 : 2, UpLo::Lo, Frame::Inertial>;
33 1 : using FluxTensorType =
34 : TensorMetafunctions::prepend_spatial_index<tnsr::aa<ComplexDataVector, 3>,
35 : 2, UpLo::Up, Frame::Inertial>;
36 : /// @}
37 :
38 : /*!
39 : * \brief The first-order flux $F^i=\{\partial_{r_\star}, \alpha
40 : * \partial_\theta\}\Psi_m$.
41 : */
42 1 : void fluxes(gsl::not_null<FluxTensorType*> flux,
43 : const Scalar<ComplexDataVector>& alpha,
44 : const GradTensorType& field_gradient);
45 :
46 : /*!
47 : * \brief The first-order flux on an element face
48 : * $F^i=\{n_{r_\star}, \alpha n_\theta\}\Psi_m$.
49 : */
50 1 : void fluxes_on_face(gsl::not_null<FluxTensorType*> flux,
51 : const Scalar<ComplexDataVector>& alpha,
52 : const tnsr::I<DataVector, 2>& face_normal_vector,
53 : const tnsr::aa<ComplexDataVector, 3>& field);
54 :
55 : /*!
56 : * \brief The source term $\beta_{ab}^{cd} (\Psi_m)_{cd} + \gamma_{iab}^{cd}
57 : * F^i_{cd}$.
58 : */
59 1 : void add_sources(gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> source,
60 : const tnsr::aaBB<ComplexDataVector, 3>& beta,
61 : const tnsr::aaBB<ComplexDataVector, 3>& gamma_rstar,
62 : const tnsr::aaBB<ComplexDataVector, 3>& gamma_theta,
63 : const tnsr::aa<ComplexDataVector, 3>& field,
64 : const FluxTensorType& flux);
65 :
66 : /// Fluxes $F^i$ for the gravitational self-force system.
67 : /// \see GrSelfForce::FirstOrderSystem
68 1 : struct Fluxes {
69 0 : using argument_tags = tmpl::list<Tags::Alpha>;
70 0 : using volume_tags = tmpl::list<>;
71 0 : using const_global_cache_tags = tmpl::list<>;
72 0 : static constexpr bool is_trivial = false;
73 0 : static constexpr bool is_discontinuous = false;
74 0 : static void apply(gsl::not_null<FluxTensorType*> flux,
75 : const Scalar<ComplexDataVector>& alpha,
76 : const tnsr::aa<ComplexDataVector, 3>& /*field*/,
77 : const GradTensorType& field_gradient);
78 0 : static void apply(gsl::not_null<FluxTensorType*> flux,
79 : const Scalar<ComplexDataVector>& alpha,
80 : const tnsr::i<DataVector, 2>& /*face_normal*/,
81 : const tnsr::I<DataVector, 2>& face_normal_vector,
82 : const tnsr::aa<ComplexDataVector, 3>& field);
83 : };
84 :
85 : /// Source terms for the gravitational self-force system.
86 : /// \see GrSelfForce::FirstOrderSystem
87 1 : struct Sources {
88 0 : using argument_tags =
89 : tmpl::list<Tags::Beta, Tags::GammaRstar, Tags::GammaTheta>;
90 0 : using const_global_cache_tags = tmpl::list<>;
91 0 : static void apply(
92 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> scalar_equation,
93 : const tnsr::aaBB<ComplexDataVector, 3>& beta,
94 : const tnsr::aaBB<ComplexDataVector, 3>& gamma_rstar,
95 : const tnsr::aaBB<ComplexDataVector, 3>& gamma_theta,
96 : const tnsr::aa<ComplexDataVector, 3>& field,
97 : const GradTensorType& /*field_gradient*/, const FluxTensorType& flux);
98 : };
99 :
100 : /*!
101 : * \brief Adds or subtracts the singular field to/from the received data on
102 : * element boundaries.
103 : *
104 : * In the regularized region we solve for the regularized field
105 : * \begin{equation}
106 : * \Psi_m^R = \Psi_m - \Psi_m^P
107 : * \text{,}
108 : * \end{equation}
109 : * so we subtract the singular field on the regularized side (where
110 : * `field_is_regularized` is true) and add it on the other side of the boundary
111 : * (where `field_is_regularized` is false). We do the same for the received
112 : * normal dot flux $n_i F^i$, but with an extra minus sign because this quantity
113 : * is defined with the face normal from the perspective of the sending element
114 : * (see `elliptic::protocols::FirstOrderSystem`).
115 : */
116 1 : struct ModifyBoundaryData {
117 : private:
118 0 : static constexpr size_t Dim = 2;
119 0 : using singular_vars_on_mortars_tag =
120 : ::Tags::Variables<tmpl::list<Tags::SingularField,
121 : ::Tags::NormalDotFlux<Tags::SingularField>>>;
122 :
123 : public:
124 0 : using argument_tags =
125 : tmpl::list<Tags::FieldIsRegularized,
126 : ::Tags::Mortars<Tags::FieldIsRegularized, Dim>,
127 : ::Tags::Mortars<singular_vars_on_mortars_tag, Dim>>;
128 : public:
129 0 : using argument_tags_linearized = tmpl::list<
130 : domain::Tags::Element<Dim>, Tags::NullSlicingBlocks<Dim>,
131 : elliptic::Tags::Background<elliptic::analytic_data::Background>>;
132 0 : using const_global_cache_tags = tmpl::list<
133 : Tags::NullSlicingBlocks<Dim>,
134 : elliptic::Tags::Background<elliptic::analytic_data::Background>>;
135 0 : static void apply(
136 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> field,
137 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> n_dot_flux,
138 : const DirectionalId<Dim>& mortar_id, bool field_is_regularized,
139 : const DirectionalIdMap<Dim, bool>& neighbors_field_is_regularized,
140 : const DirectionalIdMap<Dim, typename singular_vars_on_mortars_tag::type>&
141 : singular_vars_on_mortars);
142 0 : static void apply_linearized(
143 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> field_remote,
144 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*>
145 : n_dot_flux_remote,
146 : const tnsr::aa<ComplexDataVector, 3>& field_local,
147 : const tnsr::aa<ComplexDataVector, 3>& n_dot_flux_local,
148 : const DirectionalId<Dim>& mortar_id, const Element<Dim>& element,
149 : const std::vector<size_t>& null_slicing_blocks,
150 : const elliptic::analytic_data::Background& background);
151 : };
152 :
153 : } // namespace GrSelfForce
|