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/GridCenters.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/LinkedMessageId.hpp"
25 : #include "DataStructures/LinkedMessageQueue.hpp"
26 : #include "Domain/Structure/ObjectLabel.hpp"
27 : #include "Parallel/GlobalCache.hpp"
28 : #include "Parallel/Printf/Printf.hpp"
29 : #include "ParallelAlgorithms/Actions/UpdateMessageQueue.hpp"
30 : #include "PointwiseFunctions/GeneralRelativity/Surfaces/Tags.hpp"
31 : #include "Utilities/ErrorHandling/Assert.hpp"
32 : #include "Utilities/PrettyType.hpp"
33 : #include "Utilities/ProtocolHelpers.hpp"
34 : #include "Utilities/TMPL.hpp"
35 :
36 : /// \cond
37 : namespace Frame {
38 : struct Distorted;
39 : } // namespace Frame
40 : /// \endcond
41 :
42 : namespace control_system::Systems {
43 : /*!
44 : * \brief Tracks the centers of two neutron stars.
45 : *
46 : * Controls the function of time with the same name which can be used to
47 : * determine (until merger) the centers of the two stars.
48 : *
49 : * Requirements:
50 : * - This control system requires that there be two objects in the simulation
51 : * - Can only be used with the control_system::ControlErrors::GridCenters
52 : * control error.
53 : */
54 : template <size_t DerivOrder, typename Measurement>
55 1 : struct GridCenters : tt::ConformsTo<protocols::ControlSystem> {
56 0 : static constexpr size_t deriv_order = DerivOrder;
57 :
58 0 : static std::string name() { return "GridCenters"; }
59 :
60 0 : static std::optional<std::string> component_name(
61 : const size_t component, const size_t num_components) {
62 : ASSERT(num_components == 6,
63 : "GridCenters control expects 6 components but there are "
64 : << num_components << " instead.");
65 :
66 : const bool a_or_b = component < 3;
67 : const size_t index = component % 3;
68 : const std::string component_name =
69 : (a_or_b ? "A" : "B") +
70 : (index == 0 ? "_x"s : (index == 1 ? "_y" : "_z"));
71 :
72 : return {component_name};
73 : }
74 :
75 0 : using measurement = Measurement;
76 : static_assert(
77 : tt::conforms_to_v<measurement, control_system::protocols::Measurement>);
78 : static_assert(
79 : std::is_same_v<measurement, measurements::BothNSCenters>,
80 : "GridCenters only accepts BothNSCenters measurement currently.");
81 :
82 0 : using control_error = ControlErrors::GridCenters;
83 : static_assert(tt::conforms_to_v<control_error,
84 : control_system::protocols::ControlError>);
85 :
86 : // tag goes in control component
87 0 : struct MeasurementQueue : db::SimpleTag {
88 0 : using type = LinkedMessageQueue<
89 : double,
90 : tmpl::list<
91 : QueueTags::Center<::domain::ObjectLabel::A, Frame::Grid>,
92 : QueueTags::Center<::domain::ObjectLabel::B, Frame::Grid>,
93 : QueueTags::Center<::domain::ObjectLabel::A, Frame::Inertial>,
94 : QueueTags::Center<::domain::ObjectLabel::B, Frame::Inertial>>>;
95 : };
96 :
97 0 : using simple_tags = tmpl::list<MeasurementQueue>;
98 :
99 0 : struct process_measurement {
100 : template <typename Submeasurement>
101 0 : using argument_tags = tmpl::list<
102 : measurements::Tags::NeutronStarCenter<::domain::ObjectLabel::A,
103 : Frame::Grid>,
104 : measurements::Tags::NeutronStarCenter<::domain::ObjectLabel::B,
105 : Frame::Grid>,
106 : measurements::Tags::NeutronStarCenter<::domain::ObjectLabel::A,
107 : Frame::Inertial>,
108 : measurements::Tags::NeutronStarCenter<::domain::ObjectLabel::B,
109 : Frame::Inertial>>;
110 :
111 : template <typename Metavariables>
112 0 : static void apply(
113 : measurements::BothNSCenters::FindTwoCenters submeasurement,
114 : const std::array<double, 3> grid_center_a,
115 : const std::array<double, 3> grid_center_b,
116 : const std::array<double, 3> inertial_center_a,
117 : const std::array<double, 3> inertial_center_b,
118 : Parallel::GlobalCache<Metavariables>& cache,
119 : const LinkedMessageId<double>& measurement_id) {
120 : auto& control_sys_proxy = Parallel::get_parallel_component<
121 : ControlComponent<Metavariables, GridCenters>>(cache);
122 :
123 : Parallel::simple_action<::Actions::UpdateMessageQueue<
124 : MeasurementQueue, UpdateControlSystem<GridCenters>,
125 : QueueTags::Center<::domain::ObjectLabel::A, Frame::Grid>,
126 : QueueTags::Center<::domain::ObjectLabel::B, Frame::Grid>,
127 : QueueTags::Center<::domain::ObjectLabel::A, Frame::Inertial>,
128 : QueueTags::Center<::domain::ObjectLabel::B, Frame::Inertial>>>(
129 : control_sys_proxy, measurement_id, DataVector(grid_center_a),
130 : DataVector(grid_center_b), DataVector(inertial_center_a),
131 : DataVector(inertial_center_b));
132 :
133 : if (Parallel::get<Tags::Verbosity>(cache) >= ::Verbosity::Verbose) {
134 : Parallel::printf("%s, time = %.16f: Received measurement '%s'.\n",
135 : name(), measurement_id.id,
136 : pretty_type::name(submeasurement));
137 : }
138 : }
139 : };
140 : };
141 : } // namespace control_system::Systems
|