Исправлен атрибут при создании экземпляра модели в качестве параметра - PullRequest
0 голосов
/ 16 февраля 2019

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

parameter Real y(fixed = true);

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

parameter ComplexModel m(fixed = true);

не компилируется.Рассмотрим, например, следующую плоскую модель

model FlatModel
  parameter Real x = 4;
  parameter Real y(fixed = false);
  Real z;
  // ... + many other model elements
initial equation
  y*y = x;
  // ... + many other equations
equation
  z*z = 4*x;
end FlatModel;

Здесь неявное решение y = 2 вычисляется во время инициализации, тогда как решение z = 4 вычисляется в зависимости от времени (по крайней мере, в принципе, возможна оптимизация, несмотря на...).Но оба представляют в основном одно и то же квадратичное отношение, поэтому я хочу инкапсулировать это уравнение в отдельную модель (обратите внимание, что не каждая такая система уравнений так проста, как в этом примере):

model ComplexModel 
  Real x(fixed = false);
  Real y(fixed = false);
equation
  y * y = x;
end ComplexModel;

и попробуйте использоватьэто так:

  model RefactoredFlatModel
    parameter Real x = 4;
    parameter Real y(fixed = false);
    Real z;
    parameter ComplexModel mStatic;
    ComplexModel mDynamic;
  initial equation
    mStatic.x = x;
    y = mStatic.y;
  equation
    mDynamic.x = 4*x;
    z = mDynamic.y;
  end RefactoredFlatModel;

Но, похоже, это не сработает (компилятор сообщает о переопределенной системе).Проверка сплющенной компилятором модели показывает, почему:

class FixedTests.RefactoredFlatModel
  parameter Real x = 4.0;
  parameter Real y(fixed = false);
  Real z;
  parameter Real mStatic.x(fixed = false);
  parameter Real mStatic.y(fixed = false);
  Real mDynamic.x(fixed = false);
  Real mDynamic.y(fixed = false);
initial equation
  mStatic.x = x;
  y = mStatic.y;
equation
  mStatic.y ^ 2.0 = mStatic.x;
  mDynamic.y ^ 2.0 = mDynamic.x;
  mDynamic.x = 4.0 * x;
  z = mDynamic.y;
end FixedTests.RefactoredFlatModel;

Итак, mStatic.y ^ 2.0 = mStatic.x помещается в (зависимый от времени) раздел уравнения вместо раздела исходного уравнения, где я хотел, чтобы это было.Ясно, что модель переопределена, потому что она пытается решить для mStatic.y во времени, хотя mStatic.y является параметром и, следовательно, не зависит от времени.

Есть ли какой-нибудь способ сказать компилятору modelica поворачивать уравненияв исходные уравнения для экземпляров параметров?Потому что иначе невозможно неявно определить экземпляры параметров сложных моделей.

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Начиная с спецификации Modelica v3.4, это недопустимый Modelica, поскольку префикс parameter не должен использоваться со специализированным классом model.

. Есть несколько предложений по улучшению этого поведения (иудовлетворить ваши требования), см. https://github.com/modelica/ModelicaSpecification/issues/2311 и его источник https://github.com/modelica/ModelicaStandardLibrary/issues/1860.

0 голосов
/ 01 апреля 2019

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

model RefactoredFlatModel
  parameter Real x=4;
  parameter Real y(fixed=false);
  Real z;
  ComplexModel mStatic;
  ComplexModel mDynamic;
initial equation 
  y = mStatic.y;
equation 
  // The assignment is needed to have enough equations, even though its static
  mStatic.x = x;

  mDynamic.x = 4*x;
  z = mDynamic.y;
end RefactoredFlatModel;

Параметры можно также назначать в разделах исходных уравнений из регулярных переменных.Таким образом, вам не нужен префикс параметра для модели mStatic.Однако уравнения mStatic также должны быть определены в непрерывном отрезке времени, поэтому мы должны переместить уравнение mStatic.x = x в отрезок уравнения.

0 голосов
/ 18 февраля 2019

Редактировать (2019-02-30): Не используйте это «решение».Согласно ответу tbeu, это нарушает языковой стандарт.OpenModelica позволяет это, но не должно.


Я наконец нашел частичное решение.Если я объявлю ComplexModel, используя условные выражения в секциях initial equation и equation, я могу заставить его работать - как угодно.

model ComplexModel
  parameter Boolean fixed = true;
  Real x(fixed = false);
  Real y(fixed = false);
initial equation
  if not fixed then
    y * y = x;
  end if;
equation
  if fixed then
    y * y = x;
  end if;
end ComplexModel;

Заменив в модели RefactoredFlatModel (из вопроса)линия

parameter ComplexModel mStatic;

по

parameter ComplexModel mStatic (fixed = false);

, в результате плоская модель в итоге становится

class AdvancedMultiBody.FixedTests.RefactoredFlatModel
  parameter Real x = 4.0;
  parameter Real y(fixed = false);
  Real z;
  parameter Boolean mStatic.fixed = false;
  parameter Real mStatic.x(fixed = false);
  parameter Real mStatic.y(fixed = false);
  parameter Boolean mDynamic.fixed = true;
  Real mDynamic.x(fixed = false);
  Real mDynamic.y(fixed = false);
initial equation
  mStatic.y ^ 2.0 = mStatic.x;
  mStatic.x = x;
  y = mStatic.y;
equation
  mDynamic.y ^ 2.0 = mDynamic.x;
  mDynamic.x = 4.0 * x;
  z = mDynamic.y;
end AdvancedMultiBody.FixedTests.RefactoredFlatModel;

, т. е. я успешно переделал уравнение для mStatic.y в initial equation раздел таким образом, что можно контролировать снаружи.Хорошо то, что ComplexModel теперь полностью инкапсулирован и ему может быть присвоен атрибут «fixed = false», как того требует мой вопрос.

Плохо то, что мне нужно написать базовое уравнение y*y=xдважды внутри ComplexModel.В случае более сложных систем уравнений это может быть источником ошибки.И еще: я думаю, что синтаксис может быть нарушен, если кто-то напишет fixed=false для экземпляра ComplexModel, не являющегося параметром (приводит к исчезновению зависящего от времени уравнения, которое весьма отличается от значения fixed = false для атомарных типов данных).

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

...