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 <map> 9 : #include <memory> 10 : #include <ostream> 11 : #include <pup.h> 12 : #include <utility> 13 : #include <vector> 14 : 15 : #include "DataStructures/DataVector.hpp" 16 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp" 17 : #include "Domain/FunctionsOfTime/ThreadsafeList.hpp" 18 : #include "Utilities/Serialization/CharmPupable.hpp" 19 : 20 : namespace domain { 21 : namespace FunctionsOfTime { 22 : /*! 23 : * \ingroup ComputationalDomainGroup 24 : * \brief A function that has a piecewise-constant `MaxDeriv`th derivative. 25 : * 26 : * \note This class conforms to the requirements of the 27 : * `Parallel::GlobalCache` for objects held by mutable global cache tags. 28 : */ 29 : template <size_t MaxDeriv> 30 1 : class PiecewisePolynomial : public FunctionOfTime { 31 : public: 32 0 : PiecewisePolynomial(); 33 0 : PiecewisePolynomial(PiecewisePolynomial&&); 34 0 : PiecewisePolynomial(const PiecewisePolynomial&); 35 0 : PiecewisePolynomial& operator=(PiecewisePolynomial&&); 36 0 : PiecewisePolynomial& operator=(const PiecewisePolynomial&); 37 0 : ~PiecewisePolynomial() override; 38 : 39 0 : PiecewisePolynomial( 40 : double t, std::array<DataVector, MaxDeriv + 1> initial_func_and_derivs, 41 : double expiration_time); 42 : 43 0 : explicit PiecewisePolynomial(CkMigrateMessage* /*unused*/); 44 : 45 0 : auto get_clone() const -> std::unique_ptr<FunctionOfTime> override; 46 : 47 1 : std::unique_ptr<FunctionOfTime> create_at_time( 48 : double t, double expiration_time) const override; 49 : 50 : // clang-tidy: google-runtime-references 51 : // clang-tidy: cppcoreguidelines-owning-memory,-warnings-as-errors 52 0 : WRAPPED_PUPable_decl_template(PiecewisePolynomial<MaxDeriv>); // NOLINT 53 : 54 : /// Returns the function at an arbitrary time `t`. If `MaxDeriv` is 55 : /// 0 and `update` has been called for time `t`, the updated value 56 : /// is ignored. 57 1 : std::array<DataVector, 1> func(double t) const override { 58 : return func_and_derivs<0>(t); 59 : } 60 : /// Returns the function and its first derivative at an arbitrary time `t`. 61 : /// If `MaxDeriv` is 1 and `update` has been called for time `t`, the updated 62 : /// value is ignored. 63 1 : std::array<DataVector, 2> func_and_deriv(double t) const override { 64 : return func_and_derivs<1>(t); 65 : } 66 : /// Returns the function and the first two derivatives at an arbitrary time 67 : /// `t`. If `MaxDeriv` is 2 and `update` has been called for time `t`, the 68 : /// updated value is ignored. 69 1 : std::array<DataVector, 3> func_and_2_derivs(double t) const override { 70 : return func_and_derivs<2>(t); 71 : } 72 : 73 : /// Return the function and all derivs up to and including the `MaxDeriv` at 74 : /// an arbitrary time `t`. 75 1 : std::vector<DataVector> func_and_all_derivs(double t) const override; 76 : 77 : /// Returns the function and `MaxDerivReturned` derivatives at 78 : /// an arbitrary time `t`. 79 : /// The function has multiple components. 80 : template <size_t MaxDerivReturned = MaxDeriv> 81 1 : std::array<DataVector, MaxDerivReturned + 1> func_and_derivs(double t) const; 82 : 83 : /// Updates the `MaxDeriv`th derivative of the function at the given time. 84 : /// `updated_max_deriv` is a vector of the `MaxDeriv`ths for each component. 85 : /// `next_expiration_time` is the next expiration time. 86 : /// 87 : /// The \p time_of_update must be the same as the old expiration 88 : /// time. It is passed as a check that the calling code is 89 : /// computing the other arguments with the correct value. 90 1 : void update(double time_of_update, DataVector updated_max_deriv, 91 : double next_expiration_time) override; 92 : 93 : /// Returns the domain of validity of the function, 94 : /// including the extrapolation region. 95 1 : std::array<double, 2> time_bounds() const override; 96 : 97 1 : double expiration_after(double time) const override; 98 : 99 : // NOLINTNEXTLINE(google-runtime-references) 100 0 : void pup(PUP::er& p) override; 101 : 102 : private: 103 : template <size_t LocalMaxDeriv> 104 0 : friend bool operator==( // NOLINT(readability-redundant-declaration) 105 : const PiecewisePolynomial<LocalMaxDeriv>& lhs, 106 : const PiecewisePolynomial<LocalMaxDeriv>& rhs); 107 : 108 : template <size_t LocalMaxDeriv> 109 0 : friend std::ostream& operator<<( // NOLINT(readability-redundant-declaration 110 : std::ostream& os, 111 : const PiecewisePolynomial<LocalMaxDeriv>& piecewise_polynomial); 112 : 113 0 : void unpack_old_version(PUP::er& p, size_t version); 114 : 115 0 : void store_entry(double time_of_update, 116 : std::array<DataVector, MaxDeriv + 1> func_and_derivs, 117 : double next_expiration_time); 118 : 119 : FunctionOfTimeHelpers::ThreadsafeList<std::array<DataVector, MaxDeriv + 1>> 120 0 : deriv_info_at_update_times_; 121 0 : std::map<double, std::pair<DataVector, double>> update_backlog_{}; 122 : }; 123 : 124 : template <size_t MaxDeriv> 125 0 : bool operator!=(const PiecewisePolynomial<MaxDeriv>& lhs, 126 : const PiecewisePolynomial<MaxDeriv>& rhs); 127 : 128 : /// \cond 129 : template <size_t MaxDeriv> 130 : PUP::able::PUP_ID PiecewisePolynomial<MaxDeriv>::my_PUP_ID = 0; // NOLINT 131 : /// \endcond 132 : } // namespace FunctionsOfTime 133 : } // namespace domain