Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <pup.h>
8 :
9 : #include "ControlSystem/Protocols/ControlError.hpp"
10 : #include "ControlSystem/Tags/QueueTags.hpp"
11 : #include "ControlSystem/Tags/SystemTags.hpp"
12 : #include "DataStructures/DataVector.hpp"
13 : #include "DataStructures/TaggedTuple.hpp"
14 : #include "Domain/Creators/Tags/ObjectCenter.hpp"
15 : #include "Domain/Structure/ObjectLabel.hpp"
16 : #include "Options/Context.hpp"
17 : #include "Options/ParseError.hpp"
18 : #include "Options/String.hpp"
19 : #include "Parallel/GlobalCache.hpp"
20 : #include "Utilities/ProtocolHelpers.hpp"
21 : #include "Utilities/TMPL.hpp"
22 :
23 : /// \cond
24 : namespace domain::Tags {
25 : struct FunctionsOfTime;
26 : } // namespace domain::Tags
27 : /// \endcond
28 :
29 : namespace control_system::ControlErrors {
30 : /*!
31 : * \brief Tracks the grid-frame object centers.
32 : *
33 : * Tracks the 3d grid-frame centers of the two objects. Tracking the
34 : * grid-frame centers is better than tracking the inertial-frame centers
35 : * because the timescale at which the grid frame locations change is much
36 : * larger than the inertial ones. This is because in the grid frame only the
37 : * radial inspiral really changes because the rotation control system handles
38 : * the orbital movement. The orbital time scale is much larger than the
39 : * Cartesian coordinate location timescale, so splitting the system into
40 : * angular and radial allows for both to be slowly varying.
41 : *
42 : * The intended use case of the output of this control system is for binary
43 : * neutron star simulations where the rotation control needs to be disabled at
44 : * merger. It is also necessary for changing from harmonic to damped harmonic
45 : * gauge near when the neutron stars merge. Finally, it can also be used for
46 : * triggering a grid change from the inspiral grid to the remnant grid in a
47 : * BNS merger simulation.
48 : *
49 : * Requirements:
50 : * - This control error requires that there be either one or two objects in the
51 : * simulation (typically neutron stars).
52 : * - Currently this control error can only be used with the \link
53 : * control_system::Systems::GridCenters GridCenters \endlink control system
54 : * - There must exist a `PiecewisePolynomial<2>` function of time named
55 : * "GridCenters". It is assumed that components `[0,2]` are the grid
56 : * coordinates of object A and the components `[3,5]` are the grid
57 : * coordinates of object B.
58 : */
59 1 : struct GridCenters : tt::ConformsTo<protocols::ControlError> {
60 0 : using object_centers =
61 : domain::object_list<domain::ObjectLabel::A, domain::ObjectLabel::B>;
62 :
63 0 : using options = tmpl::list<>;
64 0 : static constexpr Options::String help{
65 : "Computes the control error for the grid centers of two objects. "
66 : "This should not take any options."};
67 :
68 : // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
69 0 : std::optional<double> get_suggested_timescale() const { return std::nullopt; }
70 :
71 0 : void reset() {}
72 :
73 0 : explicit GridCenters(const Options::Context& context = {});
74 :
75 0 : void pup(PUP::er& p);
76 :
77 : template <typename Metavariables, typename... TupleTags>
78 0 : DataVector operator()(const ::TimescaleTuner<true>& /*unused*/,
79 : const Parallel::GlobalCache<Metavariables>& cache,
80 : const double time,
81 : const std::string& function_of_time_name,
82 : const tuples::TaggedTuple<TupleTags...>& measurements) {
83 : using grid_center_A =
84 : control_system::QueueTags::Center<::domain::ObjectLabel::A,
85 : Frame::Grid>;
86 : using grid_center_B =
87 : control_system::QueueTags::Center<::domain::ObjectLabel::B,
88 : Frame::Grid>;
89 :
90 : const auto& measured_grid_position_of_A = get<grid_center_A>(measurements);
91 : const auto& measured_grid_position_of_B = get<grid_center_B>(measurements);
92 :
93 : return impl(get<domain::Tags::FunctionsOfTime>(cache)
94 : .at(function_of_time_name)
95 : ->func(time)[0],
96 : measured_grid_position_of_A, measured_grid_position_of_B);
97 : }
98 :
99 : private:
100 0 : static DataVector impl(const DataVector& fot_positions_dv,
101 : const DataVector& measured_grid_position_of_A,
102 : const DataVector& measured_grid_position_of_B);
103 : };
104 : } // namespace control_system::ControlErrors
|