rumoca 0.7.8

Modelica compiler written in RUST
Documentation

Rumoca

CI Crates.io PyPI Documentation License

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. APIs may change between releases.

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 template leveraging minijinja. The DAE IR format is consumed by Cyecca (see the ir branch for ongoing integration) for model simulation, analysis, and Python library integration with CasADi, SymPy, and other backends planned (e.g. Jax).

Future targets include:

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
VSCode Extension Full Modelica IDE support via the Rumoca Modelica extension

Installation

Compiler, Formatter, and Linter

cargo install rumoca

Python Package

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 (requires native bindings)
result = rumoca.compile_source("""
    model Test
        Real x(start=0);
    equation
        der(x) = 1;
    end Test;
""", "Test")

VSCode Extension

Prerequisites:

  1. Install Rust if you haven't already (Windows users: see rustup.rs for installer):

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    
  2. Ensure ~/.cargo/bin is in your PATH (the rustup installer typically adds this automatically). You may need to restart your terminal or run:

    source ~/.cargo/env
    
  3. Install the language server:

    cargo install rumoca
    

Install the Extension:

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

Features:

  • Syntax highlighting (semantic tokens)
  • Real-time diagnostics
  • 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

Quick Start

Compile to DAE IR (JSON)

rumoca model.mo --json > model.json

Format Modelica Files

# Format all .mo files in current directory
rumoca-fmt

# Check formatting (CI mode)
rumoca-fmt --check

# Format specific files
rumoca-fmt model.mo library.mo

# Use 4-space indentation
rumoca-fmt --config indent_size=4

# Configure blank lines between classes
rumoca-fmt --config blank_lines_between_classes=1

Configuration: Create .rumoca_fmt.toml or rumoca_fmt.toml in your project:

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

Lint Modelica Files

# Lint all .mo files in current directory
rumoca-lint

# Lint specific files
rumoca-lint model.mo

# Show only warnings and errors
rumoca-lint --level warning

# Output as JSON (for CI integration)
rumoca-lint --format json

# List available lint rules
rumoca-lint --list-rules

# Exit with error on warnings (CI mode)
rumoca-lint --deny-warnings

Available Lint 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 or rumoca_lint.toml in your project. The linter searches for config files starting from the file's directory and walking up to parent directories:

min_level = "warning"                                    # help, note, warning, error
disabled_rules = ["magic-number", "missing-documentation"]
deny_warnings = false                                    # exit with error on warnings

CLI options override config file settings.

Library Usage

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

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

    // Export to DAE IR (JSON)
    let json = result.to_json()?;
    println!("{}", json);

    Ok(())
}

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

Custom Code Generation with Templates

Rumoca supports MiniJinja templates for custom code generation:

# Generate CasADi Python code
rumoca model.mo -m MyModel --template-file templates/examples/casadi.jinja > model.py

# Generate SymPy code
rumoca model.mo -m MyModel --template-file templates/examples/sympy.jinja > model.py

The DAE structure is passed to templates as the dae variable. 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 template examples (CasADi, SymPy, Base Modelica).

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

Not Yet Implemented

Feature Notes
Stream connectors inStream, actualStream operators
Inner/outer Keywords recognized; lookup not implemented
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.

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

# Build
cargo build --release

# Run tests
cargo test

# Check formatting
cargo fmt --check
rumoca-fmt --check

# Lint
cargo clippy
rumoca-lint

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