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=\alpha^i \partial_i \Psi_m$.
40 : */
41 1 : void fluxes(gsl::not_null<FluxTensorType*> flux,
42 : const tnsr::I<ComplexDataVector, 2>& alpha,
43 : const GradTensorType& field_gradient);
44 :
45 : /*!
46 : * \brief The first-order flux on an element face
47 : * $F^i=\alpha^i n_i \Psi_m$.
48 : */
49 1 : void fluxes_on_face(gsl::not_null<FluxTensorType*> flux,
50 : const tnsr::I<ComplexDataVector, 2>& alpha,
51 : const tnsr::I<DataVector, 2>& face_normal_vector,
52 : const tnsr::aa<ComplexDataVector, 3>& field);
53 :
54 : /*!
55 : * \brief The source term $\beta_{ab}^{cd} (\Psi_m)_{cd} + \gamma_{iab}^{cd}
56 : * \partial_i (\Psi_m)_{cd}$.
57 : */
58 1 : void add_sources(gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> source,
59 : const tnsr::aaBB<ComplexDataVector, 3>& beta,
60 : const tnsr::aaBB<ComplexDataVector, 3>& gamma_rstar,
61 : const tnsr::aaBB<ComplexDataVector, 3>& gamma_theta,
62 : const tnsr::aa<ComplexDataVector, 3>& field,
63 : const GradTensorType& field_gradient);
64 :
65 : /// Fluxes $F^i$ for the gravitational self-force system.
66 : /// \see GrSelfForce::FirstOrderSystem
67 1 : struct Fluxes {
68 0 : using argument_tags = tmpl::list<Tags::Alpha>;
69 0 : using volume_tags = tmpl::list<>;
70 0 : using const_global_cache_tags = tmpl::list<>;
71 0 : static constexpr bool is_trivial = false;
72 0 : static constexpr bool is_discontinuous = false;
73 0 : static void apply(gsl::not_null<FluxTensorType*> flux,
74 : const tnsr::I<ComplexDataVector, 2>& alpha,
75 : const tnsr::aa<ComplexDataVector, 3>& /*field*/,
76 : const GradTensorType& field_gradient);
77 0 : static void apply(gsl::not_null<FluxTensorType*> flux,
78 : const tnsr::I<ComplexDataVector, 2>& alpha,
79 : const tnsr::i<DataVector, 2>& /*face_normal*/,
80 : const tnsr::I<DataVector, 2>& face_normal_vector,
81 : const tnsr::aa<ComplexDataVector, 3>& field);
82 : };
83 :
84 : /// Source terms for the gravitational self-force system.
85 : /// \see GrSelfForce::FirstOrderSystem
86 1 : struct Sources {
87 0 : using argument_tags =
88 : tmpl::list<Tags::Beta, Tags::GammaRstar, Tags::GammaTheta>;
89 0 : using const_global_cache_tags = tmpl::list<>;
90 0 : static void apply(
91 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> scalar_equation,
92 : const tnsr::aaBB<ComplexDataVector, 3>& beta,
93 : const tnsr::aaBB<ComplexDataVector, 3>& gamma_rstar,
94 : const tnsr::aaBB<ComplexDataVector, 3>& gamma_theta,
95 : const tnsr::aa<ComplexDataVector, 3>& field,
96 : const GradTensorType& field_gradient, const FluxTensorType& /*flux*/);
97 : };
98 :
99 : /*!
100 : * \brief Adds or subtracts the singular field to/from the received data on
101 : * element boundaries.
102 : *
103 : * In the regularized region we solve for the regularized field
104 : * \begin{equation}
105 : * \Psi_m^R = \Psi_m - \Psi_m^P
106 : * \text{,}
107 : * \end{equation}
108 : * so we subtract the singular field on the regularized side (where
109 : * `field_is_regularized` is true) and add it on the other side of the boundary
110 : * (where `field_is_regularized` is false). We do the same for the received
111 : * normal dot flux $n_i F^i$, but with an extra minus sign because this quantity
112 : * is defined with the face normal from the perspective of the sending element
113 : * (see `elliptic::protocols::FirstOrderSystem`).
114 : */
115 1 : struct ModifyBoundaryData {
116 : private:
117 0 : static constexpr size_t Dim = 2;
118 0 : using singular_vars_on_mortars_tag =
119 : ::Tags::Variables<tmpl::list<Tags::SingularField,
120 : ::Tags::NormalDotFlux<Tags::SingularField>>>;
121 :
122 : public:
123 0 : using argument_tags =
124 : tmpl::list<Tags::FieldIsRegularized,
125 : ::Tags::Mortars<Tags::FieldIsRegularized, Dim>,
126 : ::Tags::Mortars<singular_vars_on_mortars_tag, Dim>>;
127 : public:
128 0 : using argument_tags_linearized = tmpl::list<
129 : domain::Tags::Element<Dim>, Tags::NullSlicingBlocks<Dim>,
130 : elliptic::Tags::Background<elliptic::analytic_data::Background>>;
131 0 : using const_global_cache_tags = tmpl::list<
132 : Tags::NullSlicingBlocks<Dim>,
133 : elliptic::Tags::Background<elliptic::analytic_data::Background>>;
134 0 : static void apply(
135 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> field,
136 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> n_dot_flux,
137 : const DirectionalId<Dim>& mortar_id, bool field_is_regularized,
138 : const DirectionalIdMap<Dim, bool>& neighbors_field_is_regularized,
139 : const DirectionalIdMap<Dim, typename singular_vars_on_mortars_tag::type>&
140 : singular_vars_on_mortars);
141 0 : static void apply_linearized(
142 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*> field_remote,
143 : gsl::not_null<tnsr::aa<ComplexDataVector, 3>*>
144 : n_dot_flux_remote,
145 : const tnsr::aa<ComplexDataVector, 3>& field_local,
146 : const tnsr::aa<ComplexDataVector, 3>& n_dot_flux_local,
147 : const DirectionalId<Dim>& mortar_id, const Element<Dim>& element,
148 : const std::vector<size_t>& null_slicing_blocks,
149 : const elliptic::analytic_data::Background& background);
150 : };
151 :
152 : } // namespace GrSelfForce
|