Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <limits>
7 : #include <memory>
8 : #include <pup.h>
9 : #include <string>
10 : #include <unordered_map>
11 :
12 : #include "DataStructures/Tensor/Tensor.hpp"
13 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
14 : #include "Domain/Structure/ObjectLabel.hpp"
15 : #include "Options/String.hpp"
16 : #include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"
17 : #include "Utilities/Serialization/CharmPupable.hpp"
18 : #include "Utilities/TMPL.hpp"
19 :
20 : /// \cond
21 : namespace Frame {
22 : struct Grid;
23 : struct Inertial;
24 : struct Distorted;
25 : } // namespace Frame
26 : namespace domain::Tags {
27 : template <size_t VolumeDim>
28 : struct Domain;
29 : struct FunctionsOfTime;
30 : template <size_t VolumeDim>
31 : struct Element;
32 : template <ObjectLabel Label>
33 : struct ObjectCenter;
34 : } // namespace domain::Tags
35 : template <size_t VolumeDim>
36 : struct Domain;
37 : template <size_t VolumeDim>
38 : struct Element;
39 : namespace Tags {
40 : struct Time;
41 : } // namespace Tags
42 : /// \endcond
43 :
44 : namespace Triggers {
45 : /*!
46 : * \brief A standard trigger that monitors the separation between two objects
47 : * (either black holes or neutron stars, typically) is below a threshold.
48 : *
49 : * If `UseGridCentersFunctionOfTime` is `true` then the distance between the
50 : * two object is computed using the `GridCenters` function of time. It is
51 : * assume that the `GridCenters` function of time holds the grid coordinates,
52 : * `{x_A, y_A, z_A, x_B, y_B, z_B}`. The Cartesian distance is computed
53 : * between these two locations.
54 : *
55 : * If `UseGridCentersFunctionOfTime` is `false` then
56 : * `domain::Tags::ObjectCenter<A>` and `domain::Tags::ObjectCenter<B>` (in the
57 : * inertial frame) are used to compute the separation.
58 : *
59 : * Once the separation is smaller than (or equal to) the input separation, then
60 : * the `operator()` returns true.
61 : *
62 : * \note If `UseGridCentersFunctionOfTime` is `false` then this trigger requires
63 : * that `domain::Tags::ObjectCenter<domain::ObjectLabel::A>` and
64 : * `domain::Tags::ObjectCenter<domain::ObjectLabel::B>` are in the DataBox. It
65 : * also requires that there are two ExcisionSphere%s in the Domain named
66 : * `ExcisionSphereA/B` and that these ExcisionSphere%s have had time dependent
67 : * maps injected into them. The coordinate maps from these ExcisionSphere%s will
68 : * be used to calculate the separation in the inertial frame.
69 : *
70 : * \note If `UseGridCentersFunctionOfTime` is `true` then this trigger
71 : * requires that `GridCenters` and `Rotation` are a valid function of time and
72 : * will only trigger `true` if the `Rotation` function of time is not a
73 : * `domain::FunctionsOfTime::SettleToConstantQuaternion`.
74 : */
75 : template <bool UseGridCentersFunctionOfTime>
76 1 : class SeparationLessThan : public Trigger {
77 : public:
78 : /// \cond
79 : SeparationLessThan() = default;
80 : explicit SeparationLessThan(CkMigrateMessage* /*unused*/) {}
81 : using PUP::able::register_constructor;
82 : WRAPPED_PUPable_decl_template(SeparationLessThan); // NOLINT
83 : /// \endcond
84 :
85 0 : struct Value {
86 0 : using type = double;
87 0 : static constexpr Options::String help = {
88 : "Separation of the two horizons or neutron star centers to compare "
89 : "against."};
90 : };
91 :
92 0 : using options = tmpl::list<Value>;
93 0 : static constexpr Options::String help{
94 : "Trigger when the separation between the two horizons or neutron star "
95 : "centers is less than a certain distance."};
96 :
97 0 : explicit SeparationLessThan(double separation);
98 :
99 0 : using argument_tags = tmpl::conditional_t<
100 : UseGridCentersFunctionOfTime,
101 : tmpl::list<Tags::Time, domain::Tags::FunctionsOfTime>,
102 : tmpl::list<Tags::Time, domain::Tags::Domain<3>,
103 : domain::Tags::FunctionsOfTime,
104 : domain::Tags::ObjectCenter<domain::ObjectLabel::A>,
105 : domain::Tags::ObjectCenter<domain::ObjectLabel::B>>>;
106 :
107 0 : bool operator()(
108 : double time, const ::Domain<3>& domain,
109 : const std::unordered_map<
110 : std::string,
111 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
112 : functions_of_time,
113 : const tnsr::I<double, 3, Frame::Grid>& grid_object_center_a,
114 : const tnsr::I<double, 3, Frame::Grid>& grid_object_center_b) const;
115 :
116 0 : bool operator()(double time,
117 : const std::unordered_map<
118 : std::string,
119 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
120 : functions_of_time) const;
121 :
122 : // NOLINTNEXTLINE(google-runtime-references)
123 0 : void pup(PUP::er& p) override;
124 :
125 : private:
126 0 : double separation_{std::numeric_limits<double>::signaling_NaN()};
127 : };
128 : } // namespace Triggers
|