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 <cmath> 8 : #include <cstddef> 9 : #include <limits> 10 : #include <pup.h> 11 : 12 : #include "DataStructures/DataBox/DataBox.hpp" 13 : #include "Domain/SizeOfElement.hpp" 14 : #include "Options/String.hpp" 15 : #include "Time/StepChoosers/StepChooser.hpp" 16 : #include "Time/TimeStepRequest.hpp" 17 : #include "Time/TimeSteppers/TimeStepper.hpp" 18 : #include "Utilities/Serialization/CharmPupable.hpp" 19 : #include "Utilities/TMPL.hpp" 20 : 21 : /// \cond 22 : namespace Tags { 23 : template <typename StepperInterface> 24 : struct TimeStepper; 25 : } // namespace Tags 26 : namespace domain { 27 : namespace Tags { 28 : template <size_t Dim> 29 : struct SizeOfElement; 30 : } // namespace Tags 31 : } // namespace domain 32 : 33 : /// \endcond 34 : 35 : namespace StepChoosers { 36 : /// Sets a goal based on the CFL stability criterion, but uses the full 37 : /// size of the element as the length scale in question. 38 : /// 39 : /// This is useful as a coarse estimate for slabs, or to place a ceiling on 40 : /// another dynamically-adjusted step chooser. 41 : template <size_t Dim, typename System> 42 1 : class ElementSizeCfl : public StepChooser<StepChooserUse::Slab>, 43 : public StepChooser<StepChooserUse::LtsStep> { 44 : public: 45 : /// \cond 46 : ElementSizeCfl() = default; 47 : explicit ElementSizeCfl(CkMigrateMessage* /*unused*/) {} 48 : using PUP::able::register_constructor; 49 : WRAPPED_PUPable_decl_template(ElementSizeCfl); // NOLINT 50 : /// \endcond 51 : 52 0 : struct SafetyFactor { 53 0 : using type = double; 54 0 : static constexpr Options::String help{"Multiplier for computed step"}; 55 0 : static type lower_bound() { return 0.0; } 56 : }; 57 : 58 0 : static constexpr Options::String help{ 59 : "Sets a goal based on the CFL stability criterion, but in which " 60 : "the entire size of the element is used as the spacing in the " 61 : "computation. This is useful primarily for placing a ceiling on another " 62 : "dynamically-adjusted step chooser"}; 63 0 : using options = tmpl::list<SafetyFactor>; 64 : 65 0 : explicit ElementSizeCfl(const double safety_factor) 66 : : safety_factor_(safety_factor) {} 67 : 68 0 : using argument_tags = 69 : tmpl::list<::Tags::TimeStepper<TimeStepper>, 70 : domain::Tags::SizeOfElement<Dim>, 71 : typename System::compute_largest_characteristic_speed::base>; 72 0 : using compute_tags = 73 : tmpl::list<domain::Tags::SizeOfElementCompute<Dim>, 74 : typename System::compute_largest_characteristic_speed>; 75 : 76 0 : TimeStepRequest operator()(const TimeStepper& time_stepper, 77 : const std::array<double, Dim>& element_size, 78 : const double speed, const double last_step) const { 79 : double min_size_of_element = std::numeric_limits<double>::infinity(); 80 : for (auto face_to_face_dimension : element_size) { 81 : if (face_to_face_dimension < min_size_of_element) { 82 : min_size_of_element = face_to_face_dimension; 83 : } 84 : } 85 : const double time_stepper_stability_factor = time_stepper.stable_step(); 86 : const double step_size = safety_factor_ * time_stepper_stability_factor * 87 : min_size_of_element / (speed * Dim); 88 : return {.size_goal = std::copysign(step_size, last_step)}; 89 : } 90 : 91 1 : bool uses_local_data() const override { return true; } 92 1 : bool can_be_delayed() const override { return true; } 93 : 94 : // NOLINTNEXTLINE(google-runtime-references) 95 0 : void pup(PUP::er& p) override { 96 : StepChooser<StepChooserUse::Slab>::pup(p); 97 : StepChooser<StepChooserUse::LtsStep>::pup(p); 98 : p | safety_factor_; 99 : } 100 : 101 : private: 102 0 : double safety_factor_ = std::numeric_limits<double>::signaling_NaN(); 103 : }; 104 : 105 : /// \cond 106 : template <size_t Dim, typename System> 107 : PUP::able::PUP_ID ElementSizeCfl<Dim, System>::my_PUP_ID = 0; // NOLINT 108 : /// \endcond 109 : } // namespace StepChoosers