Fixed-Point Initialization in CoFMPy¶
Understanding Fixed-Point Initialization¶
In a co-simulation involving multiple FMUs, the user-defined initial state \(x_0\) represents the starting values for all system variables. However, if \(x_0\) is not dynamically consistent, meaning it does not satisfy the physical constraints of the system, the simulation may start from an unrealistic state, leading to numerical instabilities or incorrect results.
To correct this, CoFMPy provides a fixed-point initialization process that finds a valid initial state \(x_0^*\) close to \(x_0\), such that:
where \(f\) is the numerical time integrator, responsible for advancing the system’s state to the next time step (basically built on do_step
). This ensures that \(x_0^*\) is a fixed-point solution, meaning the system starts in a physically valid configuration.
Enabling Fixed-Point Initialization in CoFMPy¶
To ensure a dynamically valid initialization, you can enable the fixed-point initialization by setting fixed_point_init=True
when starting the simulation coordinator:
coordinator.start(config_path, fixed_point_init=True)
When fixed_point_init=False
, CoFMPy will use the user-provided or default initial values without verifying their validity. This may be faster, but it can lead to inconsistencies in coupled FMUs, which may cause instability or incorrect results.
When fixed_point_init=True
, CoFMPy internally:
- Constructs an optimization function that represents the co-simulation architecture.
- Solves for a valid initial state \(x_0^∗\) using a numerical solver, ensuring consistency across all FMUs.
- Uses
fsolve
from SciPy by default to find a solution, using:- The minimum of default integration time steps defined in each FMU’s XML metadata.
- Default solver parameters.
Customizing the Fixed-Point Solver¶
By default, CoFMPy uses SciPy's fsolve
with its default arguments. However, you can customize:
- The solver method (
fsolve
or other supported solvers). - The fixed-point iteration step size (
time_step
). - The solver’s argument passed as keyword arguments dictionnary
To modify these settings, pass the desired options using fixed_point_kwargs
:
# Customize fixed point solver
fixed_point_kwargs = {
"solver": "fsolve",
"time_step": 5e-8,
"tolerance": 1e-5,
"max_iterations": 100,
}
coordinator.start(config_path, fixed_point_init=True, fixed_point_kwargs=fixed_point_kwargs)
Supported Solvers¶
Currently, CoFMPy supports the following solver:
scipy.optimize.fsolve
- Used for finding roots of nonlinear equations via a hybrid Powell method.
- Automatically approximates the Jacobian if not provided.
- For more details, refer to the SciPy documentation:👉 fsolve — SciPy v1.15.1 Manual
Support for additional solvers is planned in future versions.