skills/fluidsim/references/advanced_features.md
FluidSim assembles forcing classes through the selected solver's registry. NS2D 0.9 advertises:
in_scriptin_script_coarsepseudo_spectralproportionaltcrandomtcrandom_anisotropicAvailability and default forced variable are solver-specific.
Base fields:
params.forcing.enable = True
params.forcing.type = "tcrandom"
params.forcing.forcing_rate = 1.0
params.forcing.key_forced = None
params.forcing.nkmin_forcing = 4
params.forcing.nkmax_forcing = 5
params.forcing.tcrandom.time_correlation = "based_on_forcing_rate"
Current source converts nkmin_forcing/nkmax_forcing to dimensional
wave-number bounds using the operator's wave-number spacing. Inspect the
resulting forced region; the integers are not necessarily physical wave
numbers.
Current normalized-forcing fields include:
params.forcing.normalized.constant_rate_of = None
params.forcing.normalized.type = "2nd_degree_eq"
params.forcing.normalized.which_root = "minabs"
The implementation can solve a quadratic normalization so the time-step-mean
injection of a quadratic quantity matches forcing_rate. The exact quadratic
quantity and key depend on the solver/forced field. Therefore:
key_forced.Do not call forcing_rate “energy input” without verifying the selected class.
The 0.9 field is:
params.forcing.tcrandom.time_correlation = "based_on_forcing_rate"
or a finite time value. Current source derives the default period as a power of the forcing rate and stores two random seeds plus the last-change time in state parameters. FluidSim 0.9.0 writes these state parameters into restart files; 0.8.6 fixed a time-correlated forcing restart bug.
For reproducibility, preserve:
Use the solver's registered InScriptForcing* interface and documented
compute_forcing_fft_each_time or coarse equivalent. Do not monkey-patch a
method with a lambda copied from an old example:
Implement a reviewed subclass/extension with unit tests on tiny sequential and MPI layouts. Validate zero-net/target injection, symmetry, and budget effects.
sim.oper provides solver-selected grids, FFT/IFFT, differentiation, vector
calculus, projections, spectra, dealiasing, and distributed-array helpers.
Method names and array layouts depend on operator class.
Never assume:
nx, ny, nz.oper.sum_wavenumbers.Use documented operator methods and inspect:
print(type(sim.oper))
print(sim.oper.axes)
print(sim.params.oper)
For custom diagnostics, test sequential and distributed shapes and compare against analytical transforms at tiny resolution.
The common Cartesian field is:
params.oper.coef_dealiasing = 2 / 3
params.oper.truncation_shape = "cubic"
FluidSim also implements phase-shift time schemes. A coefficient or scheme name does not prove alias removal for a custom nonlinearity. Verify:
Do not combine an aggressive cutoff and high-order dissipation merely to obtain a visually smooth spectrum.
Documented pseudospectral names:
EulerEuler_phaseshiftEuler_phaseshift_randomRK2RK2_trapezoidRK2_phaseshiftRK2_phaseshift_randomRK2_phaseshift_random_splitRK2_phaseshift_exactRK4The implementation treats linear terms with exact coefficients in its pseudospectral stepper and evaluates nonlinear tendencies according to the named scheme. Verify source and solver coupling before making an order/stability claim.
Always check:
deltat.cfl_coef/deltat_max comparison.USE_CFL=True only activates the solver's CFL logic; it does not guarantee all
accuracy/stability constraints are resolved.
in_script gives direct control, but use current state keys:
Simul with init_fields.type = "in_script".Old examples that fill vx/vy and then call a
spectral-to-physical conversion can overwrite the intended state. NS2D 0.9
documentation shows physical keys including ux, uy, and rot; use the
selected solver's actual keys.
FluidSim's InfoSolver/class registry supports extensions. For a research
extension:
Avoid private-method snippets from old versions without source review.
Installed methods are entry points. Discover them:
from fluidfft import get_methods
print(sorted(get_methods(ndim=2)))
print(sorted(get_methods(ndim=3)))
Set per run:
params.oper.type_fft = "fft2d.with_pyfftw"
or use FLUIDSIM_TYPE_FFT2D/FLUIDSIM_TYPE_FFT3D before process start.
Record actual method and plugin distribution.
FluidFFT's 2019 primary paper demonstrates:
Do not transfer its fastest-method or wall-time numbers to current hardware. Benchmark a bounded representative shape in the target environment.
Never call mpirun, mpiexec, srun, qsub, sbatch, OAR tools, or a
FluidDyn cluster submitter automatically.
Required preflight:
Output behavior can differ with MPI-enabled h5py. Standard h5py usually causes
rank 0 to write assembled state; MPI h5py can use an mpio driver. Verify the
locked h5py build and output path with a tiny test.
Do not loop over simulations and start them directly in one script by default. Instead:
Analyze observables with refinement and stochastic uncertainty, not only final values.
Physical-state saving is checkpoint creation:
params.output.periods_save.phys_fields = 1.0
But checkpoint usability requires:
/state_phys datasets./info_simul/params and solver metadata.Use the bundled compatibility checker before every continuation. A mechanically compatible state can still be scientifically invalid after changed viscosity, forcing, timestep, backend, or resolution.
Practical migrations from the previous skill:
>=3.11, not >=3.9 for 0.9.0.fluidsim==0.9.0 and lock dependencies.fft extra.time_stepping.cfl_coef, not CFL.forcing.tcrandom.time_correlation, not a flat field.plate2d, not fvk..nc, not .h5; spectra remain .h5.spect_energy_budg.h5, not a timestamped budget glob.load_for_restart/fluidsim-restart --only-check; preserve state
parameters and hashes.