建模中的程序控制示例
引言
要使用编程控制方法创建模型,我们将打开命令行或 Engee 脚本编辑器。工具的选择并不重要,如果创建的是示例,语法上也不会有什么不同。不过,脚本编辑器可以重构已经初始化的代码行,这对创建自己的模型非常有用。今后我们将使用脚本编辑器。
创建/加载模型
默认情况下,启动 Engee 时会创建 newmodel_1 模型,这就是我们稍后要使用的模型。不过,您也可以从以下方法中选择所需的方法来创建或加载其他模型:
创建/加载/打开模型
使用create 方法创建模型:
model = "newmodel_2" # создает переменную model со значением "model_name"
engee.create(model) # создает модель из переменной
或直接创建模型而不初始化变量:
engee.create("newmodel_2")
您可以使用load 方法加载现有模型:
engee.load("/user/newmodel_2.engee")
# или
engee.load("/user/newmodel_2.engee"; force = true) # force = true обязательно указывается в случае, если модель уже была загружена ранее
添加区块
首先,让我们使用add_block 方法将库中的代码块添加到 newmodel_1 模型中:
engee.add_block("/Basic/Sources/Sine Wave", "newmodel_1/") # добавляет блок Sin Wave из библиотеки Basic/Sources и присваивает имя автоматически
以及类似的 "终结者 "模块:
engee.add_block("/Basic/Sinks/Terminator", "newmodel_1/") # аналогично добавляет блок Terminator, но уже из другой библиотеки
在这种情况下,名称会自动分配,例如,如果模型中已经存在一个名称为 Terminator-1 的程序块,则 Terminator 会更名为 Terminator-1。 |
如有必要,您可以在模型名称的斜线/ 后添加区块名称,从而为其命名:
engee.add_block("/Basic/Sources/Sine Wave", "newmodel_1/Sine Wave-x") #добавит блок Sine Wave с именем Sin Wave-x
您可以通过delete_block 方法删除不必要的区块:
engee.delete_block("newmodel_1/Sine Wave-x") # удалит блок Sine Wave-x и все связанные с ним линии и блоки из системы
添加行
让我们使用add_line 方法在添加的区块之间添加一条连接信号线:
engee.add_line("Sine Wave/1", "Terminator/1") # устанавливает сигнал между выходным портом №1 у блока Sin Wave и входным портом №1 блока Terminator
左键单击信号并选择 Record ,启用信号记录,记录 Sin Wave 和 Terminator 块之间创建的信号线: 这是模型模拟完成后从块中检索数据所必需的。 |
设置模型参数
让我们使用get_param 方法获取模型参数:
engee.get_param("newmodel_1") - # получение параметров моделирования
输出 get_param,步长不变_。
ModelParameters( :EnableMultiTasking => false :GenerateComments => true #Параметры интегратора: :StartTime => 0.0 :StopTime => 10 :SolverType => fixed-step :SolverName => Euler :FixedStep => 0.01 )
可配置的模型参数列表因所选步骤(常量或变量)而异。例如,上述变步模型的 get_param 将显示以下参数:
变量步长 get_param 输出_.
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! 方法来更改模型的几个参数:
engee.set_param!("newmodel_1", "FixedStep" => 0.05, "StopTime" => 40) # меняем фиксированный размер шага и время окончания симуляции
接下来,重复使用get_param 来跟踪参数变化:
参数更改后的 get_param 输出结果_。
ModelParameters( :EnableMultiTasking => false :GenerateComments => true #Параметры интегратора: :StartTime => 0.0 :StopTime => 40.0 :SolverType => fixed-step :SolverName => Euler :FixedStep => 0.05 )
模拟
让我们使用run 方法对我们的模型进行一次模拟:
engee.run("newmodel_1")
由于之前启用了信号记录功能,存储仿真结果的simout 变量的值为 SimulationResult("newmodel_1/Sine Wave.1" => WorkspaceArray("newmodel_1/Sine Wave.1"))
,以表格DataFrame 表示:
输出
Dict{String, DataFrames.DataFrame} with 1 entry:
"Sine Wave.1" => 801×2 DataFrame…
让我们使用 collect
函数将模拟结果保存到 Engee RAM 中的 result
变量:
result = collect(simout["newmodel_1/Sine Wave.1"])
此外,让我们使用get_results 方法来获取模拟结果,而不必求助于 simout 变量:
包含模拟结果的两个变量("modeling_variable "和 "result")的值都是 DataFrame,但类不同--"modeling_variable "的类是 "Dict{String, DataFrames, DataFrame}","result "的类是 "DataFrames.DataFrame"。 |
为方便起见,我们继续使用 result
变量。结果 "变量的 DataFrame 包括两列—时间和值。让我们使用 Plots 库将 DataFrame 可视化:
using Plots
plot(result.time, result.value)
此外,您还可以将模拟结果保存为 CSV 格式:
|
联产
让我们使用generate_code 方法生成模型代码:
engee.generate_code("/user/newmodel_1.engee", "/user/codegen_dir") # сгенерировали код из модели newmodel_1.engee, код будет храниться в папке codegen_dir
生成的代码将位于 codegen_dir 文件夹中的 newmodel_1.h、newmodel_1.c 和 main.c 文件中。
最后,让我们使用save 方法保存我们的模型:
engee.save("/user/newmodel_1.engee"; force=true)