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 : // clang-tidy: google-runtime-references 48 : // clang-tidy: cppcoreguidelines-owning-memory,-warnings-as-errors 49 0 : WRAPPED_PUPable_decl_template(PiecewisePolynomial<MaxDeriv>); // NOLINT 50 : 51 : /// Returns the function at an arbitrary time `t`. If `MaxDeriv` is 52 : /// 0 and `update` has been called for time `t`, the updated value 53 : /// is ignored. 54 1 : std::array<DataVector, 1> func(double t) const override { 55 : return func_and_derivs<0>(t); 56 : } 57 : /// Returns the function and its first derivative at an arbitrary time `t`. 58 : /// If `MaxDeriv` is 1 and `update` has been called for time `t`, the updated 59 : /// value is ignored. 60 1 : std::array<DataVector, 2> func_and_deriv(double t) const override { 61 : return func_and_derivs<1>(t); 62 : } 63 : /// Returns the function and the first two derivatives at an arbitrary time 64 : /// `t`. If `MaxDeriv` is 2 and `update` has been called for time `t`, the 65 : /// updated value is ignored. 66 1 : std::array<DataVector, 3> func_and_2_derivs(double t) const override { 67 : return func_and_derivs<2>(t); 68 : } 69 : 70 : /// Return the function and all derivs up to and including the `MaxDeriv` at 71 : /// an arbitrary time `t`. 72 1 : std::vector<DataVector> func_and_all_derivs(double t) const override; 73 : 74 : /// Updates the `MaxDeriv`th derivative of the function at the given time. 75 : /// `updated_max_deriv` is a vector of the `MaxDeriv`ths for each component. 76 : /// `next_expiration_time` is the next expiration time. 77 : /// 78 : /// The \p time_of_update must be the same as the old expiration 79 : /// time. It is passed as a check that the calling code is 80 : /// computing the other arguments with the correct value. 81 1 : void update(double time_of_update, DataVector updated_max_deriv, 82 : double next_expiration_time) override; 83 : 84 : /// Returns the domain of validity of the function, 85 : /// including the extrapolation region. 86 1 : std::array<double, 2> time_bounds() const override; 87 : 88 1 : double expiration_after(double time) const override; 89 : 90 : // NOLINTNEXTLINE(google-runtime-references) 91 0 : void pup(PUP::er& p) override; 92 : 93 : private: 94 : template <size_t LocalMaxDeriv> 95 0 : friend bool operator==( // NOLINT(readability-redundant-declaration) 96 : const PiecewisePolynomial<LocalMaxDeriv>& lhs, 97 : const PiecewisePolynomial<LocalMaxDeriv>& rhs); 98 : 99 : template <size_t LocalMaxDeriv> 100 0 : friend std::ostream& operator<<( // NOLINT(readability-redundant-declaration 101 : std::ostream& os, 102 : const PiecewisePolynomial<LocalMaxDeriv>& piecewise_polynomial); 103 : 104 0 : void unpack_old_version(PUP::er& p, size_t version); 105 : 106 : /// Returns the function and `MaxDerivReturned` derivatives at 107 : /// an arbitrary time `t`. 108 : /// The function has multiple components. 109 : template <size_t MaxDerivReturned = MaxDeriv> 110 1 : std::array<DataVector, MaxDerivReturned + 1> func_and_derivs(double t) const; 111 : 112 0 : void store_entry(double time_of_update, 113 : std::array<DataVector, MaxDeriv + 1> func_and_derivs, 114 : double next_expiration_time); 115 : 116 : FunctionOfTimeHelpers::ThreadsafeList<std::array<DataVector, MaxDeriv + 1>> 117 0 : deriv_info_at_update_times_; 118 0 : std::map<double, std::pair<DataVector, double>> update_backlog_{}; 119 : }; 120 : 121 : template <size_t MaxDeriv> 122 0 : bool operator!=(const PiecewisePolynomial<MaxDeriv>& lhs, 123 : const PiecewisePolynomial<MaxDeriv>& rhs); 124 : 125 : /// \cond 126 : template <size_t MaxDeriv> 127 : PUP::able::PUP_ID PiecewisePolynomial<MaxDeriv>::my_PUP_ID = 0; // NOLINT 128 : /// \endcond 129 : } // namespace FunctionsOfTime 130 : } // namespace domain