Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <memory> 7 : #include <optional> 8 : #include <pup.h> 9 : #include <string> 10 : 11 : #include "Utilities/Gsl.hpp" 12 : #include "Utilities/Serialization/CharmPupable.hpp" 13 : 14 : /// \cond 15 : namespace control_system::size { 16 : struct Info; 17 : struct CrossingTimeInfo; 18 : } // namespace control_system::size 19 : /// \endcond 20 : 21 : namespace control_system::size { 22 : 23 : /*! 24 : * \brief Packages some of the inputs to the State::update, so that 25 : * State::update doesn't need a large number of arguments. 26 : */ 27 1 : struct StateUpdateArgs { 28 : /// min_char_speed is the minimum over the excision boundary 29 : /// of Eq. 89 of \cite Hemberger2012jz. 30 1 : double min_char_speed; 31 : /// min_comoving_char_speed is the minimum over the excision boundary 32 : /// of Eq. 28 of \cite Hemberger2012jz. 33 1 : double min_comoving_char_speed; 34 : /// control_error_delta_r is the control error when the control system 35 : /// is in state Label::DeltaR. 36 : /// This is Q in Eq. 96 of \cite Hemberger2012jz. 37 1 : double control_error_delta_r; 38 : /// average_radial_distance is the average distance between the horizon and 39 : /// the excision boundary. Used only for state DeltaRDriftOutward. 40 : /// If std::nullopt, then DeltaRDriftOutward will not be used. 41 1 : std::optional<double> average_radial_distance; 42 : /// max_allowed_radial_distance is the minimum distance between the horizon 43 : /// and the excision boundary that will trigger state 44 : /// Label::DeltaRDriftOutward. If std::nullopt, then DeltaRDriftOutward 45 : /// will never be triggered. 46 1 : std::optional<double> max_allowed_radial_distance; 47 : }; 48 : 49 : /*! 50 : * \brief Packages some of the inputs to the State::control_error, so that 51 : * State::control_error doesn't need a large number of arguments. 52 : */ 53 1 : struct ControlErrorArgs { 54 0 : double min_char_speed; 55 0 : double control_error_delta_r; 56 : /*! 57 : * \brief control_error_delta_r_outward is the control error in the 58 : * case DeltaRDriftOutward, the state where there is an outward drift 59 : * caused by too large separation between the horizon and the excision 60 : * boundary. If std::nullopt, then state DeltaRDriftOutward will not be used. 61 : */ 62 1 : std::optional<double> control_error_delta_r_outward; 63 : /*! 64 : * \brief avg_distorted_normal_dot_unit_coord_vector is the average of 65 : * distorted_normal_dot_unit_coord_vector over the excision 66 : * boundary. 67 : * 68 : * \details Here distorted_normal_dot_unit_coord_vector is Eq. 93 69 : * of \cite Hemberger2012jz. distorted_normal_dot_unit_coord_vector is 70 : * \f$\hat{n}_i x^i/r\f$ where \f$\nat{n}_i\f$ is the 71 : * distorted-frame unit normal to the excision boundary (pointing 72 : * INTO the hole, i.e. out of the domain), and \f$x^i/r\f$ is the 73 : * distorted-frame (or equivalently the grid frame because it is 74 : * invariant between these two frames because of the required 75 : * limiting behavior of the map we choose) Euclidean normal vector 76 : * from the center of the excision-boundary Strahlkorper to each 77 : * point on the excision-boundary Strahlkorper. 78 : */ 79 1 : double avg_distorted_normal_dot_unit_coord_vector; 80 : /*! 81 : * \brief time_deriv_of_lambda_00 is the time derivative of the quantity 82 : * lambda_00 that appears in \cite Hemberger2012jz. 83 : * 84 : * \details time_deriv_of_lambda_00 is (minus) the radial velocity of the 85 : * excision boundary in the distorted frame with respect to the grid frame. 86 : */ 87 1 : double time_deriv_of_lambda_00; 88 : }; 89 : 90 : /*! 91 : * \brief Represents a 'state' of the size control system. 92 : * 93 : * \details Each 'state' of the size control system has a different control 94 : * signal, which has a different purpose, even though each state 95 : * controls the same map quantity, namely the Y00 coefficient of the 96 : * shape map. For example, state Label::AhSpeed controls 97 : * the Y00 coefficient of the shape map so that the minimum 98 : * characteristic speed is driven towards a target value, and state 99 : * Label::DeltaR controls the Y00 coefficient of the shape 100 : * map (or the Y00 coefficient of a separate spherically-symmetric size 101 : * map) so that the minimum difference between the horizon radius and 102 : * the excision boundary radius is driven towards a constant. 103 : * 104 : * Each state has its own logic (the 'update' function) that 105 : * determines values of certain parameters (i.e. the things in 106 : * Info), including whether the control system should 107 : * transition to a different state. 108 : * 109 : * The different states are: 110 : * - Initial: drives dr/dt of the excision boundary to 111 : * Info::target_drift_velocity. 112 : * - AhSpeed: drives the minimum characteristic speed on the excision boundary 113 : * to Info::target_char_speed. 114 : * - DeltaR: drives the minimum distance between the horizon and the excision 115 : * boundary to be constant in time. 116 : * - DeltaRDriftInward: Same as DeltaR but the excision boundary has a small 117 : * velocity inward. This state is triggered when it is deemed that the 118 : * excision boundary and the horizon are too close to each other; the 119 : * small velocity makes the excision boundary and the horizon drift apart. 120 : * - DeltaRDriftOutward: Same as DeltaR but the excision boundary has a small 121 : * velocity outward. This state is triggered when it is deemed that the 122 : * excision boundary and the horizon are too far apart. 123 : * - DeltaRTransition: Same as DeltaR except for the logic that 124 : * determines how DeltaRTransition changes to other states. 125 : * DeltaRTransition is allowed (under some circumstances) to change 126 : * to state DeltaR, but DeltaRDriftOutward and DeltaRDriftInward 127 : * are never allowed to change to state DeltaR. Instead 128 : * DeltaRDriftOutward and DeltaRDriftInward are allowed (under 129 : * some circumstances) to change to state DeltaRTransition. 130 : * 131 : * The reason that DeltaRDriftInward, DeltaRDriftOutward, and 132 : * DeltaRTransition are separate states is to simplify the logic. In 133 : * principle, all 3 of those states could be merged with state 134 : * DeltaR, because the control error is the same for all four states 135 : * (except for a velocity term that could be set to zero). But if that 136 : * were done, then there would need to be additional complicated 137 : * logic in determining transitions between different states, and 138 : * that logic would depend not only on the current state, but also on 139 : * the previous state. 140 : */ 141 1 : class State : public PUP::able { 142 : public: 143 0 : State() = default; 144 0 : State(const State& /*rhs*/) = default; 145 0 : State& operator=(const State& /*rhs*/) = default; 146 0 : State(State&& /*rhs*/) = default; 147 0 : State& operator=(State&& /*rhs*/) = default; 148 0 : virtual ~State() override = default; 149 : 150 : /// Name of this state 151 1 : virtual std::string name() const = 0; 152 : 153 : /// Return a size_t that corresponds to the state number in SpEC 154 1 : virtual size_t number() const = 0; 155 : 156 0 : virtual std::unique_ptr<State> get_clone() const = 0; 157 : /*! 158 : * \brief Updates the Info in `info`. 159 : * 160 : * \note Notice that `info` includes a state, which might be different than 161 : * the current state upon return. It is the caller's responsibility to check 162 : * if the current state has changed. 163 : * 164 : * \return The return string is used as a helpful diagnostic that may be 165 : * printed to determine what logic decisions the state is making (depends on 166 : * the `control_system::Tags::Verbosity` flag). 167 : */ 168 1 : virtual std::string update( 169 : const gsl::not_null<Info*> info, const StateUpdateArgs& update_args, 170 : const CrossingTimeInfo& crossing_time_info) const = 0; 171 : /// Returns the control signal, but does not modify the state or any 172 : /// parameters. 173 1 : virtual double control_error( 174 : const Info& info, const ControlErrorArgs& control_error_args) const = 0; 175 : 176 0 : WRAPPED_PUPable_abstract(State); // NOLINT 177 0 : explicit State(CkMigrateMessage* msg) : PUP::able(msg) {} 178 : }; 179 : } // namespace control_system::size