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 <cstddef> 8 : #include <string> 9 : 10 : #include "ControlSystem/Component.hpp" 11 : #include "ControlSystem/ControlErrors/Translation.hpp" 12 : #include "ControlSystem/DataVectorHelpers.hpp" 13 : #include "ControlSystem/Measurements/BNSCenterOfMass.hpp" 14 : #include "ControlSystem/Measurements/BothHorizons.hpp" 15 : #include "ControlSystem/Protocols/ControlError.hpp" 16 : #include "ControlSystem/Protocols/ControlSystem.hpp" 17 : #include "ControlSystem/Protocols/Measurement.hpp" 18 : #include "ControlSystem/Tags/QueueTags.hpp" 19 : #include "ControlSystem/Tags/SystemTags.hpp" 20 : #include "ControlSystem/UpdateControlSystem.hpp" 21 : #include "DataStructures/DataBox/DataBox.hpp" 22 : #include "DataStructures/DataBox/Tag.hpp" 23 : #include "DataStructures/LinkedMessageQueue.hpp" 24 : #include "Domain/Structure/ObjectLabel.hpp" 25 : #include "Parallel/GlobalCache.hpp" 26 : #include "ParallelAlgorithms/Actions/UpdateMessageQueue.hpp" 27 : #include "PointwiseFunctions/GeneralRelativity/Surfaces/Tags.hpp" 28 : #include "Utilities/PrettyType.hpp" 29 : #include "Utilities/ProtocolHelpers.hpp" 30 : #include "Utilities/TMPL.hpp" 31 : 32 : /// \cond 33 : namespace Frame { 34 : struct Distorted; 35 : } // namespace Frame 36 : /// \endcond 37 : 38 : namespace control_system::Systems { 39 : /*! 40 : * \brief Controls the 3D \link 41 : * domain::CoordinateMaps::TimeDependent::Translation Translation \endlink map 42 : * 43 : * \details Controls the function \f$ \vec{T}(t) \f$ in the \link 44 : * domain::CoordinateMaps::TimeDependent::Translation Translation \endlink map. 45 : * 46 : * Requirements: 47 : * - This control system requires that there be exactly two objects in the 48 : * simulation 49 : * - Currently both these objects must be black holes 50 : * - Currently this control system can only be used with the \link 51 : * control_system::measurements::BothHorizons BothHorizons \endlink 52 : * measurement 53 : * - Currently this control system can only be used with the \link 54 : * control_system::ControlErrors::Translation Translation \endlink control 55 : * error 56 : */ 57 : template <size_t DerivOrder, typename Measurement> 58 1 : struct Translation : tt::ConformsTo<protocols::ControlSystem> { 59 0 : static constexpr size_t deriv_order = DerivOrder; 60 : 61 0 : static std::string name() { 62 : return pretty_type::short_name<Translation<DerivOrder, Measurement>>(); 63 : } 64 : 65 0 : static std::optional<std::string> component_name( 66 : const size_t component, const size_t num_components) { 67 : ASSERT(num_components == 3, 68 : "Translation control expects 3 components but there are " 69 : << num_components << " instead."); 70 : return component == 0 ? "x" : component == 1 ? "y" : "z"; 71 : } 72 : 73 0 : using measurement = Measurement; 74 : static_assert( 75 : tt::conforms_to_v<measurement, control_system::protocols::Measurement>); 76 : 77 0 : using control_error = ControlErrors::Translation; 78 : static_assert(tt::conforms_to_v<control_error, 79 : control_system::protocols::ControlError>); 80 : 81 : // tag goes in control component 82 0 : struct MeasurementQueue : db::SimpleTag { 83 0 : using type = LinkedMessageQueue< 84 : double, tmpl::list<QueueTags::Center<::domain::ObjectLabel::A>, 85 : QueueTags::Center<::domain::ObjectLabel::B>>>; 86 : }; 87 : 88 0 : using simple_tags = tmpl::list<MeasurementQueue>; 89 : 90 0 : struct process_measurement { 91 : template <typename Submeasurement> 92 0 : using argument_tags = tmpl::conditional_t< 93 : std::is_same_v<Submeasurement, 94 : measurements::BothNSCenters::FindTwoCenters>, 95 : tmpl::list< 96 : measurements::Tags::NeutronStarCenter<::domain::ObjectLabel::A>, 97 : measurements::Tags::NeutronStarCenter<::domain::ObjectLabel::B>>, 98 : tmpl::list<ylm::Tags::Strahlkorper<Frame::Distorted>>>; 99 : 100 : template <::domain::ObjectLabel Horizon, typename Metavariables> 101 0 : static void apply( 102 : measurements::BothHorizons::FindHorizon<Horizon> submeasurement, 103 : const ylm::Strahlkorper<Frame::Distorted>& strahlkorper, 104 : Parallel::GlobalCache<Metavariables>& cache, 105 : const LinkedMessageId<double>& measurement_id) { 106 : auto& control_sys_proxy = 107 : Parallel::get_parallel_component<ControlComponent< 108 : Metavariables, Translation<DerivOrder, Measurement>>>(cache); 109 : 110 : const DataVector center = 111 : array_to_datavector(strahlkorper.physical_center()); 112 : 113 : Parallel::simple_action<::Actions::UpdateMessageQueue< 114 : QueueTags::Center<Horizon>, MeasurementQueue, 115 : UpdateControlSystem<Translation>>>(control_sys_proxy, measurement_id, 116 : center); 117 : 118 : if (Parallel::get<Tags::Verbosity>(cache) >= ::Verbosity::Verbose) { 119 : Parallel::printf("%s, time = %.16f: Received measurement '%s'.\n", 120 : name(), measurement_id.id, 121 : pretty_type::name(submeasurement)); 122 : } 123 : } 124 : 125 : template <typename Metavariables> 126 0 : static void apply( 127 : measurements::BothNSCenters::FindTwoCenters submeasurement, 128 : const std::array<double, 3> center_a, 129 : const std::array<double, 3> center_b, 130 : Parallel::GlobalCache<Metavariables>& cache, 131 : const LinkedMessageId<double>& measurement_id) { 132 : auto& control_sys_proxy = 133 : Parallel::get_parallel_component<ControlComponent< 134 : Metavariables, Translation<DerivOrder, Measurement>>>(cache); 135 : 136 : const DataVector center_a_dv = array_to_datavector(center_a); 137 : Parallel::simple_action<::Actions::UpdateMessageQueue< 138 : QueueTags::Center<::domain::ObjectLabel::A>, MeasurementQueue, 139 : UpdateControlSystem<Translation>>>(control_sys_proxy, measurement_id, 140 : center_a_dv); 141 : const DataVector center_b_dv = array_to_datavector(center_b); 142 : Parallel::simple_action<::Actions::UpdateMessageQueue< 143 : QueueTags::Center<::domain::ObjectLabel::B>, MeasurementQueue, 144 : UpdateControlSystem<Translation>>>(control_sys_proxy, measurement_id, 145 : center_b_dv); 146 : 147 : if (Parallel::get<Tags::Verbosity>(cache) >= ::Verbosity::Verbose) { 148 : Parallel::printf("%s, time = %.16f: Received measurement '%s'.\n", 149 : name(), measurement_id.id, 150 : pretty_type::name(submeasurement)); 151 : } 152 : } 153 : }; 154 : }; 155 : } // namespace control_system::Systems