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