PyFMI / JModelica - приостановка симуляции и перезапуск из состояния с измененными параметрами - PullRequest
0 голосов
/ 28 ноября 2018

Я использую 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
...