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