Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <memory> 7 : 8 : #include "DataStructures/DataBox/Tag.hpp" 9 : #include "Time/OptionTags/TimeStepper.hpp" 10 : #include "Utilities/Serialization/Serialize.hpp" 11 : #include "Utilities/TMPL.hpp" 12 : 13 : namespace Tags { 14 : /// \ingroup DataBoxTagsGroup 15 : /// \ingroup TimeGroup 16 : /// The evolution TimeStepper. The template parameter should be one 17 : /// of the time stepper base classes, such as `TimeStepper` or 18 : /// `LtsTimeStepper`. 19 : /// 20 : /// For the contained object to be used, the reference tags listed in 21 : /// `time_stepper_ref_tags<StepperType>` will also need to be added to 22 : /// the DataBox. 23 : template <typename StepperType> 24 1 : struct ConcreteTimeStepper : db::SimpleTag { 25 0 : using type = std::unique_ptr<StepperType>; 26 0 : using option_tags = tmpl::list<::OptionTags::TimeStepper<StepperType>>; 27 : 28 0 : static constexpr bool pass_metavariables = false; 29 0 : static std::unique_ptr<StepperType> create_from_options( 30 : const std::unique_ptr<StepperType>& time_stepper) { 31 : return deserialize<type>(serialize<type>(time_stepper).data()); 32 : } 33 : }; 34 : 35 : /// \ingroup DataBoxTagsGroup 36 : /// \ingroup TimeGroup 37 : /// Access to a time stepper through the `StepperInterface` interface 38 : /// (such as `TimeStepper` or `LtsTimeStepper`). 39 : /// 40 : /// \details This tag cannot be added directly to the DataBox of 41 : /// GlobalCache because it contains an abstract type, but can only be 42 : /// used for retrieving the time stepper. Instead, the 43 : /// `ConcreteTimeStepper` tag should be added, along with the 44 : /// reference tags given by `time_stepper_ref_tags`. 45 : template <typename StepperInterface> 46 1 : struct TimeStepper : db::SimpleTag { 47 0 : using type = StepperInterface; 48 : }; 49 : 50 : /// \ingroup DataBoxTagsGroup 51 : /// \ingroup TimeGroup 52 : /// Reference tag to provide access to the time stepper through its 53 : /// provided interfaces, such as `Tags::TimeStepper<TimeStepper>` and 54 : /// `Tags::TimeStepper<LtsTimeStepper>`. Usually added through the 55 : /// `time_stepper_ref_tags` alias. 56 : template <typename StepperInterface, typename StepperType> 57 1 : struct TimeStepperRef : TimeStepper<StepperInterface>, db::ReferenceTag { 58 0 : using base = TimeStepper<StepperInterface>; 59 0 : using argument_tags = tmpl::list<ConcreteTimeStepper<StepperType>>; 60 0 : static const StepperInterface& get(const StepperType& stepper) { 61 : return stepper; 62 : } 63 : }; 64 : } // namespace Tags 65 : 66 : /// \ingroup TimeGroup 67 : /// List of Tags::TimeStepperRef specializations needed when adding a 68 : /// Tags::ConcreteTimeStepper. 69 : template <typename StepperType> 70 1 : using time_stepper_ref_tags = tmpl::transform< 71 : typename StepperType::provided_time_stepper_interfaces, 72 : tmpl::bind<::Tags::TimeStepperRef, tmpl::_1, tmpl::pin<StepperType>>>;