import type { ComputeNode, Renderer, Vector3 } from 'three/webgpu'; import type { TSLStorageNode, TSLUintNode, TSLUniformNode, TSLVec3Node } from '../../types/tsl.cjs'; import { RangedReadback } from '../../Utils/RangedReadback.cjs'; import { type MPMMaterialModel } from './MPMFluidModel.cjs'; import type { MPMGridContributionMode, MPMGridMirrorStorageNode } from './MPMKernelUtils.cjs'; import { MPMBinningPasses } from './compute/computeBinningPasses.cjs'; import { type MPMBoundaryOptions, type MPMGridForce, type MPMIntegrationProfile, type MPMParticleForce, type MPMParticleUpdate } from './compute/MPMComputeContracts.cjs'; /** Kernel graph shape used for particle-to-grid transfer. */ export type MPMFormulation = 'fused' | 'reference'; /** Requested particle-to-grid implementation, including feature detection. */ export type MPMP2GMode = MPMGridContributionMode | 'auto'; /** Optional spatial binning cadence for particle locality. */ export interface MPMSortingOptions { /** Grid cells grouped along each sorting axis. */ blockSize?: number | undefined; /** Number of frames between sorting passes. */ interval?: number | undefined; } /** Normalized sorting values stored by the solver. */ export interface MPMResolvedSortingOptions { /** Positive grid-cell block size. */ blockSize: number; /** Positive frame interval between sorting passes. */ interval: number; } /** Courant–Friedrichs–Lewy substep controls. */ export interface MPMCFLConfiguration { /** Maximum normalized travel distance allowed per substep. */ target?: number | undefined; /** Upper bound for adaptive substeps. */ maxSubsteps?: number | undefined; } /** Opt-in asynchronous solver diagnostics. */ export interface MPMDiagnosticsOptions { /** Audit fixed-point grid accumulation for overflow risk. */ overflowAudit?: boolean | undefined; } /** Latest resolved diagnostic counters from GPU storage. */ export interface MPMDiagnosticsSnapshot { /** Accumulated fixed-point momentum magnitude. */ momentum: number; /** Accumulated fixed-point particle mass. */ mass: number; /** Maximum squared particle speed encoded by the diagnostic pass. */ speedSquared: number; /** Whether mass or momentum reached the audited fixed-point limit. */ overflow: boolean; } /** Frame metadata supplied when resolving caller-owned post passes. */ export interface MPMStepPostPassContext { /** Zero-based solver frame before the current submission. */ frame: number; /** Full frame delta in seconds. */ dt: number; /** Number of solver substeps submitted for the frame. */ substeps: number; } /** Compute passes appended after the final solver substep. */ export type MPMPostPassList = ReadonlyArray; /** Static or frame-resolved compute passes appended to each solver submission. */ export type MPMPostPasses = MPMPostPassList | ((context: MPMStepPostPassContext) => MPMPostPassList); /** TSL values available while initializing one particle. */ export interface MPMSeedContext { /** Active particle index. */ index: TSLUintNode; } /** Optional particle state returned from a seed initializer. */ export interface MPMSeedState { /** Normalized-domain particle position. */ position?: TSLVec3Node | undefined; /** Initial normalized-domain particle velocity. */ velocity?: TSLVec3Node | undefined; } /** TSL callback that initializes one active particle. */ export type MPMSeedInitializer = (context: MPMSeedContext) => MPMSeedState | null | undefined | void; /** Construction options for {@link MPMSolver}. */ export interface MPMSolverOptions { /** Maximum allocated particle count. */ capacity?: number | undefined; /** Integer dimensions of the normalized-domain transfer grid. */ gridSize?: Vector3 | undefined; /** Material-owned particle fields and constitutive response. */ material?: MPMMaterialModel | undefined; /** Fused production graph or split reference graph. */ formulation?: MPMFormulation | undefined; /** Production behavior or strict Three.js r185 comparison behavior. */ integrationProfile?: MPMIntegrationProfile | undefined; /** Acceleration applied in normalized-domain units. */ gravity?: Vector3 | undefined; /** Velocity clamp used by the grid update. */ maxVelocity?: number | undefined; /** Threads requested for particle compute workgroups. */ workgroupSize?: number | undefined; /** Minimum fixed substeps per frame. */ substeps?: number | undefined; /** Optional adaptive CFL substep policy. */ cfl?: MPMCFLConfiguration | null | undefined; /** Optional particle locality sorting policy. */ sorting?: MPMSortingOptions | null | undefined; /** Atomic, subgroup, or automatically selected particle-to-grid path. */ p2gMode?: MPMP2GMode | undefined; /** Whether the transfer predicts density during particle-to-grid work. */ densityPrediction?: boolean | undefined; /** Pack the non-atomic grid mirror into half-precision lanes. */ packedGridMirror?: boolean | undefined; /** Partial normalized-domain boundary behavior. */ boundary?: Partial | undefined; /** Optional asynchronous overflow and CFL diagnostics. */ diagnostics?: MPMDiagnosticsOptions | null | undefined; /** Caller hook that modifies grid velocity. */ gridForce?: MPMGridForce | null | undefined; /** Caller hook that modifies particle velocity. */ particleForce?: MPMParticleForce | null | undefined; /** Caller hook that observes or adjusts the updated particle state. */ onParticleUpdate?: MPMParticleUpdate | null | undefined; /** Caller-owned compute passes appended after the final substep. */ postPasses?: MPMPostPasses | null | undefined; } /** Mutable TSL uniforms shared by the solver kernel graph. */ export interface MPMSolverUniforms { /** Integer transfer-grid dimensions. */ gridSize: TSLUniformNode<'vec3', Vector3>; /** Current substep duration in seconds. */ dt: TSLUniformNode<'float', number>; /** Simulation time at the start of the submitted frame. */ time: TSLUniformNode<'float', number>; /** Normalized-domain gravity vector. */ gravity: TSLUniformNode<'vec3', Vector3>; /** Maximum allowed velocity magnitude. */ maxVelocity: TSLUniformNode<'float', number>; /** Active particle prefix length. */ particleCount: TSLUniformNode<'uint', number>; } export type MPMParticleKernelKey = 'p2g' | 'p2gScatter' | 'p2gStress' | 'g2p'; /** Named compute kernels that make up one MPM substep. */ export interface MPMCoreKernels { /** Clears atomic grid state before transfer. */ clearGrid: ComputeNode; /** Updates grid velocity, forces, and boundaries. */ gridUpdate: ComputeNode; /** Transfers grid state back to particles. */ g2p: ComputeNode; /** Fused particle-to-grid transfer when using the production formulation. */ p2g?: ComputeNode | undefined; /** Reference-formulation particle mass and momentum scatter. */ p2gScatter?: ComputeNode | undefined; /** Reference-formulation stress scatter. */ p2gStress?: ComputeNode | undefined; } /** Compute-node array carrying Three.js batch metadata. */ export interface MPMComputeBatch extends Array { /** Stable batch identifier consumed by the renderer. */ id: string; /** Human-readable compute batch name. */ name: string; /** Renderer marker identifying the array as one compute node. */ isComputeNode: true; } /** Paired kernel lookup and ordered compute batch for one solver graph. */ export interface MPMCoreGraph { /** Named kernels for inspection and dispatch-size updates. */ kernels: MPMCoreKernels; /** Ordered passes submitted for each substep. */ passes: MPMComputeBatch; } /** Diagnostic description of the most recently submitted solver frame. */ export interface MPMStepStats { /** Submitted pass names in execution order. */ passes: string[]; /** Total compute dispatches in the batch. */ dispatches: number; /** Renderer compute submissions used by the step. */ submissions: number; /** Solver substeps represented by the batch. */ substeps: number; /** Formulation used to build the pass graph. */ formulation: MPMFormulation; /** Active integration compatibility profile. */ integrationProfile: MPMIntegrationProfile; /** Whether particle locality sorting ran this frame. */ sorted: boolean; /** Particle-to-grid implementation selected for the frame. */ p2gMode: MPMGridContributionMode; /** Active particle prefix length. */ particleCount: number; /** Latest available asynchronous counters, when enabled. */ diagnostics?: MPMDiagnosticsSnapshot | undefined; } /** Reusable WebGPU MLS-MPM/APIC solver over a normalized [0,1]^3 domain. */ export declare class MPMSolver { /** Maximum allocated particle count. */ capacity: number; /** Particle compute workgroup width. */ workgroupSize: number; /** Integer dimensions of the transfer grid. */ gridSize: Vector3; /** Total number of allocated grid cells. */ gridCellCount: number; /** Constitutive model and material-owned particle fields. */ material: MPMMaterialModel; /** Fused or split-reference kernel formulation. */ formulation: MPMFormulation; /** Active production or strict-comparison behavior. */ integrationProfile: MPMIntegrationProfile; /** Requested particle-to-grid implementation. */ p2gMode: MPMP2GMode; /** Whether density is predicted during particle-to-grid transfer. */ densityPrediction: boolean; /** Particle-to-grid implementation selected for the last frame. */ resolvedP2GMode: MPMGridContributionMode; /** Whether the read-only grid mirror uses packed half precision. */ packedGridMirror: boolean; /** Resolved locality-sorting policy, or null when disabled. */ sorting: MPMResolvedSortingOptions | null; /** Adaptive substep policy, or null when disabled. */ cfl: MPMCFLConfiguration | null; /** Opt-in diagnostic policy, or null when disabled. */ diagnostics: MPMDiagnosticsOptions | null; /** Minimum fixed substeps submitted per frame. */ substeps: number; /** Resolved normalized-domain boundary behavior. */ boundary: MPMBoundaryOptions; /** Optional caller hook applied during grid update. */ gridForce: MPMGridForce | null; /** Optional caller hook applied during particle update. */ particleForce: MPMParticleForce | null; /** Optional caller hook invoked with updated particle state. */ onParticleUpdate: MPMParticleUpdate | null; /** Caller-owned compute passes appended to a frame submission. */ postPasses: MPMPostPasses | null; /** Accumulated simulation time in seconds. */ time: number; /** Number of completed solver frames. */ frame: number; /** Primary GPU particle struct storage consumed by render mirrors. */ particleBuffer: TSLStorageNode<'struct'>; /** Alternate particle storage allocated when sorting is enabled. */ particlePongBuffer: TSLStorageNode<'struct'> | null; /** Atomic fixed-point transfer grid. */ gridAtomicBuffer: TSLStorageNode<'struct'>; /** Read-only float or packed grid state after transfer. */ gridMirrorBuffer: MPMGridMirrorStorageNode; /** Optional atomic diagnostic counters. */ diagnosticsBuffer: TSLStorageNode<'uint'> | null; /** Mutable uniforms shared by all solver kernels. */ uniforms: MPMSolverUniforms; /** Named kernels for the primary unsorted graph. */ kernels: MPMCoreKernels | null; /** Ordered primary compute batch. */ passes: MPMComputeBatch | null; /** Statistics captured for the most recent step. */ lastStepStats: MPMStepStats; /** Exact compute batch submitted by the most recent step. */ lastSubmittedBatch: MPMComputeBatch | null; _particleCount: number; _renderer: Renderer | null; _disposed: boolean; _seedInitializer: MPMSeedInitializer | null; _seedPass: ComputeNode | null; _diagnosticsReadbackPending: boolean; _diagnosticsPromise: Promise | null; _latestMaxSpeed: number; _latestDiagnostics: MPMDiagnosticsSnapshot; _diagnosticsReadback: RangedReadback | null; _binning: MPMBinningPasses | null; _clearDiagnostics: ComputeNode | null; _overflowAudit: ComputeNode | null; _sortedKernels: MPMCoreKernels | null; _sortedPasses: MPMComputeBatch | null; _subgroupKernels: MPMCoreKernels | null; _subgroupPasses: MPMComputeBatch | null; _sortedSubgroupKernels: MPMCoreKernels | null; _sortedSubgroupPasses: MPMComputeBatch | null; _strictParticleSource: TSLStorageNode<'struct'> | null; _strictParticleState: Float32Array | null; _strictParticleCount: number; _particleResetPass: ComputeNode | null; /** Allocate a reusable solver graph and its fixed-capacity GPU storage. */ constructor({ capacity, gridSize, material, formulation, integrationProfile, gravity, maxVelocity, workgroupSize, substeps, cfl, sorting, p2gMode, densityPrediction, packedGridMirror, boundary, diagnostics, gridForce, particleForce, onParticleUpdate, postPasses, }?: MPMSolverOptions); _buildCoreGraph(particles: TSLStorageNode<'struct'>, particlesWrite?: TSLStorageNode<'struct'>, p2gMode?: MPMGridContributionMode): MPMCoreGraph; _buildCorePasses(): void; /** Active prefix of the allocated particle storage. */ get particleCount(): number; /** Clamp and apply the active particle prefix to every particle dispatch. */ set particleCount(value: number); /** * Replace the active particle prefix from a shared CPU fixture and reset time. * The byte-compatible strict r185 fixture uses the solver's 20-float fluid * stride; material-specific structs are accepted when their full stride is * supplied. Loading happens outside the measured step graph. */ loadParticleState(state: Float32Array, particleCount?: number): this; /** Read the exact active particle prefix from GPU storage. */ readParticleState(renderer: Renderer): Promise; /** Restore the immutable strict source into active GPU particle storage. */ resetParticleState(renderer: Renderer, state?: Float32Array | null, particleCount?: number | null): Promise; _buildSeedPass(initializer: MPMSeedInitializer): void; /** GPU particle initialization; safe to call again to reset the solver. */ seed(renderer: Renderer, initializer?: MPMSeedInitializer | null): this; /** Advance all configured substeps in one renderer.compute() submission. */ step(renderer: Renderer, dt: number): this; _queueDiagnosticsReadback(renderer: Renderer | null): Promise | undefined; /** Resolve the latest opt-in CFL/overflow counters. */ resolveDiagnostics(renderer?: Renderer | null): Promise; /** Return a defensive snapshot of the most recent step statistics. */ getLastStepStats(): MPMStepStats; /** Release solver-owned compute nodes, storage, sorting, and readback state. */ dispose(): void; }