diff options
author | 2020-01-29 14:57:30 -0700 | |
---|---|---|
committer | 2020-01-29 14:57:30 -0700 | |
commit | bc90c8b0947ee30c127aa8a960f1c4fe25036bf7 (patch) | |
tree | b80890d933aecc473ed70ccf37644bc5838dfe83 /Source/Particles/Collision | |
parent | 3a69c525d61945db6a3bd74dd4c7b1c60c08cf65 (diff) | |
download | WarpX-bc90c8b0947ee30c127aa8a960f1c4fe25036bf7.tar.gz WarpX-bc90c8b0947ee30c127aa8a960f1c4fe25036bf7.tar.zst WarpX-bc90c8b0947ee30c127aa8a960f1c4fe25036bf7.zip |
Make collision doable for 2D-XZ.
Diffstat (limited to 'Source/Particles/Collision')
-rw-r--r-- | Source/Particles/Collision/CollisionType.H | 2 | ||||
-rw-r--r-- | Source/Particles/Collision/CollisionType.cpp | 94 | ||||
-rw-r--r-- | Source/Particles/Collision/ComputeTemperature.H | 2 | ||||
-rw-r--r-- | Source/Particles/Collision/ElasticCollisionPerez.H | 10 | ||||
-rw-r--r-- | Source/Particles/Collision/ShuffleFisherYates.H | 6 | ||||
-rw-r--r-- | Source/Particles/Collision/UpdateMomentumPerezElastic.H | 68 |
6 files changed, 94 insertions, 88 deletions
diff --git a/Source/Particles/Collision/CollisionType.H b/Source/Particles/Collision/CollisionType.H index 29fdfb029..89baac968 100644 --- a/Source/Particles/Collision/CollisionType.H +++ b/Source/Particles/Collision/CollisionType.H @@ -42,4 +42,4 @@ public: }; -#endif // WARPX_PARTICLES_COLLISION_COLLISIONTYPE_H_ +#endif ///< WARPX_PARTICLES_COLLISION_COLLISIONTYPE_H_ diff --git a/Source/Particles/Collision/CollisionType.cpp b/Source/Particles/Collision/CollisionType.cpp index a5bb1482f..f9fc67c00 100644 --- a/Source/Particles/Collision/CollisionType.cpp +++ b/Source/Particles/Collision/CollisionType.cpp @@ -14,20 +14,18 @@ CollisionType::CollisionType( std::string const collision_name) { -#if defined WARPX_DIM_XZ - amrex::Abort("Collisions only work in 3D geometry for now."); -#elif defined WARPX_DIM_RZ + #if defined WARPX_DIM_RZ amrex::Abort("Collisions only work in Cartesian geometry for now."); -#endif + #endif - // read collision species + /// read collision species std::vector<std::string> collision_species; amrex::ParmParse pp(collision_name); pp.getarr("species", collision_species); AMREX_ALWAYS_ASSERT_WITH_MESSAGE(collision_species.size() == 2, "Collision species must name exactly two species."); - // default Coulomb log, if < 0, will be computed automatically + /// default Coulomb log, if < 0, will be computed automatically m_CoulombLog = -1.0; pp.query("CoulombLog", m_CoulombLog); @@ -47,7 +45,7 @@ CollisionType::CollisionType( } using namespace amrex; -// Define shortcuts for frequently-used type names +/// Define shortcuts for frequently-used type names using ParticleType = WarpXParticleContainer::ParticleType; using ParticleTileType = WarpXParticleContainer::ParticleTileType; using ParticleBins = DenseBins<ParticleType>; @@ -61,22 +59,22 @@ namespace { findParticlesInEachCell( int const lev, MFIter const& mfi, ParticleTileType const& ptile) { - // Extract particle structures for this tile + /// Extract particle structures for this tile int const np = ptile.numParticles(); ParticleType const* particle_ptr = ptile.GetArrayOfStructs()().data(); - // Extract box properties + /// Extract box properties Geometry const& geom = WarpX::GetInstance().Geom(lev); Box const& cbx = mfi.tilebox(IntVect::TheZeroVector()); //Cell-centered box const auto lo = lbound(cbx); const auto dxi = geom.InvCellSizeArray(); const auto plo = geom.ProbLoArray(); - // Find particles that are in each cell ; - // results are stored in the object `bins`. + /// Find particles that are in each cell; + /// results are stored in the object `bins`. ParticleBins bins; bins.build(np, particle_ptr, cbx, - // Pass lambda function that returns the cell index + /// Pass lambda function that returns the cell index [=] AMREX_GPU_HOST_DEVICE (const ParticleType& p) noexcept -> IntVect { return IntVect(AMREX_D_DECL((p.pos(0)-plo[0])*dxi[0] - lo.x, @@ -105,19 +103,19 @@ void CollisionType::doCoulombCollisionsWithinTile bool const isSameSpecies, Real const CoulombLog ) { - if ( isSameSpecies ) // species_1 == species_2 + if ( isSameSpecies ) /// species_1 == species_2 { - // Extract particles in the tile that `mfi` points to + /// Extract particles in the tile that `mfi` points to ParticleTileType& ptile_1 = species_1->ParticlesAt(lev, mfi); - // Find the particles that are in each cell of this tile + /// Find the particles that are in each cell of this tile ParticleBins bins_1 = findParticlesInEachCell( lev, mfi, ptile_1 ); - // Loop over cells, and collide the particles in each cell + /// Loop over cells, and collide the particles in each cell - // Extract low-level data + /// Extract low-level data int const n_cells = bins_1.numBins(); - // - Species 1 + /// - Species 1 auto& soa_1 = ptile_1.GetStructOfArrays(); ParticleReal * const AMREX_RESTRICT ux_1 = soa_1.GetRealData(PIdx::ux).data(); @@ -134,26 +132,30 @@ void CollisionType::doCoulombCollisionsWithinTile const Real dt = WarpX::GetInstance().getdt(lev); Geometry const& geom = WarpX::GetInstance().Geom(lev); - const Real dV = geom.CellSize(0)*geom.CellSize(1)*geom.CellSize(2); + #if (AMREX_SPACEDIM == 2) + auto dV = geom.CellSize(0) * geom.CellSize(1); + #elif (AMREX_SPACEDIM == 3) + auto dV = geom.CellSize(0) * geom.CellSize(1) * geom.CellSize(2); + #endif - // Loop over cells + /// Loop over cells amrex::ParallelFor( n_cells, [=] AMREX_GPU_DEVICE (int i_cell) noexcept { - // The particles from species1 that are in the cell `i_cell` are - // given by the `indices_1[cell_start_1:cell_stop_1]` + /// The particles from species1 that are in the cell `i_cell` are + /// given by the `indices_1[cell_start_1:cell_stop_1]` index_type const cell_start_1 = cell_offsets_1[i_cell]; index_type const cell_stop_1 = cell_offsets_1[i_cell+1]; index_type const cell_half_1 = (cell_start_1+cell_stop_1)/2; - // Do not collide if there is only one particle in the cell + /// Do not collide if there is only one particle in the cell if ( cell_stop_1 - cell_start_1 >= 2 ) { - // shuffle + /// shuffle ShuffleFisherYates( indices_1, cell_start_1, cell_half_1 ); - // Call the function in order to perform collisions + /// Call the function in order to perform collisions ElasticCollisionPerez( cell_start_1, cell_half_1, cell_half_1, cell_stop_1, @@ -165,21 +167,21 @@ void CollisionType::doCoulombCollisionsWithinTile } ); } - else // species_1 != species_2 + else /// species_1 != species_2 { - // Extract particles in the tile that `mfi` points to + /// Extract particles in the tile that `mfi` points to ParticleTileType& ptile_1 = species_1->ParticlesAt(lev, mfi); ParticleTileType& ptile_2 = species_2->ParticlesAt(lev, mfi); - // Find the particles that are in each cell of this tile + /// Find the particles that are in each cell of this tile ParticleBins bins_1 = findParticlesInEachCell( lev, mfi, ptile_1 ); ParticleBins bins_2 = findParticlesInEachCell( lev, mfi, ptile_2 ); - // Loop over cells, and collide the particles in each cell + /// Loop over cells, and collide the particles in each cell - // Extract low-level data + /// Extract low-level data int const n_cells = bins_1.numBins(); - // - Species 1 + /// - Species 1 auto& soa_1 = ptile_1.GetStructOfArrays(); ParticleReal * const AMREX_RESTRICT ux_1 = soa_1.GetRealData(PIdx::ux).data(); @@ -193,7 +195,7 @@ void CollisionType::doCoulombCollisionsWithinTile index_type const* cell_offsets_1 = bins_1.offsetsPtr(); Real q1 = species_1->getCharge(); Real m1 = species_1->getMass(); - // - Species 2 + /// - Species 2 auto& soa_2 = ptile_2.GetStructOfArrays(); Real* ux_2 = soa_2.GetRealData(PIdx::ux).data(); Real* uy_2 = soa_2.GetRealData(PIdx::uy).data(); @@ -206,33 +208,37 @@ void CollisionType::doCoulombCollisionsWithinTile const Real dt = WarpX::GetInstance().getdt(lev); Geometry const& geom = WarpX::GetInstance().Geom(lev); - const Real dV = geom.CellSize(0)*geom.CellSize(1)*geom.CellSize(2); + #if (AMREX_SPACEDIM == 2) + auto dV = geom.CellSize(0) * geom.CellSize(1); + #elif (AMREX_SPACEDIM == 3) + auto dV = geom.CellSize(0) * geom.CellSize(1) * geom.CellSize(2); + #endif - // Loop over cells + /// Loop over cells amrex::ParallelFor( n_cells, [=] AMREX_GPU_DEVICE (int i_cell) noexcept { - // The particles from species1 that are in the cell `i_cell` are - // given by the `indices_1[cell_start_1:cell_stop_1]` + /// The particles from species1 that are in the cell `i_cell` are + /// given by the `indices_1[cell_start_1:cell_stop_1]` index_type const cell_start_1 = cell_offsets_1[i_cell]; index_type const cell_stop_1 = cell_offsets_1[i_cell+1]; - // Same for species 2 + /// Same for species 2 index_type const cell_start_2 = cell_offsets_2[i_cell]; index_type const cell_stop_2 = cell_offsets_2[i_cell+1]; - // ux from species1 can be accessed like this: - // ux_1[ indices_1[i] ], where i is between - // cell_start_1 (inclusive) and cell_start_2 (exclusive) + /// ux from species1 can be accessed like this: + /// ux_1[ indices_1[i] ], where i is between + /// cell_start_1 (inclusive) and cell_start_2 (exclusive) - // Do not collide if one species is missing in the cell + /// Do not collide if one species is missing in the cell if ( cell_stop_1 - cell_start_1 >= 1 && cell_stop_2 - cell_start_2 >= 1 ) { - // shuffle + /// shuffle ShuffleFisherYates(indices_1, cell_start_1, cell_stop_1); ShuffleFisherYates(indices_2, cell_start_2, cell_stop_2); - // Call the function in order to perform collisions + /// Call the function in order to perform collisions ElasticCollisionPerez( cell_start_1, cell_stop_1, cell_start_2, cell_stop_2, indices_1, indices_2, @@ -242,6 +248,6 @@ void CollisionType::doCoulombCollisionsWithinTile } } ); - } // end if ( isSameSpecies) + } ///< end if ( isSameSpecies) } diff --git a/Source/Particles/Collision/ComputeTemperature.H b/Source/Particles/Collision/ComputeTemperature.H index 81cb14dad..95fa81225 100644 --- a/Source/Particles/Collision/ComputeTemperature.H +++ b/Source/Particles/Collision/ComputeTemperature.H @@ -43,4 +43,4 @@ T_R ComputeTemperature ( return m/T_R(3.0)*(vs-(vx*vx+vy*vy+vz*vz)); } -#endif // WARPX_PARTICLES_COLLISION_COMPUTE_TEMPERATURE_H_ +#endif ///< WARPX_PARTICLES_COLLISION_COMPUTE_TEMPERATURE_H_ diff --git a/Source/Particles/Collision/ElasticCollisionPerez.H b/Source/Particles/Collision/ElasticCollisionPerez.H index b1fa64300..ef49b699b 100644 --- a/Source/Particles/Collision/ElasticCollisionPerez.H +++ b/Source/Particles/Collision/ElasticCollisionPerez.H @@ -51,7 +51,7 @@ void ElasticCollisionPerez ( int NI1 = I1e - I1s; int NI2 = I2e - I2s; - // get local T1t and T2t + /// get local T1t and T2t T_R T1t; T_R T2t; if ( T1 <= T_R(0.0) && L <= T_R(0.0) ) { @@ -64,7 +64,7 @@ void ElasticCollisionPerez ( } else { T2t = T2; } - // local density + /// local density T_R n1 = T_R(0.0); T_R n2 = T_R(0.0); T_R n12 = T_R(0.0); @@ -82,7 +82,7 @@ void ElasticCollisionPerez ( n12 = n12 / dV; } - // compute Debye length lmdD + /// compute Debye length lmdD T_R lmdD; lmdD = T_R(1.0)/std::sqrt( n1*q1*q1/(T1t*PhysConst::ep0) + n2*q2*q2/(T2t*PhysConst::ep0) ); @@ -90,7 +90,7 @@ void ElasticCollisionPerez ( amrex::max(n1,n2), T_R(-1.0/3.0) ); lmdD = amrex::max(lmdD, rmin); - // call UpdateMomentumPerezElastic() + /// call UpdateMomentumPerezElastic() { int i1 = I1s; int i2 = I2s; for (int k = 0; k < amrex::max(NI1,NI2); ++k) @@ -108,4 +108,4 @@ void ElasticCollisionPerez ( } -#endif // WARPX_PARTICLES_COLLISION_ELASTIC_COLLISION_PEREZ_H_ +#endif ///< WARPX_PARTICLES_COLLISION_ELASTIC_COLLISION_PEREZ_H_ diff --git a/Source/Particles/Collision/ShuffleFisherYates.H b/Source/Particles/Collision/ShuffleFisherYates.H index 614b44d37..adabdf9c1 100644 --- a/Source/Particles/Collision/ShuffleFisherYates.H +++ b/Source/Particles/Collision/ShuffleFisherYates.H @@ -23,13 +23,13 @@ void ShuffleFisherYates (T_index *array, T_index const is, T_index const ie) T_index buf; for (int i = ie-1; i >= is+1; --i) { - // get random number j: is <= j <= i + /// get random number j: is <= j <= i j = amrex::Random_int(i-is+1) + is; - // swop the ith array element with the jth + /// swop the ith array element with the jth buf = array[i]; array[i] = array[j]; array[j] = buf; } } -#endif // WARPX_PARTICLES_COLLISION_SHUFFLE_FISHER_YATES_H_ +#endif ///< WARPX_PARTICLES_COLLISION_SHUFFLE_FISHER_YATES_H_ diff --git a/Source/Particles/Collision/UpdateMomentumPerezElastic.H b/Source/Particles/Collision/UpdateMomentumPerezElastic.H index 05c8cd227..c7c80bb93 100644 --- a/Source/Particles/Collision/UpdateMomentumPerezElastic.H +++ b/Source/Particles/Collision/UpdateMomentumPerezElastic.H @@ -9,8 +9,8 @@ #include <WarpXConst.H> #include <AMReX_Random.H> -#include <cmath> // isnan() isinf() -#include <limits> // numeric_limits<float>::min() +#include <cmath> /// isnan() isinf() +#include <limits> /// numeric_limits<float>::min() /* \brief Update particle velocities according to * F. Perez et al., Phys.Plasmas.19.083104 (2012), @@ -32,7 +32,7 @@ void UpdateMomentumPerezElastic ( T_R const dt, T_R const L, T_R const lmdD) { - // If g = u1 - u2 = 0, do not collide. + /// If g = u1 - u2 = 0, do not collide. if ( std::abs(u1x-u2x) < std::numeric_limits<T_R>::min() && std::abs(u1y-u2y) < std::numeric_limits<T_R>::min() && std::abs(u1z-u2z) < std::numeric_limits<T_R>::min() ) @@ -40,11 +40,11 @@ void UpdateMomentumPerezElastic ( T_R constexpr inv_c2 = T_R(1.0) / ( PhysConst::c * PhysConst::c ); - // Compute Lorentz factor gamma + /// Compute Lorentz factor gamma T_R const g1 = std::sqrt( T_R(1.0) + (u1x*u1x+u1y*u1y+u1z*u1z)*inv_c2 ); T_R const g2 = std::sqrt( T_R(1.0) + (u2x*u2x+u2y*u2y+u2z*u2z)*inv_c2 ); - // Compute momenta + /// Compute momenta T_R const p1x = u1x * m1; T_R const p1y = u1y * m1; T_R const p1z = u1z * m1; @@ -52,7 +52,7 @@ void UpdateMomentumPerezElastic ( T_R const p2y = u2y * m2; T_R const p2z = u2z * m2; - // Compute center-of-mass (COM) velocity and gamma + /// Compute center-of-mass (COM) velocity and gamma T_R const mass_g = m1 * g1 + m2 * g2; T_R const vcx = (p1x+p2x) / mass_g; T_R const vcy = (p1y+p2y) / mass_g; @@ -60,11 +60,11 @@ void UpdateMomentumPerezElastic ( T_R const vcms = vcx*vcx + vcy*vcy + vcz*vcz; T_R const gc = T_R(1.0) / std::sqrt( T_R(1.0) - vcms*inv_c2 ); - // Compute vc dot v1 and v2 + /// Compute vc dot v1 and v2 T_R const vcDv1 = (vcx*u1x + vcy*u1y + vcz*u1z) / g1; T_R const vcDv2 = (vcx*u2x + vcy*u2y + vcz*u2z) / g2; - // Compute p1 star + /// Compute p1 star T_R p1sx; T_R p1sy; T_R p1sz; @@ -76,7 +76,7 @@ void UpdateMomentumPerezElastic ( p1sy = p1y + vcy*lorentz_tansform_factor; p1sz = p1z + vcz*lorentz_tansform_factor; } - else // If vcms = 0, don't do Lorentz-transform. + else /// If vcms = 0, don't do Lorentz-transform. { p1sx = p1x; p1sy = p1y; @@ -84,48 +84,48 @@ void UpdateMomentumPerezElastic ( } T_R const p1sm = std::sqrt( p1sx*p1sx + p1sy*p1sy + p1sz*p1sz ); - // Compute gamma star + /// Compute gamma star T_R const g1s = ( T_R(1.0) - vcDv1*inv_c2 )*gc*g1; T_R const g2s = ( T_R(1.0) - vcDv2*inv_c2 )*gc*g2; - // Compute the Coulomb log lnLmd + /// Compute the Coulomb log lnLmd T_R lnLmd; if ( L > T_R(0.0) ) { lnLmd = L; } else { - // Compute b0 + /// Compute b0 T_R const b0 = std::abs(q1*q2) * inv_c2 / (T_R(4.0)*MathConst::pi*PhysConst::ep0) * gc/mass_g * ( m1*g1s*m2*g2s/(p1sm*p1sm*inv_c2) + T_R(1.0) ); - // Compute the minimal impact parameter + /// Compute the minimal impact parameter T_R bmin = amrex::max(PhysConst::hbar*MathConst::pi/p1sm,b0); - // Compute the Coulomb log lnLmd + /// Compute the Coulomb log lnLmd lnLmd = amrex::max( T_R(2.0), T_R(0.5)*std::log(T_R(1.0)+lmdD*lmdD/(bmin*bmin)) ); } - // Compute s + /// Compute s T_R s = n1*n2/n12 * dt*lnLmd*q1*q1*q2*q2 / ( T_R(4.0) * MathConst::pi * PhysConst::ep0 * PhysConst::ep0 * m1*g1*m2*g2/(inv_c2*inv_c2) ) * gc*p1sm/mass_g * std::pow(m1*g1s*m2*g2s/(inv_c2*p1sm*p1sm) + T_R(1.0), 2.0); - // Compute s' + /// Compute s' T_R const vrel = mass_g*p1sm/(m1*g1s*m2*g2s*gc); T_R const sp = std::pow(T_R(4.0)*MathConst::pi/T_R(3.0),T_R(1.0/3.0)) * n1*n2/n12 * dt * vrel * (m1+m2) / amrex::max( m1*std::pow(n1,T_R(2.0/3.0)), m2*std::pow(n2,T_R(2.0/3.0)) ); - // Determine s + /// Determine s s = amrex::min(s,sp); - // Get random numbers + /// Get random numbers T_R r = amrex::Random(); - // Compute scattering angle + /// Compute scattering angle T_R cosXs; T_R sinXs; if ( s <= T_R(0.1) ) @@ -133,7 +133,7 @@ void UpdateMomentumPerezElastic ( while ( true ) { cosXs = T_R(1.0) + s * std::log(r); - // Avoid the bug when r is too small such that cosXs < -1 + /// Avoid the bug when r is too small such that cosXs < -1 if ( cosXs >= T_R(-1.0) ) { break; } r = amrex::Random(); } @@ -157,18 +157,18 @@ void UpdateMomentumPerezElastic ( } sinXs = std::sqrt(T_R(1.0) - cosXs*cosXs); - // Get random azimuthal angle + /// Get random azimuthal angle T_R const phis = amrex::Random() * T_R(2.0) * MathConst::pi; T_R const cosphis = std::cos(phis); T_R const sinphis = std::sin(phis); - // Compute post-collision momenta pfs in COM + /// Compute post-collision momenta pfs in COM T_R p1fsx; T_R p1fsy; T_R p1fsz; - // p1sp is the p1s perpendicular + /// p1sp is the p1s perpendicular T_R p1sp = std::sqrt( p1sx*p1sx + p1sy*p1sy ); - // Make sure p1sp is not almost zero + /// Make sure p1sp is not almost zero if ( p1sp > std::numeric_limits<T_R>::min() ) { p1fsx = ( p1sx*p1sz/p1sp ) * sinXs*cosphis + @@ -180,15 +180,15 @@ void UpdateMomentumPerezElastic ( p1fsz = (-p1sp ) * sinXs*cosphis + ( T_R(0.0) ) * sinXs*sinphis + ( p1sz ) * cosXs; - // Note a negative sign is different from - // Eq. (12) in Perez's paper, - // but they are the same due to the random nature of phis. + /// Note a negative sign is different from + /// Eq. (12) in Perez's paper, + /// but they are the same due to the random nature of phis. } else { - // If the previous p1sp is almost zero - // x->y y->z z->x - // This set is equivalent to the one in Nanbu's paper + /// If the previous p1sp is almost zero + /// x->y y->z z->x + /// This set is equivalent to the one in Nanbu's paper p1sp = std::sqrt( p1sy*p1sy + p1sz*p1sz ); p1fsy = ( p1sy*p1sx/p1sp ) * sinXs*cosphis + ( p1sz*p1sm/p1sp ) * sinXs*sinphis + @@ -205,7 +205,7 @@ void UpdateMomentumPerezElastic ( T_R const p2fsy = -p1fsy; T_R const p2fsz = -p1fsz; - // Transform from COM to lab frame + /// Transform from COM to lab frame T_R p1fx; T_R p2fx; T_R p1fy; T_R p2fy; T_R p1fz; T_R p2fz; @@ -223,7 +223,7 @@ void UpdateMomentumPerezElastic ( p2fy = p2fsy + vcy * factor2; p2fz = p2fsz + vcz * factor2; } - else // If vcms = 0, don't do Lorentz-transform. + else /// If vcms = 0, don't do Lorentz-transform. { p1fx = p1fsx; p1fy = p1fsy; @@ -233,7 +233,7 @@ void UpdateMomentumPerezElastic ( p2fz = p2fsz; } - // Rejection method + /// Rejection method r = amrex::Random(); if ( w2 > r*amrex::max(w1, w2) ) { @@ -255,4 +255,4 @@ void UpdateMomentumPerezElastic ( } -#endif // WARPX_PARTICLES_COLLISION_UPDATE_MOMENTUM_PEREZ_ELASTIC_H_ +#endif ///< WARPX_PARTICLES_COLLISION_UPDATE_MOMENTUM_PEREZ_ELASTIC_H_ |