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 : #include <memory>
9 : #include <pup.h>
10 :
11 : #include "DataStructures/TaggedTuple.hpp"
12 : #include "DataStructures/Tensor/IndexType.hpp"
13 : #include "DataStructures/Tensor/Tensor.hpp"
14 : #include "Evolution/Systems/CurvedScalarWave/Tags.hpp"
15 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
16 : #include "Options/String.hpp"
17 : #include "PointwiseFunctions/AnalyticData/ScalarTensor/ScalarField/AnalyticData.hpp"
18 : #include "Utilities/MakeWithValue.hpp"
19 : #include "Utilities/Serialization/CharmPupable.hpp"
20 : #include "Utilities/TMPL.hpp"
21 :
22 : namespace ScalarTensor::AnalyticData::ScalarField {
23 :
24 : /*!
25 : * \brief Analytic profile for the scalar field composed by two superimposed
26 : * $\frac{A}{r}$ profiles.
27 : *
28 : * This profile is inteded to be used in binary black hole configurations, and
29 : * describes the superposition of two $\frac{A}{r}$ profiles, centered on the
30 : * two black holes. The expression of the profile then reads
31 : * \begin{equation}
32 : * \Psi(x^i) = \frac{A_a}{|x^i - x^i_a|} + \frac{A_b}{|x^i - x^i_b|},
33 : * \end{equation}
34 : * where $\Psi$ is the scalar field, $x_{a,b}$ are the coordinate locations of
35 : * the centers of the two profiles and $A_{a,b}$ are the amplitudes. Note that
36 : * the norm for the distance is computed using the eucledian metric.
37 : */
38 : template <size_t Dim>
39 1 : class SuperposedInverser
40 : : public ScalarTensor::AnalyticData::ScalarField::AnalyticData<Dim> {
41 : public:
42 0 : struct AmplitudeA {
43 0 : using type = double;
44 0 : static constexpr Options::String help = "Scaled Amplitude A.";
45 : };
46 0 : struct AmplitudeB {
47 0 : using type = double;
48 0 : static constexpr Options::String help = "Scaled Amplitude B.";
49 : };
50 0 : struct LocationA {
51 0 : using type = std::array<double, Dim>;
52 0 : static constexpr Options::String help = "Location of black hole A.";
53 : };
54 0 : struct LocationB {
55 0 : using type = std::array<double, Dim>;
56 0 : static constexpr Options::String help = "location of black hole B.";
57 : };
58 :
59 0 : using options = tmpl::list<AmplitudeA, AmplitudeB, LocationA, LocationB>;
60 0 : static constexpr Options::String help{
61 : "Superposed 1/r intitial guesses for the scalar field in a black hole "
62 : "binary system."};
63 :
64 0 : using scalar_field_tags =
65 : typename ScalarTensor::AnalyticData::ScalarField::AnalyticData<
66 : Dim>::scalar_field_tags;
67 :
68 0 : SuperposedInverser() = default;
69 0 : SuperposedInverser(const SuperposedInverser&) = default;
70 0 : SuperposedInverser& operator=(const SuperposedInverser&) = default;
71 0 : SuperposedInverser(SuperposedInverser&&) = default;
72 0 : SuperposedInverser& operator=(SuperposedInverser&&) = default;
73 0 : ~SuperposedInverser() override = default;
74 0 : SuperposedInverser(double amplitude_a, double amplitude_b,
75 : std::array<double, Dim> location_a,
76 : std::array<double, Dim> location_b);
77 :
78 : /// \cond
79 : explicit SuperposedInverser(CkMigrateMessage* m)
80 : : ScalarTensor::AnalyticData::ScalarField::AnalyticData<Dim>(m) {}
81 : using PUP::able::register_constructor;
82 : WRAPPED_PUPable_decl_template(SuperposedInverser); // NOLINT
83 : /// \endcond
84 :
85 : std::unique_ptr<ScalarTensor::AnalyticData::ScalarField::AnalyticData<Dim>>
86 0 : get_clone() const override;
87 :
88 0 : tuples::TaggedTuple<::CurvedScalarWave::Tags::Psi> variables(
89 : const tnsr::I<DataVector, Dim>& x,
90 : tmpl::list<::CurvedScalarWave::Tags::Psi> /*meta*/) const;
91 :
92 : tuples::TaggedTuple<::CurvedScalarWave::Tags::Phi<Dim, Frame::Inertial>>
93 0 : variables(
94 : const tnsr::I<DataVector, Dim>& x,
95 : tmpl::list<::CurvedScalarWave::Tags::Phi<Dim, Frame::Inertial>> /*meta*/)
96 : const;
97 :
98 : template <typename... RequestedTags>
99 0 : tuples::TaggedTuple<RequestedTags...> variables(
100 : const tnsr::I<DataVector, Dim>& x,
101 : tmpl::list<RequestedTags...> /*meta*/) const {
102 : static_assert(
103 : tmpl::size<tmpl::list_difference<tmpl::list<RequestedTags...>,
104 : scalar_field_tags>>::value == 0,
105 : "The requested tag is not supported");
106 : return {make_with_value<typename RequestedTags::type>(x, 0.)...};
107 : }
108 :
109 0 : void pup(PUP::er& p) override;
110 :
111 : private:
112 0 : double amplitude_a_{std::numeric_limits<double>::signaling_NaN()};
113 0 : double amplitude_b_{std::numeric_limits<double>::signaling_NaN()};
114 0 : std::array<double, Dim> location_a_{
115 : std::numeric_limits<double>::signaling_NaN()};
116 0 : std::array<double, Dim> location_b_{
117 : std::numeric_limits<double>::signaling_NaN()};
118 :
119 : template <size_t SpatialDim>
120 0 : friend bool operator==(const SuperposedInverser<SpatialDim>& lhs,
121 : const SuperposedInverser<SpatialDim>& rhs);
122 : };
123 :
124 : template <size_t SpatialDim>
125 0 : bool operator!=(const SuperposedInverser<SpatialDim>& lhs,
126 : const SuperposedInverser<SpatialDim>& rhs);
127 : } // namespace ScalarTensor::AnalyticData::ScalarField
|