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 : 9 : #include "DataStructures/DataBox/Tag.hpp" 10 : #include "DataStructures/Tensor/TypeAliases.hpp" 11 : #include "Options/String.hpp" 12 : #include "ParallelAlgorithms/Interpolation/Protocols/ComputeTargetPoints.hpp" 13 : #include "ParallelAlgorithms/Interpolation/Tags.hpp" 14 : #include "Utilities/Gsl.hpp" 15 : #include "Utilities/PrettyType.hpp" 16 : #include "Utilities/ProtocolHelpers.hpp" 17 : #include "Utilities/Requires.hpp" 18 : #include "Utilities/TMPL.hpp" 19 : #include "Utilities/TaggedTuple.hpp" 20 : 21 : /// \cond 22 : class DataVector; 23 : namespace PUP { 24 : class er; 25 : } // namespace PUP 26 : namespace db { 27 : template <typename TagsList> 28 : class DataBox; 29 : } // namespace db 30 : namespace intrp { 31 : namespace Tags { 32 : template <typename TemporalId> 33 : struct TemporalIds; 34 : } // namespace Tags 35 : } // namespace intrp 36 : /// \endcond 37 : 38 : namespace intrp { 39 : 40 : namespace OptionHolders { 41 : /// A line segment extending from `Begin` to `End`, 42 : /// containing `NumberOfPoints` uniformly-spaced points including the endpoints. 43 : /// 44 : /// \note Input coordinates are interpreted in `Frame::Inertial` 45 : template <size_t VolumeDim> 46 1 : struct LineSegment { 47 0 : struct Begin { 48 0 : using type = std::array<double, VolumeDim>; 49 0 : static constexpr Options::String help = {"Beginning endpoint"}; 50 : }; 51 0 : struct End { 52 0 : using type = std::array<double, VolumeDim>; 53 0 : static constexpr Options::String help = {"Ending endpoint"}; 54 : }; 55 0 : struct NumberOfPoints { 56 0 : using type = size_t; 57 0 : static constexpr Options::String help = { 58 : "Number of points including endpoints"}; 59 0 : static type lower_bound() { return 2; } 60 : }; 61 0 : using options = tmpl::list<Begin, End, NumberOfPoints>; 62 0 : static constexpr Options::String help = { 63 : "A line segment extending from Begin to End, containing NumberOfPoints" 64 : " uniformly-spaced points including the endpoints."}; 65 : 66 0 : LineSegment(std::array<double, VolumeDim> begin_in, 67 : std::array<double, VolumeDim> end_in, size_t number_of_points_in); 68 : 69 0 : LineSegment() = default; 70 : 71 : // NOLINTNEXTLINE(google-runtime-references) 72 0 : void pup(PUP::er& p); 73 : 74 0 : std::array<double, VolumeDim> begin{}; 75 0 : std::array<double, VolumeDim> end{}; 76 0 : size_t number_of_points{}; 77 : }; 78 : 79 : template <size_t VolumeDim> 80 0 : bool operator==(const LineSegment<VolumeDim>& lhs, 81 : const LineSegment<VolumeDim>& rhs); 82 : template <size_t VolumeDim> 83 0 : bool operator!=(const LineSegment<VolumeDim>& lhs, 84 : const LineSegment<VolumeDim>& rhs); 85 : 86 : } // namespace OptionHolders 87 : 88 : namespace OptionTags { 89 : template <typename InterpolationTargetTag, size_t VolumeDim> 90 0 : struct LineSegment { 91 0 : using type = OptionHolders::LineSegment<VolumeDim>; 92 0 : static constexpr Options::String help{ 93 : "Options for interpolation onto line segment."}; 94 0 : static std::string name() { 95 : return pretty_type::name<InterpolationTargetTag>(); 96 : } 97 0 : using group = InterpolationTargets; 98 : }; 99 : } // namespace OptionTags 100 : 101 : namespace Tags { 102 : template <typename InterpolationTargetTag, size_t VolumeDim> 103 0 : struct LineSegment : db::SimpleTag { 104 0 : using type = OptionHolders::LineSegment<VolumeDim>; 105 0 : using option_tags = 106 : tmpl::list<OptionTags::LineSegment<InterpolationTargetTag, VolumeDim>>; 107 : 108 0 : static constexpr bool pass_metavariables = false; 109 0 : static type create_from_options(const type& option) { return option; } 110 : }; 111 : } // namespace Tags 112 : 113 : namespace TargetPoints { 114 : /// \brief Computes points on a line segment. 115 : /// 116 : /// Conforms to the intrp::protocols::ComputeTargetPoints protocol 117 : /// 118 : /// For requirements on InterpolationTargetTag, see 119 : /// intrp::protocols::InterpolationTargetTag 120 : template <typename InterpolationTargetTag, size_t VolumeDim, typename Frame> 121 1 : struct LineSegment : tt::ConformsTo<intrp::protocols::ComputeTargetPoints> { 122 0 : using const_global_cache_tags = 123 : tmpl::list<Tags::LineSegment<InterpolationTargetTag, VolumeDim>>; 124 0 : using is_sequential = std::false_type; 125 0 : using frame = Frame; 126 : 127 : template <typename Metavariables, typename DbTags> 128 0 : static tnsr::I<DataVector, VolumeDim, Frame> points( 129 : const db::DataBox<DbTags>& box, 130 : const tmpl::type_<Metavariables>& /*meta*/) { 131 : const auto& options = 132 : get<Tags::LineSegment<InterpolationTargetTag, VolumeDim>>(box); 133 : 134 : // Fill points on a line segment 135 : const double fractional_distance = 1.0 / (options.number_of_points - 1); 136 : tnsr::I<DataVector, VolumeDim, Frame> target_points( 137 : options.number_of_points); 138 : for (size_t n = 0; n < options.number_of_points; ++n) { 139 : for (size_t d = 0; d < VolumeDim; ++d) { 140 : target_points.get(d)[n] = 141 : gsl::at(options.begin, d) + 142 : n * fractional_distance * 143 : (gsl::at(options.end, d) - gsl::at(options.begin, d)); 144 : } 145 : } 146 : return target_points; 147 : } 148 : 149 : template <typename Metavariables, typename DbTags, typename TemporalId> 150 0 : static tnsr::I<DataVector, VolumeDim, Frame> points( 151 : const db::DataBox<DbTags>& box, const tmpl::type_<Metavariables>& meta, 152 : const TemporalId& /*temporal_id*/) { 153 : return points(box, meta); 154 : } 155 : }; 156 : 157 : } // namespace TargetPoints 158 : } // namespace intrp