DINLINE void operator()(DataBoxJ dataBoxJ, const PosType pos, const VelType velocity, const ChargeType charge, const float_X deltaTime) { this->charge = charge; const float3_X deltaPos = float3_X(velocity.x() * deltaTime / cellSize.x(), velocity.y() * deltaTime / cellSize.y(), velocity.z() * deltaTime / cellSize.z()); const PosType oldPos = pos - deltaPos; Line<float3_X> line(oldPos, pos); DataSpace<DIM3> gridShift; /* Define in which direction the particle leaves the cell. * It is not relevant whether the particle leaves the cell via * the positive or negative cell border. * * 0 == stay in cell * 1 == leave cell */ DataSpace<simDim> leaveCell; /* calculate the offset for the virtual coordinate system */ for(int d=0; d<simDim; ++d) { int iStart; int iEnd; constexpr bool isSupportEven = ( supp % 2 == 0 ); RelayPoint< isSupportEven >()( iStart, iEnd, line.m_pos0[d], line.m_pos1[d] ); gridShift[d] = iStart < iEnd ? iStart : iEnd; // integer min function /* particle is leaving the cell */ leaveCell[d] = iStart != iEnd ? 1 : 0; /* shift the particle position to the virtual coordinate system */ line.m_pos0[d] -= gridShift[d]; line.m_pos1[d] -= gridShift[d]; } /* shift current field to the virtual coordinate system */ auto cursorJ = dataBoxJ.shift(gridShift).toCursor(); /** * \brief the following three calls separate the 3D current deposition * into three independent 1D calls, each for one direction and current component. * Therefore the coordinate system has to be rotated so that the z-direction * is always specific. */ using namespace cursor::tools; cptCurrent1D( DataSpace<simDim>(leaveCell.y(),leaveCell.z(),leaveCell.x()), twistVectorFieldAxes<PMacc::math::CT::Int < 1, 2, 0 > >(cursorJ), rotateOrigin < 1, 2, 0 > (line), cellSize.x() ); cptCurrent1D( DataSpace<simDim>(leaveCell.z(),leaveCell.x(),leaveCell.y()), twistVectorFieldAxes<PMacc::math::CT::Int < 2, 0, 1 > >(cursorJ), rotateOrigin < 2, 0, 1 > (line), cellSize.y() ); cptCurrent1D( leaveCell, cursorJ, line, cellSize.z() ); }