rumoca 0.7.19

Modelica compiler written in RUST
Documentation

Rumoca

CI Crates.io PyPI Documentation License

A Modelica compiler written in Rust. Rumoca parses Modelica source files and exports to the DAE IR Format (supporting both implicit and explicit model serialization), or via user-customizable templates using MiniJinja. The DAE IR format is consumed by Cyecca for model simulation, analysis, and Python library integration with CasADi, SymPy, and other backends.

Note: Rumoca is in early development. While already usable for many practical tasks, you may encounter issues. Please file bug reports to help improve the compiler.

Quick Start

# Install
cargo install rumoca

# Compile to DAE IR (JSON)
rumoca model.mo --json > model.json

# Format Modelica files
rumoca-fmt

# Lint Modelica files
rumoca-lint

Installation

Rust (Compiler, Formatter, Linter)

cargo install rumoca

Python

The Python package bundles the Rust compiler, so no separate Rust installation is needed:

pip install rumoca
import rumoca

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

# Get as JSON string or Python dict
json_str = result.to_base_modelica_json()
model_dict = result.to_base_modelica_dict()

# Compile from string
result = rumoca.compile_source("""
    model Test
        Real x(start=0);
    equation
        der(x) = 1;
    end Test;
""", "Test")

Rust Library

[dependencies]
rumoca = "0.7"
use rumoca::Compiler;

fn main() -> anyhow::Result<()> {
    let result = Compiler::new()
        .model("MyModel")
        .compile_file("model.mo")?;

    let json = result.to_json()?;
    println!("{}", json);
    Ok(())
}

Tools

Tool Description
rumoca Main compiler - parses Modelica and exports DAE IR (JSON)
rumoca-fmt Code formatter for Modelica files (like rustfmt)
rumoca-lint Linter for Modelica files (like clippy)
rumoca-lsp Language Server Protocol server for editor integration

Formatter

rumoca-fmt                              # Format all .mo files
rumoca-fmt --check                      # Check formatting (CI mode)
rumoca-fmt model.mo                     # Format specific files
rumoca-fmt --config indent_size=4       # Custom indentation

Configuration: Create .rumoca_fmt.toml in your project:

indent_size = 2
use_tabs = false
max_line_length = 100
blank_lines_between_classes = 1

Linter

rumoca-lint                     # Lint all .mo files
rumoca-lint --level warning     # Show only warnings and errors
rumoca-lint --format json       # JSON output for CI
rumoca-lint --list-rules        # List available rules
rumoca-lint --deny-warnings     # Exit with error on warnings

Available Rules:

Rule Level Description
naming-convention note CamelCase for types, camelCase for variables
missing-documentation note Classes without documentation strings
unused-variable warning Declared but unused variables
undefined-reference error References to undefined variables
parameter-no-default help Parameters without default values
empty-section note Empty equation or algorithm sections
magic-number help Magic numbers that should be constants
complex-expression note Overly complex/deeply nested expressions
inconsistent-units warning Potential unit inconsistencies
redundant-extends warning Duplicate or circular extends

Configuration: Create .rumoca_lint.toml in your project:

min_level = "warning"
disabled_rules = ["magic-number", "missing-documentation"]
deny_warnings = false

Custom Code Generation

Rumoca supports MiniJinja templates for custom code generation:

rumoca model.mo -m MyModel --template-file templates/examples/casadi.jinja > model.py
rumoca model.mo -m MyModel --template-file templates/examples/sympy.jinja > model.py

Example template:

# Generated from {{ dae.model_name }}
{% for name, comp in dae.x | items %}
{{ name }}: {{ comp.type_name }} (start={{ comp.start }})
{% endfor %}

See templates/examples/ for complete examples (CasADi, SymPy, Base Modelica).

VSCode Extension

Search for "Rumoca Modelica" in the VSCode Extensions marketplace, or install from the marketplace page.

Rumoca VSCode Extension Demo

The extension includes a bundled rumoca-lsp language server - no additional installation required.

Features:

  • Syntax highlighting (semantic tokens)
  • Real-time diagnostics with type checking
  • Autocomplete for keywords, built-in functions, and class members
  • Go to definition / Find references
  • Document symbols and outline
  • Code formatting
  • Hover information
  • Signature help
  • Code folding
  • Inlay hints
  • Code lens with reference counts
  • Rename symbol
  • Call hierarchy
  • Document links

Configuring Library Paths:

{
  "rumoca.modelicaPath": [
    "/path/to/ModelicaStandardLibrary",
    "/path/to/other/library"
  ]
}

Alternatively, set the MODELICAPATH environment variable. See the extension documentation for details.

Integration with Cyecca

rumoca model.mo --json > model.json
from cyecca.io.rumoca import import_rumoca

model = import_rumoca('model.json')
# Use model for simulation, analysis, code generation, etc.

Modelica Language Support

Fully Supported

  • Class definitions: model, class, block, connector, record, type, package, function
  • Components: Declarations with modifications, array subscripts
  • Inheritance: extends clause with recursive resolution
  • Equations: Simple, connect, if, for, when equations
  • Algorithms: Assignment, if, for, while, when statements
  • Expressions: Binary/unary operators, function calls, if-expressions, arrays
  • Type prefixes: flow, stream, discrete, parameter, constant, input, output
  • Modifications: Component and class modifications
  • Packages: Nested packages, package.mo/package.order directory structure, MODELICAPATH
  • Imports: Qualified, renamed, unqualified (.*), selective ({a,b})
  • Functions: Single and multi-output functions, tuple equations (a,b) = func()
  • Built-in operators: der(), pre(), reinit(), time, trig functions, array functions
  • Event functions: noEvent, smooth, sample, edge, change, initial, terminal
  • Annotations: Parsed and exported to JSON on components

Partially Supported

Feature Status
Connect equations Flow/potential semantics implemented; stream not yet supported
External functions external keyword recognized; no linking
Inner/outer Basic outer→inner resolution implemented; nested scopes in progress
Complex operators Complex record expansion; operator overloading in progress

Not Yet Implemented

Feature Notes
Stream connectors inStream, actualStream operators
Redeclarations redeclare, replaceable parsed only
Overloaded operators operator class prefix recognized only
State machines Synchronous language elements (Ch. 17)
Expandable connectors Dynamic connector sizing
Overconstrained connectors Connections.root, branch, etc.

MSL Compatibility

Rumoca is tested against the Modelica Standard Library 4.1.0.

Metric Result
Parse Rate 100% (2551/2551 files)
Compile Rate 100% (2283/2283 models)

Balance Check Results:

Status Count Percentage Description
Balanced 790 34.6% Fully determined (equations = unknowns)
Partial 1072 47.0% Under-determined by design (external connectors)
Unbalanced 421 18.4% Needs further work

Partial models have external connector flow variables that receive equations when connected in a larger system.

What Works Well:

  • Modelica.Blocks (Integrator, Der, Gain, etc.)
  • Modelica.Electrical.Analog.Basic
  • Array handling with size() and parameter-dependent dimensions
  • Conditional equations with parameter evaluation
  • When equations and discrete event handling

Known Limitations (421 unbalanced models):

Category Notes
Algorithm sections Assignments not yet counted as equations
Complex enumerations Some types not yet substituted
Stream connectors inStream/actualStream not implemented
External functions Functions without equation bodies
Operator records Operator overloading not implemented

Architecture

Modelica Source -> Parse -> Flatten -> BLT -> DAE -> DAE IR (JSON)
                   (AST)   (Flat)    (Match)  (DAE)
                                                          |
                                                       Cyecca
                                                          |
                                               CasADi/SymPy/JAX/etc.

Structural Analysis:

  • Hopcroft-Karp matching (O(E√V)) for equation-variable assignment
  • Tarjan's SCC algorithm for topological ordering and algebraic loop detection
  • Pantelides algorithm for DAE index reduction (detects high-index systems)
  • Tearing for algebraic loops (reduces nonlinear system size)

Development

cargo build --release   # Build
cargo test              # Run tests
cargo fmt --check       # Check Rust formatting
cargo clippy            # Lint Rust code
rumoca-fmt --check      # Check Modelica formatting
rumoca-lint             # Lint Modelica files

Roadmap

Export Targets:

Import Targets:

Contributing

Contributions welcome! All contributions must be made under the Apache-2.0 license.

License

Apache-2.0 (LICENSE)

Citation

@inproceedings{condie2025rumoca,
  title={Rumoca: Towards a Translator from Modelica to Algebraic Modeling Languages},
  author={Condie, Micah and Woodbury, Abigaile and Goppert, James and Andersson, Joel},
  booktitle={Modelica Conferences},
  pages={1009--1016},
  year={2025}
}

See Also