PIC and FLIP
FLIP transfers combine particle values with grid updates. They are useful when pure PIC is too diffusive but pure FLIP is too noisy. JustPIC provides them in both directions and for both vertex and centroid grids:
| Direction | Vertices | Centroids |
|---|---|---|
| grid → particles (blend) | grid2particle_flip! | centroid2particle_flip! |
| particles → grid (increment) | particle2grid_flip! | particle2centroid_flip! |
All of them accept single fields or tuples of fields in 2D and 3D, and run unchanged on every backend, including Float32.
Grid to particles
Given current grid field F, previous grid field F₀, and the existing particle field Fp:
grid2particle_flip!(Fp, F, F₀, particles; α=0.5)The blend parameter is:
α | Method |
|---|---|
1 | pure PIC: replace with interpolated current-grid value |
0 | pure FLIP: add the interpolated grid change to the particle value |
between 0 and 1 | PIC/FLIP blend |
Conceptually, the blend combines the current-grid estimate with the particle value plus the grid increment:
current grid ──interpolate──▶ PIC value ──┐
├── α PIC + (1 − α) FLIP ──▶ particle
old/current grids ──difference──▶ Δgrid ──┘
particle + Δgrid ───────────────────────▶ FLIP valueThe usual time-step pattern is:
F₀ .= F
# update F on the grid
grid2particle_flip!(Fp, F, F₀, particles; α=0.5)The source arrays use the same ghost layout rules as grid2particle!; pass ghost_1, ghost_2, and ghost_3 when a direction is physical-only.
centroid2particle_flip!(Fp, F, F₀, particles; α) does the same with cell-centered fields in the particles.xci layout; its ghosted, ghost_1, ghost_2 and ghost_3 keywords are those of centroid2particle!.
Particles to grid
The reverse transfer accumulates the change of a particle field, Fp - Fp₀, onto a grid field with the same weights as particle2grid! and particle2centroid!:
particle2grid_flip!(F, Fp, Fp₀, particles) # F += Σ ω (Fp - Fp₀) / Σ ω
particle2centroid_flip!(Fc, Fp, Fp₀, particles)F is only modified where at least one particle contributes (Σ ω ≠ 0), so the result carries over the previous grid value elsewhere. No temporary arrays or atomics are involved: each grid node gathers from the particles around it.
A complete example that uses both directions on a centroid field is in PIC/FLIP temperature update in 2D.
API
JustPIC.grid2particle_flip! Function
grid2particle_flip!(Fp, F, F0, particles; α = 0.0)Update particle values with a PIC/FLIP blend.
α = 1 gives pure PIC, α = 0 gives pure FLIP, and intermediate values blend between the two updates.
Arguments
Fp: particle field (or tuple of particle fields) to update in place.F: current grid field (or tuple of fields).F0: previous grid field (or tuple of fields), same layout asF.particles: particle container; its vertex gridparticles.xviis used.α: PIC fraction in the PIC/FLIP blend, in[0, 1].ghost_1,ghost_2,ghost_3: whetherFandF0include ghost nodes in each coordinate direction. Disable a keyword for a physical-only direction.
Note
The older method grid2particle_flip!(Fp, xvi, F, F0, particles; ...) that takes the vertex coordinates explicitly is deprecated; use the method above.
JustPIC.centroid2particle_flip! Function
centroid2particle_flip!(Fp, F, F0, particles; α = 0.0, ghosted = true)Update particle values from cell-centered fields with a PIC/FLIP blend.
α = 1 gives pure PIC, α = 0 gives pure FLIP: Fp += F - F0, with F and F0 interpolated to the particle. Fp, F and F0 may be single fields or tuples of fields. See centroid2particle! for the ghosted, ghost_1, ghost_2 and ghost_3 keywords.
JustPIC.particle2grid_flip! Function
particle2grid_flip!(F, Fp, Fp0, particles; ghost_1 = true, ghost_2 = true, ghost_3 = true)Add the interpolated particle increment Fp - Fp0 to the grid nodes F: F += Σ ω (Fp - Fp0) / Σ ω, with the weights of particle2grid!.
F, Fp and Fp0 may be single fields or tuples of fields. Nodes with no surrounding particles are left unchanged.
Arguments
F: nodal array (or tuple of arrays) to update in place.Fp: current particle field.Fp0: particle field at the previous state, with the same layout asFp.particles: particle container.ghost_1,ghost_2,ghost_3: whetherFincludes ghost nodes in each coordinate direction. Disable a keyword for a physical-only direction.
JustPIC.particle2centroid_flip! Function
particle2centroid_flip!(F, Fp, Fp0, particles; ghost_1 = true, ghost_2 = true, ghost_3 = true)Add the interpolated particle increment Fp - Fp0 to the cell centers F: F += Σ ω (Fp - Fp0) / Σ ω, with the weights of particle2centroid!.
F, Fp and Fp0 may be single fields or tuples of fields. Cells with no particles are left unchanged. See particle2grid_flip! for the arguments.