jmodelica.org/5081

ная цель

Анализ чувствительности сети централизованного теплоснабжения.

Подход

Модель Modelica системы (в Dymola) с использованием библиотек AixLib и BuildingSystem

Экспорт модели в качестве симулятора FMU

Используйте SALib (библиотека Python для анализа чувствительности), чтобы определить образцы (параметр развертки)

Используйте PyFMI для запуска модели в цикле for в Python для всех отдельных выборок (и распараллеливание цикла for возможно с использованием JobLib для выполнения моделирования на нескольких процессорах)

SALib для выполнения анализа чувствительности на основе дисперсии (http://salib.readthedocs.io/en/latest/basics.html#an-example)

Первый шаг

Простая модельная модель функции Ишигами (не зависит от времени). Эта функция часто используется для проверки методов анализа чувствительности (https://www.sfu.ca/~ssurjano/ishigami.html).

Код Python (включая загрузку FMU с PyFMI и развертку параметров) работает нормально.

Проблема

После определенного количества симуляции мы получаем ошибку. Вывод ошибки выглядит не всегда одинаково. Иногда мы получаем

FMUException: Ошибка загрузки двоичного файла. Не удалось загрузить DLL: Eine DLL-Initialisierungsroutine ist fehlgeschlagen.

Перевод: процедура инициализации DLL не выполнена.

И иногда мы получаем:

FMUException: Ошибка загрузки двоичного файла. Не удалось загрузить DLL: Für diesen Befehl ist nicht genügend Speicher verfügbar.

Перевод: естьнедостаточно памяти доступно для этой команды.

Происходит ошибкапосле примерно 650 прогонов симуляции, Это не зависит от того, выполняются ли симуляции в меньших блоках циклов, которые повторяются один за другим, или один цикл for проходит через все симуляции. Перезапустив консоль / процесс python, можно снова запустить новое моделирование.

Рабочая обстановка:

Windows 10, Python 2.7, PyFMI, установленный с использованием pip (не JModelica), Python-кодирование на ноутбуке Jupyther (на Mozilla Firefox)

У нас есть только базовые знания Python и PyFMI, и мы действительно боремся с этой ошибкой!

прикрепление

Ниже вы можете найти

Модель Modelica, используемая для экспорта совместного моделирования FMU из Dymola (с использованием CVode)

Код Python в виде файла py

Выходной точечный график кода питона.

Я также сделал сообщение на форуме JModelica, где вы можете загрузить файлы напрямую (FMU, блокнот Jupyter и т. Д.):http://www.jmodelica.org/27925

Модель Modelica

model IshigamiFunction

  final parameter Real a = 7;

  final parameter Real b = 0.05;

  parameter Real x1 = 1;

  parameter Real x2 = 1;

  parameter Real x3 = 1;

  Real f;

equation

  f = sin(x1) + a * sin(x2)^2 + b * x3^4 * sin(x1);

end IshigamiFunction;

Код Python

import numpy as np
import pylab as pl
from pyfmi import load_fmu
from SALib.sample import saltelli
from SALib.analyze import sobol
from ipywidgets import FloatProgress
from IPython.display import display


n = 100

problem = {
    'num_vars': 3,
    'names': ['x1', 'x2', 'x3'],
    'bounds': [[-np.pi, np.pi],
               [-np.pi, np.pi],
               [-np.pi, np.pi]]
}

param_values = saltelli.sample(problem, n)

fmu = 'Model\IshigamiFunction\IshigamiFunction.fmu'
n_sim = param_values.shape[0]

# Progress bar
f = FloatProgress(min = 0, max = n_sim, description='Progress:')
display(f)

# Numpy array to save results
y = np.zeros([param_values.shape[0]])
x1 = np.zeros([param_values.shape[0]])
x2 = np.zeros([param_values.shape[0]])
x3 = np.zeros([param_values.shape[0]])

for i, X in enumerate(param_values):
    model = load_fmu(fmu)  
    model.set(problem['names'], X)
    res = model.simulate(final_time = 1)
    y[i] = res['f'][-1]
    x1[i] = res['x1'][-1]
    x2[i] = res['x2'][-1]
    x3[i] = res['x3'][-1]
    f.value += 1


# Scatter plots
fig = pl.figure(figsize=(20, 5))
pl.clf()

pl.subplot(1,3,1)
pl.plot(x1, y, 'or')
pl.ylabel('x1')
pl.xlabel('f')

pl.subplot(1,3,2)
pl.plot(x2, y, 'ob')
pl.ylabel('x2')
pl.xlabel('f')

pl.subplot(1,3,3)
pl.plot(x3, y, 'og')
pl.ylabel('x3')
pl.xlabel('f')

pl.suptitle('Scatter plots')
pl.show()

# Sensitivity analysis
Si = sobol.analyze(problem, y, print_to_console=True)

Выходной сюжет из скрипта Python

Обновить

Я сделал еще несколько тестов, и вот что я нашел:

В зависимости от того, экспортируется ли FMU из Dymola или из JModelica, поведение может быть другим:

Использование FMU, экспортированного из Dymola:

Принимаяload_fmu линия из цикла for, кажется, работаетДаже сload_fmu не в цикле есть иногда сбоиДобавление новой строкиmodel.reset() передmodel.set(...) Команда, кажется, работает нормальноРезультаты отличаются при моделировании с или безmodel.reset() -> Почему ??model.instantiate() вместоmodel.reset() -> не работает. Использование памяти в диспетчере задач увеличивается примерно до 350 МБ, а затем

FMUException: Не удалось создать экземпляр модели. Смотрите журнал для получения дополнительной информации.

Файл журнала с log_level = 4:

FMIL: module = FMILIB, log level = 4: XML specifies FMI standard version 2.0
FMIL: module = FMILIB, log level = 4: Loading 'win32' binary with 'default' platform types
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiInstantiateModel completed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiInstantiateSlave
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiInstantiateModel completed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiInstantiateSlave
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetReal: x1 = -1.76101
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetReal: x2 = -2.53414
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetReal: x3 = 0.116583
FMIL: module = Model, log level = 4: [][FMU status:OK] fmi2SetupExperiment: startTime is set to 0
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiEnterSlaveInitializationMode...
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiEnterSlaveInitializationMode completed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiExitSlaveInitializationMode...
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiExitSlaveInitializationMode completed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmi,GetReal: x1 = -1.76101
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: x2 = -2.53414
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: x3 = 0.116583
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: a = 7
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: b = 0.05
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetReal: f = 1.29856
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.002
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.004
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.006
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiGetDerivatives
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.008
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.01
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.012
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.014
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.016
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.018
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.02
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep

...

FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.99
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.992
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.994
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.996
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 0.998
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiSetTime to 1
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiDoStep
FMIL: module = Model, log level = 1: [][FMU status:Fatal] The license file was not found. Use the environment variable "DYMOLA_RUNTIME_LICENSE" to specify your Dymola license file.

FMIL: module = Model, log level = 1: [][FMU status:Fatal] Instantiation failed
FMIL: module = Model, log level = 4: [][FMU status:OK] fmiFreeModelInstance

Использование FMU, экспортированного из JModelica:

Работает нормально, даже еслиload_fmu находится в цикле for (но медленнее)Этот опыт не соответствует примеру, приведенному в документации JModelica в главе 5.4.2 (http://www.jmodelica.org/api-docs/usersguide/2.1/ch05s04.html#d0e1854) гдеload_fmu команда дается в цикле forКомандаmodel.reset() или жеmodel.instatiate() требуется в цикле for (в отличие от Dymola FMU)-> Почему ??

Мои вопросы:

Как правильно выполнять цикл, который многократно моделирует модель FMU с разными параметрами?

В чем разница между использованиемmodel.reset(), model.instatiate() или никто из них?

прикрепление

Вот график, показывающий разницу между цикломmodel.reset() и без этого.

FMU, экспортированный из JModelica (не требует лицензии), можно скачать здесь:http://www.jmodelica.org/27925#comment-6668

Ответы на вопрос(1)

Ваш ответ на вопрос