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

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

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

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

Условным сечением является сечение верхнего уровня, охраняемое 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.

Похожие темы