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