Modelica: начальное условие для функции шага

Я хотел бы задать вопрос Modelica о том, когда функция, и следующий исходный код не может быть правильно функционировал. Переменная Pstart_CONV является начальным условием для der(x_calc) в операторе if, а значение Pstart_CONV задается x, когда "когда оператор" становится истинным. Поскольку x является пошаговой функцией, я хочу назначить начальное условие для der(x_calc), чтобы x можно было продолжить для всей области.

Большое спасибо,

Источник:

model Unnamed4
  Real  Pstart_CONV;

  Real P_crit_ratio;
  parameter Real P_crit_ratio_criteria = 2.00;

  Real x;
  Real x_calc(start=0);

equation 
  P_crit_ratio = 10-time;

  when P_crit_ratio <= P_crit_ratio_criteria then
    Pstart_CONV = x;
  end when;

  if P_crit_ratio >= P_crit_ratio_criteria then
    x = time^2;
    x_calc = 0;
  else
    der(x_calc) = time * 5;
    x = x_calc + Pstart_CONV;
  end if;   
end Unnamed4;

1 ответ

Решение

С этим кодом я вижу две проблемы. Основная из них связана с тем, что это то, что называется проблемой "переменного индекса". Я займусь этим. Но сначала я хочу отметить, что ваш if а также when пункты не синхронизированы должным образом. Я имею в виду, что изменение в поведении, представленное вашим if утверждение не обязательно произойдет в тот же момент, когда when пункт активирован.

Чтобы решить эту проблему, вы можете легко реорганизовать вашу модель так:

model Model1
  Real Pstart_CONV;
  Real P_crit_ratio;
  parameter Real P_crit_ratio_criteria=2.00;
  Real x;
  Real x_calc(start=0);
  Boolean trigger(start=false);
equation 
  P_crit_ratio = 10-time;

  when P_crit_ratio <= P_crit_ratio_criteria then
    Pstart_CONV = x;
    trigger = true;
  end when;

  if trigger then
    der(x_calc) = time * 5;
    x = x_calc + Pstart_CONV;
  else
    x_calc = 0;
    x = time^2;
  end if;
end Model1;

Теперь оба if а также when пункты привязаны к trigger переменная. Теперь мы можем решить вашу главную проблему, которая заключается в том, что на одной стороне вашего if заявление у вас есть:

der(x_calc) = time * 5;

... а с другой стороны у вас есть:

x_calc = 0;

На практике это означает, что для части моделирования вы решаете x_calc используя дифференциальное уравнение, а во время другой части моделирования вы решаете x_calc используя алгебраическое уравнение. Это приводит к проблеме "переменной индекса", потому что "индекс" DAE изменяется в зависимости от того, является ли значение trigger это правда или ложь.

Один из подходов к этому - немного изменить уравнения. Вместо использования уравнения x_calc = 0 мы указываем начальное условие 0 за x_calc а затем применить дифференциальное уравнение, которое говорит, что значение x_calc не меняется, т.е. der(x_calc) = 0, Другими словами, получить то же поведение, удалив настройки алгебраического уравнения x_calc к константе и заменяя ее уравнением, в котором мы устанавливаем начальное значение x_calc быть желаемым значением, а затем добавить дифференциальное уравнение, которое, по сути, просто говорит о значении x_calc не меняется

Внесение такого изменения в вашем случае приводит к следующей модели:

model Model2
  Real Pstart_CONV;
  Real P_crit_ratio;
  parameter Real P_crit_ratio_criteria=2.0;
  Real x;
  Real x_calc(start=0);
  Boolean trigger(start=false);
initial equation
  x_calc = 0;
equation
  P_crit_ratio = 10-time;

  when P_crit_ratio <= P_crit_ratio_criteria then
    Pstart_CONV = x;
    trigger = true;
  end when;

  if trigger then
    der(x_calc) = time * 5;
    x = x_calc + Pstart_CONV;
  else
    der(x_calc) = 0;
    x = time^2;
  end if;
end Model2;

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

Надеюсь, это поможет.

Другие вопросы по тегам