Skip to content

Feature/fmi3#16

Open
joakimono wants to merge 10 commits intomasterfrom
feature/fmi3
Open

Feature/fmi3#16
joakimono wants to merge 10 commits intomasterfrom
feature/fmi3

Conversation

@joakimono
Copy link
Copy Markdown
Contributor

cppfmu provides FMI 3.0 co-simulation support through a separate interface (cppfmu_cs_fmi3.hpp / cppfmu_cs_fmi3.cpp) and C API wrapper (fmi3_functions.cpp). The FMI 3.0 interface uses a distinct SlaveInstance3 class rather than extending the FMI 1.0/2.0 SlaveInstance, due to fundamental differences in the type system, memory model, logger signature, instantiation parameters, and DoStep signature.

Build with CPPFMU_FMI_3=ON (CMake) or use_fmi_version=3 (Conan).

Implemented Features

All of the following have corresponding virtual methods on SlaveInstance3 that users can override. Default implementations throw std::logic_error for non-empty variable references (consistent with FMI 1.0/2.0 behavior).

Category Functions
Type access Get/SetFloat32, Get/SetFloat64, Get/SetInt864, Get/SetUInt864, Get/SetBoolean, Get/SetString, Get/SetBinary
Clocks GetClock, SetClock
Derivatives GetDirectionalDerivative, GetAdjointDerivative, GetOutputDerivatives
Dependencies GetVariableDependencies, GetNumberOfVariableDependencies
FMU state GetFMUState, SetFMUState, FreeFMUState, SerializeFMUState, DeserializeFMUState
Event Mode EnterEventMode, EvaluateDiscreteStates, UpdateDiscreteStates, EnterStepMode
DoStep Enhanced signature with eventHandlingNeeded, terminateSimulation, earlyReturn, lastSuccessfulTime
Queries GetNumberOfEventIndicators, GetNumberOfContinuousStates
Lifecycle Enter/ExitInitializationMode, Terminate, Reset
Logging SetDebugLogging with category support

Genuine Stubs (No Virtual Method)

These functions are hardcoded in fmi3_functions.cpp to always return fmi3Error. No virtual method exists on SlaveInstance3 for users to override.

Function Purpose
fmi3EnterConfigurationMode Structural parameter tuning (optional)
fmi3ExitConfigurationMode Structural parameter tuning (optional)
fmi3GetIntervalDecimal Variable-interval output clocks (optional)
fmi3GetIntervalFraction Variable-interval output clocks (optional)
fmi3GetShiftDecimal Shifted clocks (optional)
fmi3GetShiftFraction Shifted clocks (optional)
fmi3SetIntervalDecimal Variable-interval output clocks (optional)
fmi3SetIntervalFraction Variable-interval output clocks (optional)
fmi3SetShiftDecimal Shifted clocks (optional)
fmi3SetShiftFraction Shifted clocks (optional)

Additionally, the Intermediate Update Callback parameter accepted during fmi3InstantiateCoSimulation is stored but never invoked.

Memory Management

FMI 3.0 does not provide memory allocator callbacks. Use standard C++ new/delete directly, or cppfmu::AllocateUnique3<T>() for managed ownership.

Logger

FMI 3.0 uses a fixed-signature logger callback (no varargs, no instance name). The fmi3_functions.cpp wrapper handles this internally; model code does not need to interact with the logger directly.

Test Coverage

The tests/cs_test_fmi3.cpp / tests/cs_slave_fmi3.cpp test fixture covers:

  • All type Get/Set round-trips (Float32, Float64, Int32, Boolean, Binary)
  • Directional and output derivatives (error path + success path)
  • Adjoint derivative and variable dependencies (error path — not implemented in test slave)
  • FMU state lifecycle (get, serialize, free, deserialize, set, free, restore verification)
  • Enhanced DoStep with output parameter assertions
  • Event Mode lifecycle (EnterEventMode → EvaluateDiscreteStates → UpdateDiscreteStates → EnterStepMode)
  • GetNumberOfEventIndicators / GetNumberOfContinuousStates
  • fmi3GetVersion, fmi3SetDebugLogging, fmi3Reset, fmi3Terminate
  • Null-instance safety for fmi3FreeInstance
  • Invalid value reference error paths

joakimono added 9 commits May 4, 2026 16:57
Add SlaveInstance3 base class with full FMI 3.0 co-simulation API:
- 13 Get/Set types (Float32/64, Int8-64, UInt8-64, Boolean, String, Binary, Clock)
- Directional and adjoint derivatives
- Variable dependencies and output derivatives
- FMU state serialization
- FMI 3.0 DoStep with event/early return output params

New files: cppfmu_cs_fmi3.hpp, cppfmu_cs_fmi3.cpp, fmi3_functions.cpp
Updated: cppfmu_common.hpp, CMakeLists.txt, conanfile.py, test_package
- Add FMIByte type alias for FMI 3.0
- Remove dead instanceName storage in FMI 3.0 Component
- Enforce debugLoggingEnabled in FMI 3.0 Logger (skip non-error messages)
- Add GetNumberOfEventIndicators/GetNumberOfContinuousStates virtual methods
- Create tests/cs_slave_fmi3.cpp (test slave for FMI 3.0)
- Create tests/cs_test_fmi3.cpp (integration test for FMI 3.0)
- Update CMakeLists.txt to build cs_test for FMI 3.0
…est coverage

Document FMI 3.0 support status in README:
- Add supported versions table
- List fully implemented vs stub features
- Explain why SlaveInstance3 was created instead of extending
  SlaveInstance (type system, memory model, logger, instantiation,
  enhanced DoStep)
- Update usage sections for FMI 1.0/2.0 vs FMI 3.0
- Note memory management differences (FMI allocator vs standard C++)

Add fmi3GetBinary/fmi3SetBinary test coverage:
- Implement SetBinary/GetBinary in TestSlave3 (vr=3)
- Test set/get round-trip with known byte pattern
- Test size query with nullptr values array
- Test invalid value reference error path
- Fix nullptr handling in GetBinary to avoid segfault
Add four new virtual methods to SlaveInstance3:
- EnterEventMode() — does nothing by default
- EvaluateDiscreteStates() — does nothing by default
- UpdateDiscreteStates() — sets all output flags to 'no events' defaults
- EnterStepMode() — does nothing by default

Replace hardcoded 'not supported' stubs in fmi3_functions.cpp with
proper try/catch forwarding to the new virtuals, following the same
pattern used by all other FMI functions.

Add test coverage for the full Event Mode lifecycle:
EnterEventMode → EvaluateDiscreteStates → UpdateDiscreteStates →
EnterStepMode, verifying all output parameters from UpdateDiscreteStates.
Move Event Mode, Binary, adjoint derivatives, and variable dependencies
from the 'stubs' section to 'fully implemented' since they all have
corresponding virtual methods on SlaveInstance3 that users can override.

Clarify that only Configuration Mode, Clock interval/shift functions,
and Intermediate Update Callback are genuine stubs (no virtual method).
Add note that GetClock/SetClock have virtual methods with default
throw-on-nonzero-vr behavior, consistent with other type Get/Set methods.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a parallel FMI 3.0 co-simulation integration path to CPPFMU alongside the existing FMI 1.0/2.0 support, covering the public C++ interface, C wrapper layer, packaging/build selection, tests, and user documentation.

Changes:

  • Introduces FMI 3.0-specific runtime APIs via cppfmu_cs_fmi3.*, fmi3_functions.cpp, and new FMI 3.0 aliases/logging support in cppfmu_common.hpp.
  • Wires FMI 3.0 selection into CMake/Conan/test-package flows and bumps the library version to 1.3.0.
  • Adds FMI 3.0-focused documentation and a dedicated test fixture/test executable.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
version.txt Bumps package/library version to 1.3.0.
tests/cs_test_fmi3.cpp Adds FMI 3.0 end-to-end wrapper tests.
tests/cs_slave_fmi3.cpp Adds FMI 3.0 test slave fixture.
test_package/main.cpp Adds FMI 3.0 consumer-side sample entry point.
test_package/CMakeLists.txt Selects the correct wrapper source for packaged consumers.
README.md Documents FMI 3.0 support, usage, and packaging.
fmi3_functions.cpp Implements the FMI 3.0 C API forwarding layer.
cppfmu_cs_fmi3.hpp Declares the FMI 3.0 C++ co-simulation interface.
cppfmu_cs_fmi3.cpp Provides default FMI 3.0 interface behavior.
cppfmu_common.hpp Adds FMI 3.0 type aliases and logging utilities.
conanfile.py Adds FMI 3.0 package option/dependency handling.
CMakeLists.txt Adds FMI 3.0 build/install/test path selection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/cs_slave_fmi3.cpp
Comment thread tests/cs_test_fmi3.cpp Outdated
Comment thread fmi3_functions.cpp Outdated
Comment thread CMakeLists.txt Outdated
Comment thread CMakeLists.txt
Comment thread CMakeLists.txt Outdated
Comment thread cppfmu_common.hpp Outdated
Comment thread README.md
- Fix invalid value reference test to use vr=999 instead of vr=1, which
  is actually valid in TestSlave3 (tests/cs_test_fmi3.cpp)
- Fix logger callback to forward all log levels to simulation environment,
  not just errors/fatal when debug logging is disabled (fmi3_functions.cpp)
- Only install cppfmu_cs.hpp for FMI 1/2 builds; it's unusable with FMI 3
  since Memory and Logger types are compiled out (CMakeLists.txt)
- Add guard to reject conflicting CPPFMU_FMI_1 + CPPFMU_FMI_3 configuration
- Enable regression tests for FMI 1.0 builds (previously skipped)
- Use distinct sentinel value for FMIPending in FMI 3.0 to avoid confusion
  with FMIWarning (cppfmu_common.hpp)
- Add Float32, Int32, and Boolean accessors to TestSlave3 fixture to
  support new test cases (tests/cs_slave_fmi3.cpp)
- Update README conan examples to show FMI 3.0 usage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants