DINLINE uint32_t numNewParticles(T_Acc const & acc, FrameType& ionFrame, int localIdx) { /* alias for the single macro-particle */ auto particle = ionFrame[localIdx]; /* particle position, used for field-to-particle interpolation */ floatD_X pos = particle[position_]; const int particleCellIdx = particle[localCellIdx_]; /* multi-dim coordinate of the local cell inside the super cell */ DataSpace<TVec::dim> localCell(DataSpaceOperations<TVec::dim>::template map<TVec > (particleCellIdx)); /* interpolation of E- */ const picongpu::traits::FieldPosition<typename fields::Solver::NummericalCellType, FieldE> fieldPosE; ValueType_E eField = Field2ParticleInterpolation() (cachedE.shift(localCell).toCursor(), pos, fieldPosE()); /* and B-field on the particle position */ const picongpu::traits::FieldPosition<typename fields::Solver::NummericalCellType, FieldB> fieldPosB; ValueType_B bField = Field2ParticleInterpolation() (cachedB.shift(localCell).toCursor(), pos, fieldPosB()); /* define number of bound macro electrons before ionization */ float_X prevBoundElectrons = particle[boundElectrons_]; IonizationAlgorithm ionizeAlgo; /* determine number of new macro electrons to be created */ uint32_t newMacroElectrons = ionizeAlgo( bField, eField, particle, this->randomGen(acc) ); return newMacroElectrons; }
/** Functor implementation * * @param ionFrame reference to frame of the to-be-ionized particles * @param localIdx local (linear) index in super cell / frame * @param numNewFreeMacroElectrons reference to variable for each * thread that stores the number of macro electrons to be * created during the current time step */ DINLINE void operator()(FrameType& ionFrame, int localIdx, unsigned int& numNewFreeMacroElectrons) { /* alias for the single macro-particle */ auto particle = ionFrame[localIdx]; /* particle position, used for field-to-particle interpolation */ floatD_X const pos = particle[position_]; int const particleCellIdx = particle[localCellIdx_]; /* multi-dim coordinate of the local cell inside the super cell */ DataSpace<SuperCellSize::dim> localCell(DataSpaceOperations<SuperCellSize::dim>::template map<SuperCellSize > (particleCellIdx)); /* interpolation of density */ const fieldSolver::numericalCellType::traits::FieldPosition<FieldTmp> fieldPosRho; ValueType_Rho densityV = Field2ParticleInterpolation() (cachedRho.shift(localCell).toCursor(), pos, fieldPosRho()); /* and energy density field on the particle position */ const fieldSolver::numericalCellType::traits::FieldPosition<FieldTmp> fieldPosEne; ValueType_Ene kinEnergyV = Field2ParticleInterpolation() (cachedEne.shift(localCell).toCursor(), pos, fieldPosEne()); /* density in sim units */ float_X const density = densityV[0]; /* energy density in sim units */ float_X const kinEnergyDensity = kinEnergyV[0]; /* Returns the new number of bound electrons for an integer number of macro electrons */ IonizationAlgorithm ionizeAlgo; numNewFreeMacroElectrons = ionizeAlgo( kinEnergyDensity, density, particle, this->randomGen() ); /** ionization of the ion by reducing the number of bound electrons * * optimization: only accesses global memory if the charge * state did really change * * @warning substracting a float from a float can potentially * create a negative boundElectrons number for the ion, * see #1850 for details */ if( numNewFreeMacroElectrons > 0u ) particle[ boundElectrons_ ] -= float_X( numNewFreeMacroElectrons ); }