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/String.hpp"
15 : #include "PointwiseFunctions/ConstraintDamping/DampingFunction.hpp"
16 : #include "Utilities/Serialization/CharmPupable.hpp"
17 : #include "Utilities/TMPL.hpp"
18 :
19 : /// \cond
20 : class DataVector;
21 : namespace PUP {
22 : class er;
23 : } // namespace PUP
24 : namespace domain::FunctionsOfTime {
25 : class FunctionOfTime;
26 : } // namespace domain::FunctionsOfTime
27 : /// \endcond
28 :
29 : namespace ConstraintDamping {
30 : /*!
31 : * \brief A Gaussian plus a constant: \f$f = C + A
32 : * \exp\left(-\frac{(x-x_0)^2}{w^2}\right)\f$
33 : *
34 : * \details Input file options are: `Constant` \f$C\f$, `Amplitude` \f$A\f$,
35 : * `Width` \f$w\f$, and `Center`\f$x_0\f$. The function takes input coordinates
36 : * of type `tnsr::I<T, VolumeDim, Fr>`, where `T` is e.g. `double` or
37 : * `DataVector`, `Fr` is a frame (e.g. `Frame::Inertial`), and `VolumeDim` is
38 : * the dimension of the spatial volume.
39 : */
40 : template <size_t VolumeDim, typename Fr>
41 1 : class GaussianPlusConstant : public DampingFunction<VolumeDim, Fr> {
42 : public:
43 0 : struct Constant {
44 0 : using type = double;
45 0 : static constexpr Options::String help = {"The constant."};
46 : };
47 :
48 0 : struct Amplitude {
49 0 : using type = double;
50 0 : static constexpr Options::String help = {"The amplitude of the Gaussian."};
51 : };
52 :
53 0 : struct Width {
54 0 : using type = double;
55 0 : static constexpr Options::String help = {"The width of the Gaussian."};
56 0 : static type lower_bound() { return 0.; }
57 : };
58 :
59 0 : struct Center {
60 0 : using type = std::array<double, VolumeDim>;
61 0 : static constexpr Options::String help = {"The center of the Gaussian."};
62 : };
63 0 : using options = tmpl::list<Constant, Amplitude, Width, Center>;
64 :
65 0 : static constexpr Options::String help = {
66 : "Computes a Gaussian plus a constant about an arbitrary coordinate "
67 : "center with given width and amplitude"};
68 :
69 : /// \cond
70 : WRAPPED_PUPable_decl_base_template(SINGLE_ARG(DampingFunction<VolumeDim, Fr>),
71 : GaussianPlusConstant); // NOLINT
72 :
73 : explicit GaussianPlusConstant(CkMigrateMessage* msg);
74 : /// \endcond
75 :
76 0 : GaussianPlusConstant(double constant, double amplitude, double width,
77 : const std::array<double, VolumeDim>& center);
78 :
79 0 : GaussianPlusConstant() = default;
80 0 : ~GaussianPlusConstant() override = default;
81 0 : GaussianPlusConstant(const GaussianPlusConstant& /*rhs*/) = default;
82 0 : GaussianPlusConstant& operator=(const GaussianPlusConstant& /*rhs*/) =
83 : default;
84 0 : GaussianPlusConstant(GaussianPlusConstant&& /*rhs*/) = default;
85 0 : GaussianPlusConstant& operator=(GaussianPlusConstant&& /*rhs*/) = default;
86 :
87 0 : void operator()(
88 : gsl::not_null<Scalar<double>*> value_at_x,
89 : const tnsr::I<double, VolumeDim, Fr>& x, double time,
90 : const std::unordered_map<
91 : std::string,
92 : std::unique_ptr<::domain::FunctionsOfTime::FunctionOfTime>>&
93 : functions_of_time) const override;
94 0 : void operator()(
95 : gsl::not_null<Scalar<DataVector>*> value_at_x,
96 : const tnsr::I<DataVector, VolumeDim, Fr>& x, double time,
97 : const std::unordered_map<
98 : std::string,
99 : std::unique_ptr<::domain::FunctionsOfTime::FunctionOfTime>>&
100 : functions_of_time) const override;
101 :
102 0 : auto get_clone() const
103 : -> std::unique_ptr<DampingFunction<VolumeDim, Fr>> override;
104 :
105 : // NOLINTNEXTLINE(google-runtime-references)
106 0 : void pup(PUP::er& p) override;
107 :
108 : private:
109 0 : friend bool operator==(const GaussianPlusConstant& lhs,
110 : const GaussianPlusConstant& rhs) {
111 : return lhs.constant_ == rhs.constant_ and
112 : lhs.amplitude_ == rhs.amplitude_ and
113 : lhs.inverse_width_ == rhs.inverse_width_ and
114 : lhs.center_ == rhs.center_;
115 : }
116 :
117 0 : double constant_ = std::numeric_limits<double>::signaling_NaN();
118 0 : double amplitude_ = std::numeric_limits<double>::signaling_NaN();
119 0 : double inverse_width_ = std::numeric_limits<double>::signaling_NaN();
120 0 : std::array<double, VolumeDim> center_{};
121 :
122 : template <typename T>
123 0 : void apply_call_operator(gsl::not_null<Scalar<T>*> value_at_x,
124 : const tnsr::I<T, VolumeDim, Fr>& x) const;
125 : };
126 :
127 : template <size_t VolumeDim, typename Fr>
128 0 : bool operator!=(const GaussianPlusConstant<VolumeDim, Fr>& lhs,
129 : const GaussianPlusConstant<VolumeDim, Fr>& rhs) {
130 : return not(lhs == rhs);
131 : }
132 : } // namespace ConstraintDamping
133 :
134 : /// \cond
135 : template <size_t VolumeDim, typename Fr>
136 : PUP::able::PUP_ID
137 : // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
138 : ConstraintDamping::GaussianPlusConstant<VolumeDim, Fr>::my_PUP_ID =
139 : 0; // NOLINT
140 : /// \endcond
|