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/TaggedTuple.hpp"
11 : #include "DataStructures/Tensor/TypeAliases.hpp"
12 : #include "Options/String.hpp"
13 : #include "ParallelAlgorithms/Interpolation/Protocols/ComputeTargetPoints.hpp"
14 : #include "ParallelAlgorithms/Interpolation/Tags.hpp"
15 : #include "Utilities/Gsl.hpp"
16 : #include "Utilities/PrettyType.hpp"
17 : #include "Utilities/ProtocolHelpers.hpp"
18 : #include "Utilities/Requires.hpp"
19 : #include "Utilities/TMPL.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
|