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 : #include <string>
9 : #include <type_traits>
10 :
11 : #include "DataStructures/DataVector.hpp"
12 : #include "Options/String.hpp"
13 : #include "Parallel/ArrayCollection/IsDgElementCollection.hpp"
14 : #include "Parallel/ArrayCollection/PerformAlgorithmOnElement.hpp"
15 : #include "Parallel/ArrayCollection/Tags/ElementLocations.hpp"
16 : #include "Parallel/GlobalCache.hpp"
17 : #include "ParallelAlgorithms/Actions/GetItemFromDistributedObject.hpp"
18 : #include "ParallelAlgorithms/ApparentHorizonFinder/Events/FindApparentHorizon.hpp"
19 : #include "ParallelAlgorithms/Events/ObserveFields.hpp"
20 : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
21 : #include "ParallelAlgorithms/Interpolation/Events/GetComputeItemsOnSource.hpp"
22 : #include "ParallelAlgorithms/Interpolation/Events/Interpolate.hpp"
23 : #include "ParallelAlgorithms/Interpolation/Interpolate.hpp"
24 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
25 : #include "Utilities/PrettyType.hpp"
26 : #include "Utilities/Serialization/CharmPupable.hpp"
27 : #include "Utilities/TMPL.hpp"
28 :
29 : /// \cond
30 : template <size_t Dim>
31 : class Mesh;
32 : template <size_t VolumeDim>
33 : class ElementId;
34 : namespace Parallel {
35 : template <typename Metavariables>
36 : class GlobalCache;
37 : } // namespace Parallel
38 : namespace Tags {
39 : struct Time;
40 : } // namespace Tags
41 : namespace Events::Tags {
42 : template <size_t Dim>
43 : struct ObserverMesh;
44 : } // namespace Events::Tags
45 : /// \endcond
46 :
47 0 : namespace intrp::Events {
48 : /*!
49 : * \brief Event that combines the `intrp::Events::interpolate` event with
50 : * `dg::Events::ObserveFields` specifically for common horizon finding.
51 : *
52 : * \details This is just a thin wrapper around each event and doesn't do
53 : * anything extra.
54 : */
55 : template <size_t VolumeDim, typename InterpolationTargetTag,
56 : typename InterpolatorSourceVarTags, typename Tensors,
57 : typename NonTensorComputeTagsList = tmpl::list<>>
58 1 : class FindCommonHorizon;
59 :
60 : template <size_t VolumeDim, typename InterpolationTargetTag,
61 : typename... InterpolatorSourceVarTags, typename... Tensors,
62 : typename... NonTensorComputeTags>
63 0 : class FindCommonHorizon<
64 : VolumeDim, InterpolationTargetTag, tmpl::list<InterpolatorSourceVarTags...>,
65 : tmpl::list<Tensors...>, tmpl::list<NonTensorComputeTags...>>
66 : : public Event {
67 0 : using ObserveFieldsEvent =
68 : dg::Events::ObserveFields<VolumeDim, tmpl::list<Tensors...>,
69 : tmpl::list<NonTensorComputeTags...>>;
70 0 : using InterpolateEvent =
71 : intrp::Events::Interpolate<VolumeDim, InterpolationTargetTag,
72 : tmpl::list<InterpolatorSourceVarTags...>>;
73 :
74 : public:
75 : /// \cond
76 : explicit FindCommonHorizon(CkMigrateMessage* /*unused*/) {}
77 : using PUP::able::register_constructor;
78 : WRAPPED_PUPable_decl_template(FindCommonHorizon); // NOLINT
79 : /// \endcond
80 :
81 0 : using options = tmpl::append<typename ObserveFieldsEvent::options,
82 : typename InterpolateEvent::options>;
83 0 : static constexpr Options::String help =
84 : "Starts a common horizon find and sends the evolved variables to be "
85 : "written to disk.";
86 :
87 0 : static std::string name() {
88 : return pretty_type::name<InterpolationTargetTag>();
89 : }
90 :
91 0 : FindCommonHorizon() = default;
92 :
93 0 : FindCommonHorizon(
94 : const std::string& subfile_name,
95 : FloatingPointType coordinates_floating_point_type,
96 : const std::vector<FloatingPointType>& floating_point_types,
97 : const std::vector<std::string>& variables_to_observe,
98 : std::optional<std::vector<std::string>> active_block_or_block_groups = {},
99 : std::optional<Mesh<VolumeDim>> interpolation_mesh = {},
100 : const Options::Context& context = {})
101 : : observe_fields_event_(subfile_name, coordinates_floating_point_type,
102 : floating_point_types, variables_to_observe,
103 : active_block_or_block_groups, interpolation_mesh,
104 : {name()}, context),
105 : interpolate_event_(subfile_name) {}
106 :
107 0 : using compute_tags_for_observation_box = tmpl::remove_duplicates<tmpl::append<
108 : typename ObserveFieldsEvent::compute_tags_for_observation_box,
109 : typename InterpolateEvent::compute_tags_for_observation_box>>;
110 :
111 0 : using return_tags = tmpl::list<>;
112 0 : using argument_tags = tmpl::list<::Tags::ObservationBox,
113 : ::Events::Tags::ObserverMesh<VolumeDim>>;
114 :
115 : template <typename DataBoxType, typename ComputeTagsList,
116 : typename Metavariables, typename ParallelComponent>
117 0 : void operator()(const ObservationBox<DataBoxType, ComputeTagsList>& box,
118 : const Mesh<VolumeDim>& mesh,
119 : Parallel::GlobalCache<Metavariables>& cache,
120 : const ElementId<VolumeDim>& element_id,
121 : const ParallelComponent* const component,
122 : const ObservationValue& observation_value) const {
123 : observe_fields_event_(box, mesh, cache, element_id, component,
124 : observation_value);
125 :
126 : interpolate_event_(get<typename InterpolationTargetTag::temporal_id>(box),
127 : mesh, get<InterpolatorSourceVarTags>(box)..., cache,
128 : element_id, component, observation_value);
129 : }
130 :
131 0 : using observation_registration_tags = tmpl::list<::Tags::DataBox>;
132 :
133 : template <typename DbTagsList>
134 : std::optional<
135 : std::pair<observers::TypeOfObservation, observers::ObservationKey>>
136 0 : get_observation_type_and_key_for_registration(
137 : const db::DataBox<DbTagsList>& box) const {
138 : return observe_fields_event_.get_observation_type_and_key_for_registration(
139 : box);
140 : }
141 :
142 0 : using is_ready_argument_tags = tmpl::list<>;
143 :
144 : template <typename Metavariables, typename Component>
145 0 : bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
146 : const ElementId<3>& /*element_id*/,
147 : const Component* const /*meta*/) const {
148 : return true;
149 : }
150 :
151 1 : bool needs_evolved_variables() const override { return true; }
152 :
153 : // NOLINTNEXTLINE(google-runtime-references)
154 0 : void pup(PUP::er& p) override {
155 : Event::pup(p);
156 : p | observe_fields_event_;
157 : p | interpolate_event_;
158 : }
159 :
160 : private:
161 0 : ObserveFieldsEvent observe_fields_event_;
162 0 : InterpolateEvent interpolate_event_;
163 : };
164 :
165 : /// \cond
166 : // NOLINTBEGIN
167 : template <size_t VolumeDim, typename InterpolationTargetTag,
168 : typename... InterpolatorSourceVarTags, typename... Tensors,
169 : typename... NonTensorComputeTags>
170 : PUP::able::PUP_ID FindCommonHorizon<
171 : VolumeDim, InterpolationTargetTag, tmpl::list<InterpolatorSourceVarTags...>,
172 : tmpl::list<Tensors...>, tmpl::list<NonTensorComputeTags...>>::my_PUP_ID = 0;
173 : // NOLINTEND
174 : /// \endcond
175 : } // namespace intrp::Events
176 :
177 : namespace ah::Events {
178 : /*!
179 : * \brief Event that combines the `ah::Events::FindApparentHorizon` event with
180 : * `dg::Events::ObserveFields` specifically for common horizon finding.
181 : *
182 : * \details This is just a thin wrapper around each event and doesn't do
183 : * anything extra.
184 : */
185 : template <typename HorizonMetavars, typename Tensors,
186 : typename NonTensorComputeTagsList = tmpl::list<>>
187 1 : class FindCommonHorizon;
188 :
189 : template <typename HorizonMetavars, typename... Tensors,
190 : typename... NonTensorComputeTags>
191 0 : class FindCommonHorizon<HorizonMetavars, tmpl::list<Tensors...>,
192 : tmpl::list<NonTensorComputeTags...>> : public Event {
193 0 : using ObserveFieldsEvent =
194 : dg::Events::ObserveFields<3, tmpl::list<Tensors...>,
195 : tmpl::list<NonTensorComputeTags...>>;
196 0 : using HorizonFindEvent = ah::Events::FindApparentHorizon<HorizonMetavars>;
197 :
198 : public:
199 : /// \cond
200 : explicit FindCommonHorizon(CkMigrateMessage* /*unused*/) {}
201 : using PUP::able::register_constructor;
202 : WRAPPED_PUPable_decl_template(FindCommonHorizon); // NOLINT
203 : /// \endcond
204 :
205 0 : using options = tmpl::append<typename ObserveFieldsEvent::options,
206 : typename HorizonFindEvent::options>;
207 0 : static constexpr Options::String help =
208 : "Starts a common horizon find and sends the evolved variables to be "
209 : "written to disk.";
210 :
211 0 : static std::string name() { return pretty_type::name<HorizonMetavars>(); }
212 :
213 0 : FindCommonHorizon() = default;
214 :
215 0 : FindCommonHorizon(
216 : const std::string& subfile_name,
217 : FloatingPointType coordinates_floating_point_type,
218 : const std::vector<FloatingPointType>& floating_point_types,
219 : const std::vector<std::string>& variables_to_observe,
220 : std::optional<std::vector<std::string>> active_block_or_block_groups = {},
221 : std::optional<Mesh<3>> interpolation_mesh = {},
222 : const Options::Context& context = {})
223 : : observe_fields_event_(subfile_name, coordinates_floating_point_type,
224 : floating_point_types, variables_to_observe,
225 : active_block_or_block_groups, interpolation_mesh,
226 : {name()}, context),
227 : horizon_find_event_(subfile_name) {}
228 :
229 0 : using compute_tags_for_observation_box = tmpl::remove_duplicates<tmpl::append<
230 : typename ObserveFieldsEvent::compute_tags_for_observation_box,
231 : typename HorizonFindEvent::compute_tags_for_observation_box>>;
232 :
233 0 : using return_tags = tmpl::list<>;
234 0 : using argument_tags =
235 : tmpl::list<::Tags::ObservationBox, ::Events::Tags::ObserverMesh<3>,
236 : domain::Tags::Element<3>>;
237 :
238 : template <typename DataBoxType, typename ComputeTagsList,
239 : typename Metavariables, typename ParallelComponent>
240 0 : void operator()(const ObservationBox<DataBoxType, ComputeTagsList>& box,
241 : const Mesh<3>& mesh, const Element<3>& element,
242 : Parallel::GlobalCache<Metavariables>& cache,
243 : const ElementId<3>& element_id,
244 : const ParallelComponent* const component,
245 : const ObservationValue& observation_value) const {
246 : observe_fields_event_(box, mesh, cache, element_id, component,
247 : observation_value);
248 :
249 : horizon_find_event_(
250 : get<typename HorizonMetavars::time_tag>(box), mesh, element,
251 : get<gr::Tags::SpacetimeMetric<DataVector, 3>>(box),
252 : get<gh::Tags::Pi<DataVector, 3>>(box),
253 : get<gh::Tags::Phi<DataVector, 3>>(box),
254 : get<::Tags::deriv<gh::Tags::Phi<DataVector, 3>, tmpl::size_t<3>,
255 : Frame::Inertial>>(box),
256 : cache, element_id, component, observation_value);
257 : }
258 :
259 0 : using observation_registration_tags = tmpl::list<::Tags::DataBox>;
260 :
261 : template <typename DbTagsList>
262 : std::optional<
263 : std::pair<observers::TypeOfObservation, observers::ObservationKey>>
264 0 : get_observation_type_and_key_for_registration(
265 : const db::DataBox<DbTagsList>& box) const {
266 : return observe_fields_event_.get_observation_type_and_key_for_registration(
267 : box);
268 : }
269 :
270 0 : using is_ready_argument_tags = tmpl::list<>;
271 :
272 : template <typename Metavariables, typename Component>
273 0 : bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
274 : const ElementId<3>& /*element_id*/,
275 : const Component* const /*meta*/) const {
276 : return true;
277 : }
278 :
279 1 : bool needs_evolved_variables() const override { return true; }
280 :
281 : // NOLINTNEXTLINE(google-runtime-references)
282 0 : void pup(PUP::er& p) override {
283 : Event::pup(p);
284 : p | observe_fields_event_;
285 : p | horizon_find_event_;
286 : }
287 :
288 : private:
289 0 : ObserveFieldsEvent observe_fields_event_;
290 0 : HorizonFindEvent horizon_find_event_;
291 : };
292 :
293 : /// \cond
294 : // NOLINTBEGIN
295 : template <typename HorizonMetavars, typename... Tensors,
296 : typename... NonTensorComputeTags>
297 : PUP::able::PUP_ID
298 : FindCommonHorizon<HorizonMetavars, tmpl::list<Tensors...>,
299 : tmpl::list<NonTensorComputeTags...>>::my_PUP_ID = 0;
300 : // NOLINTEND
301 : /// \endcond
302 : } // namespace ah::Events
|