Физическое моделирование часто требует инкрементного подхода моделирования. Это - хорошая практика, чтобы запуститься с простой модели, выполнения и диагностировать его, затем добавить желаемые специальные эффекты, как жидкая сжимаемость или жидкая инерция. Другой пример моделирует диод с разными уровнями сложности: линейный, диод Зенера или экспоненциал. Составные компоненты часто требуют условного включения определенного членского компонента и гибкой схемы связи.
Включая различные варианты моделирования в одном компоненте требует, чтобы применение управляющей логики определило настройку модели. Вы достигаете этой цели при помощи условных разделов в файле компонента.
Условный раздел является разделом верхнего уровня, который охраняет пункт if
. Условные разделы параллельны другим разделам верхнего уровня файла компонента, таковы как разделы уравнений или объявление.
Условный раздел запускается с ключевого слова if
и заканчивается ключевым словом end
. Это может иметь дополнительный elseif
и ответвления else
. Орган по каждому ответвлению условного раздела может содержать блоки объявлений, уравнения, разделы структуры, и так далее, но не может содержать функцию setup
.
if
и ответвления elseif
запускаются с выражения предиката. Если предикат верен, ответвление активируется. Когда все предикаты являются ложными, ответвление else
(если есть) активируется. Скомпилированная модель включает элементы (такие как объявления, уравнения, и так далее) от активных ответвлений только.
component MyComp [...] if Predicate1 [...] % body of branch1 elseif Predicate2 [...] % body of branch2 else [...] % body of branch3 end [...] end
В отличие от операторов if
в разделе уравнений, различные ответвления условного раздела могут иметь различные переменные, различное количество уравнений, и так далее. Например, у вас может быть два варианта канала, тот, который составляет резистивные свойства только и второе что также сжимаемость жидкости моделей:
component MyPipe parameters fl_c = 0; % Model compressibility? (0 - no, 1 - yes) end [...] % other parameters, variables, branches if fl_c == 0 equations % first set of equations, resistive properties only end else variables % additional variable declarations, needed to account for fluid compressibility end equations % second set of equations, including fluid compressibility end end end
В этом примере, если параметры блоков Model compressibility? (0 - no, 1 - yes) установлен в 0, первая система уравнений активируется и модели блока только резистивные свойства канала. Если пользователь блока изменяет значение параметра, то ответвление else
активируется, и скомпилированная модель включает дополнительные переменные и уравнения тот счет на жидкую сжимаемость.
Перечисления очень полезны в определении вариантов компонента, потому что они позволяют вам задать дискретный набор приемлемых значений параметров. Для примера того, как этот компонент может использовать перечисление, смотрите Используя Перечисление в Предикатах.
Вложенные условные разделы позволены. Например:
component A parameters p1 = 0; p2 = 0; p3 = 0; end if p1 > 0 [...] if p2 > 0 [...] end if p3 > 0 [...] end [...] end end
Предикаты должны быть параметрическими выражениями, потому что структура модели должна быть зафиксирована во время компиляции и не может измениться, если модель скомпилирована. Используя переменную в предикате приводит к ошибке времени компиляции:
component A [...] variables v = 0; end if v > 0 % error: v>0 is not a parametric expression because v is a variable [...] else [...] end end
Предикаты могут зависеть от параметров родительского (включение) компонент. Они не могут зависеть, прямо или косвенно, на параметрах (встроенных) компонентов участника или на доменных параметрах:
component A parameters p = 1; end parameters(Access=private) pp = c.p; end components c = MyComp; end nodes n = MyDomain; end if p > 0 % ok [...] elseif c.p > 0 % error: may not depend on parameters of embedded component [...] elseif n.p > 0 % error: may not depend on domain parameters [...] elseif pp > 0 % error: pp depends on c.p [...] end end
Доступность членов класса, объявленных в условных разделах, эквивалентна частным членам класса (Access=private)
. Они не доступны снаружи класса компонента, даже если их ответвление активно.
Осциллограф членов класса, объявленных в условном разделе, является целым классом компонента. Например:
component A nodes p = foundation.electrical.electrical; n = foundation.electrical.electrical; end parameters p1 = 1; end if p1 > 0 components r1 = MyComponentVariant1; end else components r1 = MyComponentVariant2; end end connections connect(p, r1.p); connect(n, r1.n); end end
Однако с помощью условного участника вне условного раздела, когда ответвление не является активными результатами в ошибке компиляции:
component A nodes p = foundation.electrical.electrical; n = foundation.electrical.electrical; end parameters p1 = 0; end if p1 > 0 components r1 = MyComponentVariant1; end end connections connect(p, r1.p); % error if p1=0 and the predicate is false end end
Параметры, на которые ссылаются предикаты условных разделов, непосредственно и косвенно, должны быть параметрами времени компиляции. Функция setup
не может записать в эти параметры, например:
component A parameters p1 = 1; end if p1 > 0 % p1 is a compile-time parameter [...] else [...] end function setup tmp = p1; % ok to read from p1 p1 = 10; % error: may not write to p1 here end end
Этот простой пример показывает компонент, содержащий два резистора. Резисторы могут быть соединены или последовательно или параллельно, в зависимости от значения параметра управления:
component TwoResistors nodes p = foundation.electrical.electrical; % +:left n = foundation.electrical.electrical; % -:right end parameters p1 = {1, 'Ohm'}; % Resistor 1 p2 = {1, 'Ohm'}; % Resistor 2 ct = 0; % Connection type (0 - series, 1 - parallel) end components(ExternalAccess=observe) r1 = foundation.electrical.elements.resistor(R=p1); r2 = foundation.electrical.elements.resistor(R=p2); end if ct == 0 % linear connection connections connect(p, r1.p); connect(r1.n, r2.p); connect(r2.n, n); end else % parallel connection connections connect(r1.p, r2.p, p); connect(r1.n, r2.n, n); end end end
Чтобы протестировать правильное поведение условного раздела, укажите блок Simscape Component на этот файл компонента. Поместите блок в схему с 10-вольтовым источником напряжения постоянного тока и датчик тока. Со значениями параметров по умолчанию резисторы соединяются последовательно, и ток составляет 5 А.
Если вы изменяете значение параметра Connection type (0 - series, 1 - parallel) к 1
, резисторы соединяются параллельно, и ток составляет 20 А.