Я использую Dymola 2019 для перевода моей модели Modelica в FMU, которую я затем моделирую с помощью JModelica (я нахожусь на JModelica версии 2.2 от 2018-03-15).Моя цель - иметь возможность смоделировать определенный период, проанализировать результаты, изменить определенные параметры на основе этих результатов, а затем продолжить предыдущее моделирование с того места, на котором оно было остановлено, при использовании новых значений параметров.
Я знаю, чтоget_fmu_state
и set_fmu_state
технически должны быть в состоянии сделать это, однако при попытке реализовать его мне не удалось заставить его работать, и в каталоге PyFMI, похоже, нет никаких примеров, которые используютлюбая из этих функций.Я попытался сделать следующее:
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)
Приведенный выше код работает, поскольку он не вызывает никаких исключений, хотя в конце выводит следующее предупреждение: 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?
.Но что еще более важно, при попытке сделать это на относительно сложной модели с дискретной действительной переменной, которая периодически изменяется с помощью функции sample()
Modelica, состояние этой дискретной переменной кажется неизменным во втором моделировании.Его начальное значение переносится с конца первого моделирования, но после этого оно больше не изменяется.Таким образом, res2
в предыдущем коде даст существенно отличные результаты от res3
в следующем коде:
from pyfmi import load_fmu
model = load_fmu("FMU_generated_by_Dymola.fmu")
res3 = model.simulate(final_time=10.0)
Различия сохраняются даже при удвоении количества точек связи для res3
доточнее отразить res2
.Я в недоумении, почему моя реальная дискретная переменная, похоже, превращается в константу при запуске симуляции после использования set_fmu_state()
.У кого-нибудь есть какие-либо идеи?Не правильно ли я использую set_fmu_state()
?
Стоит также отметить, что я также рассмотрел этот вопрос , но для этого, очевидно, требуется использовать compile_fmu()
вместо load_fmu()
чтобы использовать параметр "state_initial_equations": True
(не говоря уже о том, что кажется, что он не будет работать с переменными, не включенными в результаты моделирования).Я также посмотрел на этот вопрос , но это специально для Dymola, а не JModelica, и полагается на наличие желаемых состояний в файле результатов, что не всегда так.
Редактировать
Чтобы прояснить вопрос, я включил пример модели ниже.
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;
После этого Dymola 2019 используется для перевода этой модели в формат FMU, после чегоJModelica используется для запуска Python в моем вопросе.Во-первых, следующие результаты из res3
соответствуют ожидаемым:
In [1]: res3['discr'][-1]
Out [1]: 6.0
In [2]: res3['discr'][0]
Out [2]: 1.0
Однако следующие результаты из res2
показывают, что, хотя переменная непрерывная ведет себя так, как ожидается при использовании set_fmu_state()
, дискретная переменная , с другой стороны, не изменяется в течение второй симуляции:
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