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 <map> 8 : #include <memory> 9 : #include <optional> 10 : #include <string> 11 : #include <unordered_map> 12 : #include <utility> 13 : 14 : #include "ControlSystem/Averager.hpp" 15 : #include "ControlSystem/CombinedName.hpp" 16 : #include "ControlSystem/Controller.hpp" 17 : #include "ControlSystem/IsSize.hpp" 18 : #include "ControlSystem/Metafunctions.hpp" 19 : #include "ControlSystem/Protocols/ControlSystem.hpp" 20 : #include "ControlSystem/Tags/OptionTags.hpp" 21 : #include "ControlSystem/TimescaleTuner.hpp" 22 : #include "ControlSystem/UpdateFunctionOfTime.hpp" 23 : #include "DataStructures/DataBox/Tag.hpp" 24 : #include "Domain/Creators/DomainCreator.hpp" 25 : #include "ParallelAlgorithms/ApparentHorizonFinder/Tags.hpp" 26 : #include "Time/OptionTags/InitialTime.hpp" 27 : #include "Utilities/ErrorHandling/Error.hpp" 28 : #include "Utilities/Gsl.hpp" 29 : #include "Utilities/ProtocolHelpers.hpp" 30 : #include "Utilities/StdHelpers.hpp" 31 : #include "Utilities/TMPL.hpp" 32 : #include "Utilities/TaggedTuple.hpp" 33 : #include "Utilities/TypeTraits/CreateHasStaticMemberVariable.hpp" 34 : 35 : /// \cond 36 : template <class Metavariables, typename ControlSystem> 37 : struct ControlComponent; 38 : namespace control_system { 39 : template <typename ControlSystem> 40 : struct OptionHolder; 41 : } // namespace control_system 42 : namespace domain::OptionTags { 43 : template <size_t Dim> 44 : struct DomainCreator; 45 : } // namespace domain::OptionTags 46 : namespace OptionTags { 47 : struct InitialTime; 48 : } // namespace OptionTags 49 : /// \endcond 50 : 51 : /// \ingroup ControlSystemGroup 52 : /// All DataBox tags related to the control system 53 : namespace control_system::Tags { 54 : /// \ingroup DataBoxTagsGroup 55 : /// \ingroup ControlSystemGroup 56 : /// DataBox tag for writing control system data to disk 57 1 : struct WriteDataToDisk : db::SimpleTag { 58 0 : using type = bool; 59 0 : using option_tags = tmpl::list<OptionTags::WriteDataToDisk>; 60 : 61 0 : static constexpr bool pass_metavariables = false; 62 0 : static type create_from_options(const type& option) { return option; } 63 : }; 64 : 65 : /// \ingroup DataBoxTagsGroup 66 : /// \ingroup ControlSystemGroup 67 : /// DataBox tag for writing the centers of the horizons to disk. 68 : /// 69 : /// This is controlled by the `control_system::OptionTags::WriteDataToDisk` 70 : /// option in the input file. 71 1 : struct ObserveCenters : ::ah::Tags::ObserveCentersBase, db::SimpleTag { 72 0 : using type = bool; 73 0 : using option_tags = tmpl::list<OptionTags::WriteDataToDisk>; 74 : 75 0 : static constexpr bool pass_metavariables = false; 76 0 : static type create_from_options(const type& option) { return option; } 77 : }; 78 : 79 : /// \ingroup DataBoxTagsGroup 80 : /// \ingroup ControlSystemGroup 81 : /// DataBox tag for the averager 82 : /// 83 : /// To compute the `deriv_order`th derivative of a control error, the max 84 : /// derivative we need from the averager is the `deriv_order - 1`st derivative. 85 : template <typename ControlSystem> 86 1 : struct Averager : db::SimpleTag { 87 0 : using type = ::Averager<ControlSystem::deriv_order - 1>; 88 : 89 0 : using option_tags = 90 : tmpl::list<OptionTags::ControlSystemInputs<ControlSystem>>; 91 0 : static constexpr bool pass_metavariables = false; 92 0 : static type create_from_options( 93 : const control_system::OptionHolder<ControlSystem>& option_holder) { 94 : return option_holder.averager; 95 : } 96 : }; 97 : 98 : namespace detail { 99 : template <bool AllowDecrease, size_t Dim> 100 : void initialize_tuner( 101 : gsl::not_null<::TimescaleTuner<AllowDecrease>*> tuner, 102 : const std::unique_ptr<::DomainCreator<Dim>>& domain_creator, 103 : const double initial_time, const std::string& name); 104 : } // namespace detail 105 : 106 : /// \ingroup DataBoxTagsGroup 107 : /// \ingroup ControlSystemGroup 108 : /// DataBox tag for the timescale tuner 109 : template <typename ControlSystem> 110 1 : struct TimescaleTuner : db::SimpleTag { 111 : private: 112 0 : static constexpr bool is_size = 113 : control_system::size::is_size_v<ControlSystem>; 114 : 115 : public: 116 0 : using type = ::TimescaleTuner<not is_size>; 117 : 118 : template <typename Metavariables> 119 0 : using option_tags = 120 : tmpl::list<OptionTags::ControlSystemInputs<ControlSystem>, 121 : domain::OptionTags::DomainCreator<Metavariables::volume_dim>, 122 : ::OptionTags::InitialTime>; 123 0 : static constexpr bool pass_metavariables = true; 124 : 125 : template <typename Metavariables> 126 0 : static type create_from_options( 127 : const control_system::OptionHolder<ControlSystem>& option_holder, 128 : const std::unique_ptr<::DomainCreator<Metavariables::volume_dim>>& 129 : domain_creator, 130 : const double initial_time) { 131 : auto tuner = option_holder.tuner; 132 : detail::initialize_tuner(make_not_null(&tuner), domain_creator, 133 : initial_time, ControlSystem::name()); 134 : return tuner; 135 : } 136 : }; 137 : 138 : /// \ingroup DataBoxTagsGroup 139 : /// \ingroup ControlSystemGroup 140 : /// DataBox tag for the controller 141 : template <typename ControlSystem> 142 1 : struct Controller : db::SimpleTag { 143 0 : using type = ::Controller<ControlSystem::deriv_order>; 144 : 145 : template <typename Metavariables> 146 0 : using option_tags = 147 : tmpl::list<OptionTags::ControlSystemInputs<ControlSystem>, 148 : domain::OptionTags::DomainCreator<Metavariables::volume_dim>, 149 : ::OptionTags::InitialTime>; 150 0 : static constexpr bool pass_metavariables = true; 151 : 152 : template <typename Metavariables> 153 0 : static type create_from_options( 154 : const control_system::OptionHolder<ControlSystem>& option_holder, 155 : const std::unique_ptr<::DomainCreator<Metavariables::volume_dim>>& 156 : domain_creator, 157 : const double initial_time) { 158 : type controller = option_holder.controller; 159 : auto tuner = option_holder.tuner; 160 : detail::initialize_tuner(make_not_null(&tuner), domain_creator, 161 : initial_time, ControlSystem::name()); 162 : 163 : controller.set_initial_update_time(initial_time); 164 : controller.assign_time_between_updates(min(tuner.current_timescale())); 165 : 166 : return controller; 167 : } 168 : }; 169 : 170 : /// \ingroup DataBoxTagsGroup 171 : /// \ingroup ControlSystemGroup 172 : /// DataBox tag for the control error 173 : template <typename ControlSystem> 174 1 : struct ControlError : db::SimpleTag { 175 0 : using type = typename ControlSystem::control_error; 176 : 177 0 : using option_tags = 178 : tmpl::list<OptionTags::ControlSystemInputs<ControlSystem>>; 179 0 : static constexpr bool pass_metavariables = false; 180 : 181 0 : static type create_from_options( 182 : const control_system::OptionHolder<ControlSystem>& option_holder) { 183 : return option_holder.control_error; 184 : } 185 : }; 186 : 187 : /// \ingroup DataBoxTagsGroup 188 : /// \ingroup ControlSystemGroup 189 : /// Tag that determines how many measurements will occur per control 190 : /// system update. This will usually be stored in the global cache. 191 1 : struct MeasurementsPerUpdate : db::SimpleTag { 192 0 : using type = int; 193 : 194 0 : using option_tags = tmpl::list<OptionTags::MeasurementsPerUpdate>; 195 0 : static constexpr bool pass_metavariables = false; 196 0 : static int create_from_options(const int measurements_per_update) { 197 : return measurements_per_update; 198 : } 199 : }; 200 : 201 : /// \ingroup DataBoxTagsGroup 202 : /// \ingroup ControlSystemGroup 203 : /// DataBox tag that keeps track of which measurement we are on. 204 1 : struct CurrentNumberOfMeasurements : db::SimpleTag { 205 0 : using type = int; 206 : }; 207 : 208 : /// \ingroup DataBoxTagsGroup 209 : /// \ingroup ControlSystemGroup 210 : /// DataBox tag that holds the verbosity used to print info about the control 211 : /// system algorithm. 212 1 : struct Verbosity : db::SimpleTag { 213 0 : using type = ::Verbosity; 214 : 215 0 : using option_tags = tmpl::list<OptionTags::Verbosity>; 216 0 : static constexpr bool pass_metavariables = false; 217 0 : static type create_from_options(const ::Verbosity verbosity) { 218 : return verbosity; 219 : } 220 : }; 221 : 222 : /*! 223 : * \brief Tag meant to be stored in the GlobalCache that stores a map between 224 : * names of control systems and the "combined" name that that control system is 225 : * part of. 226 : * 227 : * \details The "combined" name for each control system is computed using 228 : * `control_system::system_to_combined_names` where the list of control systems 229 : * is taken from the `component_list` type alias of the metavariables. Each 230 : * "combined" name corresponds to a different 231 : * `control_system::protocols::Measurement`. 232 : */ 233 1 : struct SystemToCombinedNames : db::SimpleTag { 234 0 : using type = std::unordered_map<std::string, std::string>; 235 : 236 : template <typename Metavariables> 237 0 : using option_tags = tmpl::list<>; 238 0 : static constexpr bool pass_metavariables = true; 239 : 240 : private: 241 : template <typename Component> 242 0 : using system = typename Component::control_system; 243 : 244 : public: 245 : template <typename Metavariables> 246 0 : static type create_from_options() { 247 : using all_control_components = 248 : metafunctions::all_control_components<Metavariables>; 249 : using all_control_systems = 250 : tmpl::transform<all_control_components, tmpl::bind<system, tmpl::_1>>; 251 : 252 : return system_to_combined_names<all_control_systems>(); 253 : } 254 : }; 255 : 256 : /*! 257 : * \brief Map between "combined" names and the 258 : * `control_system::UpdateAggregator`s that go with each. 259 : */ 260 1 : struct UpdateAggregators : db::SimpleTag { 261 0 : using type = 262 : std::unordered_map<std::string, control_system::UpdateAggregator>; 263 : }; 264 : } // namespace control_system::Tags