/** * cpml.ts — Convolutional Perfectly Matched Layer (CPML) numerics for FDTD. * * Pure, allocation-light helpers for the Roden–Gedney complex-frequency-shifted * CPML used by {@link FDTDSolver} to terminate open boundaries with very low * reflection. This module is intentionally free of Yee bookkeeping so the * grading and recursion coefficients can be unit-tested against their analytic * limits (no loss ⇒ pass-through; deep PML ⇒ strong decay). * * ## Stretched-coordinate formulation * * Each PML axis replaces the spatial derivative ∂/∂x by the stretched operator * * ∂/∂x → (1/κ_x) ∂/∂x + ψ_x * * where ψ_x is a recursively-updated convolution memory field: * * ψ_x^{n} = b_x · ψ_x^{n-1} + a_x · (ΔF/Δx)^{n} * b_x = exp( −(σ_x/κ_x + α_x) · Δt/ε₀ ) * a_x = σ_x / (κ_x (σ_x + κ_x α_x)) · (b_x − 1) * * Outside the PML region σ_x = α_x = 0 and κ_x = 1, giving b_x = 1, a_x = 0, * 1/κ_x = 1 — i.e. ψ stays zero and the operator collapses to the ordinary * central difference. This is what makes the layer reflectionless to machine * grading: the interior update is bit-identical to plain FDTD. * * ## Conductivity grading * * σ(x) = σ_max · (d/L)^m with polynomial order m (3–4 typical) and depth d into * the layer (0 at the inner edge, L at the outer PEC wall). σ_max is chosen for * a target theoretical reflection R₀: * * σ_max = −(m+1) · ln(R₀) / (2 · η₀ · L) * * with η₀ = √(μ₀/ε₀) the vacuum impedance and L = thickness · Δ the physical * layer depth. * * @module simulation */ declare const EPS0 = 8.8541878128e-12; declare const ETA0: number; export interface CpmlParams { /** Polynomial grading order m (default 3). */ order?: number; /** Target theoretical reflection R₀ at normal incidence (default 1e-6). */ targetReflection?: number; /** Max coordinate-stretch κ_max ≥ 1 (default 1 = pure CFS loss, no stretch). */ kappaMax?: number; /** Max frequency-shift α_max ≥ 0 (default 0). Improves evanescent/late-time. */ alphaMax?: number; } /** Per-grid-line CPML recursion coefficients along one axis. */ export interface CpmlProfile { /** Decay factor b at each grid index (1 outside the PML). */ b: Float32Array; /** Convolution weight a at each grid index (0 outside the PML). */ a: Float32Array; /** Inverse coordinate stretch 1/κ at each grid index (1 outside the PML). */ invKappa: Float32Array; /** True if any index carries loss (a PML region exists on this axis). */ active: boolean; } /** * Build CPML recursion coefficients sampled at `numPoints` grid locations along * one axis. `halfOffset` shifts the sample point by +0.5 cell (use 0.5 for * H-aligned / face-staggered components, 0 for E-aligned / edge components). * * Returns unit/pass-through coefficients when `thickness <= 0`. */ export declare function computeAxisProfile(numPoints: number, halfOffset: 0 | 0.5, ncells: number, thickness: number, cellSize: number, dt: number, params?: CpmlParams): CpmlProfile; /** * Recursive-convolution update for one ψ memory cell. * * ψ ← b·ψ + a·derivative (derivative = ΔF/Δ, the finite difference / spacing) * * Returns the new ψ. Kept as a tiny pure function so the recursion is * unit-testable in isolation. */ export declare function updatePsi(psi: number, b: number, a: number, derivative: number): number; export { EPS0 as CPML_EPS0, ETA0 as CPML_ETA0 }; //# sourceMappingURL=cpml.d.ts.map