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