Engee 文档
Notebook

使用变体源和变体接收器块

在这个例子中,我们将展示这些块是如何工作的。 Variant SourceVariant Sink. 这些模块允许您在作为子系统的输入数据的生成器或输出数据的使用者的模型的不同实现之间切换。

导言

假设您需要计算具有不同输入传感器,不同循环图或用于在输出处过滤数据的不同算法的模型的操作。 对于这样的测试,您可以组装几个单独的模型,其数量很快就会变得不切实际。 或者您可以将所有模型组装成一个模型,并使用变量切换条件。

在这个简化的示例中,模型配置将由两个标量变量设置。:

In [ ]:
Pkg.add(["Combinatorics"])
In [ ]:
V = 1;
W = 1;

该模型具有多个由外部变量控制的信号线开关。

image.png

每个块中的信号选择条件 Variant SourceVariant Sink 它们是使用表达式设置的。

首先采用true值的表达式确定数据从某个子系统传输或传输到某个子系统的端口号。 让我们来解释在这个方案中实现的系统的不同变体。:

*如果 W==1 是真实的表达 Variant Source1 激活输入 Sine3,以及何时 V==4 入口被激活 Sine4.
*何时 V==1Variant Source 2 跳过块中的信号 Sine1,以及何时 V==2 -来自单位的信号 Add1.
*如果块 Add1 不活动,则 Variant Source 1 它也将处于非活动状态,然后块将被禁用。 Sine3Sine4 (座 Sine3 活动时 V==2 && W==1,和块 Sine4 活动时 V==2 && W==2).
*尤洛克 Gain3 活动无论是当 V==1,或何时 V==2;在其他条件下(例如,当 V=4)我们会得到一个错误,因为在输出端口 Out1 不会给出输出信号。
*出口处的街区 Variant Sink1 他们变得活跃时 W==1 (Gain5) 或何时 W==2 (Gain2, Substract, Terminator).
*最后,块 Sine6, SumOut2 它们始终处于活动状态,它们不受选择系统选项的条件限制。 为了确保这些块仅在特定条件下执行,您可以在它们之前和之后放置块。 Variant Source/Sink 两者都有一个单一的入口和出口。

在某些条件组合下,此模型返回错误,因为子系统的输出端口必须接收活动信号,而不考虑子系统的变体。 不可能在同一时间向任何块发送活动和非活动信号,有必要使用块明确设计这种系统的输出端口 Variant Source/Sink 设置默认值。

运行脚本

In [ ]:
mName = "variant_source_sink"
model = mName in [m.name for m in engee.get_all_models()] ? engee.open( mName ) : engee.load( "$(@__DIR__)/$(mName).engee" );
data = engee.run( mName )
Out[0]:
Dict{String, DataFrames.DataFrame} with 1 entry:
  "Gain3.1" => 51×2 DataFrame
In [ ]:
plot( data["Gain3.1"].time, data["Gain3.1"].value )
Out[0]:

运行多个脚本

现在,我们将在一个循环中运行模型的几个变体,切换状态变量,以便使用输入条件的组合来显示系统在不同场景中的工作方式。

In [ ]:
using Combinatorics
In [ ]:
# Зададим все интересующие нас входные условия
vV = [1,2,4];
vW = [1,2,4];

# Загрузим модель
mName = "variant_source_sink"
model = mName in [m.name for m in engee.get_all_models()] ? engee.open( mName ) : engee.load( "$(@__DIR__)/$(mName).engee" );

# Успех выполнения мы будем хранить в матрице, которую инициализируем пропущенными значениями
run_success = NaN .* zeros(length(vV), length(vW))

# Пройдемся по всем комбинациям входных условий и проверим, выполнится ли модель
for c in combinations( vcat( vV,vW ), 2  )
    V,W = c[1],c[2]
    i = findfirst( vV.==c[1] )
    j = findfirst( vW.==c[2] )
    
    try
        # Запустим модель на выполнение
        data = engee.run( mName )
    catch e
        # Если модель выполнилась с ошибкой, запишем 0 в выходную матрицу
        run_success[i,j] = 0
    else
        # Запишем единицу только если условие catch не сработало
        run_success[i,j] = 1
    end

end

让我们显示一个图表,在这个图表上,我们将收集模型不同变体的发射统计数据。

In [ ]:
gr()
# Вывод не интерактивной карты, отражающей успех выполнения модели
heatmap( run_success, xticks=(range(1,length(vV)), vV), yticks=(range(1,length(vW)), vW),
         xlabel = 'V', ylabel='W', title="Успех выполнения модели", yflip = true, cbar=false, c=:Blues )
# Аннотация поверх каждой ячейки
annotate!( vec(tuple.((1:length(vV))', (1:length(vW)), string.(Int32.(run_success)))) )
Out[0]:

结论

我们已经看到几个系统变体可以组装在一个画布上。 此方法简化了测试,并允许您一次生成许多代码变体,以进一步自动化半自然建模。

示例中使用的块