exponenta event banner

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

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

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

Условные сечения

Условный раздел - это раздел верхнего уровня, охраняемый if пункт. Условные сечения параллельны другим разделам верхнего уровня файла компонента, например разделам описания или уравнений.

Условный раздел начинается с if ключевое слово и заканчивается end ключевое слово. Он может быть необязательным elseif и else филиалы. Тело каждой ветви условного раздела может содержать блоки объявления, уравнения, секции структуры и т. д., но не может содержать setup функция.

if и elseif ветви начинаются с предикатного выражения. Если предикат имеет значение true, ветвь активируется. Когда все предикаты имеют значение false, 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

В этом примере, если параметр блока «Сжимаемость модели»? (0 - нет, 1 - да) имеет значение 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 на этот файл компонента. Поместите блок в цепь с 10V источником постоянного напряжения и датчиком тока. При использовании значений параметров по умолчанию резисторы подключаются последовательно, а ток 5A.

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

Связанные темы