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 :
13 : #include "DataStructures/DataVector.hpp"
14 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
15 : #include "Domain/FunctionsOfTime/ThreadsafeList.hpp"
16 : #include "Utilities/Serialization/CharmPupable.hpp"
17 : #include "Utilities/StdHelpers.hpp"
18 :
19 : namespace domain::FunctionsOfTime {
20 : /*!
21 : * \brief A function that is integrated manually.
22 : * \details This function only works with global time steppers that have
23 : * strictly positively increasing substeps. When evaluated at this global time
24 : * step, it returns the function and first derivative at that time step. It
25 : * therefore needs to be updated every time step with its current values.
26 : */
27 1 : class IntegratedFunctionOfTime : public FunctionOfTime {
28 : public:
29 0 : IntegratedFunctionOfTime();
30 0 : IntegratedFunctionOfTime(IntegratedFunctionOfTime&&);
31 0 : IntegratedFunctionOfTime(const IntegratedFunctionOfTime&);
32 0 : IntegratedFunctionOfTime& operator=(IntegratedFunctionOfTime&&);
33 0 : IntegratedFunctionOfTime& operator=(const IntegratedFunctionOfTime&);
34 0 : ~IntegratedFunctionOfTime() override;
35 : /*!
36 : * \brief Constructs the function using the initial time, initial values,
37 : * derivative and expiration time. If `rotation` is true, the function will be
38 : * converted to a quaternion before it is output as used by the `Rotation`
39 : * map.
40 : */
41 1 : IntegratedFunctionOfTime(double t,
42 : std::array<double, 2> initial_func_and_derivs,
43 : double expiration_time, bool rotation);
44 :
45 : // clang-tidy: google-runtime-references
46 : // clang-tidy: cppcoreguidelines-owning-memory,-warnings-as-errors
47 0 : WRAPPED_PUPable_decl_template(IntegratedFunctionOfTime); // NOLINT
48 :
49 0 : explicit IntegratedFunctionOfTime(CkMigrateMessage* /*unused*/);
50 :
51 0 : auto get_clone() const -> std::unique_ptr<FunctionOfTime> override;
52 :
53 1 : std::unique_ptr<FunctionOfTime> create_at_time(
54 : double t, double expiration_time) const override;
55 :
56 1 : std::array<DataVector, 1> func(double t) const override;
57 1 : std::array<DataVector, 2> func_and_deriv(double t) const override;
58 1 : [[noreturn]] std::array<DataVector, 3> func_and_2_derivs(
59 : double /*t*/) const override;
60 :
61 : /*!
62 : * \brief Updates the function to the next global time step. The
63 : * `updated_value_and_derivative` argument needs to be a DataVector of size 2,
64 : * with the zeroth element holding the function's value and the first element
65 : * holding its derivative. If `rotation_` is set to true, this corresponds to
66 : * the angle and the angular velocity for a rotation about the z-axis.
67 : */
68 1 : void update(double time_of_update, DataVector updated_value_and_derivative,
69 : double next_expiration_time) override;
70 :
71 1 : double expiration_after(double time) const override;
72 :
73 1 : std::array<double, 2> time_bounds() const override;
74 :
75 1 : void truncate_at_time(double time) override;
76 :
77 : // NOLINTNEXTLINE(google-runtime-references)
78 0 : void pup(PUP::er& p) override;
79 :
80 : private:
81 0 : friend bool operator==( // NOLINT(readability-redundant-declaration)
82 : const IntegratedFunctionOfTime& lhs, const IntegratedFunctionOfTime& rhs);
83 :
84 : template <size_t MaxDerivReturned>
85 0 : std::array<DataVector, MaxDerivReturned + 1> func_and_derivs(double t) const;
86 : FunctionOfTimeHelpers::ThreadsafeList<std::array<double, 2>>
87 0 : deriv_info_at_update_times_;
88 0 : std::map<double, std::pair<DataVector, double>> update_backlog_{};
89 0 : bool rotation_ = false;
90 : };
91 :
92 0 : bool operator!=(const IntegratedFunctionOfTime& lhs,
93 : const IntegratedFunctionOfTime& rhs);
94 : } // namespace domain::FunctionsOfTime
|