Time Evolution¶
The codebase supports several real-time integration strategies. The best choice depends on accuracy needs, grid topology, and available hardware.
Solver families¶
| Solver | Method key | Typical use |
|---|---|---|
| Reference finite difference RK4 | rk4-fdm |
Baseline correctness and convergence studies |
| Fused finite difference RK4 | rk4-fdm-fused |
Faster CPU or backend-agnostic finite-difference runs |
| CUDA fused RK4 | rk4-cuda |
GPU production runs |
| Split-step FFT | split-step-fft |
Second-order Strang splitting on periodic grids |
| CUDA split-step FFT | split-step-fft-cuda |
Second-order spectral evolution on a periodic CUDA grid |
| Interaction-picture RK4 | ip-rk4 |
Spectral-style evolution when its assumptions fit |
| ETD-RK2 | etd-rk2 |
Periodic spectral evolution with exponential differencing |
| GPU-native Lawson IF-RK | ifrk-fft-cuda |
Selectable fourth-, fifth-, seventh-, eighth-, or ninth-order spectral runs |
| Lawson IF-RK4 alias | ifrk4-fft-cuda |
Historical fourth-order method name |
Choosing a solver¶
Recommended order:
- Prototype with
rk4-fdm. - Confirm time-step and grid convergence.
- Move to
rk4-fdm-fusedorrk4-cuda(FDM production) once the physics setup is stable. - For periodic-grid spectral campaigns, use
ifrk-fft-cuda(GPU-native with built-in reservoirs, stage-coupled). - Use
split-step-fftorsplit-step-fft-cudafor second-order spectral evolution on periodic grids, including reservoir-coupled cases. Neither evaluateskinetic_relaxation_eta.
Spectral solver limitations¶
All spectral solvers (split-step-fft, split-step-fft-cuda, ip-rk4, etd-rk2, ifrk-fft-cuda, ifrk4-fft-cuda)
are FFT-only and therefore accept the periodic grid only. Selecting a
closed-interval grid raises SolverCompatibilityError at configuration time.
For closed-interval domains use the finite-difference family: rk4-fdm,
rk4-fdm-fused or rk4-cuda.
See Running on GPUs for CUDA solver requirements and CUDA graph chunking.
etd-rk2 advances the reservoir via a separate midpoint step, not stage-coupled
with psi. It is not a production path for quadratic-double threshold studies.
Time-step guidance¶
There is no hard-coded CFL guard in the runtime path. You must validate dt yourself.
Practical procedure:
- Run the same case with progressively smaller
dt. - Track observables such as maximum density, integrated norm, and threshold times.
- Stop decreasing
dtonly when those observables are stable at the tolerance your study needs.
The bundled tests already encode this mindset by checking decay laws, spatial uniformity, and solver-to-solver agreement.
Real time only¶
The current package does not expose a dedicated imaginary-time evolution driver. If you need true ground-state workflows, add them explicitly and document the numerical assumptions before using them for production research.
Batched simulations¶
A leading axis runs independent simulations on one grid. Construct a state and
zero reservoir fields with the same batch_size:
from polarism import SimulationState, create_reservoir
state = SimulationState(grid, seed=7, batch_size=3)
reservoir = create_reservoir(cfg.reservoir, cfg.physics, grid,
precision="double", batch_size=3)
state.psi and every reservoir field have shape (3, ny, nx). The seed
produces the same initial wavefunction in every member as a single unbatched
state with that seed; assign state.psi to customize members. Pass one shared
(ny, nx) potential and a callable pump(t) returning either a shared
(ny, nx) pump or individual (3, ny, nx) pump fields. The boundary profile
and mask are shared across the batch. reservoir.reset(batch_size=3) restores
batched zero fields; reservoir.reset() restores unbatched zero fields.
All built-in solvers accept batched states. Spatial derivatives and FFTs use the last two axes, so batch members do not interact. See the solver batch capability table for CUDA paths.