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 1 : void truncate_at_time(double time) override;
100 :
101 : // NOLINTNEXTLINE(google-runtime-references)
102 0 : void pup(PUP::er& p) override;
103 :
104 : private:
105 : template <size_t LocalMaxDeriv>
106 0 : friend bool operator==( // NOLINT(readability-redundant-declaration)
107 : const PiecewisePolynomial<LocalMaxDeriv>& lhs,
108 : const PiecewisePolynomial<LocalMaxDeriv>& rhs);
109 :
110 : template <size_t LocalMaxDeriv>
111 0 : friend std::ostream& operator<<( // NOLINT(readability-redundant-declaration
112 : std::ostream& os,
113 : const PiecewisePolynomial<LocalMaxDeriv>& piecewise_polynomial);
114 :
115 0 : void unpack_old_version(PUP::er& p, size_t version);
116 :
117 0 : void store_entry(double time_of_update,
118 : std::array<DataVector, MaxDeriv + 1> func_and_derivs,
119 : double next_expiration_time);
120 :
121 : FunctionOfTimeHelpers::ThreadsafeList<std::array<DataVector, MaxDeriv + 1>>
122 0 : deriv_info_at_update_times_;
123 0 : std::map<double, std::pair<DataVector, double>> update_backlog_{};
124 : };
125 :
126 : template <size_t MaxDeriv>
127 0 : bool operator!=(const PiecewisePolynomial<MaxDeriv>& lhs,
128 : const PiecewisePolynomial<MaxDeriv>& rhs);
129 :
130 : /// \cond
131 : template <size_t MaxDeriv>
132 : PUP::able::PUP_ID PiecewisePolynomial<MaxDeriv>::my_PUP_ID = 0; // NOLINT
133 : /// \endcond
134 : } // namespace FunctionsOfTime
135 : } // namespace domain
|