Skip to content

Commit

Permalink
Simplify SEE processing to one function, allow for only one SEE proba…
Browse files Browse the repository at this point in the history
…bility
  • Loading branch information
budjensen committed Feb 28, 2025
1 parent 9207629 commit fb3bf81
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 102 deletions.
9 changes: 1 addition & 8 deletions Source/Particles/ParticleBoundaries.H
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 0 additions & 8 deletions Source/Particles/ParticleBoundaries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
93 changes: 26 additions & 67 deletions Source/Particles/ParticleBoundaries_K.H
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ 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) {
if (xmin_bc == ParticleBoundaryType::Open) {
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;
}
Expand All @@ -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<int>(SEE_probability_xmin);

SEE_probability = SEE_probability_xmin - static_cast<amrex::Real>(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;
Expand All @@ -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;
}
Expand All @@ -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<int>(SEE_probability_xmax);

SEE_probability = SEE_probability_xmax - static_cast<amrex::Real>(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;
Expand Down Expand Up @@ -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
Expand All @@ -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)
{
Expand All @@ -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);
Expand All @@ -169,21 +141,19 @@ 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);
}
#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);
Expand Down Expand Up @@ -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<int>(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<int>(max_SEE_probability);

SEE_probability = max_SEE_probability - static_cast<amrex::Real>(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<int>(SEE_probability);
SEE_probability = SEE_probability - static_cast<amrex::Real>(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
Expand Down Expand Up @@ -302,7 +262,6 @@ namespace ApplyParticleBoundaries {
amrex::Vector<amrex::ParticleReal> uxp_new(SEE_num_particles_added);
amrex::Vector<amrex::ParticleReal> uyp_new(SEE_num_particles_added);
amrex::Vector<amrex::ParticleReal> uzp_new(SEE_num_particles_added);
amrex::Vector<amrex::ParticleReal> 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++) {
Expand Down
15 changes: 2 additions & 13 deletions Source/Particles/PhysicalParticleContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
11 changes: 5 additions & 6 deletions Source/Particles/WarpXParticleContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit fb3bf81

Please sign in to comment.