Постановка компонентов в стационарной модели Modelica

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

Я подготовил примерный случай с двумя параллельными насосами, которые должны подавать в систему заданный общий расход (vTotal). Один насос является насосом с переменной частотой и обеспечивает расход (v1), пропорциональный рабочей частоте (fPump1), которая может варьироваться от 0 до fMax. Другой насос - это насос с фиксированной скоростью, который выдает фиксированный расход (v2IfRunning), когда он работает, и нулевой расход, когда он не работает.

Цель состоит в том, чтобы определить количество работающих насосов и частоту насосов с регулируемой скоростью. Насос с регулируемой скоростью всегда работает, а насос с фиксированной скоростью используется только тогда, когда насосу с регулируемой скоростью необходимо работать с частотой, превышающей fMax. Мой пример кода ниже:

model TwoPumpCode
  // Pump 1
  Modelica.SIunits.Frequency fPump1 "pump 1 frequency";
  Modelica.SIunits.Frequency fMax = 50 "maximum frequency";
  Modelica.SIunits.VolumeFlowRate v1;

  // Pump 2
  // Boolean runPump2(start=false) "true if pump 2 should run";
  Modelica.SIunits.VolumeFlowRate v2IfRunning = 30;
  Modelica.SIunits.VolumeFlowRate v2 
    "actual flow through pump 2";

  Integer nPumpsRunning(start = 1) "number of pumps running";

  // Total flow
  Modelica.SIunits.VolumeFlowRate vTotal = 70;

equation 
  // Calculate the flow through pump 1 as a function of frequency
  v1 = fPump1;

  // Calculate the flow through pump 2 based upon running state
  if fPump1 > fMax then
    nPumpsRunning = 2;
    v2 = v2IfRunning;
  else
    nPumpsRunning = 1;
    v2 = 0;
  end if;

  // Calculate the total flow
  vTotal = v1 + v2;

end TwoPumpCode;

Опять же, это стационарная модель. Я пробовал использовать if, when, reinit, логические переменные для состояния pumpRunning, целочисленные переменные для количества работающих насосов и т. Д., И я все еще не могу найти решение для устойчивого состояния.

Любые предложения будут ценны.

Спасибо, Джастин


person Justin Kauffman    schedule 24.04.2017    source источник
comment
Вы можете отделить логику управления от вашей модели насоса, как это делается, например, в моделях MSL. Затем у вас есть модель насоса с переключателем включения / выключения и контроллером. В контроллере используйте гистерезис, чтобы избежать дребезга.   -  person matth    schedule 24.04.2017
comment
Спасибо за отзыв, мат. Остальная часть системы является чисто установившейся, поэтому я бы предпочел по возможности избегать динамики контроллера. Можете ли вы порекомендовать конкретный пример из MSL, который я могу просмотреть?   -  person Justin Kauffman    schedule 24.04.2017
comment
Контроллеры, подобные Modelica.Blocks.Logical.OnOffController, не добавляют динамику, поскольку нет хранилища / интеграции и т. Д., Они используют условие if, как и ваш код. Может, не стоит называть это контроллером, а лучше логическим блоком !? Вы можете найти пример использования на github: git.io/v9IGP   -  person matth    schedule 24.04.2017


Ответы (2)


Теперь я понимаю это лучше. Проблема в том, что нам нужно разделить переменные.

model TwoPumpCode
  Modelica.SIunits.VolumeFlowRate vTotal = 70-40*time;
  model TwoPumpSimple
  // Pump 1
  Modelica.SIunits.Frequency fPump1 "pump 1 frequency";
  Modelica.SIunits.Frequency fMax = 50 "maximum frequency";
  Modelica.SIunits.VolumeFlowRate v1;

  // Pump 2
  // Boolean runPump2(start=false) "true if pump 2 should run";
  Modelica.SIunits.VolumeFlowRate v2IfRunning = 30;
  Modelica.SIunits.VolumeFlowRate v2 
    "actual flow through pump 2";

  Integer nPumpsRunning(start = 1) "number of pumps running";
    // Total flow
  input Modelica.SIunits.VolumeFlowRate vTotal;
  input Boolean activeSecond;
  equation
     // Calculate the flow through pump 1 as a function of frequency
  v1 = fPump1;

  // Calculate the flow through pump 2 based upon running state
  if activeSecond  then
    nPumpsRunning = 2;
    v2 = v2IfRunning;
  else
    nPumpsRunning = 1;
    v2 = 0;
  end if;

  // Calculate the total flow
  vTotal = v1 + v2;
  end TwoPumpSimple;
  //TwoPumpSimple first(vTotal=vTotal,activeSecond=first.fPump1>first.fMax);
  TwoPumpSimple first(vTotal=vTotal,activeSecond=false);
  TwoPumpSimple second(vTotal=vTotal,activeSecond=first.fPump1>first.fMax);
end TwoPumpCode;

Прокомментированная строка такая же, как и первое решение, и превратила ее в отдельную проблему, но иногда эта проблема не имеет решения.

Новый вариант делает следующее: 1 Какая высокая частота нужна без 2-го насоса?

2 Следует ли активировать 2-й насос?

3 Вычислите новую частоту - на основе этого.

Добавление некоторого гистерезиса в решение будет иметь аналогичный эффект.

person Hans Olsson    schedule 24.04.2017
comment
Ганс, я попробовал ваш подход, и вы правы, что он моделируется в Димоле. Однако полученные результаты не кажутся правильными. Мои окончательные результаты: activeSecond = true, nPumpsRunning = 2, v2 = 0, v1 = 70, fPump1 = 70. Эти результаты кажутся несовместимыми друг с другом. - person Justin Kauffman; 24.04.2017
comment
Ах, понятно - проблема в условии fPump1 ›fMax. Если мы заменим его на vTotal ›fMax, эта симуляция заработает. - person Hans Olsson; 24.04.2017

Основываясь на обратной связи от Мэтта, я смог использовать оператор pre () на примере из Modelica.Blocks.Logical.OnOffController. Функциональный код показан ниже для справки.

model TwoPumpCode_matth
  // Pump 1
  Modelica.SIunits.Frequency fPump1 "pump 1 frequency";
  Modelica.SIunits.Frequency fMax = 50 "maximum frequency";
  Modelica.SIunits.VolumeFlowRate v1;

  // Pump 2
  parameter Boolean runPump2InitialValue = false;
  Boolean runPump2(start=runPump2InitialValue) "true if pump 2 should run";
  Modelica.SIunits.VolumeFlowRate v2IfRunning = 30;
  Modelica.SIunits.VolumeFlowRate v2 "actual flow through pump 2";

  // Total flow
  Modelica.SIunits.VolumeFlowRate vTotal = 70;

initial equation 
  pre(runPump2) = runPump2InitialValue;

equation 
  // Calculate the flow through pump 1 as a function of frequency
  v1 = fPump1;

  // Calculate the flow through pump 2 based upon running state
  runPump2 = pre(runPump2) or (fPump1 > fMax);
  if runPump2 then
    v2 = v2IfRunning;

  else
    v2 = 0;

  end if;

  // Calculate the total flow
  vTotal = v1 + v2;

end TwoPumpCode_matth;
person Justin Kauffman    schedule 24.04.2017