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 "Domain/Creators/Tags/ObjectCenter.hpp" 14 : #include "Domain/Structure/ObjectLabel.hpp" 15 : #include "Options/Context.hpp" 16 : #include "Options/ParseError.hpp" 17 : #include "Options/String.hpp" 18 : #include "Parallel/GlobalCache.hpp" 19 : #include "Utilities/ProtocolHelpers.hpp" 20 : #include "Utilities/TMPL.hpp" 21 : #include "Utilities/TaggedTuple.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