Modelica to FMU converter with Dymola and OpenModelica support.
- Multiple backends: Supports both Dymola and OpenModelica compilers
- Automatic backend selection: Automatically detects available compilers
- FMI 1.0, 2.0, and 3.0 support: Generate Co-Simulation and Model Exchange FMUs
- Python API: Programmatic access for integration into workflows
- Command-line interface: Simple CLI with
compileandchecksubcommands
Install the latest stable release from PyPI using uv:
uv pip install feelpp-mo2fmuTo use OpenModelica as a backend, install with the optional dependency:
uv pip install "feelpp-mo2fmu[openmodelica]"This will install OMPython for Python integration with OpenModelica.
To run simulations and validate FMUs (useful for testing):
uv pip install "feelpp-mo2fmu[simulation]"This will install FMPy for FMU simulation and validation.
For development or to use the latest unreleased features:
git clone https://github.com/feelpp/mo2fmu.git
cd mo2fmu
uv venv .venv-mo2fmu
source .venv-mo2fmu/bin/activate # On Windows: .venv-mo2fmu\Scripts\activate
uv pip install -e ".[all]"The Dymola installation location can be configured via environment variables:
export DYMOLA_ROOT=/opt/dymola-2025xRefresh1-x86_64/
export DYMOLA_EXECUTABLE=/usr/local/bin/dymola
export DYMOLA_WHL=Modelica/Library/python_interface/dymola-2025.1-py3-none-any.whlEnvironment Variables:
DYMOLA_ROOT: Path to Dymola installation root directory (default:/opt/dymola-2025xRefresh1-x86_64/)DYMOLA_EXECUTABLE: Path to Dymola executable binary (default:/usr/local/bin/dymola)DYMOLA_WHL: Relative path to Dymola Python wheel from DYMOLA_ROOT (default:Modelica/Library/python_interface/dymola-2025.1-py3-none-any.whl)DYMOLA_STARTUP_RETRY_TIMEOUT: Time in seconds to wait for a shareable Dymola seat before failing (default:0)DYMOLA_STARTUP_RETRY_INTERVAL: Delay in seconds between startup retries while waiting for a seat (default:30)
OpenModelica can be configured via environment variables:
export OPENMODELICA_HOME=/usr/lib/omcEnvironment Variables:
OPENMODELICA_HOME: Path to OpenModelica installation (default: auto-detected)
The mo2fmu CLI provides two subcommands: compile and check.
$ mo2fmu --help
Usage: mo2fmu [OPTIONS] COMMAND [ARGS]...
mo2fmu - Convert Modelica models to Functional Mock-up Units (FMUs).
Use 'mo2fmu compile' to generate FMUs or 'mo2fmu check' to verify compilers.
Options:
-v, --version Show version information.
--help Show this message and exit.
Commands:
check Check availability of Modelica compilers and their FMI support.
compile Compile a Modelica model to FMU.Generate FMUs from Modelica models:
$ mo2fmu compile --help
Usage: mo2fmu compile [OPTIONS] MO OUTDIR
Compile a Modelica model to FMU.
Options:
--name TEXT Custom name for the FMU (default: .mo file stem).
-l, --load TEXT Load one or more Modelica packages.
--flags TEXT Compiler-specific flags for FMU translation.
-t, --type [all|cs|me|csSolver] FMI type: cs (Co-Simulation), me (Model Exchange),
all, or csSolver.
--fmi-version [1|2|3] FMI version. FMI 3.0 requires Dymola 2024+
or OpenModelica 1.21+.
-b, --backend [dymola|openmodelica|auto]
Modelica compiler backend (default: auto-detect).
--dymola PATH Path to Dymola root directory.
--dymola-exec PATH Path to Dymola executable.
--dymola-whl PATH Path to Dymola wheel file (relative to Dymola root).
-v, --verbose Enable verbose output.
-f, --force Overwrite existing FMU.
--help Show this message and exit.Compile Examples:
# Basic compilation (auto-detect backend)
mo2fmu compile model.mo ./output
# Compile with OpenModelica backend
mo2fmu compile --backend openmodelica model.mo ./output
# Compile FMI 3.0 Co-Simulation FMU with verbose output
mo2fmu compile -v --fmi-version 3 --type cs model.mo ./output
# Force overwrite existing FMU
mo2fmu compile -f model.mo ./output
# Load additional Modelica packages
mo2fmu compile --load package1.mo --load package2.mo model.mo ./outputVerify compiler availability and FMI support:
$ mo2fmu check --help
Usage: mo2fmu check [OPTIONS]
Check availability of Modelica compilers and their FMI support.
Options:
--dymola PATH Path to Dymola root directory.
--dymola-exec PATH Path to Dymola executable.
--dymola-whl PATH Path to Dymola wheel file (relative to Dymola root).
--json Output results as JSON.
--help Show this message and exit.Check Examples:
# Check all available compilers
mo2fmu check
# Output as JSON (for scripting)
mo2fmu check --json
# Check with custom Dymola path
mo2fmu check --dymola /opt/dymola-2024xThe recommended API provides a clean interface with automatic backend selection:
from feelpp.mo2fmu import CompilationRequest, checkCompilers, compileFmu, compileFmus, getCompiler
# Auto-detect and use available compiler
result = compileFmu("path/to/model.mo", "./output")
if result.success:
print(f"FMU created at {result.fmu_path}")
else:
print(f"Error: {result.error_message}")
# Explicitly use OpenModelica
result = compileFmu("path/to/model.mo", "./output", backend="openmodelica")
# Compile FMI 3.0 Model Exchange FMU
result = compileFmu(
"path/to/model.mo",
"./output",
fmiType="me",
fmiVersion="3",
verbose=True,
)
# Check available compilers
available = checkCompilers()
for name, info in available.items():
print(f"{name}: available={info['available']}, fmiSupport={info.get('fmiSupport', [])}")
# Get a specific compiler instance for more control
compiler = getCompiler("openmodelica")
if compiler.is_available:
print(f"Using {compiler.name}")
# Batch compilation with one Dymola session
requests = [
CompilationRequest(
mo="path/to/model_a.mo",
outdir="./output/a",
fmu_model_name="ModelA",
force=True,
),
CompilationRequest(
mo="path/to/model_b.mo",
outdir="./output/b",
fmu_model_name="ModelB",
force=True,
),
]
results = compileFmus(requests, backend="dymola")For full control, use the compiler classes directly:
from feelpp.mo2fmu import (
DymolaCompiler,
OpenModelicaCompiler,
ModelicaModel,
CompilationConfig,
)
from pathlib import Path
# Using OpenModelica
compiler = OpenModelicaCompiler()
if compiler.is_available:
model = ModelicaModel(Path("path/to/model.mo"))
config = CompilationConfig(
fmi_type="cs", # Co-Simulation
fmi_version="3", # FMI 3.0
verbose=True,
)
result = compiler.compile(model, Path("./output"), config)
if result.success:
print(f"FMU created: {result.fmu_path}")
else:
print(f"Compilation failed: {result.error_message}")
# Using Dymola
compiler = DymolaCompiler()
if compiler.is_available:
result = compiler.compile(model, Path("./output"), config)The original API is still available for backward compatibility:
from feelpp.mo2fmu import mo2fmu
mo2fmu(
mo="path/to/model.mo",
outdir="path/to/output/dir",
fmumodelname="MyFMUModel",
load=("Modelica", "SomePackage"),
flags=("-d=initialization",),
type="cs",
version="2",
dymola_root="/path/to/dymola/root",
dymolapath="/path/to/dymola/executable",
dymolawhl="path/to/dymola.whl",
verbose=True,
force=False,
backend="dymola", # or "openmodelica", "auto"
)| Feature | Dymola | OpenModelica |
|---|---|---|
| License | Commercial | Open Source (GPL) |
| FMI 1.0 | ✓ | ✓ |
| FMI 2.0 | ✓ | ✓ |
| FMI 3.0 | ✓ (2024+) | ✓ (v1.21+) |
| Co-Simulation | ✓ | ✓ |
| Model Exchange | ✓ | ✓ |
| csSolver type | ✓ | ✗ |
| Modelica Standard Library | ✓ | ✓ |
| BuildingSystems | ✓ | Partial |
| Buildings Library | ✓ | ✓ |
The test suite includes unit tests and FMU simulation tests:
# Run all tests
uv run pytest
# Run with verbose output
uv run pytest -v
# Run only unit tests (no simulation)
uv run pytest tests/test_compilers.py tests/test_mo2fmu.py
# Run simulation tests (requires FMPy)
uv run pytest tests/test_fmu_simulation.pyOur GitHub Actions workflow (.github/workflows/ci.yml) includes:
build_wheel: code-quality checks, Python tests, wheel build, and artifact uploadbuild_docs: Antora site build and GitHub Pages deployment onmainrelease: on tagsvX.Y.Z, downloads the built wheel, creates a GitHub release, and publishes to PyPI
The release being prepared is 1.0.0.
Release metadata is maintained in:
pyproject.toml: Python package versionCHANGELOG.md: release notespackage.jsonanddocs/antora.yml: documentation metadata
Documentation metadata under docs/ and package.json should be kept aligned when needed, but they are not the authoritative Python package version.
Release process:
- Update
pyproject.tomlandCHANGELOG.md. - Push the release branch to GitHub.
- Create and push a tag such as
v1.0.0. - Let
.github/workflows/ci.ymlrun the release job to publish the wheel to GitHub Releases and PyPI.
We welcome contributions! Please:
- Fork the repository and create a feature branch.
- Adhere to existing coding conventions; add python tests where appropriate.
- Update documentation (docs/) for any new features.
- Submit a pull request with a clear description of your changes.
This project is licensed under the MIT License. See LICENSE for full details.