Modelica model architecture
Skill WolframResearch/system-modeler-ai-toolkit/modelica-model-architecture
Architecture and structuring guidance for Wolfram System Modeler / Modelica (.mo) models and libraries. Use this skill BEFORE writing equations whenever creating, implementing, structuring, or refactoring a model or library, to decide component decomposition, connectors, component reuse, file/folder layout, units, and naming. Triggers on phrases like 'create/build a Modelica model', 'implement this model/paper in Modelica', 'make a WSM model', 'write a Modelica library', 'structure/architect this model', 'single .mo file vs directory', 'split this into components', 'refactor this model/library', or any decomposition / connector / component-reuse / file-layout decision. Whenever you are about to write a multi-class library, consult this skill first to choose directory-form (one class per file) storage rather than a single monolithic .mo. Complements the validate/simulate/diagnose/annotate Modelica skills; for assembling a specific component library (e.g. create-hydraulic-model) defer to that domain skill.From its SKILL.md
npx -y skills add WolframResearch/system-modeler-ai-toolkit --skill modelica-model-architectureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
15.2 KB, ~3.6k tokens by cl100k_base, as published. Nobody here has run it
WSM / Modelica model architecture
Use this when creating or restructuring a WSM/Modelica model or library — before writing equations. This skill covers the architecture and structuring decisions that come first (sections 1-7), then the library conventions — naming, plots, documentation HTML, testing, icons, library shape — that a model or library must meet before it is "done" (sections 8-9). Read sections 8-9 before declaring a library done.
The default in Modelica is object-oriented decomposition into reusable components. Reach for a flat all-in-one model only under the explicit exception in section 5.
Working method
- Propose a step-by-step plan and wait for explicit approval before any edit. Present it as numbered steps.
- Offer the user a "one-shot" option: they may approve the whole sequence at once and have you execute it end to end without stopping between steps.
- If the user takes the one-shot option, first state the choices you will make
autonomously — the decisions you would otherwise have stopped to ask about
(e.g. authoring
GettingStarted/Introduction, storing example result plots, adding icons, how far to decompose). One-shot suppresses the questions, not the decisions; surfacing the defaults up front lets the user veto before you build. - When creating a library, recommend a parallel test library from the start. Add a unit test for each component as you build it — not at the end.
- Never delete the user's model files to "start clean." When the toolchain errors, fix the code forward — a validate/simulate failure is almost always a wrong name or missing load, not a reason to throw the work away. Deleting files to reset loses work and is rarely what the user wants.
1. Reuse before building (priority order)
When you need a component (or a connector), look in this order and only build new if nothing fits:
- MSL — the Modelica Standard Library.
- The user's own Git-repo libraries (e.g. what lives in their repo).
- Wolfram libraries — bundled / add-on WSM libraries.
- Your own component — last resort.
The same order applies to connectors: reuse a standard connector
(Modelica.Blocks.Interfaces, mechanical Flange, electrical Pin,
Thermal.HeatPort, Fluid ports, ...) before inventing one.
Ground every MSL name in the docs — do not recall paths from memory. MSL
component paths are easy to misremember: there is no Modelica.Blocks.Math.Sine
(sine is Modelica.Blocks.Sources.Sine), no Math.Subtract (use
Math.Feedback for u1 - u2, or Math.Add with k2 = -1), and no
Nonlinear.Saturation (the saturation block is Nonlinear.Limiter). Before you
write an MSL class name, confirm it with the search-modelica-docs skill. If a
later validate reports Element not found ... in Modelica..., the path is wrong
— look the correct one up with search-modelica-docs; do not grep or walk
the System Modeler install tree hunting for it.
2. Components by default; design the connector first
Whether something should be a component hinges on the interface, not the part. Componentize where you can draw a clean connector:
- a small, stable set of physically-conjugate effort/flow pairs
(
v/i,p/m_flow,f/v,T/Q_flow); - regime-independent — the variables crossing don't change meaning with global state;
- low-bandwidth — you're not smuggling a neighbour's internal state across.
If a cut would force a wide or regime-dependent connector, or would break a global constraint that no single component owns, the boundary is in the wrong place: move it, or keep just that coupled residue together.
Use flow for conserved quantities and stream for transported fluid
properties.
3. Composition vs inheritance (two reuse axes - don't conflate)
- Composition (instantiate + connect): "is made of" — distinct physical parts wired in the diagram.
- Inheritance (
partialbase +extends): "is a kind of" — variants that share equation structure (e.g. two heat exchangers sharing the same balance and wall equations).
4. Granularity
Decompose at real engineering joints — the parts an engineer would name (pump, valve, wall, zone). Avoid trivial one-variable wrappers, and do not merge genuinely simultaneous physics that has no clean internal interface.
5. Monolith exception
A single all-equations model is acceptable only as a first correctness pass on a numerically hard model. When you do it:
- say so explicitly, and
- end with a concrete written decomposition proposal — name the components
and the connector or
partialbase each would become — not an open-ended offer to "refactor later".
Even when no clean connector exists (a tightly coupled DAE — shared pressure
state, regime-dependent coupling), still factor the reusable equation
structure into partial base classes and functions (see section 3). A model
that derives a generic control volume, then specialises it, is decomposed even if
its zones cannot be cut into separately-connected components.
Never present a monolith as the finished structure.
6. One class per file (for version control)
One-off model vs library. If the user just wants a single throwaway model
(not a reusable library), write one self-contained .mo file holding that
model — it is simpler to author, validate, and simulate. Reach for the
directory form below only when building a library or a genuinely multi-class
model.
Store libraries in directory form:
package.mo+package.orderat each level,- subpackages as folders,
- each
model/block/function/record/connectorin its ownName.mo.
This makes version handling far easier: granular diffs, fewer merge conflicts,
per-component blame and review. Exception: a few tiny, tightly-coupled leaf
classes (e.g. some Types) may share a file.
Names must be valid Modelica identifiers. A package/class name — and the
directory or file that holds it — is letters, digits, and underscores only, and
must not start with a digit: no hyphens or spaces (inverted-pendulum is
illegal; use InvertedPendulum). A directory-form library's folder name must
equal its package name, and the dotted --name you pass the launcher (e.g.
InvertedPendulum.Controller) is built from these identifiers.
7. Units - always declare
Every variable/parameter that has a unit must declare it, in this priority:
- An SI type from
Modelica.Units.SI(e.g.SI.Pressure p). - Else a NonSI type from
Modelica.Units.NonSI. - Else the
unit=attribute (e.g.Real areaPerLength(unit="m2/m")).
Signals flowing through connectors are SI; use displayUnit for friendly
labels (note a displayUnit default needs a literal value).
Use the MSL 4.x names — this toolchain ships MSL 4.x, and the old 3.2 names
flatten with confusing "not found" errors. Write Modelica.Units.SI.* (not
Modelica.SIunits.*), and source frequency is f= (not freqHz=). Declare the
dependency as annotation(uses(Modelica(version = "4.1.0"))).
8. Conventions
These are the library conventions every WSM/Modelica model and library must follow. Sections 8a-8h are the detail behind the section 9 checklist.
8a. Naming and code
- camelCase, no underscores for parameters and variables, starting lower
case (
heatSource), following the MSL naming conventions. - Use meaningful names —
enthalpy, noth. - Avoid any tool-dependent code, so the library stays tool-independent.
- Store all external resources (images, CAD, PDFs) in a
Resourcesfolder in the library directory, referenced via Modelica URIs (never raw paths); use only resources you have the rights to use. - Review experiment settings (time unit, solver, tolerance, step) so they are relevant for each example.
8b. Units
Covered in section 7 — every variable/parameter with a unit declares it (SI type
→ NonSI type → unit= attribute). Signals through connectors are SI; use
displayUnit for friendly labels.
8c. Documentation text
- All classes documented; all parameters and variables, including
protected, have a one-line description. - First character uppercase; for one-line descriptions of params, variables, and classes, no trailing period.
- Spelling and grammar must be correct.
- Do not set custom font style/size styling.
- Write library names spaced ("Rotating Machinery", not "RotatingMachinery").
- Wrap component, class, variable, and instance names in the text with
<code>.
8d. HTML documentation
- Use only
<h4>and<h5>headings — never<h1>-<h3>(those are used by the auto-generated docs). Headings must not end with a:. - Each component's doc, in this order: general information (how the class works, no subsections) → References (relevant articles) → optionally Implementation, Limitations, Notes, Examples, Acknowledgments (in that order).
- Put any revision history in
annotation(Documentation(revisions="...")); "what's new" goes in the revisions, e.g.:<h4>New in Version 1.2.0</h4> <ul> <li>Library is now available for free for Wolfram System Modeler users</li> </ul>
8e. Plot styling
- Add model plots to the library examples; set at least one as the default plot.
- Plot titles and legends should be meaningful. Raw component paths are fine
when already clear (e.g.
R1.v,R2.v); replace them only when the default is ambiguous or unwieldy (deep nesting, generic names like.y). - Plot titles: sentence case, no trailing period (e.g. "Fuel consumption of an aircraft"). Legends: start uppercase, no trailing period.
- Explores are optional (prefer them for faster simulations); control-panel names and explore parameter descriptions start uppercase.
8f. Appearance / icons and availability
- Every class has an icon. Follow the
MSL icon conventions,
except the
%nametext uses color{64, 64, 64}. - State which platforms (Mac, Windows, Linux) the library supports, with good reasons for any exclusion.
- Declare all dependencies with
usesannotations, including the MSL version (e.g.uses(Modelica(version = "4.1.0"))). State any additional software needed.
8g. Library structure and documentation shape
Every library's top-level package.order starts with the same three nodes, in
this order, then the library-specific components/subpackages:
GettingStarted ← always present, info-only model
Conventions ← encouraged; omit only when no cross-cutting reference exists
Examples ← always present, runnable models
...Components (with Utilities, Types), other subpackages...
GettingStartedandConventionsare info-only models (not packages):preferredView = "info",DocumentationClass = true. Fold any existingIntroduction/TroubleshootingintoConventions(or, if substantial, keepTroubleshootingas a sibling with a consistent shape).- The top-level
package.modoc is the library elevator pitch: a one/two- paragraph summary, a short linked list of 4-8 core abstractions, three "where to go next" links (GettingStarted/Conventions/Examples), and a<h4>References</h4>section if applicable. It must not duplicateGettingStartedorConventions. GettingStartedskeleton (same sections, same order): one-paragraph summary → Building Blocks (linked core components) → Worked example (diagram screenshots + a simulation plot) → Next steps (links toConventionsandExamples).Conventionsskeleton (always these<h5>sections, in order): Symbols & Notation → Units & Display Units → Connectors & Sign Conventions → Styling → References. Keep a heading even when its content is one line.Examplesis apackage(subpackage it by category past ~8 examples). Each example documents its purpose and what to observe after simulating, and should preferably cover all main components in the library.- Cross-link with Modelica URIs (
modelica://Library.Path.Class), never raw HTML paths. EveryGettingStartedends with Next steps; everyConventionsopens with a one-line link toGettingStarted; link components to confusable siblings.
8h. Testing
- Create a parallel test library named
<Library>Tests(e.g.Hydraulic->HydraulicTests). Every component gets its corresponding unit test(s) there as it is created, not at the end. - If the example models do not cover every component, the test library must exercise the remaining ones.
9. Definition of done
A model or library is not "done" — and success must not be reported — until these hold:
- Each class validates, and examples build/simulate, without warnings (justify any exception).
- Every class has an icon (invoke the
annotate-modelica-graphicsskill) and a one-line description; every parameter/variable, includingprotected, has a description and — where it has one — a unit. - Every example documents its purpose and what to observe, and carries
stored result-plot annotations (
figures=, at least one default plot) — invoke theannotate-modelica-plotsskill once it simulates. Give each figure an identifiable title and a one-linecaption; if the model replicates a published reference, name figures to match it (e.g."Fig. 6 - …") and note the correspondence in the caption. (Pure pass/fail assertion tests need no figure; anything meant to be simulated and inspected does.) - Every component has a unit test in the parallel
<Library>Tests. - The library follows the three-slot top-level shape —
GettingStarted,Conventions,Examplesfirst inpackage.order(section 8g). - If a monolith was used, a concrete decomposition proposal is on the table (section 5).
Treat this as a checklist to run through and report against, not a list to skim.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.