Skip to main content

Python interface for the Rumoca Modelica compiler

Project description

Rumoca Python Interface

Python wrapper for the Rumoca Modelica compiler, enabling seamless integration with Cyecca for code generation and simulation.

Installation

Prerequisites

  1. Build Rumoca (Rust toolchain required):
cd /path/to/rumoca
cargo build --release
  1. Add to PATH (optional but recommended):
export PATH=$PATH:/path/to/rumoca/target/release

Install Python Package

# From source (development)
cd rumoca/python
pip install -e .

# With Cyecca integration
pip install -e ".[cyecca]"

# With Jupyter notebook support
pip install -e ".[notebook]"

# Everything
pip install -e ".[all]"

Quick Start

Basic Usage

import rumoca

# Compile a Modelica model
result = rumoca.compile("bouncing_ball.mo")

# Export to Base Modelica JSON
result.export_base_modelica_json("bouncing_ball.json")

# Or get as string
json_str = result.to_base_modelica_json()

# Or get as Python dict
model_dict = result.to_base_modelica_dict()

Integration with Cyecca

import rumoca
from cyecca.io import import_base_modelica

# Compile Modelica model
result = rumoca.compile("my_model.mo")
result.export_base_modelica_json("my_model.json")

# Import into Cyecca
model = import_base_modelica("my_model.json")

print(f"Model: {model.name}")
print(f"States: {[v.name for v in model.variables if v.is_state]}")

Code Generation with Cyecca

import rumoca
from cyecca.io.base_modelica import import_base_modelica
from cyecca.backends.casadi import generate_casadi
from cyecca.backends.sympy import generate_sympy

# Compile to Base Modelica
result = rumoca.compile("my_model.mo")
result.export_base_modelica_json("my_model.json")

# Import with Cyecca
model = import_base_modelica("my_model.json")

# Generate CasADi code
casadi_code = generate_casadi(model)
with open("my_model_casadi.py", "w") as f:
    f.write(casadi_code)

# Generate SymPy code
sympy_code = generate_sympy(model)
with open("my_model_sympy.py", "w") as f:
    f.write(sympy_code)

Jupyter Notebook Workflow

See examples/bouncing_ball_demo.ipynb for a complete example.

# Cell 1: Compile
import rumoca
from cyecca.io import import_base_modelica
import matplotlib.pyplot as plt

result = rumoca.compile("bouncing_ball.mo")
result.export_base_modelica_json("bouncing_ball.json")

# Cell 2: Import and inspect
model = import_base_modelica("bouncing_ball.json")
print(f"States: {[v.name for v in model.variables if not v.is_parameter]}")

# Cell 3: Generate simulation code
from cyecca.codegen import generate_simulation_code
code = generate_simulation_code(model, backend="python")

# Cell 4: Simulate and plot
results = code.simulate(t_span=(0, 10), dt=0.01)
plt.plot(results['t'], results['h'], label='Height')
plt.plot(results['t'], results['v'], label='Velocity')
plt.legend()
plt.show()

API Reference

rumoca.compile(model_file, rumoca_bin=None)

Compile a Modelica model file.

Parameters:

  • model_file (str | Path): Path to the Modelica (.mo) file
  • rumoca_bin (str | Path, optional): Path to rumoca binary (auto-detected if None)

Returns:

  • CompilationResult: Object containing the compiled model

Raises:

  • FileNotFoundError: If model file doesn't exist
  • RuntimeError: If rumoca binary not found
  • CompilationError: If compilation fails

Example:

result = rumoca.compile("bouncing_ball.mo")

CompilationResult

Result of compiling a Modelica model.

Methods

to_base_modelica_json() -> str

Export model to Base Modelica JSON format as a string.

Returns:

  • str: JSON string containing Base Modelica representation (MCP-0031)

Raises:

  • CompilationError: If export fails

Example:

result = rumoca.compile("model.mo")
json_str = result.to_base_modelica_json()
export_base_modelica_json(output_file)

Export model to Base Modelica JSON file.

Parameters:

  • output_file (str | Path): Path where JSON file will be written

Raises:

  • CompilationError: If export fails

Example:

result = rumoca.compile("model.mo")
result.export_base_modelica_json("model.json")
to_base_modelica_dict() -> dict

Get Base Modelica representation as Python dictionary.

Returns:

  • dict: Dictionary containing Base Modelica model data

Example:

result = rumoca.compile("model.mo")
data = result.to_base_modelica_dict()
print(f"Parameters: {len(data['parameters'])}")
export(template_file) -> str

Advanced: Export using a custom template.

Parameters:

  • template_file (str | Path): Path to custom Jinja2 template file

Returns:

  • str: Generated code as string

Note: For standard code generation, use to_base_modelica_json() + Cyecca instead.

Examples

Example 1: Simple Compilation

import rumoca

# Compile and export in one go
result = rumoca.compile("integrator.mo")
result.export_base_modelica_json("integrator.json")

Example 2: Inspect Model Structure

import rumoca

result = rumoca.compile("rover.mo")
model_data = result.to_base_modelica_dict()

print(f"Model: {model_data['model_name']}")
print(f"Parameters: {len(model_data['parameters'])}")
print(f"Variables: {len(model_data['variables'])}")
print(f"Equations: {len(model_data['equations'])}")

Example 3: Full Workflow with Cyecca

import rumoca
from cyecca.io.base_modelica import import_base_modelica
from cyecca.backends.casadi import generate_casadi

# Step 1: Compile Modelica to Base Modelica
result = rumoca.compile("quadrotor.mo")
result.export_base_modelica_json("quadrotor.json")

# Step 2: Import with Cyecca
model = import_base_modelica("quadrotor.json")

# Step 3: Generate CasADi code
casadi_code = generate_casadi(model)

# Step 4: Save generated code
with open("quadrotor_casadi.py", "w") as f:
    f.write(casadi_code)

Example 4: Error Handling

import rumoca

try:
    result = rumoca.compile("my_model.mo")
    result.export_base_modelica_json("output.json")
except FileNotFoundError as e:
    print(f"Model file not found: {e}")
except rumoca.CompilationError as e:
    print(f"Compilation failed: {e}")

Architecture

Subprocess-Based Wrapper

The current implementation uses a subprocess-based wrapper that:

  1. Calls the rumoca binary as a subprocess with --json flag
  2. Receives Base Modelica JSON via stdout
  3. Parses JSON into Python dictionaries
  4. Captures stderr for error reporting

Advantages:

  • Simple implementation
  • Easy to maintain
  • Works with existing Rumoca binary
  • Fast native JSON serialization in Rust

Workflow:

Python → subprocess(rumoca --json) → Base Modelica JSON → Python dict
                                            ↓
                                        Cyecca
                                            ↓
                                     Generated Code

Future: PyO3 Bindings

A future version may use PyO3 for native Rust-Python bindings:

  • Direct access to Rumoca's DAE structures
  • No subprocess overhead
  • Zero-copy data transfer
  • Tighter integration possibilities

Troubleshooting

"Rumoca binary not found"

Solution 1: Add rumoca to PATH:

export PATH=$PATH:/path/to/rumoca/target/release

Solution 2: Specify binary path explicitly:

result = rumoca.compile("model.mo", rumoca_bin="/path/to/rumoca")

Compilation errors

Check the Modelica syntax by running rumoca directly:

rumoca your_model.mo --json

If successful, you should see Base Modelica JSON output.

Development

Running Tests

cd rumoca/python
pip install -e ".[dev]"
pytest

Type Checking

mypy rumoca

Code Formatting

black rumoca tests

Contributing

Contributions welcome! Please:

  1. Run tests: pytest
  2. Check types: mypy rumoca
  3. Format code: black rumoca tests
  4. Update documentation

License

Apache 2.0 (same as Rumoca)

See Also

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rumoca-0.7.1.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rumoca-0.7.1-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file rumoca-0.7.1.tar.gz.

File metadata

  • Download URL: rumoca-0.7.1.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for rumoca-0.7.1.tar.gz
Algorithm Hash digest
SHA256 2da1918c6423c96c5acb1493f38a18acf18157edddac45e5f7ca7dedcccf80e5
MD5 2acca5b06feb62de0360860797757fa3
BLAKE2b-256 27ab31cb361b159d09cf0aa8bbdb372c64e353a44411265b916983570e56546f

See more details on using hashes here.

File details

Details for the file rumoca-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: rumoca-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for rumoca-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ce8f19da507a0c4ad711cfc7b8ed684e47a08be0291334c3e24d491b64c61608
MD5 5d6cb69464a316989d87bfe20dccdfde
BLAKE2b-256 b08d7702f1e87351c9880aa0f13c1e27d3382a941a540ac7e671f9c38e8ae93c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page