The binary FMU interface (#2779) allows FMUs to be evaluated pointwise. This is would in principle allow the FMU to be integrated using the existing Integrator class, but this would potentially be very limited and inefficient, due to:
- Excessive initializations of the FMU, which is expensive
- No event handling
- No easy way to incorporate piecewise constant control inputs
- Derivative calculation might be very expensive
- Need to keep track of which states are differential and which are algebraic
To get around this, it makes sense to add a dedicated Simulator plugin class which can be constructed from an FMU function instance:
dae = DaeBuilder(...)
...
f = dae.fmu_fun(...)
time_grid = ...
simulator = casadi.simulator('simulator', f, time_grid)
To start with, the simulator class would only be defined for fmu_functions, but it could easily be extended to symbolic representations of the dynamic system. It would also not be differentiable, at least not at first. It might be possible and desirable to combine this class with the integrator class, but given the disruption it would result in, it's better to keep the classes separate at first, but with maximum amount of communality. The dynamic system argument should correspond to a state-space representation with quadratures: (t, x, z, p, u) -> (xdot, alg, y, qdot). The Simulator class will have the same signature as Integrator but add piecewise controls ("u") and outputs ("y").
To be able to simulate an FMU, a CVodes plugin makes sense to begin with.
Update:
This issue has taken some unexpected turns. The latest conclusion is that maintaining both Integrator and Simulator is not realistic. Instead, Integrator has now been extended with elements from the Simulator class, in particular control inputs. The output support has been left out since they can be calculated after the integration with few drawbacks. What remains of this issue is to port forward sensitivity approach from Simulator to Integrator, i.e. add "nfwd" as an option, instead of deducing it from the number of columns in the oracle_ inputs/outputs.
The binary FMU interface (#2779) allows FMUs to be evaluated pointwise. This is would in principle allow the FMU to be integrated using the existing Integrator class, but this would potentially be very limited and inefficient, due to:
To get around this, it makes sense to add a dedicated Simulator plugin class which can be constructed from an FMU function instance:
To start with, the simulator class would only be defined for fmu_functions, but it could easily be extended to symbolic representations of the dynamic system. It would also not be differentiable, at least not at first. It might be possible and desirable to combine this class with the integrator class, but given the disruption it would result in, it's better to keep the classes separate at first, but with maximum amount of communality. The dynamic system argument should correspond to a state-space representation with quadratures:
(t, x, z, p, u) -> (xdot, alg, y, qdot). The Simulator class will have the same signature as Integrator but add piecewise controls ("u") and outputs ("y").To be able to simulate an FMU, a CVodes plugin makes sense to begin with.
Update:
This issue has taken some unexpected turns. The latest conclusion is that maintaining both
IntegratorandSimulatoris not realistic. Instead,Integratorhas now been extended with elements from theSimulatorclass, in particular control inputs. The output support has been left out since they can be calculated after the integration with few drawbacks. What remains of this issue is to port forward sensitivity approach fromSimulatortoIntegrator, i.e. add "nfwd" as an option, instead of deducing it from the number of columns in the oracle_ inputs/outputs.