A reference solver with capacity particle slots; height is the terrain (none by default).
Optionalcapacity?: numberMost particles. Fixed at construction.
OptionalcellSize?: numberGrid spacing Δx, metres. Particles are emitted 2 per cell per axis (8 per cell). Fixed at construction.
Optionalcfl?: numberCourant number C of the stable step dt ≤ C·Δx / (maxSpeed + sound speed) (see mpmStableStep).
Optionalfriction?: numberTerrain friction coefficient (Coulomb): 0 slips, large values stick.
Optionalgravity?: [number, number, number]Gravity, m/s².
Optionalmaterials?: { [key: string]: { [key: string]: number | undefined } | undefined }Materials compiled in (keys, fixed at construction) and their parameters (live).
OptionalmaxSpeed?: numberParticle speed limit, m/s: the "max particle speed" of the stable step, enforced in G2P.
OptionalmaxSubsteps?: numberMost substeps per frame; past it the simulation runs slower than real time instead of going unstable.
Optionalorigin?: [number, number, number]World position of the domain's minimum corner, metres. Moving it shifts the domain by whole cells (the particles keep their world positions; those left outside freeze). Floating-origin safe: the GPU only sees positions relative to it.
Optionalrender?: { colors?: string[]; opacity?: number; size?: number; strainScale?: number }Drawing through the particle pool's unlit shading.
Optionalcolors?: string[]Colour ramp by volume change J: first key squashed, middle at rest, last stretched (1 to 8 #rrggbb).
Optionalopacity?: numberOpacity.
Optionalsize?: numberSprite width, in particle spacings (Δx / 2).
OptionalstrainScale?: numberHow much volume change spans the colour ramp: key = 0.5 + (J − 1) × strainScale.
Optionalresolution?: [number, number, number]Grid nodes along x, y, z (8…160 each). Fixed at construction.
Optionalseed?: string | numberSeed for the emission jitter.
Optionalsubsteps?: numberSubsteps per frame at least. More are added when the frame is longer than the stable step allows.
Optionalwalls?: booleanDomain sides act as slip walls (else particles that leave the domain freeze).
Kinematic colliders, world metres (as MPMSolver.setColliders).
ReadonlydataParticles.
ReadonlyfrictionFriction multiplier per node column (see MPMReference.setFriction).
ReadonlygridLast grid: x, y, z velocity and mass per node.
ReadonlyheightsBaked node-column heights (local).
ReadonlymaterialsMaterial names by index.
ReadonlyoptionsResolved settings.
Simulated seconds.
Total particle mass, kg.
Total particle momentum, kg·m/s.
Scales the terrain friction by friction(x, z) per node column, as MPMSolver.setFriction; null for 1.
Advances a frame of frameDt seconds in substeps (see mpmTimeStep); returns the substeps.
One P2G → grid → G2P substep of dt seconds.
The MLS-MPM substep in plain TypeScript, for tiny particle sets: the same weights, fixed-point P2G, grid update, terrain boundary and G2P as the GPU solver, in float64. Used by the tests to check the GPU (within float tolerance) and the physics (momentum, resting on terrain).