[FMI] Add FMI 3.0 export (#15686)#15692
Open
adrpo wants to merge 18 commits into
Open
Conversation
76c87c7 to
23cf0a6
Compare
0910f52 to
b32ff74
Compare
Open
6130336 to
2c74f9d
Compare
Add support for exporting Functional Mock-up Units in FMI 3.0 format from
OpenModelica, for both the C and the C++ (Cpp) simulation runtimes. Covers
Model Exchange and Co-Simulation for the C runtime and Model Exchange for the
Cpp runtime; a first cut of Scheduled Execution is present for the C runtime.
The FMI 3.0 C and C++ model interfaces are self-contained and do not depend on
the FMI 2.0 OpenModelica wrapper files, so the two can evolve independently.
Verified with fmpy: exported FMUs validate against the FMI 3.0 schema and
simulate correctly (Model Exchange matches the analytic solution; Co-Simulation
matches the FMI 2.0 behaviour of the same model). Real/Integer/Boolean/String
variables map to the FMI 3.0 typed elements with correct, globally unique value
references.
Compiler / scripting
- FMI.mo: accept "3.0" in checkFMIVersion/canExportFMU, add isFMIVersion30 and
the "se" type / isFMISEType.
- SimCodeUtil.mo: FMI 3.0 value-reference helpers (per-base-type offsets that
make the references globally unique), the FMI ModelStructure and the
remaining FMI-2.0-only SimVar code paths extended to FMI 3.0.
- SimCodeMain.mo: generate the FMIDER jacobian and the output-alias preOpt
modules for FMI 3.0; package only the FMI 3.0 model interface source.
- SimCodeTV/SimCodeBackendTV: expose the new helpers/predicates to templates.
- boot/LoadCompilerSources.mos and Compiler/.cmake/{template_compilation,
meta_modelica_source_list}.cmake: register CodegenFMU3 for both bootstrap
build systems.
Code generation
- CodegenFMU3.tpl: new released-FMI-3.0 modelDescription.xml generator (typed
ModelVariables, instantiationToken, explicit time variable, ModelStructure
referencing value references, ModelExchange/CoSimulation/ScheduledExecution).
- CodegenFMU.tpl / CodegenFMUCpp.tpl: dispatch the FMI 3.0 modelDescription and
runtime, emit the FMI3_*_VR_OFFSET macros, .def exports, include paths and
the FMI 3.0 platform tuple (e.g. x86_64-linux) for the binaries folder.
Runtime
- fmi/export/fmi/fmi3*.h, cpp/FMU3/fmi3*.h: vendored official FMI 3.0 headers.
- fmi/export/openmodelica/fmu3_model_interface.c/.h: self-contained FMI 3.0 C
interface (own model engine + inlined Co-Simulation solver setup).
- cpp/FMU3/FMU3Wrapper.{h,cpp}, FMU3GlobalSettings.h, FMU3Interface.cpp:
FMI-3.0-native C++ wrapper and interface (no FMI 2.0 files or headers).
Build / packaging
- RuntimeSources (.tpl/.cmake) + c/Makefile.common + fmi/CMakeLists.txt +
cpp/CMakeLists.txt + cpp/cmake_3.14.cmake + fmi/export/buildproject/
CMakeLists.txt.in: package and install the FMI 3.0 sources/headers for both
the autotools and the CMake builds.
Tests
- testsuite/openmodelica/fmi/ModelExchange/3.0 (fmi3_attributes_01, fmi3_types)
- testsuite/openmodelica/fmi/CoSimulation/3.0 (fmi3_cs_01)
- testsuite/openmodelica/cppruntime/fmu/modelExchange/3.0 (testCppFMI3)
registered in the top-level testsuite Makefile.
- .CI/scripts/SimulationRuntime-license-exceptions.txt: list the vendored
FMI 3.0 reference headers.
Follow-ups: full Scheduled Execution (currently a stub), FMUState / directional
derivatives / Clocks / binary (stubbed), and a generated buildDescription.xml.
Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…a#15686) Add FMI 3.0 FMU export for the new backend (--newBackend), including native FMI 3.0 array variables (--newBackend --simCodeScalarize=false). Previously the new backend had no FMU export at all: generateModelCodeNewBackend only called callTargetTemplates (plain simulation), so buildModelFMU(..., --newBackend) failed. Compiler / SimCode: - SimCodeMain.mo: thread TranslateModelKind through the new-backend dispatch; for FMU() call callTargetTemplatesFMU on the converted SimCode and set fullPathPrefix / fmuTargetName / valueReferences / a minimal ModelStructure (continuous state derivatives + outputs). - NSimVar.mo: populate the FMI SimVar attributes (exportVar, causality, variability, initial_) and numArrayElement (dimension sizes). - SimCodeUtil.mo: getValueReferenceMapping public and element-aware; the FMI 3.0 value references (getFMI3ValueReference / getFMI3TypeOffset / getFMI3TimeValueReference) use the per-scalar, element-cumulative layout so each (array) variable occupies a contiguous, non-colliding block; numScalarElems / getFMIScalarVRs / getFMI3ArrayStart / createMinimalFMIModelStructure; getNumElems made public. - SimCodeTV.mo: expose the new helpers to the templates. Code generation: - CodegenFMU.tpl: native array variables; per-scalar NUMBER_OF_* sizes and getReal/setReal block boundaries; STATES/STATESDERIVATIVES expand arrays to their scalar element value references; DimensionsFMU sets the runtime array dimensions in read_input_fmu so the value vectors are sized correctly; the broadcast scalar of an array start (array constructor / reduction) is used for the start attribute. - CodegenFMU3.tpl: native array variables (<Float64 ...><Dimension start="N"/></Float64>), per-scalar derivative attribute and array start attribute. Runtime: - fmu3_model_interface.c: the typed get/set functions handle nValues (the contiguous scalar block of an array variable); read_input_fmu is called before calculateAllScalarLength so the array dimensions are known before the value vectors are sized. Verified with fmpy: scalar and array models (e.g. Real x[3], mixed Real/Integer arrays) export, compile, validate against the FMI 3.0 schema and simulate to the analytic solution (Model Exchange); Co-Simulation also runs. Scalar export (new and old backend) is unaffected. Adds the testsuite case openmodelica/fmi/ModelExchange/3.0/fmi3_arrays.mos. Follow-ups: explicit non-uniform array starts (currently broadcast); more than one array variable in a single get/set call; ModelStructure dependencies; integer/boolean/string multi-array refinements. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
Generate terminalsAndIcons/terminalsAndIcons.xml grouping the variables that
stem from a connector into one Terminal per connector instance.
Connector membership is taken from the flat-model component type: a variable
whose exported cref has a connector-typed qualifier (identType T_COMPLEX/
T_SUBTYPE_BASIC with ClassInf.CONNECTOR) is a member of that connector. The
terminal info is computed in SimCodeUtil.getFMI3Terminals from the SimVars and
emitted by CodegenFMU3, so it flows through SimCode to the templates (no
scripting post-step). Works for both the old and the new backend.
- SimCode.mo / SimCodeTV.mo: FmiTerminal, FmiTerminalMember
- SimCodeUtil.getFMI3Terminals (+ connector cref detection helpers)
- CodegenFMU3: fmiTerminalsAndIcons{,File}, Terminal3, TerminalMember3
- CodegenFMU.translateModel: write the file for FMI 3.0
- SimCodeMain: create terminalsAndIcons/ when the model has terminals
- testsuite: openmodelica/fmi/ModelExchange/3.0/fmi3_terminals.mos
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…ca#15686) A Modelica ExternalObject is an opaque handle (void*) stored in the runtime's extObjs array. It is now exported as an FMI 3.0 <Binary> variable whose value is the raw bytes of the handle (sizeof(void*)). Previously external objects were not exported at all. - SimCodeUtil: external objects get their own per-base-type value-reference block; getFMI3TypeOffset places Binary after the strings; the independent variable (time) shifts past the binary block. - CodegenFMU3: ModelVariables now iterates extObjVars; Variable3 emits <Binary> (causality=local, variability=fixed) via BinaryVariableAttributes3 (uses the SimVar cref directly, as external objects carry no exportVar). - CodegenFMU: NUMBER_OF_EXTERNALOBJECTS and FMI3_BINARY_VR_OFFSET defines; time VR shifted accordingly. CodegenFMUCpp: matching offset defines for VR consistency (the C++ runtime Binary get/set remain stubs). - fmu3_model_interface.c: fmi3GetBinary/fmi3SetBinary read/write the external object handle from fmuData->simulationInfo->extObjs (bounds-checked, one void*-sized value per reference). - testsuite: openmodelica/fmi/ModelExchange/3.0/fmi3_binary_extobj.mos Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…5686) Wire up FMU state save/restore and serialization for FMI 3.0, for both the C and the C++ runtime, and advertise the capability in modelDescription.xml. C runtime (fmu3_model_interface.c): - the public fmi3GetFMUState/fmi3SetFMUState/fmi3FreeFMUState and fmi3SerializedFMUStateSize/fmi3SerializeFMUState/fmi3DeserializeFMUState were stubs returning fmi3Error; delegate them to the existing native omc*FMUstate helpers (which snapshot the simulation ring buffer and the parameters). - broaden the get/set/free state masks to allow ContinuousTimeMode and Terminated, so FMU state can be taken/restored while stepping. C++ runtime (FMU3/FMU3Wrapper, FMU3Interface): - implement getFMUState/setFMUState/freeFMUState and the (de)serialization on FMU3Wrapper, snapshotting time, the continuous states and the full real/integer/boolean/string arrays through the bulk IContinuous accessors; - wire the FMU3Interface entry points to the wrapper. CodegenFMU3: ModelExchange/CoSimulation/ScheduledExecution now advertise canGetAndSetFMUState="true" and canSerializeFMUState="true" unconditionally (decoupled from the FMU_EXPERIMENTAL switch, which also gates unrelated experimental features). testsuite: add fmi3_fmustate.mos; update fmi3_cs_01.mos expected flags. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
Implement fmi3GetDirectionalDerivative for both runtimes. The symbolic FMIDER Jacobian generation and the native evaluation helpers already existed and are shared with FMI 2.0 (enabled with -d=-disableDirectionalDerivatives); only the public FMI 3.0 entry points were stubs returning fmi3Error. - C runtime (fmu3_model_interface.c): delegate fmi3GetDirectionalDerivative to omcGetDirectionalDerivative, mapping the unknown/known value references back to the per-real-type references (seed -> dvKnown, sensitivity -> dvUnknown). - C++ runtime (FMU3/FMU3Interface.cpp): delegate to FMU3Wrapper::getDirectionalDerivative with the same value-reference mapping. When directional derivatives are enabled the ModelExchange/CoSimulation element already advertises providesDirectionalDerivatives="true" (it follows the FMIDER Jacobian). fmi3GetAdjointDerivative stays a stub (not provided). testsuite: add fmi3_directional_derivatives.mos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
In FMI 2.0 the FMU source file list was carried in modelDescription.xml (<SourceFiles>); FMI 3.0 removed that and uses sources/buildDescription.xml instead. Generate it for the C source FMU. - CodegenFMU3: fmiBuildDescription emits a BuildConfiguration with the model identifier, a C SourceFileSet listing every source file, the FMI2_/FMI3_OVERRIDE_FUNCTION_PREFIX preprocessor definitions and the "." and "fmi" include directories (matching the FMU's own CMake/Make recipe). fmiBuildDescriptionFile writes sources/buildDescription.xml (skipped when no sources are shipped, e.g. --fmiFilter=blackBox). - CodegenFMU.translateModel: write it for FMI 3.0 alongside modelDescription.xml. Verified schema-valid and importer-buildable: compiling exactly per the buildDescription (the listed sources, -I. -Ifmi and the two defines) produces a working binary that simulates to the analytic solution. testsuite: add fmi3_builddescription.mos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…ica#15686) Export the model's clocked partitions as FMI 3.0 output <Clock> variables and make them functional at runtime. The engine already ticks the clocks internally during event mode (handleTimersFMI); this surfaces them through the FMI 3.0 API. - SimCode / SimCodeUtil: FmiClock type and getFMI3Clocks, mapping each base clock (REAL/RATIONAL/EVENT clock kind) to an output clock with its intervalVariability and period/fraction. Clocks get their own value-reference block after the binary block; the time value reference shifts past it. - CodegenFMU3: emit <Clock> variables (Clock3). - CodegenFMU / CodegenFMUCpp: NUMBER_OF_CLOCKS and FMI3_CLOCK_VR_OFFSET defines, time VR shifted accordingly. - fmu3_model_interface.c: implement fmi3GetClock (active when the base clock fired at the current event, from baseClocks[i].stats), fmi3GetIntervalDecimal and fmi3GetIntervalFraction (the clock period). fmi3SetClock stays a stub (no input clocks). - C++ runtime: VR offsets kept consistent and fmi3GetClock/fmi3GetIntervalDecimal wired to FMU3Wrapper (output-clock activation is a C++ runtime limitation). Verified: a periodic Clock(0.1) is declared as an output clock and ticks at t=0.1/0.2/0.3 with interval 0.1 via the FMI 3.0 C API (Model Exchange). testsuite: add fmi3_clocks.mos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
The FMU-state commit made canGetAndSetFMUState / canSerializeFMUState unconditionally "true" for FMI 3.0 (the runtime now implements them). The Cpp runtime ModelExchange test still expected "false" — update its baseline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…delica#15686) Adds FMI 3.0 graphical user annotations (ticket OpenModelica#15686 task 9): the model Icon is rendered to an SVG and an <GraphicalRepresentation> plus per-port <TerminalGraphicalRepresentation> are written into terminalsAndIcons.xml. New Qt-free C++ library OMGraphics (Compiler/runtime), mirroring OMEdit's annotation graphics model: - OMGraphics.{h,cpp}: data model (shapes/coordinate system/icon) + an SVG renderer (rectangle/line/polygon/ellipse+arc/text/bitmap, Modelica y-up to SVG y-down, %name substitution), a generic JSON value, an iconFromJson annotation parser and the FMI 3.0 GraphicalRepresentation XML emitter. Pure and standalone-testable. - OMGraphics_omc.cpp: walks the in-memory model-instance reference of issue OpenModelica#15219 (boxed list-form MetaModelica JSON) into the renderer. Used only for the graphical side: the model icon, and each placed connector's placement box and connector-type icon. - Registered in the CMake, autoconf (Makefile.common) and OMDev mingw builds. Split of concerns: - Ports and their input/output direction come from the flat model. SimCodeUtil.getFMI3Terminals also emits a single-member terminal for each top-level scalar input/output variable (from SimVars inputVars/outputVars); signal connectors such as RealInput/RealOutput collapse to plain input/output Real in the flat model and are detected this way. No JSON or modelDescription.xml is consulted for the direction. - Placement geometry and icon shapes come from the model instance (graphics only). CevalScriptBackend renders icons/<modelIdentifier>.svg and icons/<iconBaseName>.svg, and injects a TerminalGraphicalRepresentation (placement box + iconBaseName) into the matching SimCode <Terminal>, keeping the FMI 3.0 schema order (GraphicalRepresentation before Terminals). New backend support: the new backend marked no variable as FMI input/output (modelDescription had no causality, outputVars was empty). NFVariable gains an isOutput helper; NSimVar.parseBinding now sets INPUT/OUTPUT causality from the variable direction and the SimVars build collects the output interface, so the FMI 3.0 terminals (and modelDescription causality) work with --newBackend too. Testsuite: new fmi3_graphics.mos (model icon, GraphicalRepresentation, placed input/output ports with their TerminalGraphicalRepresentation and rendered port icons); fmi3_terminals.mos updated for the new top-level output port terminal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
2c74f9d to
918a685
Compare
…elica#15686) Implements a simple Scheduled Execution (SE) strategy (ticket OpenModelica#15686 task 10), building on the FMI 3.0 clock support: each base clock is one model partition, and the simulation algorithm activates it via fmi3ActivateModelPartition. - fmu3_model_interface.c: fmi3ActivateModelPartition was a no-op. It now maps the clock value reference to its base-clock index (FMI3_CLOCK_VR_OFFSET + index, the same scheme as fmi3GetClock), advances the model to the activation time and runs that clocked partition (its synchronous equations + interval update) directly, i.e. without handleBaseClock's Model-Exchange sub-clock timer scheduling and its initialization-time deferral (there is no internal event loop in SE). Any pending continuous/algebraic evaluation is flushed first and the deferred-update flag is cleared afterwards so the next fmi3Get* returns the freshly computed clocked outputs instead of re-evaluating over them. The clock activation stats are updated so fmi3GetClock / fmi3GetInterval* keep working. - CodegenFMU3.tpl: for a Scheduled Execution FMU the model clocks are declared as input clocks (causality="input"); the importer activates the associated model partition. Model Exchange / Co-Simulation keep output clocks. The FMU type is threaded through fmiModelVariables3 to Clock3. Verified with a Scheduled Execution driver on a clocked counter (y = previous(y) + 1 on Clock(0.1)): activating the partition at t=0.1,0.2,0.3 yields y=1,2,3. Testsuite: new fmi3_scheduled.mos (ScheduledExecution element and input clock). All 11 FMI 3.0 ModelExchange/3.0 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…nModelica#15686) The FMI 3.0 standard resolves a TerminalGraphicalRepresentation iconBaseName as a relative URI against terminalsAndIcons/terminalsAndIcons.xml, and requires a PNG image file (the SVG is only an optional companion); the FMU-layout section likewise places the FMU/terminal icon files in terminalsAndIcons/. The previous export instead wrote SVG-only icons to a top-level icons/ directory and emitted iconBaseName without an extension, so an importer could not resolve them. Now all icon files are written to terminalsAndIcons/: the model icon as icon.png (+ icon.svg companion) and each placed connector port icon as <base>.png (+ <base>.svg), with iconBaseName="<base>.png". A TerminalGraphicalRepresentation is only emitted when its PNG was written, since iconBaseName is mandatory. To produce the mandatory PNG without pulling in Qt or an image library, add a small zlib-only rasteriser to the OMGraphics runtime (renderIconPNG): supersampled anti-aliased scanline fill for Rectangle/Polygon/Ellipse and thick polylines for Line (Text/Bitmap are skipped), encoded as an RGBA PNG via zlib compress2 + crc32. PNG bytes contain NUL and cannot pass through a NUL-terminated MetaModelica String, so the new extern-C entry points OMGraphics_writeIconPNGFromHandle / OMGraphics_writePlacedConnectorIconPNG write the file directly given a destination path. Updated fmi3_graphics.mos to the new terminalsAndIcons/ layout (PNG + SVG per icon, iconBaseName with .png). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…5686) A connector potential variable is often eliminated as an alias (e.g. flange_a.phi == flange_b.phi == the state phi). Such a variable is still a real member of its terminal and is emitted in modelDescription.xml (CodegenFMU3 writes the alias var lists into ModelVariables), but getFMI3Terminals only scanned the non-alias var lists, so the member was dropped: a mechanical flange exported with only its flow member (tau) and not its potential member (phi). getFMI3Terminals now also scans the alias var lists (aliasVars, intAliasVars, boolAliasVars, stringAliasVars); connectorMemberOf already filters to connector members, so non-connector aliases are ignored. Real vars are scanned first so the canonical member ordering is preserved, and members are de-duplicated by memberName (which must be unique per terminal in FMI 3.0). Adds fmi3_terminals_alias.mos covering a two-flange inertia whose phi members are aliases: each flange terminal now keeps both tau and phi, and every member variableName resolves to a variable in modelDescription.xml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…ule (OpenModelica#15686) Align the terminalsAndIcons.xml terminals with the FMI 3.0 semantics (and with Dymola's export): - variableKind is now the connection-semantics kind, not the variable causality: "inflow" for a flow connector member (Kirchhoff's law), "signal" otherwise (values intended to be equal across a connection). The previous code emitted causality strings (input/output/local/parameter), which are not the predefined variableKind values and conflate two different concepts (causality is already in modelDescription.xml). - matchingRule is "plug" for an ordinary, fully-defined Modelica connector (all members must match) and "bus" only for expandable connectors, instead of always "bus". - terminalKind now carries the connector type path (e.g. Modelica.Mechanics.Rotational.Interfaces.Flange_a), taken from the connector type in the cref, so importers can check type compatibility. The flow flag cannot be read from the connector type stored in the cref (it keeps only the type path, not the member attributes), so it is captured from the BackendDAE connectorType in a new SimVar field isConnectorFlow, set in dlowvarToSimvar. The new backend does not yet track this and emits "signal" for flow members (TODO noted in NSimVar.convert). Updates fmi3_terminals.mos, fmi3_terminals_alias.mos and fmi3_graphics.mos to the new attribute values. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…penModelica#15686) The new backend's SimVar did not carry the connector flow flag, so flow connector members were exported with variableKind="signal" instead of "inflow". NFVariable already exposes the flow attribute (Variable.isFlow, reading attributes.connectorType), so add an isConnectorFlow field to the new-backend SimVar, populate it in NSimVar.create, and forward it in the conversion to the old SimCodeVar instead of the previous hard-coded false. With this, --newBackend produces the same terminal variableKind (inflow for flow members, signal otherwise) as the default backend. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…penModelica#15686) FMI 3.0 represents an alias variable as an <Alias> child element of its canonical variable, sharing that variable's valueReference (it carries no own valueReference, factor or causality). OM instead emitted every alias as a separate ModelVariables entry with its own valueReference. This switches local positive aliases to the FMI 3.0 <Alias> form (matching e.g. Dymola), which also lets terminal members reference connector-member aliases (such as flange_a.phi == phi) by name without giving them a separate variable. - getFMI3VariableAliases / isFMI3NestableAlias (SimCodeUtil): a SimVar is nestable when it is a positive (non-negated), scalar alias with no causality of its own (local); an <Alias> cannot express a factor or a causality, so negated and input/output/parameter aliases stay as full variables. - CodegenFMU3.tpl: nestable aliases are skipped in the ModelVariables loop and instead emitted as <Alias> children of their canonical variable (CloseWithAliases3 turns the self-closing element into an open/close pair when children exist). The canonical variable keeps its valueReference, so nothing is renumbered; the alias' former value reference simply becomes an unused gap (allowed by FMI 3.0). Validated with fmpy on the sandbox models (terminals referencing the alias names resolve); all FMI 3.0 ME and CS testsuite cases pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…ctors (OpenModelica#15686) Export a model's unconnected acausal (physical) connectors as a causal FMU boundary so the FMU can be reconnected into a physical circuit (as Dymola does for FMI terminal export). An unconnected flow variable is normally given a `flow = 0` equation; for FMI 3.0 export this instead exposes the flow as an input and the connector's potential variable(s) as outputs, and drops the zero-flow equation. The backend then causalizes the model in the natural "component driven by its boundary flows" form. For Modelica.Mechanics.Rotational MyInertia this yields flange_a.tau/flange_b.tau as inputs and flange_a.phi/flange_b.phi as outputs (der(w) now depends on the torque inputs), matching Dymola's causalization. Verified functionally: driving flange_a.tau = 1 (J = 1) gives w(1) = 1 and phi(1) = 0.5 (rigid-body response). - NFFlatten.causalizeAcausalConnectors / causalizeAcausalVar: run at the end of resolveConnections, gated on BUILDING_FMU and FMI_VERSION == "3.0". Finds the `flow = 0` equations of unconnected flow connector members, drops them, marks those flows as inputs and the matching potentials (same connector instance) as outputs. Balance-neutral, so it does not change solvability. - fmi3_terminals_alias.mos updated: the flange members are now causalized (potential -> output, flow -> input) and still appear in the terminal. Only FMI 3.0 export is affected. fmpy validates the result and all FMI 3.0 ME/CS testsuite cases pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
…kend test (OpenModelica#15686) The flange causalization breaks the new backend: once the zero-flow equations are replaced by boundary inputs, NBResolveSingularities.balanceInitialization fails and no FMU is produced. Gate causalizeAcausalConnectors on `not settings.newBackend` so the new backend keeps building (it exports the unconnected flange as before: flow as a fixed parameter, potential as an <Alias> of the state). The old backend is unaffected and still produces the causal boundary. The other FMI 3.0 terminal features added in this series (terminals, variableKind inflow/signal, terminalKind, matchingRule=plug, <Alias> emission, flow detection) work correctly on both backends. Add fmi3_terminals_alias_nb.mos, the --newBackend counterpart of fmi3_terminals_alias.mos, asserting those features and documenting that causalization is not applied on the new backend. (Broader new-backend FMI 3.0 modelDescription/ModelStructure has separate pre-existing limitations and is not covered here.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Adrian Pop <adrian.pop@liu.se>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is currently work in progress to support FMI3 export in OM (#15686).
modelDescription.xmlinput/output causalityCheck the commits for the latest updates to the messages