ModelingToolkit.jl Backend
Symbolic round-trip with Julia’s acausal modeling framework
Overview
The ModelingToolkit.jl backend generates Julia code for simulating dynamical systems using ModelingToolkit.jl (MTK). From a single YAML experiment specification, render_code("mtk") produces a self-contained Julia script that:
- Defines a
@componentwith symbolic parameters, variables, and equations - Compiles the system via
mtkcompile(structural simplification) - Constructs an
ODEProblemand solves it - Plots the solution
Unlike the NetworkDynamics.jl backend, which targets network-based simulations with explicit graph topology, the MTK backend works with standalone dynamical systems and leverages MTK’s symbolic equation processing.
Key Feature: Symbolic Round-Trip
The MTK backend supports a symbolic round-trip between SymPy and ModelingToolkit.jl:
- tvbo stores equations as SymPy expressions (parsed from YAML)
- The MTK template renders them to Julia’s symbolic DSL (
Dt(x) ~ ...) - MTK’s
mtkcompileperforms structural transformations (e.g., higher-order ODE lowering) - The transformed equations are extracted back into SymPy via
get_lowered_equations()
This means tvbo can leverage MTK’s symbolic engine for transformations that would be complex to implement in pure Python.
Examples
| Example | Features Demonstrated |
|---|---|
| Higher-Order ODE Lowering | equation_order, Dt(Dt(x)), automatic auxiliary variables, SymPy ↔︎ MTK round-trip |
Quick Start
from tvbo import SimulationExperiment
# Load experiment from YAML
exp = SimulationExperiment.from_file("yaml/lorenz_higher_order.yaml")
# Generate ModelingToolkit.jl code
julia_code = exp.render_code("mtk")
print(julia_code)
# Run the simulation (requires Julia + MTK)
result = exp.run("mtk")Symbolic Round-Trip
from tvbo.adapters.modelingtoolkit import ModelingToolkitAdapter
adapter = ModelingToolkitAdapter(exp)
# Get lowered first-order equations from MTK as SymPy
lowered = adapter.get_lowered_equations()
for name, eq in lowered["equations"].items():
print(eq)How it Works
The code generation pipeline:
- YAML → Python objects:
SimulationExperiment.from_file()parses the YAML intoDynamics,Coupling,Network, andIntegratorinstances - SymPy equations:
Dynamics.get_equations()parses equation strings into SymPy, respectingequation_orderfor higher-order derivatives - Mako template: The
mtkformat uses a single templatetvbo-mtk-experiment.jl.makothat generates:@componentfunction with@parameters,@variables, and equations- Nested
Dt(Dt(x))for higher-order ODEs mtkcompilefor structural simplificationODEProblem+solvewith the specified integrator
- Symbolic rendering: Equations are rendered to MTK syntax via
MTKPrinter(scalar operators, no broadcasting dots)