For example, this is my modelica model
model Test
Real x(start = 1000);
input Real k;
equation
der(x) = -k * x;
end Test;
from pyfmi import load_fmu
model = load_fmu('D:/FMU/Test.fmu')
model.initialize(0,10)
def f(time):
global model
x = model.get('x')
return time*0.1
inputs = ('k', f)
result = model.simulate(final_time=10, input=inputs)
How can I get the value of x in function f,or how can I get the value of the current state and then adjust the input parameters to continue the simulation? I tried to get it via model.get(), but failed. Thanks a lot for your help!
I would like to reframe your question a little bit as follows:
The model I change to this
model Test
parameter Real k = 10;
parameter Real x_start = 1000;
Real x(start=x_start, fixed=true);
equation
der(x) = -k*x;
end Test;
And the script to this (and I use deprecated JModelica compiler to make the FMU, but instead the FMU can be made by for instance OpenModelica ver 1.25 or later)
# Setup framework
from pymodelica import compile_fmu
from pyfmi import load_fmu
import matplotlib.pyplot as plt
# Compile model
fmu_model = compile_fmu('Test','Test.mo', target='cs')
# Load model
model = load_fmu(fmu_model)
# Simulate
result1 = model.simulate(start_time=0, final_time=1)
x1 = model.get('x')
model.reset()
model.set('k', 1)
model.set('x_start',x1)
result2 = model.simulate(start_time=1, final_time=2)
x2 = model.get('x')
# Plot results
plt.figure()
plt.semilogy(result1['time'], result1['x'])
plt.semilogy(result2['time'], result2['x'])
plt.xlabel('Time'); plt.ylabel('x'); plt.grid()
plt.show()
Hope this address your main question?
Note, that the method can be easily generalised for continuous time systems. A dictionary of all the continuous time states can be obtained by the PyFMI-command
model.get_states_list()
For further inspiration on how to handle the more general case, take a look at the example on my Github page
run the example, and in cell 17 you see application of continued simulation after a parameter change. Also take a look at the Python setup file BPL_TEST2_Batch_explore.py where you find the code for simu(,'cont').
Here is in the FMI-standard a procedure to get and set the total state of an FMU, i.e. including both continuous and discrete time states and more.
model.get_fmu_state()
model.set_fmu_state()
However, the FMUs generated by OpenModelica (or deprecated JModelica) does not support this functionality. Therefore, the approach described above has a place.