Engee documentation
Notebook

Application of programme control of the model

This example demonstrates one of the tools of model management - programme control.

Software control allows you to create, run and save models, as well as change their parameters in the script editor using special commands.

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

Creating and saving a model

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
)

Creating a model:

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

View the name of an open model by using the function:

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

Saving a model using the function save():

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

The model has been saved to the specified path:

image.png

You can view the list of open models using the function 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
)

Loading a model and changing modelling parameters

image1.png

If the model is not yet open in the editor, we load the model using the function load(). If it is already open, we use the function open(). Then we get the modelling parameters with the command 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
)

You can change the simulation parameters with the function 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
)

Running a simulation

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

Runs the execution of the model. If no model is specified, runs a simulation of the current model. If the model is not open, the NoModelOpenedException exception is thrown.

Arguments:

  • verbose: whether to print the progress, default is verbose=false.

  • m::Model: the model relative to which the operation is performed, defaults to the current model.

    Example:

      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...

Run the model with simulation progress output:

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

Viewing simulation results

Simulation results can be retrieved using the function get_results():

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

Returns the results of the last model simulation as a dictionary Dict{String, DataFrame}, where key is the name of the port being tracked.

If the model is not open, an exception is printed NoModelOpenedException.

If the simulation is not running, the exception ModelIsNotRunningException is thrown.

Arguments:

  • m::Model: the model against which the operation is performed, default is the current model.

    Example:

      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 

Display the results obtained from the simulation:

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

Writing simulation results to variables and displaying a summary table with the results:

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

Plot the changes in the values obtained from the simulation:

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

Conclusion:

This example demonstrated the use of software model control to run a simulation from a script.

During code execution, a new model was created and saved, the finished model was loaded, the simulation parameters were changed, and, using a graphics library, the results of the simulation were displayed and converted into a usable form.

Blocks used in example