10#include "interpolator.hxx"
22 for (
index_t i = 0; i < N; ++i) {
36 std::array<int_t, N> result{};
38 std::array<int_t, Dim> offset{};
43 for (
index_t i = 0; i < total; ++i) {
47 for (
int_t d = 0; d < Dim; ++d) {
61 for (
int_t k = Dim - 1; k >= 0; --k) {
62 index += offset[k] * stride;
65 result[out++] = index;
73 std::array<int_t, 8> result{};
75 const std::array<std::array<int_t, 2>, 8> offsets = {
76 {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}};
79 for (
const auto offset : offsets) {
82 for (
int_t k = 1; k >= 0; --k) {
83 index += offset[k] * stride;
86 result[out++] = index;
94 std::array<int_t, 26> result{};
96 const std::array<std::array<int_t, 3>, 26> offsets = {
97 {{-1, -1, -1}, {-1, -1, 0}, {-1, -1, 1}, {-1, 0, 0}, {-1, 0, 1},
98 {-1, 0, -1}, {-1, 1, 0}, {-1, 1, 1}, {-1, 1, -1}, {0, -1, -1},
99 {0, -1, 0}, {0, -1, 1}, {0, 0, 1}, {0, 0, -1}, {0, 1, 0},
100 {0, 1, 1}, {0, 1, -1}, {1, -1, -1}, {1, -1, 0}, {1, -1, 1},
101 {1, 0, 0}, {1, 0, 1}, {1, 0, -1}, {1, 1, 0}, {1, 1, 1},
105 for (
const auto offset : offsets) {
108 for (
int_t k = 2; k >= 0; --k) {
109 index += offset[k] * stride;
112 result[out++] = index;
121 KOKKOS_INLINE_FUNCTION
122 bool operator()(
const ValueType &v)
const {
return v[0] != v[0]; }
128void TEMPLATED_CLASSNAME::CreateClusters(
void) {
129 assert(this->mRadius > 0);
130 assert(this->mRelativeOverlap > 0 && this->mRelativeOverlap < 1);
132 const std::string _region_name =
"RbfPumInterpolator::create_clusters";
133 Kokkos::Profiling::ScopedRegion region(_region_name);
134 const ExecSpace execspace{};
137 const Point lower = this->mSourceBvh.bounds().minCorner();
138 const Point upper = this->mSourceBvh.bounds().maxCorner();
142 const fp_t spacing = std::sqrt(4.0 / Dim) * this->mRadius *
148 int_t nb_centers = 1;
149 for (
int_t axis = 0; axis < Dim; ++axis) {
150 fp_t edge_length = upper[axis] - lower[axis];
151 edge_length = (edge_length < 0) ? (-edge_length) : (edge_length);
154 shape[axis] = std::ceil(std::max(
fp_consts::one(), edge_length / spacing));
158 distances[axis] = edge_length / shape[axis];
159 if (distances[axis] < min_distance) {
160 min_distance = distances[axis];
164 nb_centers *= ++shape[axis];
168 this->mClusters =
decltype(this->mClusters)(
169 Kokkos::view_alloc(execspace, Kokkos::WithoutInitializing,
172 auto centers_candidates = this->mClusters;
174 Kokkos::parallel_for(
175 _region_name +
"::p_for fill centers candidates",
176 Kokkos::RangePolicy(execspace, 0, nb_centers),
177 KOKKOS_LAMBDA(
const index_t &i) {
180 Kokkos::Array<int_t, Dim> coords{};
181 for (
int_t axis = Dim - 1; axis >= 0; --axis) {
183 for (
int_t d = axis - 1; d >= 0; --d) {
186 coords[axis] = i_copy / prod;
187 i_copy -= coords[axis] * prod;
193 for (
int_t k = Dim - 1; k >= 0; --k) {
194 index += coords[k] * stride;
199 centers_candidates(index) = Point{lower};
200 for (
int_t axis = 0; axis < Dim; ++axis) {
201 centers_candidates(index)[axis] += distances[axis] * coords[axis];
210 centers_candidates, this->mRadius * this->mRadius};
211 this->mSourceBvh.query(execspace, tag_empty_centers,
212 tag_empty_centers_callback);
215 this->mTargetBvh.query(execspace, tag_empty_centers,
216 tag_empty_centers_callback);
223 this->mSourceBvh.query(execspace, transform_to_nearest,
224 transform_to_nearest_callback);
228 fp_t threshold = 0.4 * min_distance;
229 threshold *= threshold;
230 auto centers_host = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{},
233 for (
index_t i = 0; i < centers_host.extent(0); ++i) {
235 if (centers_host(i)[0] == centers_host(i)[0]) {
236 for (
auto off : neighbors_offsets) {
240 int_t neighbor_id = i + off;
241 if (neighbor_id >= 0 && neighbor_id < centers_host.extent_int(0)) {
242 auto center = centers_host(i);
243 auto neighbor = centers_host(neighbor_id);
245 if (neighbor[0] == neighbor[0] &&
247 centers_host(i)[0] = NAN;
254 Kokkos::deep_copy(centers_candidates, centers_host);
258 tag_empty_centers =
decltype(tag_empty_centers){centers_candidates};
259 tag_empty_centers_callback =
decltype(tag_empty_centers_callback){
260 centers_candidates, this->mRadius * this->mRadius};
261 this->mTargetBvh.query(execspace, tag_empty_centers,
262 tag_empty_centers_callback);
265 const auto end = Kokkos::Experimental::remove_if(
266 _region_name +
"::remove_if", execspace, centers_candidates,
268 const int_t dist = Kokkos::Experimental::distance(
269 Kokkos::Experimental::begin(centers_candidates), end);
270 Kokkos::resize(this->mClusters, dist);
constexpr auto ZCurveNeighborOffsets< 2 >(int_t shape[2])
: 2D specialization of ZCurveNeighborOffsets for faster computations
constexpr index_t CompileTimePow(void)
A pow function computed at compile time.
KOKKOS_INLINE_FUNCTION fp_t SquaredDifference(const ::ArborX::Point< Dim, coordinates_t > &lhs, const ::ArborX::Point< Dim, coordinates_t > &rhs) noexcept
Returns the squared distance between two points, and check for NaN values.
constexpr auto ZCurveNeighborOffsets(int_t shape[Dim])
Return the indices offsets of the spatial neighbors given the shape of the space.
constexpr auto ZCurveNeighborOffsets< 3 >(int_t shape[3])
: 3D specialization of ZCurveNeighborOffsets for faster computations
KOKKOS_INLINE_FUNCTION fp_t max(void)
KOKKOS_INLINE_FUNCTION consteval fp_t one(void)
A functor which returns true is a given point is tagged for removal (=> if its first dimension coordi...
KOKKOS_INLINE_FUNCTION bool operator()(const ValueType &v) const
A custon ArborX callback which tags empty regions centers, by setting the x axis value of the center ...
Support struct for an ArborX predicate.