A Python framework for heterogeneous system co-simulation (Modelica FMUs, OpenSim, FEM).
Project description
SysSimX
SysSimX is a free and open-source Python library for system simulation. It allows you to build hybrid and heterogenous system models by connecting system component models from different environments, including:
- FMU Components - Functional Mock-up Units (FMI 2.0 Co-Simulation)
- OpenSim Components - Musculoskeletal biomechanics models using OpenSim
- FEM Components - Finite Element Models using NGSolve
- Custom Python Components - User-defined models implemented directly in Python
The library comes with a user documentation site that includes installation instructions, core concepts, API references, and tutorials covering fundamental techniques, tool integrations, and a case study.
Key Features
-
Graph-Based Execution: Automatic dependency analysis with direct feedthrough and algebraic loop detection. Components are executed in topologically sorted order.
-
Algebraic Loop Handling: Detection and iterative solving using the Interface Jacobian-based Co-Simulation Algorithm (IJCSA).
-
Hybrid Co-Simulation: Event detection via zero-crossing indicators with bisection-based time localization and superdense time semantics.
-
Multiple Master Algorithms: Choose from Jacobi (parallel), Gauss-Seidel (sequential), or Hybrid (event-driven) algorithms.
-
Multi-Tool Integration: Seamlessly connect FMUs, OpenSim models, and NGSolve FEM models in a single system.
-
Multi-Model Switching: Dynamically switch between multiple models of the same component during simulation.
-
Unit-Aware Connections: Automatic unit conversion between ports using Pint.
-
Extensible Component API: Base class for custom components with lifecycle methods for initialization, stepping, and output updates.
Installation
The syssimx package is available on PyPI. You can install it using pip. Optional extras are available for FMU, OpenSim, and FEM support.
Basic install
pip install syssimx
Optional extras
pip install "syssimx[fmu]"
pip install "syssimx[fem]"
pip install "syssimx[dev]"
pip install "syssimx[all]"
pip install "syssimx[full]"
OpenSim note (important)
OpenSim is conda-only and ABI-coupled to specific NumPy/SciPy builds. Recommended order:
- Install
syssimxwithpip. - Install OpenSim with
condausing ABI-compatible NumPy/SciPy pins.
See the full installation guide:
docs/01_getting_started/01_installation.ipynb
Quickstart Example
The example below creates a simple linear source feeding an integrator.
import matplotlib.pyplot as plt
from syssimx import CoSimComponent, Connection, System
from syssimx.core import PortSpec, PortType
class LinearSource(CoSimComponent):
def __init__(self, name: str, a: float = 1.0, b: float = 0.0):
super().__init__(name, group="Source")
self.a = a
self.b = b
self.output_specs.update({
"y": PortSpec(name="y", type=PortType.REAL, direction="out")
})
def _initialize_component(self, t0: float) -> None:
pass
def _do_step_internal(self, t: float, dt: float) -> None:
pass
def _update_output_states(self, t: float | None = None, event_names=None):
t_now = 0.0 if t is None else t
self.outputs["y"].set(self.a * t_now + self.b, t)
class Integrator(CoSimComponent):
def __init__(self, name: str, x0: float = 0.0):
super().__init__(name, group="Integrator")
self.x0 = x0
self.input_specs.update({
"u": PortSpec(name="u", type=PortType.REAL, direction="in")
})
self.output_specs.update({
"y": PortSpec(name="y", type=PortType.REAL, direction="out")
})
def _initialize_component(self, t0: float) -> None:
self.x = self.x0
self.outputs["y"].set(self.x, t0)
def _do_step_internal(self, t: float, dt: float) -> None:
u = self.inputs["u"].get()
self.x = self.x + dt * float(u)
def _update_output_states(self, t: float | None = None, event_names=None):
self.outputs["y"].set(self.x, t)
source = LinearSource(name="LinearSource", a=1.0, b=0.0)
integrator = Integrator(name="Integrator", x0=0.0)
system = System(name="QuickstartSystem")
system.add_component(source)
system.add_component(integrator)
system.add_connection(Connection(
src_comp="LinearSource", src_port="y",
dst_comp="Integrator", dst_port="u",
))
system.initialize(t0=0.0)
system.run(t0=0.0, tf=5.0, dt=0.1)
history = system.get_history()
t_vals, data = history["Integrator"]
y_vals = data["y"]
plt.plot(t_vals, y_vals)
plt.xlabel("Time (s)")
plt.ylabel("Integrator output")
plt.title("SysSimX Quickstart")
plt.grid(True)
plt.show()
For the complete walkthrough, see:
docs/01_getting_started/02_quickstart.ipynb
Documentation
- Documentation entry:
docs/index.rst - Installation guide:
docs/01_getting_started/01_installation.ipynb - Core concepts:
docs/01_getting_started/03_concepts.ipynb - Quickstart tutorial:
docs/01_getting_started/02_quickstart.ipynb - API docs:
docs/02_api/ - Tutorials and case studies:
docs/03_core_tutorials/docs/04_tool_integration/docs/05_case_study/
Project Status
SysSimX is under active development. APIs and behavior may evolve as algorithms and component integrations are extended.
License
- Project license: MIT (
LICENSE) - Third-party dependencies and attributions:
THIRD_PARTY_LICENSES.MD
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file syssimx-0.1.5.tar.gz.
File metadata
- Download URL: syssimx-0.1.5.tar.gz
- Upload date:
- Size: 85.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db4fb8f2cd7bfb8db1d6b62c90dcff4f973a6c5d955ba7aaa25685c2ac30cce4
|
|
| MD5 |
2b749b3e065dd56787456817df7bf277
|
|
| BLAKE2b-256 |
e1e78e040d9a9aff7361ad193e55b47c2d60b763a0576d68600ed15a97d019ad
|
Provenance
The following attestation bundles were made for syssimx-0.1.5.tar.gz:
Publisher:
publish-pypi.yml on FlorianFrech/SystemSimulation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
syssimx-0.1.5.tar.gz -
Subject digest:
db4fb8f2cd7bfb8db1d6b62c90dcff4f973a6c5d955ba7aaa25685c2ac30cce4 - Sigstore transparency entry: 1008442454
- Sigstore integration time:
-
Permalink:
FlorianFrech/SystemSimulation@34e018c3e1096ec43444f343ae31b281d50d51e1 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/FlorianFrech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@34e018c3e1096ec43444f343ae31b281d50d51e1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file syssimx-0.1.5-py3-none-any.whl.
File metadata
- Download URL: syssimx-0.1.5-py3-none-any.whl
- Upload date:
- Size: 96.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64c757af00f5ce04ff135bc5c02ffd1238c835cdcb45a68d7a8555a99dd99b12
|
|
| MD5 |
c420e3df880951afcbc81bbee8561919
|
|
| BLAKE2b-256 |
712148ad0f971000655d5034dac2dfb7ccc0e8b1242a40b5419739c049bc15e2
|
Provenance
The following attestation bundles were made for syssimx-0.1.5-py3-none-any.whl:
Publisher:
publish-pypi.yml on FlorianFrech/SystemSimulation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
syssimx-0.1.5-py3-none-any.whl -
Subject digest:
64c757af00f5ce04ff135bc5c02ffd1238c835cdcb45a68d7a8555a99dd99b12 - Sigstore transparency entry: 1008442458
- Sigstore integration time:
-
Permalink:
FlorianFrech/SystemSimulation@34e018c3e1096ec43444f343ae31b281d50d51e1 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/FlorianFrech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@34e018c3e1096ec43444f343ae31b281d50d51e1 -
Trigger Event:
push
-
Statement type: