Architecture¶
This page summarizes how PyPIC3D is organized and how data flows through a run.
Execution Flow¶
PyPIC3D.__main__.mainparses--configand enables JAX settings.initialization.initialize_simulationbuilds defaults, loads TOML, computes derived world parameters, builds grids, initializes particles and fields, and selects loop functions.run_PyPIC3Dexecutes the timestep loop, writes diagnostics/outputs, and dumps run metadata.
Core Module Map¶
PyPIC3D/__main__.py: CLI and top-level run loop.PyPIC3D/initialization.py: parameter defaults, config merge, world/grid setup, and mode selection.PyPIC3D/evolve.py: JIT-compiled per-step loops.PyPIC3D/particle.py: particle species model, initialization loaders, particle boundary handling.PyPIC3D/J.py: current deposition kernels.PyPIC3D/rho.py: charge deposition.PyPIC3D/solvers/: field update operators and electrostatic Poisson helpers.PyPIC3D/diagnostics/: phase-space plots and openPMD output.PyPIC3D/utils.py: config handling, filters, energy calculations, serialization helpers.
State Model¶
Main runtime objects:
particles: list of particle species objects.fields:electrostatic:
(E, B, J, rho, phi, external_fields)electrodynamic:
(E, B, J, rho, phi, external_fields, pml_state)
world: spatial/temporal metadata, grid spacing, grid arrays, encoded field boundary conditions.constants: physical constants and filter coefficients.
Tiled State Contract¶
The electrodynamic_yee path uses one shared tile shape for fields and particles.
The existing tile-size configuration is interpreted as this common
tile_shape = (tile_nx, tile_ny, tile_nz); there are not separate field-tile
and particle-tile dimensions in the current contract. Each tile width must
divide the corresponding physical grid size exactly, so the leading tile axes
are (ntx, nty, ntz) with ntx * tile_nx = Nx and similarly for y and
z.
Tiled fields store each vector component as compact per-tile arrays with
leading tile axes followed by a one-cell halo around the tile-local physical
interior:
(ntx, nty, ntz, tile_nx + 2, tile_ny + 2, tile_nz + 2). The halo cells
carry neighbor-tile values or exterior field boundary conditions so tiled Yee
curls can be evaluated on the physical interior without assembling a global
field.
Tiled particles use the same leading tile axes, followed by species and fixed
slot axes. Positions and velocities have shape
(ntx, nty, ntz, species, max_particles_per_tile, 3); the active mask has
shape (ntx, nty, ntz, species, max_particles_per_tile). Species-level
metadata such as charge, mass, weight, and position/velocity update masks is
stored once in SpeciesConfig and broadcast over tile slots inside the tiled
kernels. The slot capacity is set when tiled particles are initialized. Empty
slots remain inactive so the array shape stays static during JAX updates.
Retiling preserves this fixed-capacity layout. If later particle motion would place more active particles in a tile/species block than its slot capacity can hold, the tiled refresh reports overflow and the Python driver treats that as a hard error. This avoids silently dropping active particles.
Data and Output Flow¶
Diagnostics and metadata are written under
<output_dir>/data.Text outputs include energy and momentum traces.
Optional outputs include matplotlib phase-space arrays and openPMD files.
output.tomlcaptures simulation stats, resolved runtime parameters, particle summaries, and package versions.