Физическое моделирование часто требует подхода инкрементного моделирования. Это хорошая практика, чтобы начать с простой модели, запустить и диагностировать ее, а затем добавить желаемые специальные эффекты, такие как сжимаемость жидкости или инерция жидкости. Другой пример - моделирование диода с различными уровнями сложности: линейным, ценерным или экспоненциальным. Составные компоненты часто требуют условного включения определенного представителя компонента и гибкой схемы соединения.
Включение различных вариантов моделирования в один компонент требует применения логики управления для определения строения модели. Эта цель достигается с помощью условных сечений в файле компонента.
Условным сечением является сечение верхнего уровня, охраняемое 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.