diff --git a/include/picongpu/algorithms/AssignedTrilinearInterpolation.hpp b/include/picongpu/algorithms/AssignedTrilinearInterpolation.hpp index f002548900..c4d3a61dd1 100644 --- a/include/picongpu/algorithms/AssignedTrilinearInterpolation.hpp +++ b/include/picongpu/algorithms/AssignedTrilinearInterpolation.hpp @@ -20,7 +20,6 @@ #pragma once #include -#include #include #include @@ -54,9 +53,11 @@ namespace picongpu * * @tparam T_begin lower margin for interpolation * @tparam T_end upper margin for interpolation + * @tparam T_FieldAccessorFunctor type of the field access functor supporting a initializer list of simdDim + * indices * @tparam T_AssignmentFunction type of shape functors * - * @param cursor cursor pointing to the field + * @param fieldAccess field access method pointing to the particle located cell * @param shapeFunctors Array with d shape functors, where d is the dimensionality of the field represented by * cursor. The shape functor must have the interface to call * `operator()(relative_grid_point)` and return the assignment value for the given grid @@ -67,14 +68,14 @@ namespace picongpu * * @{ */ - template + template HDINLINE static auto interpolate( - const T_Cursor& cursor, - const pmacc::memory::Array& shapeFunctors) + T_FieldAccessorFunctor const& fieldAccess, + pmacc::memory::Array const& shapeFunctors) { [[maybe_unused]] constexpr auto iterations = T_end - T_begin + 1; - using type = decltype(*cursor(0, 0, 0) * shapeFunctors[0](0)); + using type = decltype(fieldAccess({0, 0, 0}) * shapeFunctors[0](0)); /* The implementation assumes that x is the fastest moving index to iterate over contiguous memory * e.g. a row, to optimize memory fetch operations. @@ -93,7 +94,7 @@ namespace picongpu /* a form factor is the "amount of particle" that is affected by this cell * so we have to sum over: cell_value * form_factor */ - result_x += *cursor(x, y, z) * shapeFunctors[0](x); + result_x += fieldAccess({x, y, z}) * shapeFunctors[0](x); result_y += result_x * shapeFunctors[1](y); } @@ -103,14 +104,14 @@ namespace picongpu } /** Implementation for 2D position*/ - template + template HDINLINE static auto interpolate( - T_Cursor const& cursor, + T_FieldAccessorFunctor const& fieldAccess, const pmacc::memory::Array& shapeFunctors) { [[maybe_unused]] constexpr int iterations = T_end - T_begin + 1; - using type = decltype(*cursor(0, 0) * shapeFunctors[0](0)); + using type = decltype(fieldAccess({0, 0}) * shapeFunctors[0](0)); /* The implementation assumes that x is the fastest moving index to iterate over contiguous memory * e.g. a row, to optimize memory fetch operations. */ @@ -123,7 +124,7 @@ namespace picongpu for(int x = T_begin; x <= T_end; ++x) // a form factor is the "amount of particle" that is affected by this cell // so we have to sum over: cell_value * form_factor - result_x += *cursor(x, y) * shapeFunctors[0](x); + result_x += fieldAccess({x, y}) * shapeFunctors[0](x); result_y += result_x * shapeFunctors[1](y); } diff --git a/include/picongpu/algorithms/FieldToParticleInterpolation.hpp b/include/picongpu/algorithms/FieldToParticleInterpolation.hpp index 95ae030ae5..2015be788f 100644 --- a/include/picongpu/algorithms/FieldToParticleInterpolation.hpp +++ b/include/picongpu/algorithms/FieldToParticleInterpolation.hpp @@ -26,8 +26,6 @@ #include "picongpu/particles/shapes.hpp" #include -#include -#include #include namespace picongpu @@ -95,28 +93,31 @@ namespace picongpu return result; }; - template - HDINLINE typename Cursor::ValueType operator()( - Cursor field, - const floatD_X& particlePos, - const VecVector& fieldPos) + template + HDINLINE auto operator()(T_FieldDataBox const& field, const floatD_X& particlePos, const VecVector& fieldPos) { /**\brief: * The following calls seperate the vector interpolation into * independent scalar interpolations. */ using Supports = typename pmacc::math::CT::make_Int::type; + using ResultType = typename T_FieldDataBox::ValueType; - typename Cursor::ValueType result; - PMACC_UNROLL(Cursor::ValueType::dim) - for(uint32_t i = 0; i < Cursor::ValueType::dim; i++) + ResultType result; + PMACC_UNROLL(ResultType::dim) + for(uint32_t i = 0; i < ResultType::dim; i++) { - auto fieldComponent - = pmacc::cursor::make_FunctorCursor(field, pmacc::algorithm::functor::GetComponent(i)); + // work on a copy to shift the field for each loop round separate + auto shiftedField = field; floatD_X particlePosShifted = particlePos; - ShiftCoordinateSystem()(fieldComponent, particlePosShifted, fieldPos[i]); + ShiftCoordinateSystem()(shiftedField, particlePosShifted, fieldPos[i]); + + auto accessFunctor = [&](DataSpace const& idx) constexpr + { + return shiftedField(idx)[i]; + }; result[i] = InterpolationMethod::template interpolate( - fieldComponent, + accessFunctor, getShapeFunctors(particlePosShifted)); } diff --git a/include/picongpu/algorithms/ShiftCoordinateSystem.hpp b/include/picongpu/algorithms/ShiftCoordinateSystem.hpp index 04a0fad8c4..aef47758c3 100644 --- a/include/picongpu/algorithms/ShiftCoordinateSystem.hpp +++ b/include/picongpu/algorithms/ShiftCoordinateSystem.hpp @@ -42,8 +42,8 @@ namespace picongpu template struct AssignToDim { - template - HDINLINE void operator()(T_Type& cursor, T_Vector& pos, const T_FieldType& fieldPos) + template + HDINLINE void operator()(T_DataBox& dataBox, T_Vector& pos, const T_FieldType& fieldPos) { const uint32_t dim = T_Vector::dim; using ValueType = typename T_Vector::type; @@ -59,7 +59,7 @@ namespace picongpu const ValueType v_pos = pos[component] - fieldPos[component]; DataSpace intShift; intShift[component] = GetOffsetToStaticShapeSystem()(v_pos); - cursor = cursor(intShift); + dataBox = dataBox.shift(intShift); pos[component] = v_pos - ValueType(intShift[component]); } }; @@ -73,8 +73,8 @@ namespace picongpu { /** shift to new coordinate system * - * shift cursor and vector to new coordinate system - * @param[in,out] cursor cursor to memory + * shift DataBox and vector to new coordinate system + * @param[in,out] dataBox DataBox pointing to the particle located cell * @param[in,out] vector short vector with coordinates in old system * - defined for [0.0;1.0) per dimension * @param fieldPos vector with relative coordinates for shift ( value range [0.0;0.5] ) @@ -85,19 +85,16 @@ namespace picongpu * - Even Support: vector is always [0.0;1.0) * - Odd Support: vector is always [-0.5;0.5) */ - template - HDINLINE void operator()(T_Cursor& cursor, T_Vector& vector, const T_FieldType& fieldPos) + template + HDINLINE void operator()(T_DataBox& dataBox, T_Vector& vector, const T_FieldType& fieldPos) { - /** \todo check if a static assert on - * "T_Cursor::dim" == T_Vector::dim == T_FieldType::dim is possible - * and does not waste registers */ - const uint32_t dim = T_Vector::dim; + constexpr uint32_t dim = T_DataBox::Dim; using Size = boost::mpl::vector1>; using CombiTypes = typename AllCombinations::type; meta::ForEach> shift; - shift(cursor, vector, fieldPos); + shift(dataBox, vector, fieldPos); } }; diff --git a/include/picongpu/particles/Particles.kernel b/include/picongpu/particles/Particles.kernel index 3270e804cc..4c3f017fb1 100644 --- a/include/picongpu/particles/Particles.kernel +++ b/include/picongpu/particles/Particles.kernel @@ -301,12 +301,10 @@ namespace picongpu const traits::FieldPosition fieldPosE; const traits::FieldPosition fieldPosB; - auto functorEfield = CreateInterpolationForPusher()( - eBox.shift(localCell).toCursor(), - fieldPosE()); - auto functorBfield = CreateInterpolationForPusher()( - bBox.shift(localCell).toCursor(), - fieldPosB()); + auto functorEfield + = CreateInterpolationForPusher()(eBox.shift(localCell), fieldPosE()); + auto functorBfield + = CreateInterpolationForPusher()(bBox.shift(localCell), fieldPosB()); /** @todo this functor should only manipulate the momentum and all changes * in position and cell below need to go into a separate kernel diff --git a/include/picongpu/particles/interpolationMemoryPolicy/ShiftToValidRange.hpp b/include/picongpu/particles/interpolationMemoryPolicy/ShiftToValidRange.hpp index 66d39b5800..0eef70d8f9 100644 --- a/include/picongpu/particles/interpolationMemoryPolicy/ShiftToValidRange.hpp +++ b/include/picongpu/particles/interpolationMemoryPolicy/ShiftToValidRange.hpp @@ -35,7 +35,7 @@ namespace picongpu HDINLINE T_MemoryType memory(const T_MemoryType& mem, const T_PosType& pos) const { const T_PosType pos_floor = math::floor(pos); - return mem(precisionCast(pos_floor)); + return mem.shift(precisionCast(pos_floor)); } template diff --git a/include/picongpu/particles/ionization/byCollision/ThomasFermi/ThomasFermi_Impl.hpp b/include/picongpu/particles/ionization/byCollision/ThomasFermi/ThomasFermi_Impl.hpp index dfecb4e63a..495c87cb34 100644 --- a/include/picongpu/particles/ionization/byCollision/ThomasFermi/ThomasFermi_Impl.hpp +++ b/include/picongpu/particles/ionization/byCollision/ThomasFermi/ThomasFermi_Impl.hpp @@ -248,11 +248,11 @@ namespace picongpu /* interpolation of density */ const picongpu::traits::FieldPosition fieldPosRho; ValueType_Rho densityV - = Field2ParticleInterpolation()(cachedRho.shift(localCell).toCursor(), pos, fieldPosRho()); + = Field2ParticleInterpolation()(cachedRho.shift(localCell), pos, fieldPosRho()); /* and energy density field on the particle position */ const picongpu::traits::FieldPosition fieldPosEne; ValueType_Ene kinEnergyV - = Field2ParticleInterpolation()(cachedEne.shift(localCell).toCursor(), pos, fieldPosEne()); + = Field2ParticleInterpolation()(cachedEne.shift(localCell), pos, fieldPosEne()); /* density in sim units */ float_X const density = densityV[0]; diff --git a/include/picongpu/particles/ionization/byField/ADK/ADK_Impl.hpp b/include/picongpu/particles/ionization/byField/ADK/ADK_Impl.hpp index d23d9fc8ea..02c305d830 100644 --- a/include/picongpu/particles/ionization/byField/ADK/ADK_Impl.hpp +++ b/include/picongpu/particles/ionization/byField/ADK/ADK_Impl.hpp @@ -191,12 +191,10 @@ namespace picongpu DataSpaceOperations::template map(particleCellIdx)); /* interpolation of E- */ const picongpu::traits::FieldPosition fieldPosE; - ValueType_E eField - = Field2ParticleInterpolation()(cachedE.shift(localCell).toCursor(), pos, fieldPosE()); + ValueType_E eField = Field2ParticleInterpolation()(cachedE.shift(localCell), pos, fieldPosE()); /* and B-field on the particle position */ const picongpu::traits::FieldPosition fieldPosB; - ValueType_B bField - = Field2ParticleInterpolation()(cachedB.shift(localCell).toCursor(), pos, fieldPosB()); + ValueType_B bField = Field2ParticleInterpolation()(cachedB.shift(localCell), pos, fieldPosB()); IonizationAlgorithm ionizeAlgo; /* determine number of new macro electrons to be created and energy used for ionization */ diff --git a/include/picongpu/particles/ionization/byField/BSI/BSI_Impl.hpp b/include/picongpu/particles/ionization/byField/BSI/BSI_Impl.hpp index 7015248408..43d0a7cba1 100644 --- a/include/picongpu/particles/ionization/byField/BSI/BSI_Impl.hpp +++ b/include/picongpu/particles/ionization/byField/BSI/BSI_Impl.hpp @@ -181,8 +181,7 @@ namespace picongpu DataSpaceOperations::template map(particleCellIdx)); /* interpolation of E */ const picongpu::traits::FieldPosition fieldPosE; - ValueType_E eField - = Field2ParticleInterpolation()(cachedE.shift(localCell).toCursor(), pos, fieldPosE()); + ValueType_E eField = Field2ParticleInterpolation()(cachedE.shift(localCell), pos, fieldPosE()); /* this is the point where actual ionization takes place */ IonizationAlgorithm ionizeAlgo{}; diff --git a/include/picongpu/particles/ionization/byField/Keldysh/Keldysh_Impl.hpp b/include/picongpu/particles/ionization/byField/Keldysh/Keldysh_Impl.hpp index d5c1bf2b83..58da2ff0b3 100644 --- a/include/picongpu/particles/ionization/byField/Keldysh/Keldysh_Impl.hpp +++ b/include/picongpu/particles/ionization/byField/Keldysh/Keldysh_Impl.hpp @@ -191,12 +191,10 @@ namespace picongpu DataSpaceOperations::template map(particleCellIdx)); /* interpolation of E- */ const picongpu::traits::FieldPosition fieldPosE; - ValueType_E eField - = Field2ParticleInterpolation()(cachedE.shift(localCell).toCursor(), pos, fieldPosE()); + ValueType_E eField = Field2ParticleInterpolation()(cachedE.shift(localCell), pos, fieldPosE()); /* and B-field on the particle position */ const picongpu::traits::FieldPosition fieldPosB; - ValueType_B bField - = Field2ParticleInterpolation()(cachedB.shift(localCell).toCursor(), pos, fieldPosB()); + ValueType_B bField = Field2ParticleInterpolation()(cachedB.shift(localCell), pos, fieldPosB()); IonizationAlgorithm ionizeAlgo; /* determine number of new macro electrons to be created and energy used for ionization */