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 <memory>
8 : #include <pup.h>
9 :
10 : #include "DataStructures/TaggedTuple.hpp"
11 : #include "DataStructures/Tensor/IndexType.hpp"
12 : #include "DataStructures/Tensor/Tensor.hpp"
13 : #include "Evolution/Systems/CurvedScalarWave/Tags.hpp"
14 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
15 : #include "Options/String.hpp"
16 : #include "PointwiseFunctions/AnalyticData/ScalarTensor/ScalarField/AnalyticData.hpp"
17 : #include "Utilities/MakeWithValue.hpp"
18 : #include "Utilities/Serialization/CharmPupable.hpp"
19 : #include "Utilities/TMPL.hpp"
20 :
21 : namespace ScalarTensor::AnalyticData::ScalarField {
22 :
23 : /*!
24 : * \brief $\frac{A}{r}$ profile for the scalar field.
25 : *
26 : * The expression of the profile as a function of the coordinates reads
27 : * \begin{equation}
28 : * \Psi(x^i) = \frac{A}{|x^i - x^i_0|},
29 : * \end{equation}
30 : * where $\Psi$ is the scalar field, $x^i_0 = (0, 0, 0)$ is the coordinate
31 : * location of the center of the profile and $A$ is the amplitude. Note that the
32 : * norm for the distance is computed using the eucledian metric.
33 : */
34 : template <size_t Dim>
35 1 : class Inverser
36 : : public ScalarTensor::AnalyticData::ScalarField::AnalyticData<Dim> {
37 : public:
38 0 : struct Amplitude {
39 0 : using type = double;
40 0 : static constexpr Options::String help = "Scaled Amplitude.";
41 : };
42 :
43 0 : using options = tmpl::list<Amplitude>;
44 0 : static constexpr Options::String help{
45 : "A/r profile for initial guess of the scalar field."};
46 :
47 0 : using scalar_field_tags =
48 : typename ScalarTensor::AnalyticData::ScalarField::AnalyticData<
49 : Dim>::scalar_field_tags;
50 :
51 0 : Inverser() = default;
52 0 : Inverser(const Inverser&) = default;
53 0 : Inverser& operator=(const Inverser&) = default;
54 0 : Inverser(Inverser&&) = default;
55 0 : Inverser& operator=(Inverser&&) = default;
56 0 : ~Inverser() override = default;
57 :
58 0 : explicit Inverser(double amplitude);
59 :
60 : /// \cond
61 : explicit Inverser(CkMigrateMessage* m)
62 : : ScalarTensor::AnalyticData::ScalarField::AnalyticData<Dim>(m) {}
63 : using PUP::able::register_constructor;
64 : WRAPPED_PUPable_decl_template(Inverser); // NOLINT
65 : /// \endcond
66 :
67 : std::unique_ptr<ScalarTensor::AnalyticData::ScalarField::AnalyticData<Dim>>
68 0 : get_clone() const override;
69 :
70 0 : tuples::TaggedTuple<::CurvedScalarWave::Tags::Psi> variables(
71 : const tnsr::I<DataVector, Dim>& x,
72 : tmpl::list<::CurvedScalarWave::Tags::Psi> /*meta*/) const;
73 :
74 : tuples::TaggedTuple<::CurvedScalarWave::Tags::Phi<Dim, Frame::Inertial>>
75 0 : variables(
76 : const tnsr::I<DataVector, Dim>& x,
77 : tmpl::list<::CurvedScalarWave::Tags::Phi<Dim, Frame::Inertial>> /*meta*/)
78 : const;
79 :
80 : template <typename... RequestedTags>
81 0 : tuples::TaggedTuple<RequestedTags...> variables(
82 : const tnsr::I<DataVector, Dim>& x,
83 : tmpl::list<RequestedTags...> /*meta*/) const {
84 : static_assert(
85 : tmpl::size<tmpl::list_difference<tmpl::list<RequestedTags...>,
86 : scalar_field_tags>>::value == 0,
87 : "The requested tag is not supported");
88 : return {make_with_value<typename RequestedTags::type>(x, 0.)...};
89 : }
90 :
91 0 : void pup(PUP::er& p) override;
92 :
93 : private:
94 0 : double amplitude_{std::numeric_limits<double>::signaling_NaN()};
95 :
96 : template <size_t SpatialDim>
97 0 : friend bool operator==(const Inverser<SpatialDim>& lhs,
98 : const Inverser<SpatialDim>& rhs);
99 : };
100 :
101 : template <size_t SpatialDim>
102 0 : bool operator!=(const Inverser<SpatialDim>& lhs,
103 : const Inverser<SpatialDim>& rhs);
104 :
105 : } // namespace ScalarTensor::AnalyticData::ScalarField
|