modonda (Python)
Public beta: the command line, the Python package and the VS Code extension are not published during the public beta. This page describes them for reference. To use ModOnda today, open the live workbench in your browser.
Python API of ModOnda, a fast Modelica compiler and simulator written in Rust. The compiler runs in-process: no OMC server, no Dymola licence, no files written unless you ask. It covers what scripts usually do with OMPython or Dymola's Python interface: load models, change parameters, simulate, read trajectories as NumPy arrays, linearize, and export FMUs.
The package was daedalus, then diokle, and is now modonda; import daedalus and import diokle need updating.
In plain terms: from a Python script or notebook you load a model, change its parameters, run it, and get the results as arrays you can plot or analyze. OMPython and Dymola's Python interface do the same job with other tools; this one needs no separate program.
import modonda
m = modonda.Model("library/ModOnda", "ModOnda.Examples.TorqueConverter.StallTest")
print(m.experiment, m.states)
m.set_parameters({"engine.J": 0.3}) # dotted names: mapping form
r = m.simulate(stop=2.0, n=1000, vars=["rpm_engine", "rpm_stall_theory"])
r.time, r["rpm_engine"] # NumPy arrays
df = r.to_pandas() # if pandas is installed
r.stats["solver"]["steps"]
lin = modonda.Model("crates/modonda-core/tests/models/linearize.mo", "Lin.MassSpringDamper").linearize()
lin.A, lin.B, lin.C, lin.D, lin.states, lin.inputs, lin.outputs
Install
From a checkout (needs a Rust toolchain):
python -m venv .venv && . .venv/bin/activate
pip install maturin
cd crates/modonda-py
maturin develop --release # or: maturin build --release && pip install target/wheels/*.whl
pip install pytest pandas && pytest
The wheel is abi3 (one build for CPython 3.9 and later). The crate is not a member
of the cargo workspace, so plain cargo build --workspace does not need Python.
API
modonda.Model(paths, name, *, index_reduction=True, tearing=True)
Loads paths (a path or list of paths: .mo files and library directories, like the
positional arguments of the modonda CLI; a directory with a package.mo is parsed
on demand) plus the directories in $MODONDA_LIB, and translates model name.
Failures raise modonda.TranslationError with the compiler's message.
| member | |
|---|---|
name, states, warnings |
model name, selected states, translation warnings |
experiment |
the experiment annotation as a dict |
stats |
translation statistics (as modonda check prints them) |
variables(kind=None) |
list of modonda.Variable (name, kind, type, unit, display_unit, description, state, output, protected, final, free, value); kind filters: "parameter", "input", "state", "continuous", "discrete", "constant" |
parameters() |
{name: value}: evaluated defaults with overrides applied |
set_parameters(mapping=None, **kw) |
override parameters or top-level inputs for later runs (unknown names raise KeyError); reset_parameters() clears them |
simulate(start, stop, n, tol, method, vars, *, interval, step, params, store_events, timeout) |
returns a Result; unset options come from the experiment annotation; method is bdf (default), radau, esdirk, dopri5, auto, rk4 or euler; params apply to this run only; the GIL is released while it runs |
derivatives(t, states, *, inputs, params, read) |
The right-hand side der(x) = f(t, x, u) at given points, as a dictionary of arrays: a way to check or plot the model's dynamics without simulating. |
linearize(at=None, *, start, tol, method, params, jacobian="exact") |
returns a Linearization (after initialization, or after simulating to at) |
steady(*, at=None, free=None, targets=None, tol=None, method=None, params=None) |
steady state (der(x) = 0), as the JSON object the core returns; free / targets trim |
linear_analysis(*, at=None, inputs=None, outputs=None, bode=False, step=False, reduce=None, lqr=None) |
linearize and analyze (poles, zeros, margins); JSON from the core. Needs a top-level input Real |
export_fmu(path=None, *, fmi_lib=None, fmi_version=2) |
writes an FMI 2.0 or 3.0 FMU (fmi_version=3) with Model Exchange and Co-Simulation, and returns its path |
Simulation failures raise modonda.SimulationError; its partial attribute holds the
Result up to the failure, if any. Both errors derive from modonda.ModOndaError.
modonda.Result
time (NumPy array), result["x"], names, "x" in result, len(result) (rows),
stats (solver steps, rejected steps, f-evals, Jacobians, events, timings), log,
final(name), at(name, t), unit(name), description(name), to_dict(),
to_pandas(), write_csv(path, names=None), write_mat(path) (Dymola-compatible).
modonda.read_mat(path) reads a .mat result file back.
modonda.Linearization
A, B, C, D (2-D NumPy arrays of der(x) = A x + B u, y = C x + D u),
states, inputs, outputs, the operating point x0, u0, y0, dx0, time,
eigenvalues(), to_modelica() (OpenModelica-style linearized_model), and
str(lin) for the text report of modonda linearize.
FMU export
The FMU embeds the model-independent FMI runtime library built from
crates/modonda-fmi (cargo build --release -p modonda-fmi gives
target/release/libmodonda_fmi.so). export_fmu finds it at fmi_lib=,
$MODONDA_FMI_LIB, inside the installed package, or next to a modonda executable
on PATH. fmi_version=2 (the default) writes an FMI 2.0 FMU; fmi_version=3 writes FMI 3.0 (fmiVersion="3.0" in modelDescription.xml).
Coming from OMPython / Dymola
OMPython ModelicaSystem / Dymola |
modonda |
|---|---|
ModelicaSystem(file, "M", ["Modelica"]) / openModel + translateModel |
Model([file, msl_dir], "M") |
getQuantities() / getParameters() |
variables() / parameters() |
setParameters(["a=1"]) |
set_parameters({"a": 1}) |
setSimulationOptions(...), simulate() / simulateModel |
simulate(stop=..., n=..., tol=..., method=...) |
getSolutions(["time", "x"]) / DyMat |
r.time, r["x"], r.to_pandas(), read_mat() |
linearize() / linearizeModel |
linearize() |
convertMo2Fmu / translateModelFMU |
export_fmu() |