1#ifndef IPPL_FEMINTERPOLATE_H
2#define IPPL_FEMINTERPOLATE_H
14 template <
typename T,
unsigned Dim>
15 KOKKOS_INLINE_FUNCTION
void
22 for (
unsigned d = 0; d < Dim; ++d) {
23 const T s = (x[d] - origin[d]) / hr[d];
24 const size_t e =
static_cast<size_t>(Kokkos::floor(s));
26 xi[d] = s -
static_cast<T
>(e);
31 template<
class View,
class IVec, std::size_t... Is>
32 KOKKOS_INLINE_FUNCTION
33 auto view_ptr_impl(View& v,
const IVec& I, std::index_sequence<Is...>)
34 ->
decltype(&v(I[Is]...)) {
38 template<
int D,
class View,
class IVec>
39 KOKKOS_INLINE_FUNCTION
40 auto view_ptr(View& v,
const IVec& I)
41 ->
decltype(view_ptr_impl(v, I, std::make_index_sequence<D>{})) {
42 return view_ptr_impl(v, I, std::make_index_sequence<D>{});
58 template <
typename AttribIn,
typename Field,
typename PosAttrib,
typename Space,
59 typename policy_type = Kokkos::RangePolicy<typename Field::execution_space>>
61 const PosAttrib& pp,
const Space& space,
62 policy_type iteration_policy)
64 constexpr unsigned Dim = Field::dim;
65 using T =
typename Field::value_type;
66 using view_type =
typename Field::view_type;
67 using mesh_type =
typename Field::Mesh_t;
69 static IpplTimings::TimerRef t = IpplTimings::getTimer(
"assemble_rhs_from_particles(P1)");
71 IpplTimings::startTimer(t);
73 view_type view = f.getView();
76 mesh_type& mesh = f.get_mesh();
78 const auto hr = mesh.getMeshSpacing();
79 const auto origin = mesh.getOrigin();
83 const int nghost = f.getNghost();
85 Field lumpedMass(mesh, layout);
86 space.evaluateLumpedMass(lumpedMass);
88 view_type view_lumpedmass = lumpedMass.getView();
91 auto d_attr = attrib.getView();
92 auto d_pos = pp.getView();
95 auto device_space = space.getDeviceMirror();
97 Kokkos::parallel_for(
"assemble_rhs_from_particles_P1", iteration_policy,
98 KOKKOS_LAMBDA(
const size_t p) {
100 const T val = d_attr(p);
105 locate_element_nd_and_xi<T, Dim>(hr, origin, x, e_nd, xi);
108 const auto dofs = device_space.getGlobalDOFIndices(e_nd);
111 for (
size_t a = 0; a < dofs.dim; ++a) {
112 const size_t local = device_space.getLocalDOFIndex(e_nd, dofs[a]);
113 const T w = device_space.evaluateRefElementShapeFunction(local, xi);
116 const auto v_nd = device_space.getMeshVertexNDIndex(dofs[a]);
119 for (
unsigned d = 0; d < Dim; ++d) {
120 I[d] =
static_cast<size_t>(v_nd[d] - lDom[d].first() + nghost);
122 const T m =
apply(view_lumpedmass, I);
124 Kokkos::atomic_add(view_ptr<Dim>(view, I), val * w / m);
129 static IpplTimings::TimerRef accumulateHaloTimer = IpplTimings::getTimer(
"accumulateHalo");
130 IpplTimings::startTimer(accumulateHaloTimer);
132 IpplTimings::stopTimer(accumulateHaloTimer);
136 template<
class View,
class IVec, std::size_t... Is>
137 KOKKOS_INLINE_FUNCTION
138 decltype(
auto) view_ref_impl(View& v,
const IVec& I, std::index_sequence<Is...>) {
142 template<
int D,
class View,
class IVec>
143 KOKKOS_INLINE_FUNCTION
144 decltype(
auto) view_ref(View& v,
const IVec& I) {
145 return view_ref_impl(v, I, std::make_index_sequence<D>{});
161 template <
typename AttribOut,
typename Field,
typename PosAttrib,
typename Space,
162 typename policy_type = Kokkos::RangePolicy<typename Field::execution_space>>
167 policy_type iteration_policy)
169 constexpr unsigned Dim = Field::dim;
170 using T =
typename AttribOut::value_type;
171 using field_value_type =
typename Field::value_type;
172 using view_type =
typename Field::view_type;
173 using mesh_type =
typename Field::Mesh_t;
175 static IpplTimings::TimerRef timer =
176 IpplTimings::getTimer(
"interpolate_field_to_particles(P1)");
177 IpplTimings::startTimer(timer);
179 view_type view = coeffs.getView();
180 const mesh_type& mesh = coeffs.get_mesh();
182 const auto hr = mesh.getMeshSpacing();
183 const auto origin = mesh.getOrigin();
187 const int nghost = coeffs.getNghost();
190 auto d_pos = pp.getView();
191 auto d_out = attrib_out.getView();
194 auto device_space = space.getDeviceMirror();
196 Kokkos::parallel_for(
"interpolate_to_diracs_P1", iteration_policy,
197 KOKKOS_LAMBDA(
const size_t p) {
203 locate_element_nd_and_xi<T, Dim>(hr, origin, x, e_nd, xi);
205 const auto dofs = device_space.getGlobalDOFIndices(e_nd);
207 field_value_type up = field_value_type(0);
209 for (
size_t a = 0; a < dofs.dim; ++a) {
210 const size_t local = device_space.getLocalDOFIndex(e_nd, dofs[a]);
211 const field_value_type w = device_space.evaluateRefElementShapeFunction(local, xi);
213 const auto v_nd = device_space.getMeshVertexNDIndex(dofs[a]);
215 for (
unsigned d = 0; d < Dim; ++d) {
216 I[d] =
static_cast<size_t>(v_nd[d] - lDom.first()[d] + nghost);
219 up += view_ref<Dim>(view, I) * w;
221 d_out(p) =
static_cast<T
>(up);
238 template <
typename AttribOut,
typename Field,
typename PosAttrib,
typename Space,
239 typename policy_type = Kokkos::RangePolicy<typename Field::execution_space>>
244 policy_type iteration_policy)
246 constexpr unsigned Dim = Field::dim;
247 using T =
typename Field::value_type;
248 using view_type =
typename Field::view_type;
249 using mesh_type =
typename Field::Mesh_t;
251 static IpplTimings::TimerRef timer =
252 IpplTimings::getTimer(
"interpolate_field_to_particles(P1)");
253 IpplTimings::startTimer(timer);
256 const auto firstElementVertexPoints = space.getElementMeshVertexPoints(
Vector<size_t, Dim>(0));
258 space.getInverseTransposeTransformationJacobian(firstElementVertexPoints);
260 view_type view = coeffs.getView();
261 const mesh_type& mesh = coeffs.get_mesh();
263 const auto hr = mesh.getMeshSpacing();
264 const auto origin = mesh.getOrigin();
268 const int nghost = coeffs.getNghost();
271 auto d_pos = pp.getView();
272 auto d_out = attrib_out.getView();
275 auto device_space = space.getDeviceMirror();
277 Kokkos::parallel_for(
"interpolate_to_diracs_P1", iteration_policy,
278 KOKKOS_LAMBDA(
const size_t p) {
284 locate_element_nd_and_xi<T, Dim>(hr, origin, x, e_nd, xi);
286 const auto dofs = device_space.getGlobalDOFIndices(e_nd);
290 for (
size_t a = 0; a < dofs.dim; ++a) {
291 const size_t local = device_space.getLocalDOFIndex(e_nd, dofs[a]);
292 Vector<T, Dim> w = device_space.evaluateRefElementShapeFunctionGradient(local, xi);
295 const auto v_nd = device_space.getMeshVertexNDIndex(dofs[a]);
297 for (
unsigned d = 0; d < Dim; ++d) {
298 I[d] =
static_cast<size_t>(v_nd[d] - lDom.first()[d] + nghost);
303 up += -(view_ref<Dim>(view, I) * w);
Definition FieldLayout.h:166
KOKKOS_INLINE_FUNCTION constexpr decltype(auto) apply(const View &view, const Coords &coords)
Definition IpplOperations.h:64
void interpolate_grad_to_diracs(AttribOut &attrib_out, const Field &coeffs, const PosAttrib &pp, const Space &space, policy_type iteration_policy)
Interpolate a P1 FEM field gradient to particle positions.
Definition FEMInterpolate.hpp:240
void assemble_rhs_from_particles(const AttribIn &attrib, Field &f, const PosAttrib &pp, const Space &space, policy_type iteration_policy)
Assemble a P1 FEM load vector (RHS) from particle attributes.
Definition FEMInterpolate.hpp:60
void interpolate_to_diracs(AttribOut &attrib_out, const Field &coeffs, const PosAttrib &pp, const Space &space, policy_type iteration_policy)
Interpolate a P1 FEM field to particle positions.
Definition FEMInterpolate.hpp:163
KOKKOS_INLINE_FUNCTION void locate_element_nd_and_xi(const Vector< T, Dim > &hr, const Vector< T, Dim > &origin, const Vector< T, Dim > &x, Vector< size_t, Dim > &e_nd, Vector< T, Dim > &xi)
Mapping from global position to element ND index and reference coordinates (xi ∈ [0,...
Definition FEMInterpolate.hpp:16