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