Rust-powered system simulation

Drop-in replacement for PathSim. 50-100x faster. Same Python API, powered by a Rust simulation engine with automatic compilation to optimized Rust IR.

Example
Loading...

About

FastSim is a Rust reimplementation of PathSim. The Python API matches PathSim line for line, so existing models run unchanged, but the simulation core and numeric hot path execute entirely in compiled Rust, producing typical speedups of 50 to 100 times. PathSim remains the open-source reference, well suited to learning, research, and small models. FastSim is the proprietary production build of the same API, available under a commercial license. Reach out via Consulting or Support above if you want to evaluate it for your team or set up access for a production deployment.

Beyond running the shared API faster, FastSim adds capabilities that have no PathSim equivalent: a JIT compiler that traces Python callbacks into optimized Rust IR with symbolic automatic differentiation, dedicated blocks for index-1 differential-algebraic equations, and a periodic steady-state solver that finds the limit cycle of a driven system directly via Anderson-accelerated shooting. Custom blocks you subclass yourself run at the same native speed, with only the constructor staying in Python.

FastSim is currently in private development. Leave your email below to hear when it launches.

Performance

FastSim vs PathSim

Cost per integration step across diverse dynamical systems. Lower is better. Each benchmark uses the same model, solver, and tolerances for both engines.

FastSim vs SciPy

Cost per integration step versus scipy.integrate.solve_ivp: RK45 for non-stiff, BDF for stiff. Plain uses an unmodified Python right-hand side; Numba JIT JIT-compiles the same RHS with numba.njit, the fast-path for advanced Python users. FastSim (blocks) runs the full block-diagram pipeline; FastSim (standalone) is the bare integrator. Lower is better.

FastSim vs CasADi

Cost per integration step versus CasADi CVODES (Sundials). FastSim (blocks) runs the full block-diagram pipeline; FastSim (standalone) is the bare integrator on the same right-hand side. Same tolerances throughout. Lower is better.

FastSim vs Diffrax

Cost per integration step versus Diffrax (JAX): Tsit5 for non-stiff, Kvaerno5 for stiff. Diffrax XLA-compiles the entire integration loop on first call; some highly stiff problems exceed Kvaerno's adaptive step budget and are omitted. FastSim (blocks) runs the full block-diagram pipeline; FastSim (standalone) is the bare integrator. Lower is better.

FastSim vs diffeqpy

Cost per integration step versus diffeqpy (DifferentialEquations.jl): Tsit5 for non-stiff, Rodas5P for stiff. Warm is steady-state cost; Cold includes Julia's first-call JIT compile. FastSim (blocks) runs the full block-diagram pipeline; FastSim (standalone) is the bare integrator. Lower is better.

JIT compilation

FastSim ships its own NumPy-compatible symbolic tracer. User-supplied Python callbacks get traced lazily the first time they run: the right-hand side of an ODE, the algebraic law of a Function, the output of a Source, the dynamics and outputs of a DynamicalSystem. Every arithmetic operation, every NumPy ufunc, every np.stack, np.sum, np.where or @ on the symbolic inputs records a node into an SSA graph. A pipeline of optimization passes (constant folding, CSE, algebraic identities, FMA fusion, dead-code elimination) simplifies the graph, which is then lowered into a flat Rust tape the simulation evaluates directly.

Once the trace succeeds, the Python interpreter is no longer involved inside the integration loop. Callbacks execute at Rust-native speed with no marshaling, no GIL, no per-op NumPy dispatch. The same graph is also differentiated symbolically to produce an analytical Jacobian that implicit solvers like ESDIRK43 consume for their Newton stage solve. Tracing covers every block that takes a user-supplied function: ODE, Function, Source, DynamicalSystem, DynamicalFunction, Wrapper, MassMatrixDAE, SemiExplicitDAE, and FullyImplicitDAE. If a callback uses something the tracer can't lower, that single block falls back to Python while the rest of the simulation keeps running native.

Differential-algebraic equations

FastSim treats index-1 DAEs as first-class blocks in three canonical forms. The SemiExplicitDAE block takes a system split into differential and algebraic parts and reduces it to a pure ODE by solving the algebraic constraint with an inner Newton iteration at every right-hand side evaluation, which means any of the 21 solvers can integrate it, including explicit ones. MassMatrixDAE covers the case where a constant mass matrix multiplies the derivative vector, with zero rows allowed so that physical conservation laws can enter the model directly. FullyImplicitDAE accepts the general residual and requires an implicit solver. All three blocks feed their analytical Jacobians to the stage solver when the user callback is traceable, which is what keeps the preconditioned Anderson acceleration fast.

Periodic steady state

FastSim finds the periodic limit cycle of a driven system directly via matrix-free Anderson-accelerated shooting on the period map g(x₀) = x(T; x₀). sim.periodic_steady_state(period, ...) integrates one period with the inner ODE solver of your choice — explicit, implicit, multistep, DAE-extended — then runs a per-block Anderson step that nudges x₀ toward the fixed point. No monodromy matrix is assembled or factorized; only function evaluations. Convergence uses the same WRMS-scaled NLS_COEF threshold every implicit-stage solver in FastSim does, so tolerances carry over from transient runs without retuning. Pays off when settling time exceeds roughly ten forcing periods — high-Q resonators, weakly-damped loops, large LC filters.

Native FMI 3.0

FastSim implements the FMI 3.0 standard directly in Rust. ModelExchangeFMU exposes the FMU's derivative function as a block right-hand side that the solver integrates alongside everything else, with event indicators translating into ZeroCrossing events and FMU-announced time events populating a ScheduleList. CoSimulationFMU runs the FMU on a fixed communication grid, scheduled through a block-internal event, and the full event-mode handshake runs whenever the FMU signals an event. The FMU behaves like any other block in the graph.

Get notified

FastSim is in private development. Leave your email and we’ll send a single message when it’s available, with details on access and licensing. No newsletter, no spam. For evaluation or production access today, reach out via Consulting or Support above.