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 <optional>
8 : #include <pup.h>
9 : #include <string>
10 : #include <type_traits>
11 :
12 : #include "DataStructures/DataVector.hpp"
13 : #include "Domain/Structure/ElementId.hpp"
14 : #include "NumericalAlgorithms/Spectral/Mesh.hpp"
15 : #include "Options/String.hpp"
16 : #include "Parallel/ArrayCollection/IsDgElementCollection.hpp"
17 : #include "Parallel/ArrayCollection/PerformAlgorithmOnElement.hpp"
18 : #include "Parallel/ArrayCollection/Tags/ElementLocations.hpp"
19 : #include "Parallel/GlobalCache.hpp"
20 : #include "ParallelAlgorithms/Actions/GetItemFromDistributedObject.hpp"
21 : #include "ParallelAlgorithms/ApparentHorizonFinder/Events/FindApparentHorizon.hpp"
22 : #include "ParallelAlgorithms/Events/ObserveFields.hpp"
23 : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
24 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
25 : #include "Utilities/PrettyType.hpp"
26 : #include "Utilities/Serialization/CharmPupable.hpp"
27 : #include "Utilities/TMPL.hpp"
28 : #include "Utilities/TypeTraits/CreateGetTypeAliasOrDefault.hpp"
29 :
30 : /// \cond
31 : namespace Tags {
32 : struct Time;
33 : } // namespace Tags
34 : namespace Events::Tags {
35 : template <size_t Dim>
36 : struct ObserverMesh;
37 : } // namespace Events::Tags
38 : /// \endcond
39 :
40 : namespace ah::Events {
41 : /*!
42 : * \brief Event that combines the `ah::Events::FindApparentHorizon` event with
43 : * `dg::Events::ObserveFields` specifically for common horizon finding.
44 : *
45 : * \details The volume data is sent to the `observers::ObserverWriter` with the
46 : * name of the \p HorizonMetavars as its dependency, so the ObserverWriter
47 : * holds the data until the horizon finder reports with
48 : * `ah::callbacks::SendDependencyToObserverWriter` whether the horizon find
49 : * succeeded (then the data is written to disk) or failed (then the data is
50 : * dropped). Other than that, this is just a thin wrapper around each event.
51 : */
52 : template <typename HorizonMetavars, typename Tensors,
53 : typename NonTensorComputeTagsList = tmpl::list<>>
54 1 : class FindCommonHorizon;
55 :
56 : template <typename HorizonMetavars, typename... Tensors,
57 : typename... NonTensorComputeTags>
58 0 : class FindCommonHorizon<HorizonMetavars, tmpl::list<Tensors...>,
59 : tmpl::list<NonTensorComputeTags...>> : public Event {
60 0 : using ObserveFieldsEvent =
61 : dg::Events::ObserveFields<3, tmpl::list<Tensors...>,
62 : tmpl::list<NonTensorComputeTags...>>;
63 0 : using HorizonFindEvent = ah::Events::FindApparentHorizon<HorizonMetavars>;
64 :
65 : public:
66 : /// \cond
67 : explicit FindCommonHorizon(CkMigrateMessage* /*unused*/) {}
68 : using PUP::able::register_constructor;
69 : WRAPPED_PUPable_decl_template(FindCommonHorizon); // NOLINT
70 : /// \endcond
71 :
72 0 : using options = tmpl::append<typename ObserveFieldsEvent::options,
73 : typename HorizonFindEvent::options>;
74 0 : static constexpr Options::String help =
75 : "Starts a common horizon find and sends the evolved variables to be "
76 : "written to disk.";
77 :
78 0 : static std::string name() { return pretty_type::name<HorizonMetavars>(); }
79 :
80 0 : FindCommonHorizon() = default;
81 :
82 0 : FindCommonHorizon(
83 : const std::string& subfile_name,
84 : FloatingPointType coordinates_floating_point_type,
85 : const std::vector<FloatingPointType>& floating_point_types,
86 : const std::vector<std::string>& variables_to_observe,
87 : std::optional<std::vector<std::string>> active_block_or_block_groups = {},
88 : std::optional<Mesh<3>> interpolation_mesh = {},
89 : std::optional<Mesh<3>> projection_mesh = {},
90 : const Options::Context& context = {})
91 : : observe_fields_event_(subfile_name, coordinates_floating_point_type,
92 : floating_point_types, variables_to_observe,
93 : active_block_or_block_groups, interpolation_mesh,
94 : projection_mesh,
95 : std::optional<std::string>{name()}, context),
96 : horizon_find_event_(subfile_name) {}
97 :
98 0 : using compute_tags_for_observation_box = tmpl::remove_duplicates<tmpl::append<
99 : typename ObserveFieldsEvent::compute_tags_for_observation_box,
100 : typename HorizonFindEvent::compute_tags_for_observation_box>>;
101 :
102 0 : using return_tags = tmpl::list<>;
103 0 : using argument_tags =
104 : tmpl::list<::Tags::ObservationBox, ::Events::Tags::ObserverMesh<3>,
105 : domain::Tags::Element<3>>;
106 :
107 : template <typename DataBoxType, typename ComputeTagsList,
108 : typename Metavariables, typename ParallelComponent>
109 0 : void operator()(const ObservationBox<DataBoxType, ComputeTagsList>& box,
110 : const Mesh<3>& mesh, const Element<3>& element,
111 : Parallel::GlobalCache<Metavariables>& cache,
112 : const ElementId<3>& element_id,
113 : const ParallelComponent* const component,
114 : const ObservationValue& observation_value) const {
115 : observe_fields_event_(box, mesh, cache, element_id, component,
116 : observation_value);
117 :
118 : horizon_find_event_(
119 : get<typename HorizonMetavars::time_tag>(box), mesh, element,
120 : get<gr::Tags::SpacetimeMetric<DataVector, 3>>(box),
121 : get<gh::Tags::Pi<DataVector, 3>>(box),
122 : get<gh::Tags::Phi<DataVector, 3>>(box),
123 : get<::Tags::deriv<gh::Tags::Phi<DataVector, 3>, tmpl::size_t<3>,
124 : Frame::Inertial>>(box),
125 : cache, element_id, component, observation_value);
126 : }
127 :
128 0 : using observation_registration_tags = tmpl::list<::Tags::DataBox>;
129 :
130 : template <typename DbTagsList>
131 : std::optional<
132 : std::pair<observers::TypeOfObservation, observers::ObservationKey>>
133 0 : get_observation_type_and_key_for_registration(
134 : const db::DataBox<DbTagsList>& box) const {
135 : return observe_fields_event_.get_observation_type_and_key_for_registration(
136 : box);
137 : }
138 :
139 0 : using is_ready_argument_tags = tmpl::list<>;
140 :
141 : template <typename Metavariables, typename Component>
142 0 : bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
143 : const ElementId<3>& /*element_id*/,
144 : const Component* const /*meta*/) const {
145 : return true;
146 : }
147 :
148 1 : bool needs_evolved_variables() const override { return true; }
149 :
150 : // NOLINTNEXTLINE(google-runtime-references)
151 0 : void pup(PUP::er& p) override {
152 : Event::pup(p);
153 : p | observe_fields_event_;
154 : p | horizon_find_event_;
155 : }
156 :
157 : private:
158 0 : ObserveFieldsEvent observe_fields_event_;
159 0 : HorizonFindEvent horizon_find_event_;
160 : };
161 :
162 : /// \cond
163 : // NOLINTBEGIN
164 : template <typename HorizonMetavars, typename... Tensors,
165 : typename... NonTensorComputeTags>
166 : PUP::able::PUP_ID
167 : FindCommonHorizon<HorizonMetavars, tmpl::list<Tensors...>,
168 : tmpl::list<NonTensorComputeTags...>>::my_PUP_ID = 0;
169 : // NOLINTEND
170 : /// \endcond
171 : } // namespace ah::Events
|