Документация Engee
Notebook

Применение программного управления моделью

Данный пример демонстрирует один из инструментов управления моделью - программное управление.

Программное управление позволяет создавать, запускать и сохранять модели, а также изменять их параметры в редакторе скриптов с помощью специальных команд.

In [ ]:
cd( @__DIR__ ) # Переместимся в каталог, где лежит текущий скрипт
homePath = string(@__DIR__)
Out[0]:
"/user/start/examples/base_simulation/command_control"

Создание и сохранение модели

In [ ]:
# Для повторного запуска команды create
if "model" in [m.name for m in engee.get_all_models()]
    engee.close("model", force=true)
end
Out[0]:
Model(
	name: newmodel_1
	id: 44f96846-5a38-40ef-bb8a-53aed569e391
)

Создание модели:

In [ ]:
engee.create("model")
Out[0]:
Model(
	name: model
	id: b1ef1997-a2a6-4c65-8f4d-8c251ab2e2c0
)

Просмотр имени открытой модели осуществляется функцией:

engee.get_current_model()::Model
    engee.gcm()::Model
In [ ]:
m = engee.gcm()
Out[0]:
Model(
	name: model
	id: b1ef1997-a2a6-4c65-8f4d-8c251ab2e2c0
)

Сохранение модели с помощью функции save():

In [ ]:
engee.save( "model", "$homePath/model.engee"; force=true )
Out[0]:
Model(
	name: model
	id: b1ef1997-a2a6-4c65-8f4d-8c251ab2e2c0
)

Модель была сохранена по указанному пути:

image.png

Просмотр списка открытых моделей можно произвести с помощью функции get_all_models():

In [ ]:
engee.get_all_models()
Out[0]:
3-element Vector{Engee.Types.Model}:
 Model(
	name: model
	id: b1ef1997-a2a6-4c65-8f4d-8c251ab2e2c0
)

 Model(
	name: newmodel_1
	id: 44f96846-5a38-40ef-bb8a-53aed569e391
)

 Model(
	name: program_control_model
	id: b27bcfc6-48bb-4546-b400-dc7fa3e7c3ad
)

Загрузка модели и изменение параметров моделирования

image1.png

Если модель еще не открыта в редакторе, то мы загружаем модель с помощью функции load(). Если уже открыта, то нужно пользоваться функцией open(). Затем получаем параметры моделирования с помощью команды get_param():

In [ ]:
if "program_control_model" in [m.name for m in engee.get_all_models()]
    m = engee.open( "program_control_model" ) # загрузка модели
else
    m = engee.load( "$homePath/program_control_model.engee" ) # если модель уже открыта, выполните эту строчку
end

m_param = engee.get_param( "program_control_model" ) # получение параметров моделирования
Out[0]:
ModelParameters(
  :EnableMultiTasking => false
  :GenerateComments => true

  #Параметры интегратора:
  :StartTime => 0.0
  :StopTime => 10
  :SolverName => Tsit5
  :SolverType => variable-step
  :MaxStep => auto
  :MinStep => auto
  :InitialStep => auto
  :RelTol => auto
  :AbsTol => auto
  :OutputOption => true
  :OutputTimes => 1e-2
)

Параметры моделирования можно изменить с помощью функции set_param!():

In [ ]:
engee.set_param!("program_control_model", "SolverName" => "Tsit5", "SolverType" => "variable-step") #= меняем постоянный шаг решателя
                                                                  на переменный и изменяем сам решатель =#
engee.get_param("program_control_model") # выводим параметры с внесёнными изменениями
Out[0]:
ModelParameters(
  :EnableMultiTasking => false
  :GenerateComments => true

  #Параметры интегратора:
  :StartTime => 0.0
  :StopTime => 10
  :SolverName => Tsit5
  :SolverType => variable-step
  :MaxStep => auto
  :MinStep => auto
  :InitialStep => auto
  :RelTol => auto
  :AbsTol => auto
  :OutputOption => true
  :OutputTimes => 1e-2
)
In [ ]:
engee.set_param!("program_control_model", "MinStep" => "auto", "MaxStep" => "auto") #= меняем постоянный шаг решателя
                                                                  на переменный и изменяем сам решатель =#
engee.get_param("program_control_model") # выводим параметры с внесёнными изменениями
Out[0]:
ModelParameters(
  :EnableMultiTasking => false
  :GenerateComments => true

  #Параметры интегратора:
  :StartTime => 0.0
  :StopTime => 10
  :SolverName => Tsit5
  :SolverType => variable-step
  :MaxStep => auto
  :MinStep => auto
  :InitialStep => auto
  :RelTol => auto
  :AbsTol => auto
  :OutputOption => true
  :OutputTimes => 1e-2
)

Запуск симуляции

run([m::Model]; verbose=false)

Запускает исполнение модели. Если модель не указана, запускает симуляцию текущей модели. Если модель не открыта, то бросается исключение NoModelOpenedException.

Аргументы:

  • verbose: выводить ли прогресс на печать, по умолчанию verbose=false.

  • m::Model: модель, относительно которой выполняется операция, по умолчанию текущая модель.

    Пример:

engee> m = engee.load("start/examples/powersystems/models/power_line_apv.engee")
      engee> engee.run(m)
      Dict{String, DataFrame} with 6 entries:
         "Va" => 40001×2 DataFrame…
         "Ia" => 40001×2 DataFrame…
         "Ib" => 40001×2 DataFrame…
         "Ic" => 40001×2 DataFrame…
         "Vc" => 40001×2 DataFrame…
         "Vb" => 40001×2 DataFrame…

Запуск модели с выводом прогресса симуляции:

In [ ]:
engee.run(m, verbose=true)
Building...
Progress 100%
Out[0]:
Dict{String, DataFrames.DataFrame} with 3 entries:
  "Add.1"         => 1001×2 DataFrame…
  "Sine Wave-1.1" => 1001×2 DataFrame…
  "Sine Wave.1"   => 1001×2 DataFrame

Просмотр результатов симуляции

Результаты симуляции можно получить с помощью функции get_results():

engee.get_results(model_name::String)
    engee.get_results(model::Model)
    engee.get_results()

Возвращает результаты последней симуляции модели в виде словаря Dict{String, DataFrame}, где ключ - имя отслеживаемого порта.

Если модель не открыта, то выводится исключение NoModelOpenedException.

Если симуляция не запущена, то выводится исключение ModelIsNotRunningException.

Аргументы:

  • m::Model: модель, относительно которой выполняется операция, по-умолчанию, текущая модель.

    Пример:

engee> m = engee.load("start/examples/powersystems/models/power_line_apv.engee")
      engee> results1 = engee.run(m);
      engee> results2 = engee.get_results(m)
      Dict{String, DataFrame} with 6 entries:
        "Va" => 40001×2 DataFrame…
        "Ia" => 40001×2 DataFrame…
        "Ib" => 40001×2 DataFrame…
        "Ic" => 40001×2 DataFrame…
        "Vc" => 40001×2 DataFrame…
        "Vb" => 40001×2 DataFrame…
      engee> results1 == results2
      true

Отображение результатов, полученных в ходе симуляции:

In [ ]:
results = engee.get_results( "program_control_model" )
Out[0]:
Dict{String, DataFrames.DataFrame} with 3 entries:
  "Add.1"         => 1001×2 DataFrame…
  "Sine Wave-1.1" => 1001×2 DataFrame…
  "Sine Wave.1"   => 1001×2 DataFrame

Запись результатов моделирования в переменные и вывод итоговой таблицы с результатами:

In [ ]:
sin1 = engee.get_results("program_control_model")["Sine Wave.1"]
sin2 = engee.get_results("program_control_model")["Sine Wave-1.1"]
sum_signal = engee.get_results("program_control_model")["Add.1"]
table = hcat(hcat(sin1, sin2[:,2], makeunique=true), sum_signal[:,2], makeunique=true) # используя сложение массивов по горизонтали (hcat()), составляем таблицу
first(table, 10) # выводим первые 10 значений получившейся таблицы
Out[0]:

10 rows × 4 columns

timevaluex1x1_1
Float64Float64Float64Float64
10.00.00.8414710.841471
20.010.009999830.8468320.856832
30.020.01999870.8521080.872107
40.030.02999550.8572990.887294
50.040.03998930.8624040.902394
60.050.04997920.8674230.917402
70.060.0599640.8723550.932319
80.070.06994280.8772010.947143
90.080.07991470.8819580.961873
100.090.08987850.8866270.976505

Строим график изменения величин, полученных в результате симуляции:

In [ ]:
using Plots
plot(table[:,1], table[:,2])
plot!(table[:,1], table[:,3])
plot!(table[:,1], table[:,4])
Out[0]:

Вывод:

В данном примере было продемонстрировано применение программного управления моделью для запуска симуляции из скрипта.

В ходе выполнения кода, была создана и сохранена новая модель, загружена готовая модель, изменены параметры симуляции, а также, с помощью графической библиотеки, были выведены результаты моделирования и преобразованы в удобный вид.

Блоки, использованные в примере