void PusherPonderomotivePositionBorisV::operator()( Particles &particles, SmileiMPI *smpi, int istart, int iend, int ithread, int ipart_ref ) { /////////// not vectorized std::vector<double> *Phi_mpart = &( smpi->dynamics_PHI_mpart[ithread] ); std::vector<double> *GradPhi_mpart = &( smpi->dynamics_GradPHI_mpart[ithread] ); double charge_sq_over_mass_dts4, charge_over_mass_sq; double gamma0, gamma0_sq, gamma_ponderomotive; double pxsm, pysm, pzsm; //int* cell_keys; double *momentum[3]; for( int i = 0 ; i<3 ; i++ ) { momentum[i] = &( particles.momentum( i, 0 ) ); } double *position[3]; for( int i = 0 ; i<nDim_ ; i++ ) { position[i] = &( particles.position( i, 0 ) ); } #ifdef __DEBUG double *position_old[3]; for( int i = 0 ; i<nDim_ ; i++ ) { position_old[i] = &( particles.position_old( i, 0 ) ); } #endif short *charge = &( particles.charge( 0 ) ); int nparts = GradPhi_mpart->size()/3; double *Phi_m = &( ( *Phi_mpart )[0*nparts] ); double *GradPhi_mx = &( ( *GradPhi_mpart )[0*nparts] ); double *GradPhi_my = &( ( *GradPhi_mpart )[1*nparts] ); double *GradPhi_mz = &( ( *GradPhi_mpart )[2*nparts] ); //particles.cell_keys.resize(nparts); //cell_keys = &( particles.cell_keys[0]); #pragma omp simd for( int ipart=istart ; ipart<iend; ipart++ ) { // begin loop on particles // ! ponderomotive force is proportional to charge squared and the field is divided by 4 instead of 2 charge_sq_over_mass_dts4 = ( double )( charge[ipart] )*( double )( charge[ipart] )*one_over_mass_*dts4; // (charge over mass)^2 charge_over_mass_sq = ( double )( charge[ipart] )*one_over_mass_*( charge[ipart] )*one_over_mass_; // compute initial ponderomotive gamma gamma0_sq = 1. + momentum[0][ipart]*momentum[0][ipart] + momentum[1][ipart]*momentum[1][ipart] + momentum[2][ipart]*momentum[2][ipart] + ( *( Phi_m+ipart-ipart_ref ) )*charge_over_mass_sq; gamma0 = sqrt( gamma0_sq ) ; // ponderomotive force for ponderomotive gamma advance (Grad Phi is interpolated in time, hence the division by 2) pxsm = charge_sq_over_mass_dts4 * ( *( GradPhi_mx+ipart-ipart_ref ) ) / gamma0_sq ; pysm = charge_sq_over_mass_dts4 * ( *( GradPhi_my+ipart-ipart_ref ) ) / gamma0_sq ; pzsm = charge_sq_over_mass_dts4 * ( *( GradPhi_mz+ipart-ipart_ref ) ) / gamma0_sq ; // update of gamma ponderomotive gamma_ponderomotive = gamma0 + ( pxsm*momentum[0][ipart]+pysm*momentum[1][ipart]+pzsm*momentum[2][ipart] ) ; // Move the particle #ifdef __DEBUG for( int i = 0 ; i<nDim_ ; i++ ) { position_old[i][ipart] = position[i][ipart]; } #endif for( int i = 0 ; i<nDim_ ; i++ ) { position[i][ipart] += dt*momentum[i][ipart]/gamma_ponderomotive; } } // end loop on particles //#pragma omp simd //for (int ipart=0 ; ipart<nparts; ipart++ ) { // // for ( int i = 0 ; i<nDim_ ; i++ ){ // cell_keys[ipart] *= nspace[i]; // cell_keys[ipart] += round( (position[i][ipart]-min_loc_vec[i]) * dx_inv_[i] ); // } // //} // end loop on particles }
void PusherBorisV::operator()( Particles &particles, SmileiMPI *smpi, int istart, int iend, int ithread, int ipart_ref ) { std::vector<double> *Epart = &( smpi->dynamics_Epart[ithread] ); std::vector<double> *Bpart = &( smpi->dynamics_Bpart[ithread] ); double *invgf = &( smpi->dynamics_invgf[ithread][0] ); double charge_over_mass_dts2; double inv_det_T, Tx, Ty, Tz; double local_invgf; //int IX; //int* cell_keys; double *momentum[3]; for( int i = 0 ; i<3 ; i++ ) { momentum[i] = &( particles.momentum( i, 0 ) ); } double *position[3]; for( int i = 0 ; i<nDim_ ; i++ ) { position[i] = &( particles.position( i, 0 ) ); } #ifdef __DEBUG double *position_old[3]; for( int i = 0 ; i<nDim_ ; i++ ) { position_old[i] = &( particles.position_old( i, 0 ) ); } #endif short *charge = &( particles.charge( 0 ) ); int nparts = Epart->size()/3; double *Ex = &( ( *Epart )[0*nparts] ); double *Ey = &( ( *Epart )[1*nparts] ); double *Ez = &( ( *Epart )[2*nparts] ); double *Bx = &( ( *Bpart )[0*nparts] ); double *By = &( ( *Bpart )[1*nparts] ); double *Bz = &( ( *Bpart )[2*nparts] ); //particles.cell_keys.resize(nparts); //cell_keys = &( particles.cell_keys[0]); double dcharge[nparts]; #pragma omp simd for( int ipart=istart ; ipart<iend; ipart++ ) { dcharge[ipart] = ( double )( charge[ipart] ); } #pragma omp simd for( int ipart=istart ; ipart<iend; ipart++ ) { double psm[3], um[3]; charge_over_mass_dts2 = dcharge[ipart]*one_over_mass_*dts2; // init Half-acceleration in the electric field psm[0] = charge_over_mass_dts2*( *( Ex+ipart-ipart_ref ) ); psm[1] = charge_over_mass_dts2*( *( Ey+ipart-ipart_ref ) ); psm[2] = charge_over_mass_dts2*( *( Ez+ipart-ipart_ref ) ); //(*this)(particles, ipart, (*Epart)[ipart], (*Bpart)[ipart] , (*invgf)[ipart]); um[0] = momentum[0][ipart] + psm[0]; um[1] = momentum[1][ipart] + psm[1]; um[2] = momentum[2][ipart] + psm[2]; // Rotation in the magnetic field local_invgf = charge_over_mass_dts2 / sqrt( 1.0 + um[0]*um[0] + um[1]*um[1] + um[2]*um[2] ); Tx = local_invgf * ( *( Bx+ipart-ipart_ref ) ); Ty = local_invgf * ( *( By+ipart-ipart_ref ) ); Tz = local_invgf * ( *( Bz+ipart-ipart_ref ) ); inv_det_T = 1.0/( 1.0+Tx*Tx+Ty*Ty+Tz*Tz ); psm[0] += ( ( 1.0+Tx*Tx-Ty*Ty-Tz*Tz )* um[0] + 2.0*( Tx*Ty+Tz )* um[1] + 2.0*( Tz*Tx-Ty )* um[2] )*inv_det_T; psm[1] += ( 2.0*( Tx*Ty-Tz )* um[0] + ( 1.0-Tx*Tx+Ty*Ty-Tz*Tz )* um[1] + 2.0*( Ty*Tz+Tx )* um[2] )*inv_det_T; psm[2] += ( 2.0*( Tz*Tx+Ty )* um[0] + 2.0*( Ty*Tz-Tx )* um[1] + ( 1.0-Tx*Tx-Ty*Ty+Tz*Tz )* um[2] )*inv_det_T; // finalize Half-acceleration in the electric field local_invgf = 1. / sqrt( 1.0 + psm[0]*psm[0] + psm[1]*psm[1] + psm[2]*psm[2] ); invgf[ipart-ipart_ref] = local_invgf; momentum[0][ipart] = psm[0]; momentum[1][ipart] = psm[1]; momentum[2][ipart] = psm[2]; // Move the particle #ifdef __DEBUG for( int i = 0 ; i<nDim_ ; i++ ) { position_old[i][ipart] = position[i][ipart]; } #endif local_invgf *= dt; for( int i = 0 ; i<nDim_ ; i++ ) { position[i][ipart] += psm[i]*local_invgf; } } // This is temporarily moved to SpeciesV.cpp //#pragma omp simd //for (int ipart=istart ; ipart<iend; ipart++ ) { // // for ( int i = 0 ; i<nDim_ ; i++ ){ // cell_keys[ipart] *= nspace[i]; // cell_keys[ipart] += round( (position[i][ipart]-min_loc_vec[i]) * dx_inv_[i] ); // } // //} }