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 "Evolution/Systems/GeneralizedHarmonic/ConstraintDamping/DampingFunction.hpp" 15 : #include "Options/String.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 gh::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 1 : void operator()(const gsl::not_null<Scalar<double>*> value_at_x, 88 : const tnsr::I<double, VolumeDim, Fr>& x, double time, 89 : const std::unordered_map< 90 : std::string, 91 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 92 : functions_of_time) const override; 93 1 : void operator()(const gsl::not_null<Scalar<DataVector>*> value_at_x, 94 : const tnsr::I<DataVector, VolumeDim, Fr>& x, double time, 95 : const std::unordered_map< 96 : std::string, 97 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 98 : functions_of_time) const override; 99 : 100 0 : auto get_clone() const 101 : -> std::unique_ptr<DampingFunction<VolumeDim, Fr>> override; 102 : 103 : // NOLINTNEXTLINE(google-runtime-references) 104 0 : void pup(PUP::er& p) override; 105 : 106 : private: 107 0 : friend bool operator==(const GaussianPlusConstant& lhs, 108 : const GaussianPlusConstant& rhs) { 109 : return lhs.constant_ == rhs.constant_ and 110 : lhs.amplitude_ == rhs.amplitude_ and 111 : lhs.inverse_width_ == rhs.inverse_width_ and 112 : lhs.center_ == rhs.center_; 113 : } 114 : 115 0 : double constant_ = std::numeric_limits<double>::signaling_NaN(); 116 0 : double amplitude_ = std::numeric_limits<double>::signaling_NaN(); 117 0 : double inverse_width_ = std::numeric_limits<double>::signaling_NaN(); 118 0 : std::array<double, VolumeDim> center_{}; 119 : 120 : template <typename T> 121 0 : void apply_call_operator(const gsl::not_null<Scalar<T>*> value_at_x, 122 : const tnsr::I<T, VolumeDim, Fr>& x) const; 123 : }; 124 : 125 : template <size_t VolumeDim, typename Fr> 126 0 : bool operator!=(const GaussianPlusConstant<VolumeDim, Fr>& lhs, 127 : const GaussianPlusConstant<VolumeDim, Fr>& rhs) { 128 : return not(lhs == rhs); 129 : } 130 : } // namespace gh::ConstraintDamping 131 : 132 : /// \cond 133 : template <size_t VolumeDim, typename Fr> 134 : PUP::able::PUP_ID 135 : gh::ConstraintDamping::GaussianPlusConstant<VolumeDim, Fr>::my_PUP_ID = 136 : 0; // NOLINT 137 : /// \endcond