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 1 : bool must_set_step_size() const override { return false; }
94 :
95 : // NOLINTNEXTLINE(google-runtime-references)
96 0 : void pup(PUP::er& p) override {
97 : StepChooser<StepChooserUse::Slab>::pup(p);
98 : StepChooser<StepChooserUse::LtsStep>::pup(p);
99 : p | safety_factor_;
100 : }
101 :
102 : private:
103 0 : double safety_factor_ = std::numeric_limits<double>::signaling_NaN();
104 : };
105 :
106 : /// \cond
107 : template <size_t Dim, typename System>
108 : PUP::able::PUP_ID ElementSizeCfl<Dim, System>::my_PUP_ID = 0; // NOLINT
109 : /// \endcond
110 : } // namespace StepChoosers
|