PACMAN 0.1.0
Portable Algorithms for Coupling, Mapping, and Adaptive iNterpolation
Loading...
Searching...
No Matches
ArborXCallbacks.hpp
Go to the documentation of this file.
1//
2// This file is subject to the terms and conditions defined in
3// file 'LICENSE', which is part of this source code package.
4//
5
6#pragma once
7
8#include <ArborX.hpp>
9#include <algorithms/ArborX_ClosestPoint.hpp>
10
11#include "common/concepts.hpp"
12#include "common/transfer.hxx"
13#include "common/types.hpp"
15
20
21namespace PACMAN {
22namespace FiniteElements {
23
26template <KokkosViewRank<1> ViewType> struct PointNearest { ViewType points; };
27
31template <typename ExecSpace, int_t Dim>
33 using MemorySpace = typename ExecSpace::memory_space;
34
35 Transfer<ExecSpace, Dim> transfer;
36 Kokkos::View<int *, MemorySpace> parents;
37
39 template <typename Predicate, typename Value>
40 KOKKOS_FUNCTION auto operator()(const Predicate &predicate,
41 const Value &value) const {
42
43 const int predicate_index = ArborX::getData(predicate);
44 const int_t curElem = parents(value.index); // RAMZI: is it needed ?
45 const auto cellType = transfer.cellTypes(curElem);
46
47 Kokkos::Array<fp_t, MaxNodesPerElt> warr;
48 Kokkos::Array<coordinates_t, MaxNodesPerElt * Dim> Xarr;
49 Kokkos::Array<coordinates_t, Dim> tpa;
50 Kokkos::View<coordinates_t *, ExecSpace> tp(tpa.data(), Dim);
51
52 for (int_t j = 0; j < Dim; j++) {
53 tp(j) = transfer.targetPoints(predicate_index, j);
54 }
55 const auto localConn =
56 Kokkos::subview(transfer.connValues,
57 Kokkos::make_pair(transfer.connOffsets(curElem),
58 transfer.connOffsets(curElem + 1)));
59 const offset_t nbConnNodes =
60 transfer.connOffsets(curElem + 1) - transfer.connOffsets(curElem);
61 Kokkos::View<fp_t *, ExecSpace> weights(warr.data(), nbConnNodes);
62 Kokkos::View<coordinates_t **, ExecSpace> Xcoor(Xarr.data(), nbConnNodes,
63 Dim);
64 for (int_t j = 0; j < nbConnNodes; ++j) {
65 const auto nodeId = localConn(j);
66 for (int_t k = 0; k < Dim; ++k) {
67 Xcoor(j, k) = transfer.sourcePoints(nodeId)[k];
68 }
69 }
70 if (ApplyNewtonOnElement<ExecSpace, Dim>(cellType, Xcoor, tp,
71 weights /*, false*/)) {
72 for (int_t j = 0; j < nbConnNodes; ++j) {
73 const auto nodeId = localConn(j);
74 for (index_t component = 0;
75 component < transfer.sourceValues.extent(1); ++component) {
76 transfer.targetValues(predicate_index, component) +=
77 weights[j] * transfer.sourceValues(nodeId, component);
78 }
79 }
80 transfer.targetStatus(predicate_index) = TransferStatus::INTER;
81 return ArborX::CallbackTreeTraversalControl::early_exit;
82 } else {
83 return ArborX::CallbackTreeTraversalControl::normal_continuation;
84 }
85 }
86};
87
91template <typename ExecSpace, int_t Dim> struct PointTriangleProjection {
92 using MemorySpace = typename ExecSpace::memory_space;
93
94 Kokkos::View<coordinates_t **, MemorySpace> targetPointsPtr;
95 Kokkos::View<int_t *, MemorySpace> parentElt;
96 Kokkos::View<TransferStatus *, MemorySpace> status;
97 Kokkos::View<int_t *, MemorySpace> skinParents;
98
100 template <typename Predicate, typename Value, typename OutputFunctor>
101 KOKKOS_FUNCTION void operator()(const Predicate &predicate,
102 const Value &value,
103 const OutputFunctor &out) const {
104 const int predicate_index = ArborX::getData(predicate);
105
106 if (status(predicate_index) == TransferStatus::OUTSIDE) {
107 ArborX::Point<Dim, coordinates_t> targetPoint;
108 for (int_t k = 0; k < Dim; k++) {
109 targetPoint[k] = targetPointsPtr(predicate_index, k);
110 }
111
112 auto triangle = value.value;
113
114 using PointTag = ArborX::GeometryTraits::PointTag;
115 using TriangleTag = ArborX::GeometryTraits::TriangleTag;
116 using Point = decltype(targetPoint);
117 using Triangle = decltype(triangle);
118
119 ArborX::Details::Dispatch::distance<PointTag, TriangleTag, Point,
120 Triangle>
121 dist{};
122 targetPoint = ArborX::Experimental::closestPoint(targetPoint, triangle);
123 for (int_t k = 0; k < Dim; k++) {
124 targetPointsPtr(predicate_index, k) = targetPoint[k];
125 }
126 parentElt(predicate_index) = skinParents(value.index);
127 out(predicate_index);
128 }
129 }
130};
131
136template <typename ExecSpace, int Dim> struct PointTriangleProjectionExtrapol {
137 using MemorySpace = typename ExecSpace::memory_space;
138
139 Kokkos::View<int_t *, MemorySpace> parentElt;
140 Kokkos::View<TransferStatus *, MemorySpace> status;
141 Kokkos::View<int_t *, MemorySpace> skinParents;
142
144 template <typename Predicate, typename Value, typename OutputFunctor>
145 KOKKOS_FUNCTION void operator()(const Predicate &predicate,
146 const Value &value,
147 const OutputFunctor &out) const {
148 const int predicate_index = ArborX::getData(predicate);
149
150 if (status(predicate_index) == TransferStatus::OUTSIDE) {
151 parentElt(predicate_index) = skinParents(value.index);
152 out(predicate_index);
153 }
154 }
155};
156
159 template <typename Predicate, typename Value, typename OutputFunctor>
160 KOKKOS_FUNCTION void operator()(Predicate, const Value &value,
161 const OutputFunctor &out) const {
162 out(value.index);
163 }
164};
165
169template <typename MemorySpace, int Dim> struct PointCloudNearest {
170 Kokkos::View<coordinates_t **, MemorySpace> points;
171};
172
175template <typename MemorySpace> struct NearestPointProjection {
176 Kokkos::View<fp_t **, MemorySpace> sourceValues;
177 Kokkos::View<fp_t **, MemorySpace> targetValues;
178 Kokkos::View<TransferStatus *, MemorySpace> targetStatus;
179
180 template <typename Predicate, typename Value>
181 KOKKOS_FUNCTION void operator()(const Predicate &predicate,
182 const Value &value) const {
183 const int predicate_index = ArborX::getData(predicate);
184 for (index_t component = 0; component < sourceValues.extent(1);
185 ++component) {
186 targetValues(predicate_index, component) =
187 sourceValues(value.index, component);
188 }
189 targetStatus(predicate_index) = TransferStatus::NEAREST;
190 }
191};
192
196template <typename MemorySpace, int_t Dim> struct PointIntersect {
197 Kokkos::View<coordinates_t **, MemorySpace> points;
198};
199
200} // namespace FiniteElements
201
202} // namespace PACMAN
203
204namespace ArborX {
206template <PACMAN::KokkosViewRank<1> ViewType>
207struct AccessTraits<PACMAN::FiniteElements::PointNearest<ViewType>> {
208 using memory_space = typename ViewType::memory_space;
210 KOKKOS_FUNCTION
211 static size_t size(const Self &self) { return self.points.extent(0); }
212 KOKKOS_FUNCTION
213 static auto get(const Self &self, size_t i) {
214 return attach(nearest(self.points(i), 1), (int)i);
215 }
216};
217
219template <typename MemorySpace, int Dim>
220struct AccessTraits<
221 PACMAN::FiniteElements::PointCloudNearest<MemorySpace, Dim>> {
222 using memory_space = MemorySpace;
224
225 KOKKOS_FUNCTION
226 static size_t size(const Self &self) { return self.points.extent(0); }
227 KOKKOS_FUNCTION
228 static auto get(const Self &self, size_t i) {
229 Point<Dim, PACMAN::coordinates_t> point;
230 for (int k = 0; k < Dim; k++) {
231 point[k] = self.points(i, k);
232 }
233 return attach(nearest(point, 1), (int)i);
234 }
235};
236
238template <typename MemorySpace, int Dim>
239struct AccessTraits<PACMAN::FiniteElements::PointIntersect<MemorySpace, Dim>> {
240 using memory_space = MemorySpace;
242
243 KOKKOS_FUNCTION
244 static size_t size(const Self &self) { return self.points.extent(0); }
245 KOKKOS_FUNCTION
246 static auto get(const Self &self, size_t i) {
247 Point<Dim, PACMAN::coordinates_t> point;
248 for (int k = 0; k < Dim; k++) {
249 point[k] = self.points(i, k);
250 }
251 return attach(intersects(point), (int)i);
252 }
253};
254
255} // namespace ArborX
KOKKOS_FUNCTION bool ApplyNewtonOnElement(const cell_t type, const Kokkos::View< coordinates_t **, ExecSpace > Xcoor, const Kokkos::View< coordinates_t[Dim], ExecSpace > targetPoint, Kokkos::View< fp_t *, ExecSpace > weights, const bool forceEvaluation=false)
Dispatch Newton-based FE inversion to the correct element type.
uint32_t index_t
Definition types.hpp:20
int32_t offset_t
Definition types.hpp:21
int32_t int_t
Definition types.hpp:18
PACMAN::FiniteElements::PointCloudNearest< MemorySpace, Dim > Self
PACMAN::FiniteElements::PointIntersect< MemorySpace, Dim > Self
static KOKKOS_FUNCTION auto get(const Self &self, size_t i)
Generic callback extracting index from ArborX query values.
KOKKOS_FUNCTION void operator()(Predicate, const Value &value, const OutputFunctor &out) const
Callback assigning source value at nearest-neighbor index.
Kokkos::View< fp_t **, MemorySpace > sourceValues
Kokkos::View< fp_t **, MemorySpace > targetValues
Kokkos::View< TransferStatus *, MemorySpace > targetStatus
KOKKOS_FUNCTION void operator()(const Predicate &predicate, const Value &value) const
Predicate wrapper for nearest-neighbor queries over point clouds.
Kokkos::View< coordinates_t **, MemorySpace > points
Point-finite element intersection and interplolation callback.
KOKKOS_FUNCTION auto operator()(const Predicate &predicate, const Value &value) const
ArborX callback: project one outside target point and emit output.
Predicate wrapper for point/box intersection queries.
Kokkos::View< coordinates_t **, MemorySpace > points
Wrapper for nearest-neighbor predicates built from 1D point views.
ArborX callback variant for extrapolation mode.
KOKKOS_FUNCTION void operator()(const Predicate &predicate, const Value &value, const OutputFunctor &out) const
ArborX callback: assign nearest skin parent for outside points.
Kokkos::View< TransferStatus *, MemorySpace > status
Project outside target points onto nearest 3D skin triangle.
Kokkos::View< int_t *, MemorySpace > skinParents
KOKKOS_FUNCTION void operator()(const Predicate &predicate, const Value &value, const OutputFunctor &out) const
ArborX callback: project one outside target point and emit output.
Kokkos::View< coordinates_t **, MemorySpace > targetPointsPtr
typename ExecSpace::memory_space MemorySpace
Kokkos::View< int_t *, MemorySpace > parentElt
Kokkos::View< TransferStatus *, MemorySpace > status