Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <pup.h> 7 : 8 : #include "DataStructures/DataBox/DataBox.hpp" 9 : #include "Parallel/Tags/Metavariables.hpp" 10 : #include "Utilities/CallWithDynamicType.hpp" 11 : #include "Utilities/ErrorHandling/Assert.hpp" 12 : #include "Utilities/Serialization/CharmPupable.hpp" 13 : #include "Utilities/TMPL.hpp" 14 : #include "Utilities/TypeTraits/CreateGetTypeAliasOrDefault.hpp" 15 : 16 : /// The intended use for a step chooser. This is used to control the 17 : /// classes via factories. 18 1 : namespace StepChooserUse { 19 : struct Slab; 20 : struct LtsStep; 21 : } // namespace StepChooserUse 22 : 23 : /// \cond 24 : template <typename StepChooserUse> 25 : class StepChooser; 26 : /// \endcond 27 : 28 : /// \ingroup TimeGroup 29 : /// 30 : /// Holds all the StepChoosers 31 : namespace StepChoosers { 32 : 33 : namespace detail { 34 : CREATE_GET_TYPE_ALIAS_OR_DEFAULT(compute_tags) 35 : CREATE_GET_TYPE_ALIAS_OR_DEFAULT(simple_tags) 36 : 37 : template <typename Metavariables, bool UsingLts> 38 : using all_step_choosers = tmpl::join<tmpl::remove< 39 : tmpl::list< 40 : tmpl::at<typename Metavariables::factory_creation::factory_classes, 41 : StepChooser<StepChooserUse::Slab>>, 42 : tmpl::conditional_t< 43 : UsingLts, 44 : tmpl::at<typename Metavariables::factory_creation::factory_classes, 45 : StepChooser<StepChooserUse::LtsStep>>, 46 : tmpl::no_such_type_>>, 47 : tmpl::no_such_type_>>; 48 : } // namespace detail 49 : 50 : template <typename Metavariables, bool UsingLts> 51 0 : using step_chooser_compute_tags = tmpl::remove_duplicates<tmpl::join< 52 : tmpl::transform<detail::all_step_choosers<Metavariables, UsingLts>, 53 : detail::get_compute_tags_or_default< 54 : tmpl::_1, tmpl::pin<tmpl::list<>>>>>>; 55 : 56 : template <typename Metavariables, bool UsingLts> 57 0 : using step_chooser_simple_tags = tmpl::remove_duplicates<tmpl::join< 58 : tmpl::transform<detail::all_step_choosers<Metavariables, UsingLts>, 59 : detail::get_simple_tags_or_default< 60 : tmpl::_1, tmpl::pin<tmpl::list<>>>>>>; 61 : } // namespace StepChoosers 62 : 63 : /// A placeholder type to indicate that all constructible step choosers should 64 : /// be used in step chooser utilities that permit a list of choosers to be 65 : /// specified. 66 1 : struct AllStepChoosers {}; 67 : 68 : /// \ingroup TimeGroup 69 : /// 70 : /// \brief StepChoosers suggest upper bounds on step sizes. 71 : /// 72 : /// Concrete StepChoosers should define `operator()` returning the 73 : /// information described as the return type of `desired_step` and 74 : /// taking the `last_step_magnitude` and arguments specified by the 75 : /// class's `argument_tags` type alias. 76 : /// 77 : /// Derived classes must indicate whether the chooser is usable as a 78 : /// step chooser, slab chooser, or both by inheriting from StepChooser 79 : /// with the appropriate `StepChooserUse` template argument. A class 80 : /// cannot inherit from both base classes simultaneously; if both uses 81 : /// are supported the use must be chosen using a template parameter. 82 : template <typename StepChooserUse> 83 1 : class StepChooser : public PUP::able { 84 : protected: 85 : /// \cond HIDDEN_SYMBOLS 86 : StepChooser() = default; 87 : StepChooser(const StepChooser&) = default; 88 : StepChooser(StepChooser&&) = default; 89 : StepChooser& operator=(const StepChooser&) = default; 90 : StepChooser& operator=(StepChooser&&) = default; 91 : /// \endcond 92 : 93 : public: 94 0 : ~StepChooser() override = default; 95 : 96 0 : WRAPPED_PUPable_abstract(StepChooser); // NOLINT 97 : 98 : /// Whether the result can differ on different elements, so 99 : /// requiring communication to synchronize the result across the 100 : /// domain. This is ignored for LTS step changing. 101 : /// 102 : /// \note As this is only used for slab-size changing, the 103 : /// `last_step_magnitude` passed to the call operator is *not* 104 : /// considered local data. 105 1 : virtual bool uses_local_data() const = 0; 106 : 107 : /// The `last_step_magnitude` parameter describes the step size to be 108 : /// adjusted. It may be the step size or the slab size, or may be 109 : /// infinite if the appropriate size cannot be determined. 110 : /// 111 : /// The return value of this function contains the desired step size 112 : /// and a `bool` indicating whether the step should be accepted. 113 : /// When adjusting LTS step sizes, if the `bool` is `false`, the 114 : /// current time step will be recomputed with a step size informed 115 : /// by the desired step value returned by this function. We do not 116 : /// have the capability to reject a slab, so the `bool` is ignored 117 : /// for slab adjustment. 118 : /// 119 : /// The implementations of the call operator in derived classes 120 : /// should always return a strictly smaller step than the 121 : /// `last_step_magnitude` when they return `false` for the second 122 : /// member of the pair (indicating step rejection). 123 : /// 124 : /// The optional template parameter `StepChoosersToUse` may be used to 125 : /// indicate a subset of the constructable step choosers to use for the 126 : /// current application of `ChangeStepSize`. Passing `AllStepChoosers` 127 : /// (default) indicates that any constructible step chooser may be used. This 128 : /// option is used when multiple components need to invoke `ChangeStepSize` 129 : /// with step choosers that may not be compatible with all components. 130 : template <typename StepChoosersToUse = AllStepChoosers, typename DbTags> 131 1 : std::pair<double, bool> desired_step(const double last_step_magnitude, 132 : const db::DataBox<DbTags>& box) const { 133 : ASSERT(last_step_magnitude > 0., 134 : "Passed non-positive step magnitude: " << last_step_magnitude); 135 : using factory_classes = 136 : typename std::decay_t<decltype(db::get<Parallel::Tags::Metavariables>( 137 : box))>::factory_creation::factory_classes; 138 : using step_choosers = 139 : tmpl::conditional_t<std::is_same_v<StepChoosersToUse, AllStepChoosers>, 140 : tmpl::at<factory_classes, StepChooser>, 141 : StepChoosersToUse>; 142 : const auto result = 143 : call_with_dynamic_type<std::pair<double, bool>, step_choosers>( 144 : this, [&last_step_magnitude, &box](const auto* const chooser) { 145 : return db::apply(*chooser, box, last_step_magnitude); 146 : }); 147 : ASSERT( 148 : result.first > 0., 149 : "StepChoosers should always return positive values. Got " << result); 150 : return result; 151 : } 152 : };