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/TagName.hpp"
13 : #include "IO/Observer/ReductionActions.hpp"
14 : #include "Parallel/GlobalCache.hpp"
15 : #include "Parallel/Info.hpp"
16 : #include "Parallel/Invoke.hpp"
17 : #include "Parallel/Local.hpp"
18 : #include "Parallel/Reduction.hpp"
19 : #include "ParallelAlgorithms/Interpolation/InterpolationTargetDetail.hpp"
20 : #include "ParallelAlgorithms/Interpolation/Protocols/PostInterpolationCallback.hpp"
21 : #include "Utilities/Functional.hpp"
22 : #include "Utilities/Gsl.hpp"
23 : #include "Utilities/PrettyType.hpp"
24 : #include "Utilities/ProtocolHelpers.hpp"
25 : #include "Utilities/TMPL.hpp"
26 :
27 : /// \cond
28 : namespace db {
29 : template <typename TagsList>
30 : class DataBox;
31 : } // namespace db
32 : namespace observers {
33 : template <class Metavariables>
34 : struct ObserverWriter;
35 : } // namespace observers
36 : /// \endcond
37 :
38 : namespace intrp {
39 : namespace callbacks {
40 :
41 : namespace detail {
42 :
43 : template<typename T>
44 : struct is_array_of_double : std::false_type {};
45 :
46 : template<std::size_t N>
47 : struct is_array_of_double<std::array<double, N>> : std::true_type {};
48 :
49 : template <typename... Ts>
50 : auto make_legend(tmpl::list<Ts...> /* meta */) {
51 : std::vector<std::string> legend = {"Time"};
52 :
53 : [[maybe_unused]] auto append_tags = [&legend](auto tag) {
54 : using TagType = decltype(tag);
55 : using ReturnType = typename TagType::type;
56 :
57 : if constexpr (is_array_of_double<ReturnType>::value) {
58 : constexpr std::array<const char*, 3> suffix = {"_x", "_y", "_z"};
59 : for (size_t i = 0; i < std::tuple_size<ReturnType>::value; ++i) {
60 : legend.push_back(db::tag_name<TagType>() + gsl::at(suffix, i));
61 : }
62 : } else {
63 : legend.push_back(db::tag_name<TagType>());
64 : }
65 : };
66 :
67 : (append_tags(Ts{}), ...);
68 :
69 : return legend;
70 : }
71 :
72 : template <typename DbTags, typename... Ts>
73 : auto make_reduction_data(const db::DataBox<DbTags>& box, double time,
74 : tmpl::list<Ts...> /* meta */) {
75 : return std::make_tuple(time, get<Ts>(box)...);
76 : }
77 :
78 : } // namespace detail
79 :
80 : /// \brief post_interpolation_callback that outputs
81 : /// a time series on a surface.
82 : ///
83 : /// Uses:
84 : /// - Metavariables
85 : /// - `temporal_id`
86 : /// - DataBox:
87 : /// - `TagsToObserve`
88 : ///
89 : /// Conforms to the intrp::protocols::PostInterpolationCallback protocol
90 : ///
91 : /// For requirements on InterpolationTargetTag, see
92 : /// intrp::protocols::InterpolationTargetTag
93 : template <typename TagsToObserve, typename InterpolationTargetTag>
94 1 : struct ObserveTimeSeriesOnSurface
95 : : tt::ConformsTo<intrp::protocols::PostInterpolationCallback> {
96 0 : static constexpr double fill_invalid_points_with =
97 : std::numeric_limits<double>::quiet_NaN();
98 :
99 : template <typename DbTags, typename Metavariables, typename TemporalId>
100 0 : static void apply(const db::DataBox<DbTags>& box,
101 : Parallel::GlobalCache<Metavariables>& cache,
102 : const TemporalId& temporal_id) {
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<
109 : observers::ThreadedActions::WriteReductionDataRow>(
110 : proxy[0],
111 : std::string{"/" + pretty_type::name<InterpolationTargetTag>()},
112 : detail::make_legend(TagsToObserve{}),
113 : detail::make_reduction_data(
114 : box, InterpolationTarget_detail::get_temporal_id_value(temporal_id),
115 : TagsToObserve{}));
116 : }
117 : };
118 : } // namespace callbacks
119 : } // namespace intrp
|