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