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/Measurements/BNSCenterOfMass.hpp"
13 : #include "ControlSystem/Measurements/BothHorizons.hpp"
14 : #include "ControlSystem/Measurements/SingleHorizon.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 "Parallel/Printf/Printf.hpp"
27 : #include "ParallelAlgorithms/Actions/UpdateMessageQueue.hpp"
28 : #include "PointwiseFunctions/GeneralRelativity/Surfaces/Tags.hpp"
29 : #include "Utilities/PrettyType.hpp"
30 : #include "Utilities/ProtocolHelpers.hpp"
31 : #include "Utilities/TMPL.hpp"
32 :
33 : /// \cond
34 : namespace Frame {
35 : struct Grid;
36 : struct Inertial;
37 : struct Distorted;
38 : } // namespace Frame
39 : /// \endcond
40 :
41 : namespace control_system::Systems {
42 : /*!
43 : * \brief Controls the 3D \link
44 : * domain::CoordinateMaps::TimeDependent::Translation Translation \endlink map
45 : *
46 : * \details Controls the function \f$ \vec{T}(t) \f$ in the \link
47 : * domain::CoordinateMaps::TimeDependent::Translation Translation \endlink map.
48 : *
49 : * Requirements:
50 : * - This control system requires that there be either one or two objects in the
51 : * simulation
52 : * - This control system can only be used with the \link
53 : * control_system::measurements::BothHorizons BothHorizons \endlink
54 : * measurement, the \link
55 : * control_system::measurements::SingleHorizon<::domain::ObjectLabel::None>
56 : * \endlink measurement, or the \link
57 : * measurements::BothNSCenters::FindTwoCenters \endlink measurement.
58 : * - Currently this control system can only be used with the \link
59 : * control_system::ControlErrors::Translation Translation \endlink control
60 : * error
61 : */
62 : template <size_t DerivOrder, typename Measurement, size_t NumberOfObjects>
63 1 : struct Translation : tt::ConformsTo<protocols::ControlSystem> {
64 : public:
65 0 : static constexpr size_t deriv_order = DerivOrder;
66 :
67 0 : static std::string name() { return pretty_type::short_name<Translation>(); }
68 :
69 0 : static std::optional<std::string> component_name(
70 : const size_t component, const size_t num_components) {
71 : ASSERT(num_components == 3,
72 : "Translation control expects 3 components but there are "
73 : << num_components << " instead.");
74 : return component == 0 ? "x" : component == 1 ? "y" : "z";
75 : }
76 :
77 0 : using measurement = Measurement;
78 : static_assert(
79 : tt::conforms_to_v<measurement, control_system::protocols::Measurement>);
80 :
81 : // For BNS we only control the Translation using the CoM, not the individual
82 : // objects like for BBH.
83 0 : using control_error = ControlErrors::Translation<
84 : std::is_same_v<measurement, measurements::BothNSCenters>
85 : ? 1
86 : : NumberOfObjects>;
87 : static_assert(tt::conforms_to_v<control_error,
88 : control_system::protocols::ControlError>);
89 :
90 : // tag goes in control component
91 0 : struct MeasurementQueue : db::SimpleTag {
92 0 : using type = LinkedMessageQueue<
93 : double,
94 : tmpl::conditional_t<
95 : NumberOfObjects == 1,
96 : tmpl::list<QueueTags::Center<::domain::ObjectLabel::None>>,
97 : tmpl::append<
98 : tmpl::list<
99 : QueueTags::Center<::domain::ObjectLabel::A, Frame::Grid>,
100 : QueueTags::Center<::domain::ObjectLabel::B, Frame::Grid>>,
101 : tmpl::conditional_t<
102 : std::is_same_v<measurement, measurements::BothNSCenters>,
103 : tmpl::list<QueueTags::Center<::domain::ObjectLabel::A,
104 : Frame::Inertial>,
105 : QueueTags::Center<::domain::ObjectLabel::B,
106 : Frame::Inertial>,
107 : QueueTags::Center<::domain::ObjectLabel::None,
108 : Frame::Grid>,
109 : QueueTags::Center<::domain::ObjectLabel::None,
110 : Frame::Inertial>>,
111 : tmpl::list<>>>>>;
112 : };
113 :
114 0 : using simple_tags = tmpl::list<MeasurementQueue>;
115 :
116 0 : struct process_measurement {
117 : template <typename Submeasurement>
118 0 : using argument_tags = tmpl::conditional_t<
119 : std::is_same_v<Submeasurement,
120 : measurements::BothNSCenters::FindTwoCenters>,
121 : tmpl::list<measurements::Tags::NeutronStarCenter<
122 : ::domain::ObjectLabel::A, Frame::Grid>,
123 : measurements::Tags::NeutronStarCenter<
124 : ::domain::ObjectLabel::B, Frame::Grid>,
125 : measurements::Tags::NeutronStarCenter<
126 : ::domain::ObjectLabel::A, Frame::Inertial>,
127 : measurements::Tags::NeutronStarCenter<
128 : ::domain::ObjectLabel::B, Frame::Inertial>,
129 : measurements::Tags::SystemCenterOfMass<Frame::Grid>,
130 : measurements::Tags::SystemCenterOfMass<Frame::Inertial>>,
131 : tmpl::list<ylm::Tags::Strahlkorper<Frame::Distorted>>>;
132 :
133 : template <typename Metavariables>
134 0 : static void apply(
135 : measurements::SingleHorizon<::domain::ObjectLabel::None>::Submeasurement
136 : submeasurement,
137 : const ylm::Strahlkorper<Frame::Distorted>& strahlkorper,
138 : Parallel::GlobalCache<Metavariables>& cache,
139 : const LinkedMessageId<double>& measurement_id) {
140 : auto& control_sys_proxy = Parallel::get_parallel_component<
141 : ControlComponent<Metavariables, Translation>>(cache);
142 :
143 : Parallel::simple_action<::Actions::UpdateMessageQueue<
144 : MeasurementQueue, UpdateControlSystem<Translation>,
145 : QueueTags::Center<::domain::ObjectLabel::None>>>(
146 : control_sys_proxy, measurement_id,
147 : DataVector{strahlkorper.physical_center()});
148 :
149 : if (Parallel::get<Tags::Verbosity>(cache) >= ::Verbosity::Verbose) {
150 : Parallel::printf("%s, time = %.16f: Received measurement '%s'.\n",
151 : name(), measurement_id.id,
152 : pretty_type::name(submeasurement));
153 : }
154 : }
155 :
156 : template <::domain::ObjectLabel Horizon, typename Metavariables>
157 0 : static void apply(
158 : measurements::BothHorizons::FindHorizon<Horizon> submeasurement,
159 : const ylm::Strahlkorper<Frame::Distorted>& strahlkorper,
160 : Parallel::GlobalCache<Metavariables>& cache,
161 : const LinkedMessageId<double>& measurement_id) {
162 : auto& control_sys_proxy = Parallel::get_parallel_component<
163 : ControlComponent<Metavariables, Translation>>(cache);
164 :
165 : DataVector center(strahlkorper.physical_center());
166 :
167 : Parallel::simple_action<::Actions::UpdateMessageQueue<
168 : MeasurementQueue, UpdateControlSystem<Translation>,
169 : QueueTags::Center<Horizon>>>(control_sys_proxy, measurement_id,
170 : std::move(center));
171 :
172 : if (Parallel::get<Tags::Verbosity>(cache) >= ::Verbosity::Verbose) {
173 : Parallel::printf("%s, time = %.16f: Received measurement '%s'.\n",
174 : name(), measurement_id.id,
175 : pretty_type::name(submeasurement));
176 : }
177 : }
178 :
179 : template <typename Metavariables>
180 0 : static void apply(
181 : measurements::BothNSCenters::FindTwoCenters submeasurement,
182 : const std::array<double, 3> grid_center_a,
183 : const std::array<double, 3> grid_center_b,
184 : const std::array<double, 3> inertial_center_a,
185 : const std::array<double, 3> inertial_center_b,
186 : const std::array<double, 3> grid_system_center_of_mass,
187 : const std::array<double, 3> inertial_system_center_of_mass,
188 : Parallel::GlobalCache<Metavariables>& cache,
189 : const LinkedMessageId<double>& measurement_id) {
190 : auto& control_sys_proxy = Parallel::get_parallel_component<
191 : ControlComponent<Metavariables, Translation>>(cache);
192 :
193 : Parallel::simple_action<::Actions::UpdateMessageQueue<
194 : MeasurementQueue, UpdateControlSystem<Translation>,
195 : QueueTags::Center<::domain::ObjectLabel::A, Frame::Grid>,
196 : QueueTags::Center<::domain::ObjectLabel::B, Frame::Grid>,
197 : QueueTags::Center<::domain::ObjectLabel::A, Frame::Inertial>,
198 : QueueTags::Center<::domain::ObjectLabel::B, Frame::Inertial>,
199 : // Use None to mark "one object" since we want translation to track
200 : // the system CoM.
201 : QueueTags::Center<::domain::ObjectLabel::None, Frame::Grid>,
202 : QueueTags::Center<::domain::ObjectLabel::None, Frame::Inertial>>>(
203 : control_sys_proxy, measurement_id, DataVector(grid_center_a),
204 : DataVector(grid_center_b), DataVector(inertial_center_a),
205 : DataVector(inertial_center_b), DataVector(grid_system_center_of_mass),
206 : DataVector(inertial_system_center_of_mass));
207 :
208 : if (Parallel::get<Tags::Verbosity>(cache) >= ::Verbosity::Verbose) {
209 : Parallel::printf("%s, time = %.16f: Received measurement '%s'.\n",
210 : name(), measurement_id.id,
211 : pretty_type::name(submeasurement));
212 : }
213 : }
214 : };
215 : };
216 : } // namespace control_system::Systems
|