I'm using Dymola 2019 to translate my Modelica model into an FMU, which I then simulate with JModelica (I'm on JModelica version 2.2 from 2018-03-15). My goal is to be able to simulate a certain period, analyze the results, modify certain parameters based on these results and then continue the previous simulation from where it left off while using the new parameter values.
I know that the get_fmu_state
and set_fmu_state
are technically supposed to be able to do this, however when attempting to implement it I haven't managed to make it work, and there don't seem to be any examples in the PyFMI directory which use either of these functions. I've attempted the following:
from pyfmi import load_fmu
model = load_fmu("FMU_generated_by_Dymola.fmu")
res1 = model.simulate(final_time=5.0)
state = model.get_fmu_state()
#Here I would ideally like to use res1 to vary some parameters
model = load_fmu("FMU_generated_by_Dymola.fmu")
model.initialize()
opts = model.simulate_options()
opts['initialize'] = False
model.set_fmu_state(state)
res2 = model.simulate(start_time=5.0,final_time=10.0,options=opts)
The above code works insofar as that it doesn't raise any exceptions, though it does print the following warning at the end: WARNING:root:The simulation start time (5.000000) and the current time in the model (0.000000) is different. Is the simulation start time correctly set?
. But more importantly, when attempting this on a relatively complex model with a discrete Real variable which is changed periodically with Modelica's sample()
function, the state of this discrete variable seems to become immutable in the second simulation. Its initial value is carried over from the end of the first simulation, but after that it no longer changes. Thus, res2
in the previous code will yield substantially different results from res3
in the following code:
from pyfmi import load_fmu
model = load_fmu("FMU_generated_by_Dymola.fmu")
res3 = model.simulate(final_time=10.0)
The differences are still present even when doubling the number of communication points for res3
to more accurately reflect res2
. I'm at a loss as for why my real discrete variable seems to turn into a constant when launching a simulation after having used set_fmu_state()
. Does anyone have any ideas? Am I not using set_fmu_state()
correctly?
It's also worth noting that I've also had a look at this question, but this apparently requires using compile_fmu()
rather than load_fmu()
in order to use the "state_initial_equations": True
option (not to mention that it seems as though it wouldn't work with variables not included in the simulation results). I've also had a look at this question, but this is specifically for Dymola rather than JModelica, and relies on the desired states being present in the results file which isn't always the case.
Edit
Just to make my question clearer, I've included a sample model below.
model DiscreteContinuous
discrete Real discr "Discrete variable";
Real cont "Continuous variable";
initial equation
discr=0;
cont=0;
equation
when sample(0,2) then
discr=pre(discr)+1;
end when;
der(cont)=1;
end DiscreteContinuous;
After, Dymola 2019 is used to translate this model to FMU format after which JModelica is used to run the Python in my question. Firstly, the following results from res3
are as expected:
In [1]: res3['discr'][-1]
Out [1]: 6.0
In [2]: res3['discr'][0]
Out [2]: 1.0
However, the following results from res2
show that, while the continuous variable behaves as expected when using set_fmu_state()
, the discrete variable on other hand doesn't change throughout the second simulation:
In [3]: res2['discr'][-1]
Out [3]: 3.0
In [4]: res2['discr'][0]
Out [4]: 3.0
In [5]: res2['cont'][-1]
Out [5]: 9.9999999999999929
In [6]: res2['cont'][0]
Out [6]: 4.9999999999999964