Недискретные назначения целых переменных

Является ли недискретное присваивание выражений целым числам только в пределах algorithm a function?

Если в алгоритме требуется много параметров модели, было бы намного проще вычислить выходное значение непосредственно в разделе алгоритма модели.

Если вы используете функцию, вам необходимо передать все необходимые значения параметров из среды в качестве входных данных для функции.

Мне кажется, что спецификация Modelica заставляет инкапсулировать целые числа с недискретными назначениями локально внутри функций.

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

Для вычисления выходного значения для определенного входного значения x необходимо определить индексы базовых функций, носители которых содержат x.

Я включаю более простой случай линейной интерполяции табличных данных в качестве рабочего примера, где интервал интерполяции должен быть найден (даже если такая интерполяция не дифференцируема).

noEvent(...) в коде не требуется, так как отношения внутри секции алгоритма функции не генерируют события, если аннотация GenerateEvents=true не задана.

Тем не менее, я включил его, чтобы показать, откуда происходит недискретное присвоение целому числу i.

model testInterpol
function interpol
        input Real x;
        input Real tab[:,2];
        output Real y;
protected
        Integer i;
algorithm
  i:=size(tab,1);
  for ii in 2:size(tab,1) loop
   if noEvent(x < tab[ii,1]) then
    i := ii;
    break;
   end if;
  end for;
   y := tab[i-1,2] + (tab[i,2]-tab[i-1,2])/(tab[i,1]-tab[i-1,1])*(x-tab[i-1,1]);
end interpol;

Real x = 10*sin(8*atan(1.0)*time);
parameter Real tab[:,2]={{1,1},{2,4},{3,9},{5,25},{6,36}};
Real y;
equation
        y = interpol(x,tab);
end testInterpol;

В следующей модели тип Interpol изменяется от function до model.

Обратите внимание, что это подразумевает некоторые изменения для использования Interpol.

model testInterpolModel
model Interpol
        input Real x;
        input Real tab[:,2];
        output Real y;
protected
        Integer i;
algorithm
  i:=size(tab,1);
  for ii in 2:size(tab,1) loop
   if noEvent(x < tab[ii,1]) then
    i := ii;
    break;
   end if;
  end for;
   y := tab[i-1,2] + (tab[i,2]-tab[i-1,2])/(tab[i,1]-tab[i-1,1])*(x-tab[i-1,1]);
end Interpol;

Real x = 10*sin(8*atan(1.0)*time);
parameter Real tab[:,2]={{1,1},{2,4},{3,9},{5,25},{6,36}};
Real y;

Interpol interpol(x=x,tab=tab,y=y);
end testInterpolModel;
  • OpenModelica 1.9.3 + dev (r25613) принимает testInterpolModel

  • Dymola отклоняет модель со следующим сообщением об ошибке:

    Trying to assign a discrete variable inside a loop controlled by higher variability:
    interpol.i = ii;
    

В разделе 12.2 "Функция как специализированный класс" спецификации Modelica 3.3 rev. 1 можно найти следующее утверждение:

Компоненты функции будут внутри функции вести себя так, как если бы они имели вариабельность по времени.

Я не совсем уверен, что это значит. Если бы у этого предложения было только предложение и не было опыта с инструментами Modelica, можно было бы подумать, что утверждения из секции алгоритма функции оцениваются только в экземплярах событий, потому что они ведут себя так, как если бы они имели вариабельность в дискретном времени. Но это впечатление неверно. Операторы функции всегда выполняются, а отношения внутри функций не генерируют события, если аннотация GenerateEvents явно не установлена ​​на true.

Это указано в разделе 8.5 "События и синхронизация" спецификации:

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

Существует уже связанный билет в Track-Tracker Modelica: Ticket-Comment-Link

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

Алгоритмы в моделях можно концептуально интерпретировать как анонимные функции в отношении входов и выходов (см. раздел 11.1.2 "Выполнение алгоритма в модели" Спецификации). Все переменные, которые назначены в алгоритме, становятся выходами анонимной функции и могут использоваться в уравнениях вне алгоритма.

Но тогда эти переменные могут вводить разрывы в других частях модели.

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

У меня сложилось впечатление, что проблема будет решена, если бы было возможно объявить локальные переменные алгоритма. Для экземпляра можно разрешить объявление algorithm -local переменных, таких как i после algorithm -keyword.

Альтернативным решением могло бы стать повторное введение ключевого слова nondiscrete Modelica-Specification 1. Уже существует старый билет Modelica где такое повторное введение было предложено в комментарии. Предложение получило только одобрение, но ничего не произошло.

Ключевое слово nondiscrete можно использовать перед Integer i; во втором примере кода выше. Поскольку переменная i и присваивание i:=ii; будут nodiscrete, в этом случае noEvent также будет легальным в рамках алгоритма.

Ответы