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 : // NOLINTNEXTLINE(google-runtime-references) 76 0 : void pup(PUP::er& p) override; 77 : 78 : private: 79 0 : friend bool operator==( // NOLINT(readability-redundant-declaration) 80 : const IntegratedFunctionOfTime& lhs, const IntegratedFunctionOfTime& rhs); 81 : 82 : template <size_t MaxDerivReturned> 83 0 : std::array<DataVector, MaxDerivReturned + 1> func_and_derivs(double t) const; 84 : FunctionOfTimeHelpers::ThreadsafeList<std::array<double, 2>> 85 0 : deriv_info_at_update_times_; 86 0 : std::map<double, std::pair<DataVector, double>> update_backlog_{}; 87 0 : bool rotation_ = false; 88 : }; 89 : 90 0 : bool operator!=(const IntegratedFunctionOfTime& lhs, 91 : const IntegratedFunctionOfTime& rhs); 92 : } // namespace domain::FunctionsOfTime