Физическое моделирование часто требует подхода инкрементного моделирования. Это хорошая практика, чтобы начать с простой модели, запустить и диагностировать ее, а затем добавить желаемые специальные эффекты, такие как сжимаемость жидкости или инерция жидкости. Другой пример - моделирование диода с различными уровнями сложности: линейным, ценерным или экспоненциальным. Составные компоненты часто требуют условного включения определенного представителя компонента и гибкой схемы соединения.
Включение различных вариантов моделирования в один компонент требует применения логики управления для определения строения модели. Эта цель достигается с помощью условных сечений в файле компонента.
Условным сечением является сечение верхнего уровня, охраняемое if пункт. Условные сечения параллельны другим разделам файла компонента верхнего уровня, таким как объявления или разделы уравнений.
Условное сечение начинается со if ключевое слово и заканчивается end ключевое слово. Это может быть необязательно elseif и else ветви. Тело каждой ветви условного раздела может содержать блоки объявления, уравнения, структурные разделы и так далее, но не может содержать setup функция.
The if и elseif ветви начинаются с предикатного выражения. Если предикат равен true, ветвь активируется. Когда все предикаты ложны, 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
Параметрами, на которые ссылаются предикаты условных разделов, прямо и косвенно, должны быть параметры времени компиляции. The 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 блок на этот файл компонента. Поместите блок в схему с 10V источником постоянного напряжения и датчиком тока. При значениях параметров по умолчанию резисторы соединяются последовательно, и ток 5A.


Если вы измените значение параметра Connection type (0 - series, 1 - parallel) на 1, резисторы соединены параллельно, и ток 20A.

