DDC 0.1.0
Loading...
Searching...
No Matches
non_uniform_point_sampling.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <cassert>
8#include <cstddef>
9#include <initializer_list>
10#include <ostream>
11#include <tuple>
12#include <type_traits>
13#include <utility>
14#include <vector>
15
16#include <Kokkos_Core.hpp>
17
18#include "ddc/coordinate.hpp"
19#include "ddc/discrete_domain.hpp"
20#include "ddc/discrete_element.hpp"
21#include "ddc/discrete_space.hpp"
22#include "ddc/discrete_vector.hpp"
23
24namespace ddc {
25
26namespace detail {
27
28struct NonUniformPointSamplingBase
29{
30};
31
32} // namespace detail
33
34/// `NonUniformPointSampling` models a non-uniform discretization of the `CDim` segment \f$[a, b]\f$.
35template <class CDim>
36class NonUniformPointSampling : detail::NonUniformPointSamplingBase
37{
38public:
39 using continuous_dimension_type = CDim;
40
41 using continuous_element_type = Coordinate<CDim>;
42
43
44 using discrete_dimension_type = NonUniformPointSampling;
45
46public:
47 template <class DDim, class MemorySpace>
48 class Impl
49 {
50 template <class ODDim, class OMemorySpace>
51 friend class Impl;
52
53 Kokkos::View<continuous_element_type*, MemorySpace> m_points;
54
55 public:
56 using discrete_dimension_type = NonUniformPointSampling;
57
58 using discrete_domain_type = DiscreteDomain<DDim>;
59
60 using discrete_element_type = DiscreteElement<DDim>;
61
62 using discrete_vector_type = DiscreteVector<DDim>;
63
64 Impl() = default;
65
66 /// @brief Construct a `NonUniformPointSampling` using a brace-list, i.e. `NonUniformPointSampling mesh({0., 1.})`
67 Impl(std::initializer_list<continuous_element_type> points)
68 {
69 std::vector<continuous_element_type> host_points(points.begin(), points.end());
70 Kokkos::View<continuous_element_type*, Kokkos::HostSpace> const
71 host(host_points.data(), host_points.size());
72 Kokkos::resize(m_points, host.extent(0));
73 Kokkos::deep_copy(m_points, host);
74 }
75
76 /// @brief Construct a `NonUniformPointSampling` using a C++20 "common range".
77 template <class InputRange>
78 explicit Impl(InputRange const& points)
79 {
80 if constexpr (Kokkos::is_view_v<InputRange>) {
81 Kokkos::deep_copy(m_points, points);
82 } else {
83 std::vector<continuous_element_type> host_points(points.begin(), points.end());
84 Kokkos::View<continuous_element_type*, Kokkos::HostSpace> const
85 host(host_points.data(), host_points.size());
86 Kokkos::resize(m_points, host.extent(0));
87 Kokkos::deep_copy(m_points, host);
88 }
89 }
90
91 /// @brief Construct a `NonUniformPointSampling` using a pair of iterators.
92 template <class InputIt>
93 Impl(InputIt points_begin, InputIt points_end)
94 {
95 std::vector<continuous_element_type> host_points(points_begin, points_end);
96 Kokkos::View<continuous_element_type*, Kokkos::HostSpace> const
97 host(host_points.data(), host_points.size());
98 Kokkos::resize(m_points, host.extent(0));
99 Kokkos::deep_copy(m_points, host);
100 }
101
102 template <class OriginMemorySpace>
103 explicit Impl(Impl<DDim, OriginMemorySpace> const& impl)
104 : m_points(Kokkos::create_mirror_view_and_copy(MemorySpace(), impl.m_points))
105 {
106 }
107
108 Impl(Impl const& x) = delete;
109
110 Impl(Impl&& x) = default;
111
112 ~Impl() = default;
113
114 Impl& operator=(Impl const& x) = delete;
115
116 Impl& operator=(Impl&& x) = default;
117
118 KOKKOS_FUNCTION std::size_t size() const
119 {
120 return m_points.size();
121 }
122
123 /// @brief Lower bound index of the mesh
124 KOKKOS_FUNCTION discrete_element_type front() const noexcept
125 {
126 return discrete_element_type {0};
127 }
128
129 /// @brief Convert a mesh index into a position in `CDim`
130 KOKKOS_FUNCTION continuous_element_type
131 coordinate(discrete_element_type const& icoord) const noexcept
132 {
133 return m_points(icoord.uid());
134 }
135 };
136
137 /** Construct an Impl<Kokkos::HostSpace> and associated discrete_domain_type from an iterator
138 * containing the points coordinates along the `DDim` dimension.
139 *
140 * @param non_uniform_points a vector containing the coordinates of the points of the domain.
141 */
142 template <class DDim, class InputRange>
143 static std::tuple<typename DDim::template Impl<DDim, Kokkos::HostSpace>, DiscreteDomain<DDim>>
144 init(InputRange const non_uniform_points)
145 {
146 auto a = non_uniform_points.begin();
147 auto b = non_uniform_points.end();
148 auto n = std::distance(non_uniform_points.begin(), non_uniform_points.end());
149 assert(a < b);
150 assert(n > 0);
151 typename DDim::template Impl<DDim, Kokkos::HostSpace> disc(non_uniform_points);
152 DiscreteDomain<DDim> domain {disc.front(), DiscreteVector<DDim> {n}};
153 return std::make_tuple(std::move(disc), std::move(domain));
154 }
155
156 /** Construct 4 non-uniform `DiscreteDomain` and an Impl<Kokkos::HostSpace> from 3 iterators containing the points coordinates along the `DDim` dimension.
157 *
158 * @param domain_r an iterator containing the coordinates of the points of the main domain along the DDim position
159 * @param pre_ghost_r an iterator containing the positions of the ghost points before the main domain the DDim position
160 * @param post_ghost_r an iterator containing the positions of the ghost points after the main domain the DDim position
161 */
162 template <class DDim, class InputRange>
163 static std::tuple<
164 typename DDim::template Impl<DDim, Kokkos::HostSpace>,
165 DiscreteDomain<DDim>,
166 DiscreteDomain<DDim>,
167 DiscreteDomain<DDim>,
168 DiscreteDomain<DDim>>
170 InputRange const& domain_r,
171 InputRange const& pre_ghost_r,
172 InputRange const& post_ghost_r)
173 {
174 using discrete_domain_type = DiscreteDomain<DDim>;
175 auto n = DiscreteVector<DDim> {std::distance(domain_r.begin(), domain_r.end())};
176
177 assert(domain_r.begin() < domain_r.end());
178 assert(n > 1);
179
180 auto n_ghosts_before
181 = DiscreteVector<DDim> {std::distance(pre_ghost_r.begin(), pre_ghost_r.end())};
182 auto n_ghosts_after
183 = DiscreteVector<DDim> {std::distance(post_ghost_r.begin(), post_ghost_r.end())};
184
185 std::vector<typename InputRange::value_type> full_domain;
186
187 std::copy(pre_ghost_r.begin(), pre_ghost_r.end(), std::back_inserter(full_domain));
188 std::copy(domain_r.begin(), domain_r.end(), std::back_inserter(full_domain));
189 std::copy(post_ghost_r.begin(), post_ghost_r.end(), std::back_inserter(full_domain));
190
191 typename DDim::template Impl<DDim, Kokkos::HostSpace> disc(full_domain);
192
193 discrete_domain_type ghosted_domain
194 = discrete_domain_type(disc.front(), n + n_ghosts_before + n_ghosts_after);
195 discrete_domain_type pre_ghost
196 = discrete_domain_type(ghosted_domain.front(), n_ghosts_before);
197 discrete_domain_type main_domain
198 = discrete_domain_type(ghosted_domain.front() + n_ghosts_before, n);
199 discrete_domain_type post_ghost
200 = discrete_domain_type(main_domain.back() + 1, n_ghosts_after);
201 return std::make_tuple(
202 std::move(disc),
203 std::move(main_domain),
204 std::move(ghosted_domain),
205 std::move(pre_ghost),
206 std::move(post_ghost));
207 }
208};
209
210template <class DDim>
212 : public std::is_base_of<detail::NonUniformPointSamplingBase, DDim>
213{
214};
215
216template <class DDim>
218
219template <
220 class DDimImpl,
221 std::enable_if_t<
222 is_non_uniform_point_sampling_v<typename DDimImpl::discrete_dimension_type>,
223 int>
224 = 0>
225std::ostream& operator<<(std::ostream& out, DDimImpl const& mesh)
226{
227 return out << "NonUniformPointSampling(" << mesh.size() << ")";
228}
229
230template <class DDim, std::enable_if_t<is_non_uniform_point_sampling_v<DDim>, int> = 0>
231KOKKOS_FUNCTION Coordinate<typename DDim::continuous_dimension_type> coordinate(
232 DiscreteElement<DDim> const& c)
233{
234 return discrete_space<DDim>().coordinate(c);
235}
236
237template <class DDim, std::enable_if_t<is_non_uniform_point_sampling_v<DDim>, int> = 0>
239 DiscreteElement<DDim> i)
240{
241 return coordinate(i) - coordinate(i - 1);
242}
243
244template <class DDim, std::enable_if_t<is_non_uniform_point_sampling_v<DDim>, int> = 0>
246 DiscreteElement<DDim> i)
247{
248 return coordinate(i + 1) - coordinate(i);
249}
250
251template <class DDim, std::enable_if_t<is_non_uniform_point_sampling_v<DDim>, int> = 0>
252KOKKOS_FUNCTION Coordinate<typename DDim::continuous_dimension_type> rmin(
253 DiscreteDomain<DDim> const& d)
254{
255 return coordinate(d.front());
256}
257
258template <class DDim, std::enable_if_t<is_non_uniform_point_sampling_v<DDim>, int> = 0>
259KOKKOS_FUNCTION Coordinate<typename DDim::continuous_dimension_type> rmax(
260 DiscreteDomain<DDim> const& d)
261{
262 return coordinate(d.back());
263}
264
265template <class DDim, std::enable_if_t<is_non_uniform_point_sampling_v<DDim>, int> = 0>
266KOKKOS_FUNCTION Coordinate<typename DDim::continuous_dimension_type> rlength(
267 DiscreteDomain<DDim> const& d)
268{
269 return rmax(d) - rmin(d);
270}
271
272} // namespace ddc
friend class DiscreteDomain
KOKKOS_FUNCTION constexpr bool operator!=(DiscreteVector< OTags... > const &rhs) const noexcept
KOKKOS_FUNCTION std::size_t size() const
KOKKOS_FUNCTION continuous_element_type coordinate(discrete_element_type const &icoord) const noexcept
Convert a mesh index into a position in CDim
Impl(Impl< DDim, OriginMemorySpace > const &impl)
Impl & operator=(Impl &&x)=default
Impl & operator=(Impl const &x)=delete
Impl(std::initializer_list< continuous_element_type > points)
Construct a NonUniformPointSampling using a brace-list, i.e. NonUniformPointSampling mesh({0....
KOKKOS_FUNCTION discrete_element_type front() const noexcept
Lower bound index of the mesh.
Impl(InputRange const &points)
Construct a NonUniformPointSampling using a C++20 "common range".
Impl(InputIt points_begin, InputIt points_end)
Construct a NonUniformPointSampling using a pair of iterators.
NonUniformPointSampling models a non-uniform discretization of the CDim segment .
static std::tuple< typename DDim::template Impl< DDim, Kokkos::HostSpace >, DiscreteDomain< DDim > > init(InputRange const non_uniform_points)
Construct an Impl<Kokkos::HostSpace> and associated discrete_domain_type from an iterator containing ...
static std::tuple< typename DDim::template Impl< DDim, Kokkos::HostSpace >, DiscreteDomain< DDim >, DiscreteDomain< DDim >, DiscreteDomain< DDim >, DiscreteDomain< DDim > > init_ghosted(InputRange const &domain_r, InputRange const &pre_ghost_r, InputRange const &post_ghost_r)
Construct 4 non-uniform DiscreteDomain and an Impl<Kokkos::HostSpace> from 3 iterators containing the...
The top-level namespace of DDC.
constexpr bool is_non_uniform_point_sampling_v
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > rmax(DiscreteDomain< DDim > const &d)
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > rlength(DiscreteDomain< DDim > const &d)
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > distance_at_left(DiscreteElement< DDim > i)
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > rmin(DiscreteDomain< DDim > const &d)
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > coordinate(DiscreteElement< DDim > const &c)
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > distance_at_right(DiscreteElement< DDim > i)