Трапецеидальная интеграция нелинейной индуктивности - PullRequest
0 голосов
/ 06 ноября 2019

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

model NonlinearInductor
  import Modelica.SIunits.MagneticFlux;
  extends Modelica.Electrical.Analog.Interfaces.OnePort;

  parameter Real T[:,2]=[-1.0015,-1200;-0.0015,-200;0,0;0.0015,200;1.0015,1200]
                                                                               "piecewiselinear current versus flux relation";
  Integer nbPoints = size(T,1) "Number of interpolation points";
  Real L;  //Slop of line flux-Current; inductance
  MagneticFlux flux( start=0);

equation
  v =  der(flux);     // Faraday's Low

algorithm
                // Definition of Piecewise nonlinear inductance


if  i < T[2,1] then
   L     := ((T[1,2] - T[2,2]) / (T[1,1] - T[2,1]));
   flux  :=  L  *  (i-T[1,1]) +  T[1,2];

  elseif i >= T[nbPoints-1,1] then
   L     := (( T[nbPoints-1,2] - T[nbPoints,2]) / (T[nbPoints-1,1] - T[nbPoints,1]));
   flux  := L * (i-T[nbPoints-1,1]) +  T[nbPoints-1,2];

  else
      for iter in 2:(nbPoints-2) loop
         if i >= T[iter,1] and i <T[iter+1,1] then
            L      := (( T[iter,2] - T[iter+1,2]) / (T[iter,1] - T[iter+1,1]));
            flux   := L * (i-T[iter,1]) +  T[iter,2];
         end if;
      end for;
 end if;
end NonlinearInductor;

, и я подготовил и примеркак показано ниже:

model NonlinearInductorTest
  Modelica.Electrical.Analog.Sources.CosineVoltage cosineVoltage1(V = 25e3 * sqrt(2), freqHz = 50,
    phase=1.5707963267949)                                                                                          annotation (
    Placement(visible = true, transformation(origin = {-80, 20}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Modelica.Electrical.Analog.Basic.Resistor resistor1(R = 1000e6)  annotation (
    Placement(visible = true, transformation(origin = {-14, 20}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Modelica.Electrical.Analog.Basic.Ground ground1 annotation (
    Placement(visible = true, transformation(origin = {-80, -12}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Electrical.Analog.Basic.Capacitor capacitor1(C=0.4e-9)    annotation (
    Placement(visible = true, transformation(origin = {-50, 42}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  NonlinearInductor L annotation(
    Placement(visible = true, transformation(origin = {28, 20}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
equation
  connect(L.n, ground1.p) annotation(
    Line(points = {{28, 10}, {28, 10}, {28, -2}, {-80, -2}, {-80, -2}}, color = {0, 0, 255}));
  connect(L.p, capacitor1.n) annotation(
    Line(points = {{28, 30}, {28, 30}, {28, 42}, {-40, 42}, {-40, 42}}, color = {0, 0, 255}));
  connect(capacitor1.p, cosineVoltage1.p) annotation(
    Line(points = {{-60, 42}, {-80, 42}, {-80, 30}}, color = {0, 0, 255}));
  connect(capacitor1.n, resistor1.p) annotation(
    Line(points = {{-40, 42}, {-14, 42}, {-14, 30}}, color = {0, 0, 255}));
  connect(resistor1.n, ground1.p) annotation(
    Line(points = {{-14, 10}, {-14, -2}, {-80, -2}}, color = {0, 0, 255}));
  connect(ground1.p, cosineVoltage1.n) annotation(
    Line(points = {{-80, -2}, {-80, 10}}, color = {0, 0, 255}));
  annotation (
    uses(Modelica(version="3.2.2")),
    experiment(StartTime = 0, StopTime = 0.1, Tolerance = 1e-6, Interval = 2e-05));
end NonlinearInductorTest;

Пожалуйста, запустите пример для Solver Trapezoidal, StopTime = 0,1, Interval = 2e-05

1 Ответ

0 голосов
/ 11 ноября 2019

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

Вот обновленный код:

model NonlinearInductor2
  extends Modelica.Electrical.Analog.Interfaces.OnePort;

  parameter Real T[:,2]=[-1.0015,-1200;
                         -0.0015,-200;
                               0,0;
                          0.0015,200;
                          1.0015,1200] "piecewiselinear current versus flux relation";

  Modelica.SIunits.MagneticFlux flux( start=0);

protected 
  final parameter Real[:] i_vec = T[:, 1];
  final parameter Real[:] flux_vec = T[:, 2];

equation 
  v = der(flux);     // Faraday's Law
  flux = Modelica.Math.Vectors.interpolate(i_vec,flux_vec,i);
end NonlinearInductor2;

Помимоделая вашу модель намного проще для понимания, использование функции интерполяции также дает следующие преимущества:

  • Функция имеет определенную аннотацию smoothOrder, которая позволяет транслятору Modelica дифференцировать вашу переменную fluxаналитически.
    (С помощью аннотаций smooth и smoothOrder вы можете определить, до какого порядка производная является непрерывной)
  • Вместо раздела алгоритма мы можем использовать один раздел уравнения.
    (Вы должны избегать разделов алгоритма для описания физического поведения, так как он ограничивает транслятор Modelica в манипулировании вашими уравнениями для создания разрешимой системы. С помощью разделов алгоритма вы заставляете код оцениваться в точности так, как вы его написали, что противоречит принципуа-причинная физическая мodeling)

К сожалению, OpenModelica по-прежнему испытывает некоторые трудности при моделировании новой модели с помощью настроек симуляции (правило трапеции, допуск = 1e-6). При уменьшении допуска до 1e-4 симуляция завершается, но все равно отображается предупреждение

Перезапустите Kinsol: измените линейный решатель на KINDense.

много раз. Возможно, в этом может помочь эксперт OpenModelica.

Кстати, у Dymola нет проблем с новым кодом, независимо от выбранного решателя.

...