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::array<DataVector, 1> func(double t) const override; 54 1 : std::array<DataVector, 2> func_and_deriv(double t) const override; 55 1 : [[noreturn]] std::array<DataVector, 3> func_and_2_derivs( 56 : double /*t*/) const override; 57 : 58 : /*! 59 : * \brief Updates the function to the next global time step. The 60 : * `updated_value_and_derivative` argument needs to be a DataVector of size 2, 61 : * with the zeroth element holding the function's value and the first element 62 : * holding its derivative. If `rotation_` is set to true, this corresponds to 63 : * the angle and the angular velocity for a rotation about the z-axis. 64 : */ 65 1 : void update(double time_of_update, DataVector updated_value_and_derivative, 66 : double next_expiration_time) override; 67 : 68 1 : double expiration_after(double time) const override; 69 : 70 1 : std::array<double, 2> time_bounds() const override; 71 : 72 : // NOLINTNEXTLINE(google-runtime-references) 73 0 : void pup(PUP::er& p) override; 74 : 75 : private: 76 0 : friend bool operator==( // NOLINT(readability-redundant-declaration) 77 : const IntegratedFunctionOfTime& lhs, const IntegratedFunctionOfTime& rhs); 78 : 79 : template <size_t MaxDerivReturned> 80 0 : std::array<DataVector, MaxDerivReturned + 1> func_and_derivs(double t) const; 81 : FunctionOfTimeHelpers::ThreadsafeList<std::array<double, 2>> 82 0 : deriv_info_at_update_times_; 83 0 : std::map<double, std::pair<DataVector, double>> update_backlog_{}; 84 0 : bool rotation_ = false; 85 : }; 86 : 87 0 : bool operator!=(const IntegratedFunctionOfTime& lhs, 88 : const IntegratedFunctionOfTime& rhs); 89 : } // namespace domain::FunctionsOfTime