Skip to main content

Feel++ mo2fmu converter

Modelica to FMU converter with Dymola and OpenModelica support.

Features

  • 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 compile and check subcommands

Installation

From PyPI (Recommended)

Install the latest stable release from PyPI using uv:

uv pip install feelpp-mo2fmu

With OpenModelica Support

To 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.

With Simulation Support

To run simulations and validate FMUs (useful for testing):

uv pip install "feelpp-mo2fmu[simulation]"

This will install FMPy for FMU simulation and validation.

From Source

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]"

Configuration

Dymola Location

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.whl

Environment 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 Location

OpenModelica can be configured via environment variables:

export OPENMODELICA_HOME=/usr/lib/omc

Environment Variables:

  • OPENMODELICA_HOME: Path to OpenModelica installation (default: auto-detected)

Command Line Interface

The mo2fmu CLI provides two subcommands: compile and check.

Main Help

$ 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.

Compile Command

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 ./output

Check Command

Verify 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-2024x

Python API

Recommended API

The 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")

Using Compiler Classes Directly

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)

Legacy API

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"
)

Backend Comparison

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 ✓ ✓

Running Tests

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.py

Continuous Integration

Our GitHub Actions workflow (.github/workflows/ci.yml) includes:

  • build_wheel: code-quality checks, Python tests, wheel build, and artifact upload
  • build_docs: Antora site build and GitHub Pages deployment on main
  • release: on tags vX.Y.Z, downloads the built wheel, creates a GitHub release, and publishes to PyPI

Versioning & Release

The release being prepared is 1.0.0.

Release metadata is maintained in:

Documentation metadata under docs/ and package.json should be kept aligned when needed, but they are not the authoritative Python package version.

Release process:

  1. Update pyproject.toml and CHANGELOG.md.
  2. Push the release branch to GitHub.
  3. Create and push a tag such as v1.0.0.
  4. Let .github/workflows/ci.yml run the release job to publish the wheel to GitHub Releases and PyPI.

Contributing

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.

License

This project is licensed under the MIT License. See LICENSE for full details.

Metadata

Release files for feelpp-mo2fmu 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for feelpp-mo2fmu 1.0.0
File Interpreter ABI Platform
feelpp_mo2fmu-1.0.0-py3-none-any.whl Python 3 none any Details

Release files / feelpp_mo2fmu-1.0.0-py3-none-any.whl

Download URL feelpp_mo2fmu-1.0.0-py3-none-any.whl
Size 26.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
416425c768cd83feb4b47414025cabae278bd78c7b63dd7587170c231f0c5c7d
BLAKE2b-256 checksum
How to use checksums
08503e3aaaf3fd62bebf4f95463eb94d98519ad3d0686c76e542a48efa9efa49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

1 release file

0.6.0

1 release file

0.5.2

1 release file

0.5.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page