Использование блоков Variant Source и Variant Sink¶
В этом примере мы покажем работу блоков Variant Source
и Variant Sink
. Эти блоки позволяют переключаться между разными реализациями моделей, являющимися генераторами входных данных или потребителями выходных данных некоторой подсистемы.
Введение¶
Предположим, вам нужно просчитать работу модели с разными входными датчиками, разными циклограммами или различными алгоритмами фильтрации данных на выходе. Для такого тестирования можно собрать несколько отдельных моделей, число которых быстро станет непрактично большим. Или можно собрать все модели в одну и переключать условия при помощи переменных.
В этом упрощенном примере конфигурация модели будет задана двумя скалярными переменными:
V = 1;
W = 1;
В модели есть несколько переключателей сигнальных линий, управляемых внешними переменными.
Условия выбора сигнала в каждом блоке Variant Source
или Variant Sink
заданы при помощи выражений.
Выражение, которое первым принимает истинное значение, определяет номер порта, по которому пойдут данные от или к некоторой подсистеме. Проинтерпретируем разные варианты систем, которые реализованы на этой схеме:
- Если
W==1
является истинным выражением тоVariant Source1
активирует входSine3
, а приV==4
активируется входSine4
. - При
V==1
блокVariant Source 2
пропускает сигнал от блокаSine1
, а приV==2
– сигнал от блокаAdd1
. - Если блок
Add1
неактивен, тоVariant Source 1
тоже будет неактивным, и тогда будут отключены блокиSine3
иSine4
(блок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
,Sum
иOut2
всегда активны, на них не распространяются условия по выбору вариантов системы. Чтобы эти блоки выполнялись только при некоторых условиях, можно поставить перед и после них блокиVariant Source/Sink
оба с единственным входом и выходом.
При некоторых комбинациях условий данная модель возвращает ошибку, потому что выходные порты подсистемы должны получать активный сигнал вне зависимости от варианта подсистемы. Подача на любой блок одновременно активного и неактивного сигнала невозможна, нужно явно оформлять выходные порты такой системы при помощи блоков Variant Source/Sink
чтобы задавать значения по умолчанию.
Запуск сценария¶
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 )
plot( data["Gain3.1"].time, data["Gain3.1"].value )
Запуск нескольких сценариев¶
Теперь мы запустим несколько вариантов модели в цикле, переключая переменные состояния, чтобы при помощи комбинации входных условий показать, как система работает в разных сценариях.
using Combinatorics
# Зададим все интересующие нас входные условия
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
Выведем график, на котором будет собрана статистика по запускам разных вариантов нашей модели.
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)))) )
Заключение¶
Мы убедились в том, что на одном холсте можно собрать несколько вариантов системы. Этот метод упрощает тестирование и позволяет генерировать сразу много вариантов кода для еще большей автоматизации полунатурного моделирования.