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