13 #include "DataStructures/DataVector.hpp"
15 #include "IO/Observer/ArrayComponentId.hpp"
16 #include "IO/Observer/Helpers.hpp"
17 #include "IO/Observer/ObservationId.hpp"
18 #include "IO/Observer/ObserverComponent.hpp"
19 #include "IO/Observer/ReductionActions.hpp"
20 #include "IO/Observer/TypeOfObservation.hpp"
23 #include "Parallel/ArrayIndex.hpp"
26 #include "Parallel/Invoke.hpp"
27 #include "Parallel/Reduction.hpp"
28 #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
30 #include "Utilities/Functional.hpp"
31 #include "Utilities/Registration.hpp"
33 #include "Utilities/TaggedTuple.hpp"
43 template <
size_t VolumeDim,
typename ObservationValueTag,
typename Tensors,
44 typename EventRegistrars>
47 namespace Registrars {
48 template <
size_t VolumeDim,
typename ObservationValueTag,
typename Tensors>
52 template <
typename RegistrarList>
54 Tensors, RegistrarList>;
58 template <
size_t VolumeDim,
typename ObservationValueTag,
typename Tensors,
59 typename EventRegistrars =
61 VolumeDim, ObservationValueTag, Tensors>>>
73 template <
size_t VolumeDim,
typename ObservationValueTag,
typename... Tensors,
74 typename EventRegistrars>
76 tmpl::list<Tensors...>, EventRegistrars>
77 :
public Event<EventRegistrars> {
82 using ReductionData = tmpl::wrap<
83 tmpl::list<Parallel::ReductionDatum<double, funcl::AssertEqual<>>,
86 Parallel::ReductionData>;
93 "The name of the subfile inside the HDF5 file without an extension and "
94 "without a preceding '/'."};
99 using PUP::able::register_constructor;
103 using options = tmpl::list<SubfileName>;
105 "Observe the volume integrals of the tensors over the domain.\n"
107 "Writes reduction quantities:\n"
108 " * ObservationValueTag\n"
109 " * Volume = volume of the domain\n"
110 " * VolumeIntegral(*) = volume integral of the tensor\n"
112 "Warning: Currently, only one reduction observation event can be\n"
113 "triggered at a given observation value. Causing multiple events to\n"
114 "run at once will produce unpredictable results.";
119 using observed_reduction_data_tags =
120 observers::make_reduction_data_tags<tmpl::list<ReductionData>>;
122 using argument_tags =
123 tmpl::list<ObservationValueTag, domain::Tags::Mesh<VolumeDim>,
127 template <
typename Metavariables,
typename ArrayIndex,
128 typename ParallelComponent>
129 void operator()(
const typename ObservationValueTag::type& observation_value,
132 const typename Tensors::type&... tensors,
134 const ArrayIndex& array_index,
135 const ParallelComponent*
const )
const noexcept {
143 db::tag_name<ObservationValueTag>(),
"Volume"};
144 const auto record_integrals =
145 [&local_volume_integrals, &reduction_names, &det_jacobian, &mesh ](
146 const auto tensor_tag_v,
const auto& tensor) noexcept {
147 using tensor_tag = tmpl::type_from<decltype(tensor_tag_v)>;
148 for (
size_t i = 0; i < tensor.size(); ++i) {
149 reduction_names.push_back(
"VolumeIntegral(" +
150 db::tag_name<tensor_tag>() +
151 tensor.component_suffix(i) +
")");
152 local_volume_integrals.push_back(
158 record_integrals(tmpl::type_<Tensors>{}, tensors));
161 auto& local_observer =
162 *Parallel::get_parallel_component<observers::Observer<Metavariables>>(
165 Parallel::simple_action<observers::Actions::ContributeReductionData>(
171 subfile_path_, reduction_names,
172 ReductionData{
static_cast<double>(observation_value), local_volume,
173 local_volume_integrals});
176 using observation_registration_tags = tmpl::list<>;
178 get_observation_type_and_key_for_registration() const noexcept {
184 void pup(PUP::er& p)
override {
193 template <
size_t VolumeDim,
typename ObservationValueTag,
typename... Tensors,
194 typename EventRegistrars>
195 ObserveVolumeIntegrals<VolumeDim, ObservationValueTag, tmpl::list<Tensors...>,
197 ObserveVolumeIntegrals(
const std::string& subfile_name) noexcept
198 : subfile_path_(
"/" + subfile_name) {}
201 template <
size_t VolumeDim,
typename ObservationValueTag,
typename... Tensors,
202 typename EventRegistrars>
203 PUP::able::PUP_ID ObserveVolumeIntegrals<VolumeDim, ObservationValueTag,
204 tmpl::list<Tensors...>,
205 EventRegistrars>::my_PUP_ID =