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 <limits>
9 : #include <memory>
10 : #include <string>
11 : #include <unordered_map>
12 :
13 : #include "DataStructures/Tensor/TypeAliases.hpp"
14 : #include "Options/Auto.hpp"
15 : #include "Options/String.hpp"
16 : #include "PointwiseFunctions/ConstraintDamping/DampingFunction.hpp"
17 : #include "Utilities/Serialization/CharmPupable.hpp"
18 : #include "Utilities/TMPL.hpp"
19 :
20 : /// \cond
21 : class DataVector;
22 : namespace PUP {
23 : class er;
24 : } // namespace PUP
25 : namespace domain::FunctionsOfTime {
26 : class FunctionOfTime;
27 : } // namespace domain::FunctionsOfTime
28 : /// \endcond
29 :
30 : namespace ConstraintDamping {
31 : /*!
32 : * \brief A sum of three Gaussians plus a constant, where the Gaussian widths
33 : * are scaled by a domain::FunctionsOfTime::FunctionOfTime.
34 : *
35 : * \details The function \f$f\f$ is given by
36 : * \f{align}{
37 : * f = C + \sum_{\alpha=1}^3
38 : * A_\alpha \exp\left(-\frac{(x-(x_0)_\alpha)^2}{w_\alpha^2(t)}\right).
39 : * \f}
40 : * Input file options are: `Constant` \f$C\f$, `Amplitude[1-3]`
41 : * \f$A_\alpha\f$, `Width[1-3]` \f$w_\alpha\f$, and `Center[1-3]
42 : * `\f$(x_0)_\alpha\f$. The function takes input
43 : * coordinates \f$x\f$ of type `tnsr::I<T, 3, Frame::Grid>`, where `T` is e.g.
44 : * `double` or `DataVector`; note that this DampingFunction is only defined
45 : * for three spatial dimensions and for the grid frame. The Gaussian widths
46 : * \f$w_\alpha\f$ are scaled by the inverse of the value of a scalar
47 : * domain::FunctionsOfTime::FunctionOfTime \f$f(t)\f$: \f$w_\alpha(t) = w_\alpha
48 : * / f(t)\f$.
49 : *
50 : * You can choose one of two methods for tracking the object
51 : * centers. `ExpansionFactor` should be used for BBH simulations where the
52 : * expansion control system is used to track the objects. `ObjectCenters`
53 : * sholud be used for BNS simulations where the coordinate centers of the two
54 : * stars is tracked separately and there is no expansion control system.
55 : */
56 1 : class TimeDependentTripleGaussian : public DampingFunction<3, Frame::Grid> {
57 : private:
58 0 : enum class MovementMethods { ExpansionFactor, ObjectCenters };
59 :
60 : public:
61 : template <size_t GaussianNumber>
62 0 : struct Gaussian {
63 0 : static constexpr Options::String help = {
64 : "Parameters for one of the Gaussians."};
65 0 : static std::string name() {
66 : return "Gaussian" + std::to_string(GaussianNumber);
67 : };
68 : };
69 0 : struct Constant {
70 0 : using type = double;
71 0 : static constexpr Options::String help = {"The constant."};
72 : };
73 :
74 : template <typename Group>
75 0 : struct Amplitude {
76 0 : using group = Group;
77 0 : using type = double;
78 0 : static constexpr Options::String help = {"The amplitude of the Gaussian."};
79 : };
80 :
81 : template <typename Group>
82 0 : struct Width {
83 0 : using group = Group;
84 0 : using type = double;
85 0 : static constexpr Options::String help = {
86 : "The unscaled width of the Gaussian."};
87 0 : static type lower_bound() { return 0.; }
88 : };
89 :
90 : template <typename Group>
91 0 : struct Center {
92 0 : using group = Group;
93 0 : using type = tmpl::conditional_t<std::is_same_v<Group, Gaussian<3>>,
94 : std::array<double, 3>,
95 : Options::Auto<std::array<double, 3>>>;
96 0 : static constexpr Options::String help = {"The center of the Gaussian."};
97 : };
98 :
99 : /// \brief How to track the movement of the compact objects.
100 : ///
101 : /// - `ExpansionFactor` for BBH simulations.
102 : /// - `ObjectCenters` for BNS simulations.
103 1 : struct MovementMethod {
104 0 : using type = std::string;
105 0 : static constexpr Options::String help = {
106 : "How to track the movement of the compact objects.\n\n"
107 : "- `ExpansionFactor` for BBH simulations.\n"
108 : "- `ObjectCenters` for BNS simulations."};
109 : };
110 :
111 0 : using options =
112 : tmpl::list<Constant, Amplitude<Gaussian<1>>, Width<Gaussian<1>>,
113 : Center<Gaussian<1>>, Amplitude<Gaussian<2>>,
114 : Width<Gaussian<2>>, Center<Gaussian<2>>,
115 : Amplitude<Gaussian<3>>, Width<Gaussian<3>>,
116 : Center<Gaussian<3>>, MovementMethod>;
117 :
118 0 : static constexpr Options::String help = {
119 : "Computes a sum of a constant and 3 Gaussians (each with its own "
120 : "amplitude, width, and coordinate center), with the Gaussian widths "
121 : "scaled by the inverse of a FunctionOfTime."};
122 :
123 : /// \cond
124 : WRAPPED_PUPable_decl_base_template(
125 : SINGLE_ARG(DampingFunction<3, Frame::Grid>),
126 : TimeDependentTripleGaussian); // NOLINT
127 : /// \endcond
128 :
129 0 : explicit TimeDependentTripleGaussian(CkMigrateMessage* msg);
130 :
131 0 : TimeDependentTripleGaussian(
132 : double constant, double amplitude_1, double width_1,
133 : const std::optional<std::array<double, 3>>& center_1, double amplitude_2,
134 : double width_2, const std::optional<std::array<double, 3>>& center_2,
135 : double amplitude_3, double width_3, const std::array<double, 3>& center_3,
136 : const std::string& movement_method, const Options::Context& context = {});
137 :
138 0 : TimeDependentTripleGaussian() = default;
139 0 : ~TimeDependentTripleGaussian() override = default;
140 0 : TimeDependentTripleGaussian(const TimeDependentTripleGaussian& /*rhs*/) =
141 : default;
142 0 : TimeDependentTripleGaussian& operator=(
143 : const TimeDependentTripleGaussian& /*rhs*/) = default;
144 0 : TimeDependentTripleGaussian(TimeDependentTripleGaussian&& /*rhs*/) = default;
145 0 : TimeDependentTripleGaussian& operator=(
146 : TimeDependentTripleGaussian&& /*rhs*/) = default;
147 :
148 0 : void operator()(
149 : gsl::not_null<Scalar<double>*> value_at_x,
150 : const tnsr::I<double, 3, Frame::Grid>& x, double time,
151 : const std::unordered_map<
152 : std::string,
153 : std::unique_ptr<::domain::FunctionsOfTime::FunctionOfTime>>&
154 : functions_of_time) const override;
155 0 : void operator()(
156 : gsl::not_null<Scalar<DataVector>*> value_at_x,
157 : const tnsr::I<DataVector, 3, Frame::Grid>& x, double time,
158 : const std::unordered_map<
159 : std::string,
160 : std::unique_ptr<::domain::FunctionsOfTime::FunctionOfTime>>&
161 : functions_of_time) const override;
162 :
163 0 : auto get_clone() const
164 : -> std::unique_ptr<DampingFunction<3, Frame::Grid>> override;
165 :
166 : // NOLINTNEXTLINE(google-runtime-references)
167 0 : void pup(PUP::er& p) override;
168 :
169 : private:
170 0 : friend bool operator==(const TimeDependentTripleGaussian& lhs,
171 : const TimeDependentTripleGaussian& rhs);
172 :
173 0 : double constant_ = std::numeric_limits<double>::signaling_NaN();
174 0 : double amplitude_1_ = std::numeric_limits<double>::signaling_NaN();
175 0 : double inverse_width_1_ = std::numeric_limits<double>::signaling_NaN();
176 0 : std::optional<std::array<double, 3>> center_1_{};
177 0 : double amplitude_2_ = std::numeric_limits<double>::signaling_NaN();
178 0 : double inverse_width_2_ = std::numeric_limits<double>::signaling_NaN();
179 0 : std::optional<std::array<double, 3>> center_2_{};
180 0 : double amplitude_3_ = std::numeric_limits<double>::signaling_NaN();
181 0 : double inverse_width_3_ = std::numeric_limits<double>::signaling_NaN();
182 0 : std::array<double, 3> center_3_{};
183 0 : MovementMethods movement_method_{MovementMethods::ExpansionFactor};
184 0 : inline static const std::string function_of_time_for_scaling_{"Expansion"};
185 0 : inline static const std::string function_of_time_for_centers_{"GridCenters"};
186 :
187 : template <typename T>
188 0 : void apply_call_operator(
189 : gsl::not_null<Scalar<T>*> value_at_x, const tnsr::I<T, 3, Frame::Grid>& x,
190 : double time,
191 : const std::unordered_map<
192 : std::string,
193 : std::unique_ptr<::domain::FunctionsOfTime::FunctionOfTime>>&
194 : functions_of_time) const;
195 : };
196 :
197 0 : bool operator!=(const TimeDependentTripleGaussian& lhs,
198 : const TimeDependentTripleGaussian& rhs);
199 : } // namespace ConstraintDamping
|