Run — and control — a model you didn't build.
No team models everything in one tool. The FMI standard exists so a model built in Dymola, Simulink or anywhere else can be packaged as an FMU and run somewhere else entirely. This program is the import side of that promise: load a vendor FMU into DjiniousLab's Julia worker, co-simulate it, cross-validate it against a native re-implementation, and — the part that matters — wrap your own controller around the black box and close the loop through the FMI interface. Interoperability isn't a checkbox; it's controlling someone else's model as if it were yours.

Drop in a vendor FMU and it just runs.
An FMU is a self-contained, compiled model behind a standard C interface. The first notebook loads a Dymola-exported reference FMU into the Julia worker and co-simulates it — states out, phase orbit closed, no source code, no re-derivation. That's the baseline interoperability claim: a model authored in another tool, running here, unchanged.

Co-simulation or model-exchange — and they agree.
FMI offers two modes. In co-simulation the FMU carries its own solver and you call doStep; in model-exchange your solver integrates the FMU's derivatives. The same FMU run both ways overlays to a 1.3×10⁻³ m RMSE — the choice is about who owns the solver, not about getting different answers. That equivalence is what lets you mix an FMU into a larger Julia-solved system with confidence.


Close a loop around the black box.
The strongest interoperability claim isn't running a vendor model — it's controlling one. The hero notebook makes the imported FMU the plant and wraps a native Julia PID around it through a manual co-simulation loop: read the FMU's output, compute the control, set the FMU's input, step. The controller never sees inside the FMU; it only talks to it through the FMI interface — and drives it to a setpoint with 2.9×10⁻⁴ m tracking error. That's a controller and a vendor plant from two different worlds, meeting at the standard.

Co-simulation has its own error budget.
Coupling models at discrete communication points introduces an error all its own: between steps, each model sees its inputs held constant, so a too-large macro step lags and distorts. The program quantifies it — halving the macro step roughly halves the error (first-order convergence), a 7.6× reduction across the sweep. Knowing that error is first-order in the step size is what lets you trade accuracy against speed deliberately instead of by accident.

Every number re-derived at sign-off.
The V&V notebook re-imports the FMU and re-derives each requirement from scratch, printing a PASS/FAIL board.
| Result | Requirement | |
|---|---|---|
| Import & co-sim a vendor FMU | 101 samples | R-01 |
| CS vs ME agreement | 1.3e-3 m RMSE | R-02 |
| FMU vs native fidelity | 4.7e-3 m RMSE | R-03 |
| Closed-loop tracking error | 2.9e-4 m | R-04 |
| Co-sim error vs macro step | 7.6× reduction | R-05 |
The import side, on reference FMUs.
The deliverable is ten notebooks and the dossier — the models arrive as compiled FMUs behind the FMI C interface, not as acausal DjiniousLab components, so there's no custom block or canvas. The FMUs are Dymola-exported references rather than arbitrary third-party models; the co-simulation is single-rate with constant-input extrapolation between communication points and no algebraic-loop solver across coupled FMUs. And this is the import/co-simulate story specifically — FMU export is a separate Rust path in the platform. What the program proves is the interoperability core: load, co-simulate both ways, cross-validate, control, couple, and quantify the co-sim error — every number re-runnable, the strongest of them a native controller closing a loop around a vendor model it can't see inside.
Bring your existing models into the loop.
Book a walkthrough and we'll import your FMU, cross-validate it, and wrap your control and co-simulation studies around it live.
