Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <algorithm> 7 : #include <memory> 8 : #include <optional> 9 : #include <vector> 10 : 11 : #include "DataStructures/DataBox/DataBox.hpp" 12 : #include "Options/String.hpp" 13 : #include "Time/EvolutionOrdering.hpp" 14 : #include "Time/StepChoosers/StepChooser.hpp" 15 : #include "Time/TimeStepRequest.hpp" 16 : #include "Utilities/ErrorHandling/Assert.hpp" 17 : #include "Utilities/Serialization/CharmPupable.hpp" 18 : #include "Utilities/TMPL.hpp" 19 : 20 : /// \cond 21 : namespace PUP { 22 : class er; 23 : } // namespace PUP 24 : namespace Tags { 25 : struct FixedLtsRatio; 26 : struct TimeStep; 27 : } // namespace Tags 28 : /// \endcond 29 : 30 : namespace StepChoosers { 31 : /// Requests a slab size based on the desired step in regions with a 32 : /// fixed slab fraction. 33 : /// 34 : /// \note This StepChooser is not included in the 35 : /// `standard_step_choosers` list. Executables using the feature must 36 : /// include it explicitly in the `factory_creation` struct and add the 37 : /// `::Tags::FixedLtsRatio` tag to the element DataBox. 38 1 : class FixedLtsRatio : public StepChooser<StepChooserUse::Slab> { 39 : public: 40 : /// \cond 41 : FixedLtsRatio() = default; 42 : explicit FixedLtsRatio(CkMigrateMessage* /*unused*/) {} 43 : using PUP::able::register_constructor; 44 : WRAPPED_PUPable_decl_template(FixedLtsRatio); // NOLINT 45 : /// \endcond 46 : 47 0 : struct StepChoosers { 48 0 : using type = 49 : std::vector<std::unique_ptr<::StepChooser<StepChooserUse::LtsStep>>>; 50 0 : static constexpr Options::String help{"LTS step choosers to test"}; 51 : }; 52 : 53 0 : static constexpr Options::String help{ 54 : "Requests a slab size based on the desired step in regions with a fixed " 55 : "slab fraction."}; 56 0 : using options = tmpl::list<StepChoosers>; 57 : 58 0 : explicit FixedLtsRatio( 59 : std::vector<std::unique_ptr<::StepChooser<StepChooserUse::LtsStep>>> 60 : step_choosers); 61 : 62 0 : using argument_tags = tmpl::list<::Tags::DataBox>; 63 : 64 : template <typename DbTags> 65 0 : TimeStepRequest operator()(const db::DataBox<DbTags>& box, 66 : const double /*last_step*/) const { 67 : const auto& step_ratio = db::get<::Tags::FixedLtsRatio>(box); 68 : if (not step_ratio.has_value()) { 69 : return {}; 70 : } 71 : 72 : const auto& current_step = db::get<::Tags::TimeStep>(box); 73 : const evolution_less<double> less{current_step.is_positive()}; 74 : 75 : std::optional<double> size_goal{}; 76 : std::optional<double> size{}; 77 : for (const auto& step_chooser : step_choosers_) { 78 : const auto step_request = 79 : step_chooser->desired_step(current_step.value(), box); 80 : 81 : if (step_request.size_goal.has_value()) { 82 : if (size_goal.has_value()) { 83 : *size_goal = std::min(*size_goal, *step_request.size_goal, less); 84 : } else { 85 : size_goal = step_request.size_goal; 86 : } 87 : } 88 : if (step_request.size.has_value()) { 89 : if (size.has_value()) { 90 : *size = std::min(*size, *step_request.size, less); 91 : } else { 92 : size = step_request.size; 93 : } 94 : } 95 : 96 : // As of writing (Oct. 2024), no StepChooserUse::LtsStep chooser 97 : // sets these. 98 : ASSERT(not(step_request.end.has_value() or 99 : step_request.size_hard_limit.has_value() or 100 : step_request.end_hard_limit.has_value()), 101 : "Unhandled field set by StepChooser. Please file a bug " 102 : "containing the options passed to FixedLtsRatio."); 103 : } 104 : 105 : if (size_goal.has_value()) { 106 : *size_goal *= *step_ratio; 107 : } 108 : if (size.has_value()) { 109 : *size *= *step_ratio; 110 : if (size_goal.has_value() and less(*size_goal, *size)) { 111 : // Not allowed to request a goal and a bigger step. 112 : size.reset(); 113 : } 114 : } 115 : 116 : return {.size_goal = size_goal, .size = size}; 117 : } 118 : 119 1 : bool uses_local_data() const override; 120 1 : bool can_be_delayed() const override; 121 : 122 : template <typename F> 123 0 : void for_each_step_chooser(F&& f) const { 124 : for (const auto& step_chooser : step_choosers_) { 125 : f(*step_chooser); 126 : } 127 : } 128 : 129 0 : void pup(PUP::er& p) override; 130 : 131 : private: 132 : std::vector<std::unique_ptr<::StepChooser<StepChooserUse::LtsStep>>> 133 0 : step_choosers_; 134 : }; 135 : } // namespace StepChoosers