diff --git a/Source/Particles/ParticleBoundaries.H b/Source/Particles/ParticleBoundaries.H index 8121968bd80..677fb5cb015 100644 --- a/Source/Particles/ParticleBoundaries.H +++ b/Source/Particles/ParticleBoundaries.H @@ -67,14 +67,7 @@ struct ParticleBoundaries bool reflect_all_velocities; - amrex::Real SEE_probability_xlo = 0.0_rt; - amrex::Real SEE_probability_xhi = 0.0_rt; - amrex::Real SEE_probability_ylo = 0.0_rt; - amrex::Real SEE_probability_yhi = 0.0_rt; - amrex::Real SEE_probability_zlo = 0.0_rt; - amrex::Real SEE_probability_zhi = 0.0_rt; - - amrex::Real max_SEE_probability = 0.0_rt; + amrex::Real SEE_probability = 0.0_rt; amrex::Real v_SEE = 0.; }; ParticleBoundariesData data; diff --git a/Source/Particles/ParticleBoundaries.cpp b/Source/Particles/ParticleBoundaries.cpp index b0930affff3..b0aebf6ae5b 100644 --- a/Source/Particles/ParticleBoundaries.cpp +++ b/Source/Particles/ParticleBoundaries.cpp @@ -95,14 +95,6 @@ ParticleBoundaries::BuildReflectionModelParsers () data.reflection_model_zhi = reflection_model_zhi_parser->compile<1>(); } -void -ParticleBoundaries::SaveMaxSEEProbability () -{ - data.max_SEE_probability = std::max({data.SEE_probability_xlo, data.SEE_probability_xhi, - data.SEE_probability_ylo, data.SEE_probability_yhi, - data.SEE_probability_zlo, data.SEE_probability_zhi}); -} - void ParticleBoundaries::SetSEEvMag (amrex::Real E) { diff --git a/Source/Particles/ParticleBoundaries_K.H b/Source/Particles/ParticleBoundaries_K.H index 55729990d7f..ae9881ec61a 100644 --- a/Source/Particles/ParticleBoundaries_K.H +++ b/Source/Particles/ParticleBoundaries_K.H @@ -21,10 +21,9 @@ namespace ApplyParticleBoundaries { void apply_boundary (amrex::ParticleReal& x, amrex::Real xmin, amrex::Real xmax, bool& change_sign_ux, bool& rethermalize_x, bool& particle_lost, - bool& SEE_particle_added, int& SEE_num_particles_added, + bool& do_SEE_flag, ParticleBoundaryType xmin_bc, ParticleBoundaryType xmax_bc, amrex::Real refl_probability_xmin, amrex::Real refl_probability_xmax, - amrex::Real SEE_probability_xmin, amrex::Real SEE_probability_xmax, amrex::RandomEngine const& engine ) { if (x < xmin) { @@ -32,6 +31,7 @@ namespace ApplyParticleBoundaries { particle_lost = true; } else if (xmin_bc == ParticleBoundaryType::Absorbing) { + do_SEE_flag = true; if (refl_probability_xmin == 0 || amrex::Random(engine) > refl_probability_xmin) { particle_lost = true; } @@ -40,20 +40,6 @@ namespace ApplyParticleBoundaries { x = 2*xmin - x; change_sign_ux = true; } - if (SEE_probability_xmin > 0) { - // Configure SEE boundary emission - amrex::Real SEE_probability = SEE_probability_xmin; - if (SEE_probability_xmin >= 1) { - SEE_particle_added = true; - SEE_num_particles_added = static_cast(SEE_probability_xmin); - - SEE_probability = SEE_probability_xmin - static_cast(SEE_num_particles_added); - } - if (amrex::Random(engine) < SEE_probability) { - SEE_particle_added = true; - SEE_num_particles_added += 1; - } - } } else if (xmin_bc == ParticleBoundaryType::Reflecting) { x = 2*xmin - x; @@ -69,6 +55,7 @@ namespace ApplyParticleBoundaries { particle_lost = true; } else if (xmax_bc == ParticleBoundaryType::Absorbing) { + do_SEE_flag = true; if (refl_probability_xmax == 0 || amrex::Random(engine) > refl_probability_xmax) { particle_lost = true; } @@ -77,20 +64,6 @@ namespace ApplyParticleBoundaries { x = 2*xmax - x; change_sign_ux = true; } - if (SEE_probability_xmax > 0) { - // Configure SEE boundary emission - amrex::Real SEE_probability = SEE_probability_xmax; - if (SEE_probability_xmax >= 1) { - SEE_particle_added = true; - SEE_num_particles_added = static_cast(SEE_probability_xmax); - - SEE_probability = SEE_probability_xmax - static_cast(SEE_num_particles_added); - } - if (amrex::Random(engine) < SEE_probability) { - SEE_particle_added = true; - SEE_num_particles_added += 1; - } - } } else if (xmax_bc == ParticleBoundaryType::Reflecting) { x = 2*xmax - x; @@ -136,7 +109,7 @@ namespace ApplyParticleBoundaries { * \param z, zmin, zmax: particle z position, location of z boundary * \param ux, uy, uz: particle momenta * \param particle_lost: output, flags whether the particle was lost - * \param SEE_particle_added: output, flags whether a SEE particle was added + * \param do_SEE_flag: output, flags whether to execute SEE * \param boundaries: object with boundary condition settings */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE @@ -146,7 +119,7 @@ namespace ApplyParticleBoundaries { [[maybe_unused]] amrex::ParticleReal& z, amrex::XDim3 gridmin, amrex::XDim3 gridmax, amrex::ParticleReal& ux, amrex::ParticleReal& uy, amrex::ParticleReal& uz, - bool& particle_lost, bool& SEE_particle_added, int& SEE_num_particles_added, + bool& particle_lost, bool& do_SEE_flag, ParticleBoundaries::ParticleBoundariesData const& boundaries, amrex::RandomEngine const& engine) { @@ -157,10 +130,9 @@ namespace ApplyParticleBoundaries { #ifndef WARPX_DIM_1D_Z bool rethermalize_x = false; // stores if particle crosses x boundary and needs to be thermalized apply_boundary(x, gridmin.x, gridmax.x, change_sign_ux, rethermalize_x, particle_lost, - SEE_particle_added, SEE_num_particles_added, + do_SEE_flag, boundaries.xmin_bc, boundaries.xmax_bc, boundaries.reflection_model_xlo(-ux), boundaries.reflection_model_xhi(ux), - boundaries.SEE_probability_xlo, boundaries.SEE_probability_xhi, engine); if (rethermalize_x) { thermalize_boundary_particle(ux, uy, uz, boundaries.m_uth, engine); @@ -169,10 +141,9 @@ namespace ApplyParticleBoundaries { #ifdef WARPX_DIM_3D bool rethermalize_y = false; // stores if particle crosses y boundary and needs to be thermalized apply_boundary(y, gridmin.y, gridmax.y, change_sign_uy, rethermalize_y, particle_lost, - SEE_particle_added, SEE_num_particles_added, + do_SEE_flag, boundaries.ymin_bc, boundaries.ymax_bc, boundaries.reflection_model_ylo(-uy), boundaries.reflection_model_yhi(uy), - boundaries.SEE_probability_ylo, boundaries.SEE_probability_yhi, engine); if (rethermalize_y) { thermalize_boundary_particle(uy, uz, ux, boundaries.m_uth, engine); @@ -180,10 +151,9 @@ namespace ApplyParticleBoundaries { #endif bool rethermalize_z = false; // stores if particle crosses z boundary and needs to be thermalized apply_boundary(z, gridmin.z, gridmax.z, change_sign_uz, rethermalize_z, particle_lost, - SEE_particle_added, SEE_num_particles_added, + do_SEE_flag, boundaries.zmin_bc, boundaries.zmax_bc, boundaries.reflection_model_zlo(-uz), boundaries.reflection_model_zhi(uz), - boundaries.SEE_probability_zlo, boundaries.SEE_probability_zhi, engine); if (rethermalize_z) { thermalize_boundary_particle(uz, ux, uy, boundaries.m_uth, engine); @@ -217,45 +187,35 @@ namespace ApplyParticleBoundaries { } - /* \brief Applies absorbing, reflecting or thermal boundary condition to the input particles, along all axis. - * For reflecting boundaries, the position of the particle is changed appropriately and - * the sign of the velocity is changed (depending on the reflect_all_velocities flag). - * For absorbing, a flag is set whether the particle has been lost (it is up to the calling - * code to take appropriate action to remove any lost particles). Absorbing boundaries can - * be given a reflection coefficient for stochastic reflection of particles, this - * coefficient is zero by default. - * For thermal boundaries, the particle is first reflected and the position of the particle - * is changed appropriately. - * For SEE boundaries, the particle is removed and a new SEE particle is added. - * Note that periodic boundaries are handled in AMReX code. + /* \brief Carries out Secondary Electron Emission (SEE) by injecting new electrons + * at the boundary. The new electrons are emitted with a velocity v_SEE from + * an isotropic velocity distribution. Particles are created at the location + * of the particle that crossed the boundary (after swapping the intersecting + * coordinate to gridmax.x/y/z). * * \param xpos, ypos, zpos: particle x, y, z position before boundary conditions were applied * \param gridmin, gridmax: location of boundaries - * \param max_SEE_probability: maximum probability of adding a SEE particle at any boundary - * \param SEE_num_particles_added: number of SEE particles added + * \param SEE_probability: probability of adding a SEE particle at any boundary + * \param v_SEE: velocity magnitude of emitted SEE particles * \param engine: random number generator */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void do_SEE(amrex::ParticleReal& xpos, amrex::ParticleReal& ypos, amrex::ParticleReal& zpos, amrex::XDim3 gridmin, amrex::XDim3 gridmax, - amrex::Real const& max_SEE_probability, amrex::Real const& v_SEE, - int& SEE_num_particles_added, amrex::RandomEngine const& engine) + amrex::Real SEE_probability, amrex::Real const& v_SEE, + amrex::RandomEngine const& engine) { - // Make sure there are not more particles added (in case two boundaries were crossed by one particle) - if (SEE_num_particles_added > static_cast(max_SEE_probability) + 1) { - SEE_num_particles_added = 0; - amrex::Real SEE_probability = max_SEE_probability; + // Determine the number of SEE particles to add + int SEE_num_particles_added = 0; - // Redraw a random number to determine if SEE particles are added - if (max_SEE_probability >= 1) { - SEE_num_particles_added = static_cast(max_SEE_probability); - - SEE_probability = max_SEE_probability - static_cast(SEE_num_particles_added); - } - if (amrex::Random(engine) < SEE_probability) { - SEE_num_particles_added += 1; - } + // Redraw a random number to determine if SEE particles are added + if (SEE_probability >= 1) { + SEE_num_particles_added = static_cast(SEE_probability); + SEE_probability = SEE_probability - static_cast(SEE_num_particles_added); + } + if (amrex::Random(engine) < SEE_probability) { + SEE_num_particles_added += 1; } // Determine normal vector pointing inward from the boundary that was hit @@ -302,7 +262,6 @@ namespace ApplyParticleBoundaries { amrex::Vector uxp_new(SEE_num_particles_added); amrex::Vector uyp_new(SEE_num_particles_added); amrex::Vector uzp_new(SEE_num_particles_added); - amrex::Vector wp_new(SEE_num_particles_added, wp[i]); // Use same weight as parent // Generate velocities pointing inward from the boundary for (int n = 0; n < SEE_num_particles_added; n++) { diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index 3c4fc9fc913..45cdef1d611 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -412,21 +412,10 @@ PhysicalParticleContainer::PhysicalParticleContainer (AmrCore* amr_core, int isp if (WarpX::isAnyParticleBoundaryAbsorbing()) { // Read SEE parameters for absorbing boundaries; SEE probability defaults to zero - pp_species_name.queryWithParser("SEE_probability_xlo", m_boundary_conditions.data.SEE_probability_xlo); - pp_species_name.queryWithParser("SEE_probability_xhi", m_boundary_conditions.data.SEE_probability_xhi); - pp_species_name.queryWithParser("SEE_probability_ylo", m_boundary_conditions.data.SEE_probability_ylo); - pp_species_name.queryWithParser("SEE_probability_yhi", m_boundary_conditions.data.SEE_probability_yhi); - pp_species_name.queryWithParser("SEE_probability_zlo", m_boundary_conditions.data.SEE_probability_zlo); - pp_species_name.queryWithParser("SEE_probability_zhi", m_boundary_conditions.data.SEE_probability_zhi); - m_boundary_conditions.SaveMaxSEEProbability(); + pp_species_name.queryWithParser("SEE_probability", m_boundary_conditions.data.SEE_probability); WARPX_ALWAYS_ASSERT_WITH_MESSAGE( - (m_boundary_conditions.data.SEE_probability_xlo >= 0.) || - (m_boundary_conditions.data.SEE_probability_xhi >= 0.) || - (m_boundary_conditions.data.SEE_probability_ylo >= 0.) || - (m_boundary_conditions.data.SEE_probability_yhi >= 0.) || - (m_boundary_conditions.data.SEE_probability_zlo >= 0.) || - (m_boundary_conditions.data.SEE_probability_zhi >= 0.), + (m_boundary_conditions.data.SEE_probability >= 0.), "Secondary electron emission probability must be >= 0."); if (m_boundary_conditions.data.max_SEE_probability > 0.0) { diff --git a/Source/Particles/WarpXParticleContainer.cpp b/Source/Particles/WarpXParticleContainer.cpp index 1757f91689a..4d87cb7c119 100644 --- a/Source/Particles/WarpXParticleContainer.cpp +++ b/Source/Particles/WarpXParticleContainer.cpp @@ -1654,18 +1654,17 @@ WarpXParticleContainer::ApplyBoundaryConditions (){ ParticleReal zpos = z; bool particle_lost = false; - bool SEE_particle_added = false; - int SEE_num_particles_added = 0; + bool do_SEE_flag = false; ApplyParticleBoundaries::apply_boundaries(x, y, z, gridmin, gridmax, ux[i], uy[i], uz[i], particle_lost, - SEE_particle_added, SEE_num_particles_added, + do_SEE_flag, boundary_conditions, engine); - if (SEE_particle_added) { + if (do_SEE_flag) { ApplyParticleBoundaries::do_SEE(xpos, ypos, zpos, gridmin, gridmax, - boundary_conditions.max_SEE_probability, + boundary_conditions.SEE_probability, boundary_conditions.v_SEE, - SEE_num_particles_added, engine); + engine); } if (particle_lost) {