Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cstddef>
8 : #include <string>
9 : #include <utility>
10 : #include <vector>
11 :
12 : #include "DataStructures/DataBox/DataBox.hpp"
13 : #include "DataStructures/DataBox/TagName.hpp"
14 : #include "IO/H5/TensorData.hpp"
15 : #include "IO/Observer/ObserverComponent.hpp"
16 : #include "IO/Observer/Tags.hpp"
17 : #include "IO/Observer/VolumeActions.hpp"
18 : #include "NumericalAlgorithms/Spectral/Basis.hpp"
19 : #include "NumericalAlgorithms/Spectral/Quadrature.hpp"
20 : #include "Parallel/GlobalCache.hpp"
21 : #include "Parallel/Invoke.hpp"
22 : #include "Parallel/Local.hpp"
23 : #include "Parallel/Reduction.hpp"
24 : #include "ParallelAlgorithms/Interpolation/InterpolationTargetDetail.hpp"
25 : #include "ParallelAlgorithms/Interpolation/Protocols/PostInterpolationCallback.hpp"
26 : #include "Utilities/Functional.hpp"
27 : #include "Utilities/Gsl.hpp"
28 : #include "Utilities/PrettyType.hpp"
29 : #include "Utilities/ProtocolHelpers.hpp"
30 : #include "Utilities/TMPL.hpp"
31 :
32 : namespace intrp {
33 : namespace callbacks {
34 :
35 : /* \brief post_interpolation_callback that outputs requested tensors
36 : * interpolated onto a LineSegment. The data is written as volume data into the
37 : * `Reductions` file with Quadrature `CellCentered` and Basis
38 : * `FiniteDifference`.
39 : *
40 : * Uses:
41 : * - Metavariables
42 : * - `temporal_id`
43 : * - DataBox:
44 : * - `TensorsToObserve`
45 : * - GlobalCache:
46 : * - `observers::Tags::ReductionFileName`
47 : *
48 : * Conforms to the intrp::protocols::PostInterpolationCallback protocol
49 : *
50 : * For requirements on InterpolationTargetTag, see
51 : * intrp::protocols::InterpolationTargetTag
52 : *
53 : */
54 : template <typename TensorsToObserve, typename InterpolationTargetTag>
55 0 : struct ObserveLineSegment
56 : : tt::ConformsTo<intrp::protocols::PostInterpolationCallback> {
57 0 : static constexpr double fill_invalid_points_with =
58 : std::numeric_limits<double>::quiet_NaN();
59 :
60 0 : using const_global_cache_tags =
61 : tmpl::list<observers::Tags::ReductionFileName>;
62 :
63 : template <typename DbTags, typename Metavariables, typename TemporalId>
64 0 : static void apply(const db::DataBox<DbTags>& box,
65 : Parallel::GlobalCache<Metavariables>& cache,
66 : const TemporalId& temporal_id) {
67 : static_assert(
68 : tmpl::list_contains_v<TensorsToObserve,
69 : domain::Tags::Coordinates<
70 : Metavariables::volume_dim, Frame::Inertial>>,
71 : "When observing tensors on a line segment, please include the inertial "
72 : "coordinates in TensorsToObserve. This is so that the output file "
73 : "contains the coordinates, so then the output file is all that is "
74 : "needed for subsequent visualization or analysis of the output data.");
75 : std::vector<TensorComponent> tensor_components{};
76 : const size_t number_of_points =
77 : get<tmpl::front<TensorsToObserve>>(box)[0].size();
78 : tmpl::for_each<TensorsToObserve>(
79 : [&box, &tensor_components, &number_of_points](auto tag_v) {
80 : using Tag = tmpl::type_from<decltype(tag_v)>;
81 : const auto& tensor = get<Tag>(box);
82 : for (size_t i = 0; i < tensor.size(); ++i) {
83 : tensor_components.emplace_back(
84 : db::tag_name<Tag>() + tensor.component_suffix(i), tensor[i]);
85 : ASSERT(number_of_points == tensor[i].size(),
86 : "All tensor components are expected to have the same size "
87 : << number_of_points << ", but "
88 : << db::tag_name<Tag>() + tensor.component_suffix(i)
89 : << "has size " << tensor[i].size());
90 : }
91 : });
92 :
93 : const std::string& name = pretty_type::name<InterpolationTargetTag>();
94 : const std::string subfile_path{std::string{"/"} + name};
95 : const std::vector<size_t> extents_vector{number_of_points};
96 : const std::vector<Spectral::Basis> bases_vector{
97 : Spectral::Basis::FiniteDifference};
98 : const std::vector<Spectral::Quadrature> quadratures_vector{
99 : 1, Spectral::Quadrature::CellCentered};
100 : const observers::ObservationId& observation_id = observers::ObservationId(
101 : InterpolationTarget_detail::get_temporal_id_value(temporal_id),
102 : subfile_path + ".vol");
103 : auto& proxy = Parallel::get_parallel_component<
104 : observers::ObserverWriter<Metavariables>>(cache);
105 :
106 : // We call this on proxy[0] because the 0th element of a NodeGroup is
107 : // always guaranteed to be present.
108 : Parallel::threaded_action<observers::ThreadedActions::WriteVolumeData>(
109 : proxy[0], Parallel::get<observers::Tags::ReductionFileName>(cache),
110 : subfile_path, observation_id,
111 : std::vector<ElementVolumeData>{{name, std::move(tensor_components),
112 : extents_vector, bases_vector,
113 : quadratures_vector}});
114 : }
115 : };
116 : } // namespace callbacks
117 : } // namespace intrp
|