Master Algorithms#
Algorithm interfaces for advancing a System one time step.
- class syssimx.system.algorithms.base.Algorithm[source]#
Bases:
ABCInterface for simulation algorithms.
Implementations are responsible for advancing a System from time t to t + dt.
- _abc_impl = <_abc._abc_data object>#
Jacobi Co-Simulation Algorithm#
Jacobi-based execution algorithm for system simulation.
This module provides an implementation of the Jacobi algorithm, which is used to advance a system simulation by processing components in a parallelized order. The algorithm sets all inputs for a generation before advancing any component in that generation, solving algebraic loops within the generation, and then advancing the component states.
- Classes:
JacobiAlgorithm: Implements the Jacobi algorithm for advancing a system simulation.
- Usage:
The JacobiAlgorithm class is designed to be used as part of the system simulation framework. It processes components in a parallelized manner, which does not handle direct-feedthrough components whose outputs could become available within the same macro step to downstream components.
- Dependencies:
Algorithm: Base class for all algorithms.
solve_algebraic_scc_ijcsa: Function to solve algebraic strongly connected components.
Example
from syssimx.system.algorithms.jacobi import JacobiAlgorithm
algorithm = JacobiAlgorithm()
algorithm.step(system, t, dt)
- class syssimx.system.algorithms.jacobi.JacobiAlgorithm[source]#
Bases:
AlgorithmAdvance the system using a Jacobi-style execution order.
The algorithm sets all inputs for a generation before any component in that generation advances, then solves any algebraic loops contained in that generation, and finally advances component state.
This approach does not handle direct-feedthrough components whose outputs could become available within the same macro step to downstream components.
- _abc_impl = <_abc._abc_data object>#
Gauss-Seidel Co-Simulation Algorithm#
Gauss-Seidel execution algorithm for system simulation.
This module provides an implementation of the Gauss-Seidel algorithm, which is used to advance a system simulation by processing components in a specific order. The algorithm ensures that direct-feedthrough components are handled correctly by making their outputs available within the same macro step to downstream components in the current execution order.
- Classes:
GaussSeidelAlgorithm: Implements the Gauss-Seidel algorithm for advancing a system simulation.
- Usage:
The GaussSeidelAlgorithm class is designed to be used as part of the system simulation framework. It processes components generation by generation, solving algebraic loops within each generation before stepping components forward.
- Dependencies:
Algorithm: Base class for all algorithms.
solve_algebraic_scc_ijcsa: Function to solve algebraic strongly connected components.
Example
from syssimx.system.algorithms.gauss_seidel import GaussSeidelAlgorithm
algorithm = GaussSeidelAlgorithm()
algorithm.step(system, t, dt)
- class syssimx.system.algorithms.gauss_seidel.GaussSeidelAlgorithm[source]#
Bases:
AlgorithmAdvance the system using Gauss-Seidel-style ordering.
Components are processed generation by generation, with algebraic loops solved inside each generation before stepping components forward.
This approach accounts for direct-feedthrough components by making their outputs available within the same macro step to downstream components in the current execution order.
- _abc_impl = <_abc._abc_data object>#
Interface Jacobian-based Co-Simulation Algorithm#
Interface Jacobian-based Co-Simulation Algorithm (IJCSA).
This module implements the IJCSA algorithm for solving algebraic loops in co-simulated systems using a local and global Newton iteration on interface variables.
References
Sicklinger, S., Belsky, V., Engelmann, B., Elmqvist, H., Olsson, H., Wüchner, R. and Bletzinger, K.-.-U. (2014), Interface Jacobian-based Co-Simulation. Int. J. Numer. Meth. Engng, 98: 418-444. https://doi.org/10.1002/nme.4637
- Classes:
IJCSAAlgorithm: Main algorithm class implementing the step() method.
- Functions:
solve_algebraic_scc_ijcsa: Solves algebraic loops in strongly coupled components (SCCs) using IJCSA. solve_global_interface_ijcsa: Solves global interface equations using the IJCSA algorithm. compute_interface_residual_global: Computes the residual for all zero-delay connections in the system. compute_interface_jacobian_global: Computes the Jacobian matrix for the global interface system using finite differences.
- Usage:
The IJCSAAlgorithm class and its associated functions are designed to be used as part of the system simulation framework. The algorithm solves algebraic loops in co-simulated systems by iteratively refining interface variables until convergence.
Example
from syssimx.system.algorithms.ijcsa import IJCSAAlgorithm
algorithm = IJCSAAlgorithm(max_iter=100, tol=1e-8)
algorithm.step(system, t, dt)
- class syssimx.system.algorithms.ijcsa.IJCSAAlgorithm[source]
Bases:
AlgorithmInterface Jacobian-based Co-Simulation Algorithm (IJCSA).
This algorithm solves all algebraic loops in the system simultaneously using a global Newton iteration on the interface variables.
- name
Name of the algorithm.
- Type:
- max_iter
Maximum number of iterations for convergence.
- Type:
- tol
Tolerance for convergence.
- Type:
References
Sicklinger, S., Belsky, V., Engelmann, B., Elmqvist, H., Olsson, H., Wüchner, R. and Bletzinger, K.-.-U. (2014), Interface Jacobian-based Co-Simulation. Int. J. Numer. Meth. Engng, 98: 418-444. https://doi.org/10.1002/nme.4637
- name: str = 'IJCSA'
- max_iter: int = 50
- tol: float = 1e-06
- step(system, t, dt)[source]
Advance the system by one time step using the IJCSA algorithm.
This method solves all algebraic loops in the system using a global Newton iteration on the interface variables, ensuring consistency across all components.
- Parameters:
- Raises:
RuntimeError – If the global IJCSA algorithm fails to converge.
- Return type:
None
- __init__(name='IJCSA', max_iter=50, tol=1e-06)
- _abc_impl = <_abc._abc_data object>
- syssimx.system.algorithms.ijcsa.solve_algebraic_scc_ijcsa(system, scc, t, max_iter=50, tol=1e-06)[source]
Solve algebraic loop for a strongly coupled SCC using an interface Jacobian-based Newton iteration, following Sicklinger et al.
- Parameters:
system (System) – The system containing the strongly coupled components.
scc (list[str]) – List of component names in the strongly coupled component (SCC).
t (float) – Current simulation time.
max_iter (int, optional) – Maximum number of iterations for convergence. Defaults to 50.
tol (float, optional) – Tolerance for convergence. Defaults to 1e-6.
- Raises:
RuntimeError – If the algorithm fails to converge within the maximum number of iterations.
- Return type:
None
References
Sicklinger, S., Belsky, V., Engelmann, B., Elmqvist, H., Olsson, H., Wüchner, R. and Bletzinger, K.-.-U. (2014), Interface Jacobian-based Co-Simulation. Int. J. Numer. Meth. Engng, 98: 418-444. https://doi.org/10.1002/nme.4637
- syssimx.system.algorithms.ijcsa.compute_interface_residual_global(system, U, interface_inputs, driver_map, t)[source]
Compute the residual R(U) = U - Y(U) for all zero-delay connections in the system.
- Parameters:
system (System) – The system containing the components and connections.
U (np.ndarray) – Vector of interface input values.
interface_inputs (list[tuple[str, str]]) – List of interface input identifiers (component, port).
driver_map (dict[tuple[str, str], tuple[str, str]]) – Mapping from interface inputs to their drivers.
t (float) – Current simulation time.
- Returns:
Residual vector R(U).
- Return type:
np.ndarray
- syssimx.system.algorithms.ijcsa.compute_interface_jacobian_global(system, U, interface_inputs, driver_map, t, eps=1e-06)[source]
Compute the Jacobian matrix J ≈ ∂R/∂U for the global interface system using finite differences.
- Parameters:
system (System) – The system containing the components and connections.
U (np.ndarray) – Vector of interface input values.
interface_inputs (list[tuple[str, str]]) – List of interface input identifiers (component, port).
driver_map (dict[tuple[str, str], tuple[str, str]]) – Mapping from interface inputs to their drivers.
t (float) – Current simulation time.
eps (float, optional) – Perturbation size for finite difference approximation. Defaults to 1e-6.
- Returns:
Jacobian matrix J.
- Return type:
np.ndarray
- syssimx.system.algorithms.ijcsa.solve_global_interface_ijcsa(system, t, max_iter=50, tol=1e-06)[source]
Solve global interface equations using the IJCSA algorithm.
This method solves all zero-delay interface inputs in the system using a global Newton iteration. States are frozen at the current time, and after convergence, component input and output port states are consistent.
- Parameters:
- Raises:
RuntimeError – If the algorithm fails to converge within the maximum number of iterations.
- Return type:
None
Hybrid Co-Simulation Algorithm#
Hybrid Co-Simulation Algorithm with Event Detection and Handling.
This module provides an implementation of a hybrid co-simulation algorithm that combines continuous integration with event detection and handling. The algorithm supports superdense time semantics, event time localization, and iterative event handling to ensure accurate and consistent simulation results in the presence of discrete events.
- Classes:
- HybridAlgorithm: Implements the hybrid co-simulation algorithm with
event detection and handling.
- Functions:
_prepare_inputs: Prepares inputs for all generations and solves algebraic loops. _detect_crossings: Detects event crossings in a given time interval. _locate_event_time: Locates the event time within a given interval using bisection. _evaluate_indicators_at: Evaluates event indicators for all event source components at a target _evaluate_component_indicators: Evaluates event indicators for a single component at a target time. _detect_crossing_between: Detects crossings between two sets of indicator values for all event _restore_all_to_left: Restores all components to their state at the left boundary of the interval. _handle_events: Handles the specified events at the given time.
- Usage:
The HybridAlgorithm class is designed to be used as part of the system simulation framework. It extends the Gauss-Seidel algorithm by adding support for event detection and handling.
Example
from syssimx.system.algorithms.hybrid import HybridAlgorithm
algorithm = HybridAlgorithm()
algorithm.step(system, t, dt)
- class syssimx.system.algorithms.hybrid.HybridAlgorithm[source]#
Bases:
AlgorithmHybrid co-simulation algorithm with event detection and handling.
This algorithm combines continuous integration with event detection and handling. It supports superdense time semantics, event time localization, and iterative event handling to ensure accurate and consistent simulation results in the presence of discrete events.
- event_dedup_tol#
Tolerance for deduplicating events. Events of the same type handled within this time window are treated as duplicates and skipped.
- Type:
- gauss_seidel_algorithm#
Fallback algorithm for continuous integration in the absence of events.
- Type:
- step(system, t, dt)[source]#
Perform a hybrid co-simulation step with event detection and handling.
This method advances the simulation by one macro-step, handling events at superdense time points and falling back to the Gauss-Seidel algorithm for continuous integration when no events are detected.
- Parameters:
- Raises:
RuntimeError – If the maximum number of microsteps is reached during event handling.
- Return type:
None
- _prepare_inputs(system, t)[source]#
Prepare inputs for all generations and solve algebraic loops.
This method sets the inputs for all generations in the system and resolves any algebraic loops within each generation.
- _detect_crossings(event_sources, t_left, t_right)[source]#
Detect event crossings in a given time interval.
This method identifies events that occur within the specified time interval by evaluating event indicators and collecting internal hints from components with micro-stepping capabilities.
- Parameters:
event_sources (list[CoSimComponent]) – List of components that can generate events.
t_left (float) – Start of the time interval.
t_right (float) – End of the time interval.
- Returns:
- A tuple containing the following elements:
snapshots (dict[str, Any]): State snapshots of components at t_left.
input_cache (dict[str, dict[str, Any]]): Cached inputs of components at t_left.
indicators_left (dict[str, dict[str, float]]): Event indicator values at t_left.
crossings (list[tuple[str, str]]): List of (component name, event name) tuples where crossings were detected.
internal_hints (dict[str, list[InternalEventInfo]]): Mapping of component names to lists of InternalEventInfo.
- Return type:
- _capture_inputs(comp)[source]#
Capture the current inputs of the component.
- Parameters:
comp (CoSimComponent)
- Return type:
- _restore_with_inputs(comp, snapshot, inputs, t)[source]#
Restore the component’s state from snapshot and set its inputs.
- Parameters:
comp (CoSimComponent)
snapshot (Any)
t (float)
- Return type:
None
- _locate_event_time(event_sources, snapshots_left, input_cache, indicators_left, t_left, t_right, internal_hints=None)[source]#
Locate the event time within [t_left, t_right] using bisection.
If internal_hints are provided (from components with internal micro-stepping), the algorithm uses these to narrow the search interval before bisection, significantly reducing the number of iterations needed.
Returns the located event time and the list of (component name, event name) tuples.
- Parameters:
- Return type:
- _get_earliest_event_hint(internal_hints, t_left=None, t_right=None)[source]#
Find the earliest event hint across all components.
Only considers hints that fall within [t_left, t_right] if provided. Returns the InternalEventInfo with the smallest t_before value.
- Parameters:
- Return type:
InternalEventInfo | None
- _collect_events_at_time(event_sources)[source]#
Collect all events at the current time based on indicator values.
- _evaluate_indicators_at(event_sources, snapshots, input_cache, t_left, t_target)[source]#
Evaluate event indicators for all event source components at t_target starting from snapshots and input caches at t_left.
- Parameters:
event_sources (list[CoSimComponent]) – List of components that can generate events.
snapshots (dict[str, Any]) – State snapshots of components at t_left.
input_cache (dict[str, dict[str, Any]]) – Cached inputs of components at t_left.
t_left (float) – The left endpoint of the interval.
t_target (float) – The target time for event detection.
- Returns:
A dictionary mapping component names to dictionaries of event indicator values at t_target.
- Return type:
- _evaluate_component_indicators(comp, snapshot, inputs, t_left, t_target)[source]#
Evaluate event indicators for a single component at t_target starting from snapshot and input cache at t_left.
- Parameters:
comp (CoSimComponent) – The component to evaluate indicators for.
snapshot (Any) – The state snapshot of the component at t_left.
inputs (dict[str, Any]) – The inputs to set for the component.
t_left (float) – The left endpoint of the interval.
t_target (float) – The target time for event detection.
- Returns:
A dictionary of event indicator values at t_target.
- Return type:
- _detect_crossing_between(event_sources, indicators_prev, indicators_curr)[source]#
Detect crossings between two sets of indicator values for all event source components.
Returns a list of (component name, event name) tuples where crossings were detected.
- _restore_all_to_left(event_sources, snapshots_left, input_cache, t_left)[source]#
Restore all event source components to their state at t_left.
- handle_events(system, event_pairs, current_time)[source]#
Handles the event_pairs that occur at current_time in the given system. If multiple events occur simultaneously, checks for conflicts based on event annotations. Ensures that the result is indepnedent of the order of event handling when possible.
- Parameters:
- Raises:
RuntimeError – If non-commutative events are detected that cannot be handled simultaneously.
- Return type:
None
- _check_event_commutativity(comp, event_names)[source]#
Verify that event handlers commute (order of execution does not matter) for the given component.
Methods: 1. Check annotations that specify which states/outputs are modified by each event. 2. Run all permutations and compare results dynamically (requires state rollback).
- Parameters:
comp (CoSimComponent) – The component to check commutativity for.
- Returns:
True if the event handlers commute, False otherwise.
- Return type:
- _verify_event_commutativity_dynamically(comp, event_names)[source]#
Executes all permutations of event handling and checks if the final state is the same. This requires the component to support state snapshotting and restoration.
- Parameters:
comp (CoSimComponent) – The component to verify commutativity for.
event_names (list[str]) – The list of event names to test in permutations.
- Returns:
True if all permutations result in the same final state, False otherwise.
- Return type:
- _states_equal(state1, state2)[source]#
Compares two component states for equality. This method may need to be customized based on the component’s state structure.
- _abc_impl = <_abc._abc_data object>#