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

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

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

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

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

Похожие темы