Определение вариантов компонента

Физическое моделирование часто требует инкрементного подхода моделирования. Это - хорошая практика, чтобы запуститься с простой модели, выполнения и диагностировать его, затем добавить желаемые специальные эффекты, как жидкая сжимаемость или жидкая инерция. Другой пример моделирует диод с разными уровнями сложности: линейный, диод Зенера или экспоненциал. Составные компоненты часто требуют условного включения определенного членского компонента и гибкой схемы связи.

Включая различные варианты моделирования в одном компоненте требует, чтобы применение управляющей логики определило настройку модели. Вы достигаете этой цели при помощи условных разделов в файле компонента.

Условные разделы

Условный раздел является разделом верхнего уровня, который охраняет пункт 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 А.

Похожие темы