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 <pup.h> 11 : 12 : #include "DataStructures/DataVector.hpp" 13 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp" 14 : #include "Utilities/Serialization/CharmPupable.hpp" 15 : 16 : namespace domain { 17 : namespace FunctionsOfTime { 18 : /// \ingroup ControlSystemGroup 19 : /// \brief Given an initial function of time, transitions the map to a 20 : /// constant-in-time value. 21 : /// 22 : /// Given an initial function \f$f(t)\f$ and its first two derivatives 23 : /// at the matching time \f$t_0\f$, the constant coefficients \f$A,B,C\f$ 24 : /// are computed such that the resulting function of time 25 : /// \f$g(t)\f$ satisfies \f$g(t=t_0)=f(t=t_0)\f$ and 26 : /// approaches a constant value for \f$t > t_0\f$ on a timescale 27 : /// of \f$\tau\f$. The resultant 28 : /// function is \f[ g(t) = A + (B+C(t-t_0)) e^{-(t-t_0)/\tau} \f] 29 : /// where \f$\tau\f$=`decay_time` and \f$t_0\f$=`match_time`. 30 1 : class SettleToConstant : public FunctionOfTime { 31 : public: 32 0 : SettleToConstant() = default; 33 0 : SettleToConstant(const std::array<DataVector, 3>& initial_func_and_derivs, 34 : double match_time, double decay_time); 35 : 36 0 : ~SettleToConstant() override = default; 37 0 : SettleToConstant(SettleToConstant&&) = default; 38 0 : SettleToConstant& operator=(SettleToConstant&&) = default; 39 0 : SettleToConstant(const SettleToConstant&) = default; 40 0 : SettleToConstant& operator=(const SettleToConstant&) = default; 41 : 42 : // NOLINTNEXTLINE(google-runtime-references) 43 0 : WRAPPED_PUPable_decl_template(SettleToConstant); 44 : 45 0 : explicit SettleToConstant(CkMigrateMessage* /*unused*/) {} 46 : 47 0 : auto get_clone() const -> std::unique_ptr<FunctionOfTime> override; 48 : 49 : /// Returns the function at an arbitrary time `t`. 50 1 : std::array<DataVector, 1> func(const double t) const override { 51 : return func_and_derivs<0>(t); 52 : } 53 : /// Returns the function and its first derivative at an arbitrary time `t`. 54 1 : std::array<DataVector, 2> func_and_deriv(const double t) const override { 55 : return func_and_derivs<1>(t); 56 : } 57 : /// Returns the function and the first two derivatives at an arbitrary time 58 : /// `t`. 59 1 : std::array<DataVector, 3> func_and_2_derivs(const double t) const override { 60 : return func_and_derivs<2>(t); 61 : } 62 : 63 : /// Returns the domain of validity of the function. 64 1 : std::array<double, 2> time_bounds() const override { 65 : return {{match_time_, std::numeric_limits<double>::infinity()}}; 66 : } 67 : 68 1 : double expiration_after(const double /*time*/) const override { 69 : return std::numeric_limits<double>::infinity(); 70 : } 71 : 72 : // NOLINTNEXTLINE(google-runtime-references) 73 0 : void pup(PUP::er& p) override; 74 : 75 : private: 76 0 : friend bool operator==(const SettleToConstant& lhs, 77 : const SettleToConstant& rhs); 78 : 79 : template <size_t MaxDerivReturned = 2> 80 0 : std::array<DataVector, MaxDerivReturned + 1> func_and_derivs(double t) const; 81 : 82 0 : DataVector coef_a_, coef_b_, coef_c_; 83 0 : double match_time_{std::numeric_limits<double>::signaling_NaN()}; 84 0 : double inv_decay_time_{std::numeric_limits<double>::signaling_NaN()}; 85 : }; 86 : 87 0 : bool operator!=(const SettleToConstant& lhs, const SettleToConstant& rhs); 88 : } // namespace FunctionsOfTime 89 : } // namespace domain