Engee 文档
Notebook

在Engee中启动FMI模型

我们在Julia环境中运行FMU模型以获得仿真结果并将其用于进一步的计算。

任务说明

Fmi(Functional Mockup Interface)标准意味着将模型打包到FMU(Functional Mockup Unit)文件中,其中包含一组方程或系统建模代码(据推测,可以在Engee中调用的各种编程语言支持:Python,Java,Fortran,C++等。 包括朱莉娅)。

例如,考虑在Dymola中组装的弹簧和摆锤的模型。 要运行它,我们需要一个图书馆。 FMI.jl 和一组集合在包中的训练模型 FMIZoo.jl.

In [ ]:
Pkg.add( ["FMI", "FMIZoo"] )

连接已安装的库:

In [ ]:
using FMI
using FMIZoo

我们将对这样一个模型进行模拟。:

image.png

图书馆 FMI.jl 它允许您以多种方式运行FMI/FMU模型,我们将展示其中的两个。:

*通过命令 simulate
*通过创建自己的模拟循环和命令 fmi2DoStep.

创建时间向量(设置开始 tStart,结局 Stop 模拟和时间步长 tStep):

In [ ]:
tStart = 0.0
tStep = 0.1
tStop = 8.0
tSave = tStart:tStep:tStop
Out[0]:
0.0:0.1:8.0

启动FMU模型的最简单场景

加载模型 SpringFrictionPendulum1D 从模型包 FMIZoo.jl.

In [ ]:
fmu = loadFMU( "SpringFrictionPendulum1D", "Dymola", "2022x" )
info(fmu)
#################### Begin information for FMU ####################
	Model name:			SpringFrictionPendulum1D
	FMI-Version:			2.0
	GUID:				{2e178ad3-5e9b-48ec-a7b2-baa5669efc0c}
	Generation tool:		Dymola Version 2022x (64-bit), 2021-10-08
	Generation time:		2022-05-19T06:54:12Z
	Var. naming conv.:		structured
	Event indicators:		24
	Inputs:				0
	Outputs:			0
	States:				2
		33554432 ["mass.s"]
		33554433 ["mass.v", "mass.v_relfric"]
	Parameters:			12
		16777216 ["fricScale"]
		16777217 ["s0"]
		16777218 ["v0"]
		16777219 ["fixed.s0"]
		...
		16777223 ["mass.smin"]
		16777224 ["mass.v_small"]
		16777225 ["mass.L"]
		16777226 ["mass.m"]
		16777227 ["mass.fexp"]
	Supports Co-Simulation:		true
		Model identifier:	SpringFrictionPendulum1D
		Get/Set State:		true
		Serialize State:	true
		Dir. Derivatives:	true
		Var. com. steps:	true
		Input interpol.:	true
		Max order out. der.:	1
	Supports Model-Exchange:	true
		Model identifier:	SpringFrictionPendulum1D
		Get/Set State:		true
		Serialize State:	true
		Dir. Derivatives:	true
##################### End information for FMU #####################

让我们运行这个模型的计算,指定模拟时间的开始和结束以及要保存的变量。 mass.s. 由于模型中存在摩擦,波动会随着振幅的减小而发生,一段时间后负载就会停止。

In [ ]:
simData = simulate(fmu, (tStart, tStop); recordValues=["mass.s"], saveat=tSave)
plot( simData )
Out[0]:

计算完成后,您需要从内存中卸载FMU模型并删除所有临时数据。

In [ ]:
unloadFMU(fmu)

创建自己的模拟周期

在更复杂的情况下,例如,当您需要一次链接多个模型的工作时,您可以组织一个计算周期,其中模型将沿着某个时间矢量在其相空间中执行步骤。

下载FMU模型:

In [ ]:
fmu = loadFMU("SpringFrictionPendulum1D", "Dymola", "2022x")
Out[0]:
Model name:	SpringFrictionPendulum1D
Type:		1

Step函数需要一个专门准备的模型(一个具体的实现),我们将使用它来创建 fmi2Instantiate. 通过这种方式,可以一次从单个FMU文件初始化许多模型。

In [ ]:
instanceFMU = fmi2Instantiate!(fmu)
Out[0]:
FMU:            SpringFrictionPendulum1D
    InstanceName:   SpringFrictionPendulum1D
    Address:        Ptr{Nothing} @0x000000001d62f8c0
    State:          0
    Logging:        false
    FMU time:       -Inf
    FMU states:     nothing

在下一个单元格中,我们设置了实验(fmi2SetupExperiment),其中我们指定时间间隔的开始和结束进行模拟,那么模型必须切换到初始化模式(fmi2EnterInitializationMode)并在初始化后获得其初始状态(fmi2ExitInitializationMode).

In [ ]:
fmi2SetupExperiment(instanceFMU, tStart, tStop)

fmi2EnterInitializationMode(instanceFMU) # установить исходное состояние
fmi2ExitInitializationMode(instanceFMU)  # прочитать исходное состояние
Out[0]:
0x00000000

现在我们可以在计算周期中运行模型。 功能 fmi2DoStep 具有固定间距 tStep 允许您执行此模型的计算步骤。 如果模型具有输入参数或接收数据,则可以循环更改它们。

In [ ]:
values = []

for t in tSave
    # выставить входные параметры модели, если требуется
    # ...

    fmi2DoStep(instanceFMU, tStep)
    
    # сохранить выходы модели
    value = fmi2GetReal(instanceFMU, "mass.s")
    push!(values, value)
end

plot(tSave, values)
Out[0]:

在计算结束时,我们必须释放内存并删除中间文件。

In [ ]:
fmi2Terminate(instanceFMU)
fmi2FreeInstance!(instanceFMU)
unloadFMU(fmu)
[OK][CvodeStatistics][SpringFrictionPendulum1D]: Sundials CVode Statistics
    Stop time                                : 8.00 s
    Simulation time                          : 1.42 s
    Number of external steps                 : 80
    Number of internal steps                 : 191
    Number of non-linear iterations          : 263
    Number of non-linear convergence failures: 0
    Number of f function evaluations         : 291
    Number of g function evaluations         : 339
    Number of Jacobian-evaluations (direct)  : 7
    Maximum integration order                : 5
    Suggested tolerance scale factor         : 1.0
    Grouping used                            : no

结论

我们用一个命令启动了一个简单的FMU模型,并想出了如何组织一个计算周期,在这个周期中我们可以更新模型的输入参数并根据输出数据做出操作决策。