Operator-Partitioned Engine (OP Engine) is a lightweight multiphysics solver core for time-dependent systems. It supports explicit ODE solvers and IMEX/operator-based schemes for PDE-like models while staying framework-agnostic.
- Shared solver surface for ODEs and operator-split PDEs.
- Strong typing, minimal dependencies (NumPy + SciPy for implicit paths).
- Separates state/time management (
ModelCore) from stepping logic (CoreSolver). - Optional adapters (e.g., flepimop2) without affecting the core API.
- IMEX paths accept externally supplied operator tuples; defaults remain explicit-only.
ModelCore: state/time manager; configure axes, dtype, and optional history.CoreSolver: explicit + IMEX methods (euler,heun,imex-euler,imex-heun-tr,imex-trbdf2); acceptsRunConfigwithAdaptiveConfig,DtControllerConfig, andOperatorSpecs.matrix_ops: Laplacian/Crank–Nicolson/implicit Euler/trapezoidal builders, predictor–corrector, implicit solve cache, Kronecker helpers, grouped aggregations.- Extras:
OperatorSpecs,RunConfig,AdaptiveConfig,DtControllerConfig,Operator,GridGeometry,DiffusionConfig.
pip install op_engineWith flepimop2 adapter:
pip install "op_engine[flepimop2]"importnumpyasnpfromop_engineimportModelCore, CoreSolver# Define RHSdefrhs(t, y):
s, i, r=ybeta, gamma=0.3, 0.1returnnp.array([-beta*s*i, beta*s*i-gamma*i, gamma*i])
# Time grid and statecore=ModelCore(n_states=3, n_subgroups=1, time_grid=np.linspace(0, 10, 101))
core.set_initial_state(np.array([0.999, 0.001, 0.0])[..., None])
solver=CoreSolver(core)
solver.run(rhs) # defaults to Heun/RK2solution=core.state_array# shape (n_timesteps, state, subgroup)importnumpyasnpfromop_engineimportCoreSolver, ModelCore, OperatorSpecsn=4times=np.linspace(0.0, 1.0, 11)
core=ModelCore(n_states=n, n_subgroups=1, time_grid=times)
core.set_initial_state(np.ones((n, 1)))
# Identity implicit operator along state axisL=np.eye(n)
R=np.eye(n)
ops=OperatorSpecs(default=(L, R))
defrhs(t, y):
return-0.1*ysolver=CoreSolver(core, operators=ops.default, operator_axis="state")
solver.run(rhs, config=None) # defaults: method="heun" (explicit)# For IMEX methods set method and operators via RunConfig:# from op_engine.core_solver import RunConfig, AdaptiveConfig, DtControllerConfigModelCore: state tensor + time grid manager; supports extra axes and optional history.CoreSolver: explicit and IMEX stepping; methods:euler,heun,imex-euler,imex-heun-tr,imex-trbdf2.- Operator utilities (
matrix_ops): Laplacian builders, Crank–Nicolson/implicit Euler/trapezoidal operators, predictor-corrector builders, implicit solve cache, Kronecker helpers, grouped aggregation utilities. - Configuration helpers:
RunConfig,OperatorSpecs,AdaptiveConfig,DtControllerConfigfor method/IMEX/adaptive control. - Adapters: optional flepimop2 integration (extra dependency) via entrypoints in the adapter package. The adapter merges any
mixing_kernelsalready computed by op_system (no automatic generation) and consumes config-supplied IMEX operator specs (dict orOperatorSpecs), forwarding the chosenoperator_axistoCoreSolver.
uv sync --dev
just ciMIT License