Skip to content

New Boundary Conditions and Fixing Bug in Esirkepov Current Deposition#78

Merged
cwoolfo1 merged 11 commits into
uwplasma:mainfrom
cwoolfo1:main
Jun 6, 2026
Merged

New Boundary Conditions and Fixing Bug in Esirkepov Current Deposition#78
cwoolfo1 merged 11 commits into
uwplasma:mainfrom
cwoolfo1:main

Conversation

@cwoolfo1

@cwoolfo1 cwoolfo1 commented Jun 6, 2026

Copy link
Copy Markdown
Member
  • Adding absorbing bc for particles that actively masks particles on the boundary from particle updates and current deposition.
  • Added an Unsplit-Convolutional PML for field boundaries.
  • Identified error in new ghost cell logic for Esirkepov! Forgot to account for additional ghost cell on both boundaries since the second order shape factors can technically have a portion of weight inside the first ghost cell in certain edge cases.

Reference for PML: Martin, R., & Komatitsch, D. (2009). An unsplit convolutional perfectly matched layer technique improved at grazing incidence for the viscoelastic wave equation. Geophysical Journal International, 179(1), 333-344.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends PyPIC3D’s boundary-handling capabilities by introducing absorbing particle boundaries (via a persistent active-mask), adding an unsplit-convolutional PML implementation for FDTD field updates, and correcting Esirkepov current deposition ghost-cell handling for higher-order shapes. It also threads “external-only” prescribed E/B fields through initialization/evolve/diagnostics so particles and energy accounting can include fields that Maxwell does not evolve.

Changes:

  • Add absorbing particle BC support by masking inactive particles from pushes, deposition, and energy/moments.
  • Introduce PML configuration/state and integrate coordinate-stretched derivatives into the first-order Yee FDTD update.
  • Add external-only E/B fields and update energy + openPMD diagnostics (including thin-axis preservation) and tests.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/utils_test.py Adds unit tests for external-field loading/addition and energy masking behavior.
tests/pml_test.py Adds PML configuration, initialization, and absorption behavior tests.
tests/particle_test.py Adds tests for absorbing particle masks, initialization config acceptance, and masked deposition.
tests/openpmd_test.py Adds tests ensuring thin mesh axes are preserved in openPMD output.
tests/first_order_yee_test.py Updates tests for the new (field, pml_state) return signatures.
tests/evolve_test.py Adds tests for external-field particle pushing and mask survival under JIT.
tests/esirkepov_ghost_cells_test.py Adds regression tests for two-layer ghost folding and halo elimination.
PyPIC3D/utils.py Masks kinetic energy by active particles; adds external-field composition + loading support.
PyPIC3D/solvers/first_order_yee.py Integrates PML-stretched curls and returns/threads pml_state.
PyPIC3D/solvers/electrostatic_yee.py Fixes CG update sign convention for alpha and residual update.
PyPIC3D/particles/species_class.py Implements absorbing masks and ensures inactive particles don’t update position/velocity or moments.
PyPIC3D/particles/particle_initialization.py Allows absorbing as a per-axis particle boundary option in config.
PyPIC3D/particles/flat_particles.py Threads active_mask through flat particle representation and moment/push methods.
PyPIC3D/initialization.py Adds PML loading/state allocation; introduces and routes external-only E/B fields.
PyPIC3D/evolve.py Uses total (evolved+external) fields for particle pushes; threads external fields and pml_state.
PyPIC3D/diagnostics/openPMD.py Preserves thin axes and adds external field outputs; updates array handling.
PyPIC3D/diagnostics/fluid_quantities.py Masks particle-to-grid moments by active particles.
PyPIC3D/deposition/rho.py Prevents inactive particles from depositing charge density.
PyPIC3D/deposition/J_from_rhov.py Prevents inactive particles from depositing current in RHOV deposition.
PyPIC3D/deposition/Esirkepov.py Reworks ghost-layer logic for Esirkepov with two-layer folding and per-species BC handling.
PyPIC3D/boundary_conditions/PML.py Adds PML profile building, ADE memory, stretched derivatives, and PML-safe ghost updates.
PyPIC3D/main.py Updates runtime energy accounting to include external-only fields and new fields tuple layout.
docs/particles.rst Documents absorbing particle boundaries and masking semantics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread PyPIC3D/utils.py
Comment on lines +104 to 113
if (
isinstance(extra, (list, tuple))
and len(extra) == 2
and all(isinstance(memory, (list, tuple)) and len(memory) == 3 for memory in extra)
):
# PML memory is solver state, not a physical diagnostic field.
continue
if isinstance(extra, (list, tuple)):
field_map[f"field_{idx}"] = tuple(comp[interior] for comp in extra)
else:

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.

Comment thread PyPIC3D/utils.py
Comment on lines 228 to +235
mass = species.get_mass()
vx, vy, vz = species.get_velocity()
v2 = vx**2 + vy**2 + vz**2
active = species.get_active_mask().astype(v2.dtype)
gamma = 1.0 / jnp.sqrt(1 - v2 / C**2)
momentum2 = jnp.square(mass * gamma ) * v2
# compute the squared momentum for each particle
KE = jnp.sum( jnp.sqrt( momentum2 * C**2 + mass**2 * C**4) - mass * C**2 )
KE = jnp.sum(active * (jnp.sqrt(momentum2 * C**2 + mass**2 * C**4) - mass * C**2))
Comment thread PyPIC3D/utils.py
Comment thread PyPIC3D/diagnostics/openPMD.py
Comment thread tests/openpmd_test.py Outdated
Comment on lines +86 to +88
rho = jnp.zeros(shape_with_ghosts)
phi = jnp.zeros(shape_with_ghosts)
fields = (E, B, J, rho, phi)
Comment thread tests/particle_test.py
Comment on lines +488 to +489
vertex_grid, center_grid = build_yee_grid(world)
world["grids"] = {"vertex": vertex_grid, "center": center_grid}
cwoolfo1 and others added 2 commits June 6, 2026 12:29
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 7 comments.

Comment thread PyPIC3D/utils.py
Comment on lines +231 to +235
active = species.get_active_mask().astype(v2.dtype)
gamma = 1.0 / jnp.sqrt(1 - v2 / C**2)
momentum2 = jnp.square(mass * gamma ) * v2
# compute the squared momentum for each particle
KE = jnp.sum( jnp.sqrt( momentum2 * C**2 + mass**2 * C**4) - mass * C**2 )
KE = jnp.sum(active * (jnp.sqrt(momentum2 * C**2 + mass**2 * C**4) - mass * C**2))
Comment thread PyPIC3D/utils.py
Comment thread PyPIC3D/utils.py
Comment on lines 202 to 207
x_bc = "periodic"
if "x_bc" in config[toml_key]:
assert config[toml_key]["x_bc"] in ["periodic", "reflecting"], (
assert config[toml_key]["x_bc"] in ["periodic", "reflecting", "absorbing"], (
f"Invalid x boundary condition: {config[toml_key]['x_bc']}"
)
x_bc = config[toml_key]["x_bc"]
Comment on lines 209 to 214
y_bc = "periodic"
if "y_bc" in config[toml_key]:
assert config[toml_key]["y_bc"] in ["periodic", "reflecting"], (
assert config[toml_key]["y_bc"] in ["periodic", "reflecting", "absorbing"], (
f"Invalid y boundary condition: {config[toml_key]['y_bc']}"
)
y_bc = config[toml_key]["y_bc"]
Comment on lines 216 to 221
z_bc = "periodic"
if "z_bc" in config[toml_key]:
assert config[toml_key]["z_bc"] in ["periodic", "reflecting"], (
assert config[toml_key]["z_bc"] in ["periodic", "reflecting", "absorbing"], (
f"Invalid z boundary condition: {config[toml_key]['z_bc']}"
)
z_bc = config[toml_key]["z_bc"]
Comment thread tests/particle_test.py
Comment on lines +488 to +489
vertex_grid, center_grid = build_yee_grid(world)
world["grids"] = {"vertex": vertex_grid, "center": center_grid}
@cwoolfo1 cwoolfo1 merged commit 503af44 into uwplasma:main Jun 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants