modelon-community / PyFMI

PyFMI is a package for loading and interacting with Functional Mock-Up Units (FMUs) both for Model Exchange and Co-Simulation, which are compiled dynamic models compliant with the Functional Mock-Up Interface (FMI)
http://jmodelica.org/pyfmi
GNU Lesser General Public License v3.0
160 stars 38 forks source link

How to set initial (continuous) state before starting the simulation? #165

Closed FabiJa closed 1 year ago

FabiJa commented 1 year ago

What is the preferred way to set the initial (continuous) state of an ODE before simulation?

model = pyfmi.load_fmu(fmu_path)
model.continuous_states= numpy.array((10.))
model.simulate()

is not working. Also I had no luck with set_real(). Or is it not possible to change the initial condition, when using ´simulate()´ and I have to do it low level with ´model.setup_experiment()´ etc. ?

Thx.

PeterMeisrimelModelon commented 1 year ago

The issue in your approach is that simulation includes initialization, which will overwrite your specified continuous states. You'll need to initialize the model, overwrite the continuous states and then simulate.

The following approach should work:

fmu = load_fmu(<your_fmu>)

fmu.initialize()
fmu.continuous_states = np.array([<your_states>])

opts = fmu.simulate_options()
opts['initialize'] = False

res = fmu.simulate(options=opts)
PeterMeisrimelModelon commented 1 year ago

Did this help/resolve the issue? @FabiJa

FabiJa commented 1 year ago

Sry for the late reply.

Is fmu.initialize() really necessary? It seems to work without and gives me an error for a CoSimulation FMU.

I am using this variant:

for var in initial_state:
   fmu.set(var, initial_state[var])
PeterMeisrimelModelon commented 1 year ago

Initialization of the FMU is a required step before simulation can be done.

In PyFMI this is done either via either

Having both will result in an error. Having neither should result in an error from the FMU.

The recommended approach for CS FMUs is:

fmu = load_fmu('<name>.fmu')

fmu.initialize()

fmu.set('<state>', <value>)

opts = fmu.simulate_options()
opts['initialize'] = False

res = fmu.simulate(options=opts)

It is possible that initialization may not overwrite set values, in which case it could be done before initialization. However, this depends on the FMU.

PeterMeisrimelModelon commented 1 year ago

Marking as resolved, please notify if this is still an open issue.