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
- Build Rumoca (Rust toolchain required):
cd /path/to/rumoca
cargo build --release
- 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) filerumoca_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 existRuntimeError: If rumoca binary not foundCompilationError: 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:
- Calls the
rumocabinary as a subprocess with--jsonflag - Receives Base Modelica JSON via stdout
- Parses JSON into Python dictionaries
- 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
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:
- Run tests:
pytest - Check types:
mypy rumoca - Format code:
black rumoca tests - Update documentation
License
Apache 2.0 (same as Rumoca)
See Also
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rumoca-0.7.2.tar.gz.
File metadata
- Download URL: rumoca-0.7.2.tar.gz
- Upload date:
- Size: 12.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.2 CPython/3.12.3 Linux/6.14.0-36-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4870b4c43e1aecaa6adb6cb5f3986d5addb887c9447213708ca36ae443824e7
|
|
| MD5 |
a9c17cbfe1960203fc91e1f3381846ab
|
|
| BLAKE2b-256 |
b86f43ad71aec68459a7ec6f55b91a1171e13ac4394d6e5aca0cb87d5412a6d4
|
File details
Details for the file rumoca-0.7.2-py3-none-any.whl.
File metadata
- Download URL: rumoca-0.7.2-py3-none-any.whl
- Upload date:
- Size: 8.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.2 CPython/3.12.3 Linux/6.14.0-36-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d7f5fcf781604431e1c9ea506f62e5113298dade46bf8ca0a4b63c1b874f00a
|
|
| MD5 |
b818aec6d7606c946af0932464067eb0
|
|
| BLAKE2b-256 |
ecb475c5ed9817a5f98c0f6e10e6190dfc88989762d31799bb3cc75c74dc6616
|