Goal
Replace the hard-coded linear (CIC, order 1) particle→grid weighting with a B-spline order P = 1, 2, 3, … selectable at model setup, to reduce grid-imprint anisotropy (cardinal-axis spikes) and grid-scale noise seen in the dx30_dy10 ring test.
Why this is safe (conservation)
The 2D deposit is purely additive (grid[...,:] += wx*wy*charge), and B-spline weights of any order satisfy partition of unity (Σw=1), so total energy/momentum are conserved exactly independent of P.
Plan
- Edit
src/ParticleInCell.jl: add order-dispatched bspline_stencil, update get_absolute_i_and_w, compute_weights_and_index_mininal, construct_loop (3 functions)
- Edit
src/Operators/mapping_2D.jl: thread order through both ParticleToNode! methods
- Add
spline_order::Int = 1 config field (location TBD: model config vs grid struct)
wni struct and push_to_grid! need no changes
Gotchas
- Higher order needs wider halo (order 2 → ±1, order 3 → −1..+2); non-periodic boundaries need extra ghost layers
- Cost scales as (P+1)² per particle (4/9/16 for P=1/2/3)
- Convert Int→Val at a function barrier (outside hot loop) to avoid dynamic dispatch
- Even orders center on
round(z), odd on floor(z) — ensure normalized grid units
Validation checklist
Reference files
src/ParticleInCell.jl
src/Operators/mapping_2D.jl
src/Operators/core_2D.jl
src/custom_structures.jl
test/unit/test_pic_2d_propagation_energy_conservation.jl
Follow-up (separate)
The ring's energy growth (188→376) is not a deposition issue — investigate GetVariablesAtVertex log/ratio reconstruction as a Jensen-bias source, and consider an isotropic binomial filter on deposited fields at remesh as a complementary mitigation.
Goal
Replace the hard-coded linear (CIC, order 1) particle→grid weighting with a B-spline order
P = 1, 2, 3, …selectable at model setup, to reduce grid-imprint anisotropy (cardinal-axis spikes) and grid-scale noise seen in thedx30_dy10ring test.Why this is safe (conservation)
The 2D deposit is purely additive (
grid[...,:] += wx*wy*charge), and B-spline weights of any order satisfy partition of unity (Σw=1), so total energy/momentum are conserved exactly independent of P.Plan
src/ParticleInCell.jl: add order-dispatchedbspline_stencil, updateget_absolute_i_and_w,compute_weights_and_index_mininal,construct_loop(3 functions)src/Operators/mapping_2D.jl: threadorderthrough bothParticleToNode!methodsspline_order::Int = 1config field (location TBD: model config vs grid struct)wnistruct andpush_to_grid!need no changesGotchas
round(z), odd onfloor(z)— ensure normalized grid unitsValidation checklist
test/unit/test_pic_2d_propagation_energy_conservation.jlpasses for P=1,2,3dx30_dy10ring for P=1,2,3 — cardinal spikes should weaken, ring isotropizeReference files
src/ParticleInCell.jlsrc/Operators/mapping_2D.jlsrc/Operators/core_2D.jlsrc/custom_structures.jltest/unit/test_pic_2d_propagation_energy_conservation.jlFollow-up (separate)
The ring's energy growth (188→376) is not a deposition issue — investigate
GetVariablesAtVertexlog/ratio reconstruction as a Jensen-bias source, and consider an isotropic binomial filter on deposited fields at remesh as a complementary mitigation.