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