Анализируйте и управляйте дифференциальными алгебраическими уравнениями

Этот пример показывает, как решить дифференциальные алгебраические уравнения (ДАУ) высокого дифференциального индекса с помощью Symbolic Math Toolbox™.

Инженеры часто задают поведение своих физических объектов (механические системы, электрические устройства, и так далее) смесью дифференциальных уравнений и алгебраических уравнений. MATLAB® обеспечивает специальные числовые решатели, такие как ode15i и ode15s, способный к интеграции таких ДАУ - при условии, что их 'дифференциальный индекс' не превышает 1.

Этот пример показывает рабочий процесс от подготовки модели как система дифференциальных уравнений с алгебраическими ограничениями к числовой симуляции. Следующие функции Symbolic Math Toolbox используются.

  • daeFunction

  • findDecoupledBlocks

  • incidenceMatrix

  • isOfLowDAEIndex

  • reduceDifferentialOrder

  • massMatrixForm

  • reduceDAEIndex

  • reduceDAEToODE

  • reduceRedundancies

  • sym/decic

Задайте параметры модели

Рассмотрите 2D физический маятник, состоя из массового m, присоединенного к источнику строкой постоянной длины r. Только гравитационное ускорение g = 9.81 m/s^2 действует на массу. Модель состоит из дифференциального уравнения второго порядка для положения (x(t), y(t)) массы с неизвестной силой F(t) в строке, которая служит для хранения массы на круге. Сила направлена вдоль строки.

syms x(t) y(t) F(t) m g r
eqs = [m*diff(x(t), t, t) == F(t)/r*x(t);
       m*diff(y(t), t, t) == F(t)/r*y(t) - m*g;
       x(t)^2 + y(t)^2 == r^2]
eqs = 

(m2t2 x(t)=F(t)x(t)rm2t2 y(t)=F(t)y(t)r-gmx(t)2+y(t)2=r2)

vars = [x(t), y(t), F(t)]
vars = (x(t)y(t)F(t))

Перепишите эту систему ДАУ к системе дифференциальных алгебраических уравнений первого порядка.

[eqs, vars, newVars] = reduceDifferentialOrder(eqs, vars)
eqs = 

(mt Dxt(t)-F(t)x(t)rgm+mt Dyt(t)-F(t)y(t)r-r2+x(t)2+y(t)2Dxt(t)-t x(t)Dyt(t)-t y(t))

vars = 

(x(t)y(t)F(t)Dxt(t)Dyt(t))

newVars = 

(Dxt(t)t x(t)Dyt(t)t y(t))

Попытайтесь решить систему ДАУ Высокого Индекса

Прежде чем можно будет использовать числовой решатель MATLAB, такой как ode15i, необходимо выполнить эти шаги.

  1. Преобразуйте систему ДАУ к указателю функции MATLAB.

  2. Выберите численные значения для символьных параметров системы.

  3. Установите сопоставимые начальные условия.

Чтобы преобразовать систему ДАУ в указатель функции MATLAB, используйте daeFunction.

F = daeFunction(eqs, vars, [m, g, r])
F = function_handle with value:
    @(t,in2,in3,in4)[in3(4,:).*in4(:,1)-(in2(3,:).*in2(1,:))./in4(:,3);in3(5,:).*in4(:,1)+in4(:,1).*in4(:,2)-(in2(3,:).*in2(2,:))./in4(:,3);-in4(:,3).^2+in2(1,:).^2+in2(2,:).^2;in2(4,:)-in3(1,:);in2(5,:)-in3(2,:)]

Присвойте численные значения символьным параметрам системы: m = 1kg, g = 9.18m/s^2 и r = 1m.

f = @(t, y, yp)  F(t, y, yp, [1, 9.81, 1])
f = function_handle with value:
    @(t,y,yp)F(t,y,yp,[1,9.81,1])

Указатель на функцию f является подходящим входом для числового решателя ode15i. Следующий шаг должен вычислить сопоставимые начальные условия. Используйте odeset, чтобы установить числовые допуски. Затем используйте функцию decic MATLAB, чтобы вычислить сопоставимые начальные условия y0, yp0 для положений и производных во время t0 = 0.

opt = odeset('RelTol', 10.0^(-4), 'AbsTol' , 10.0^(-4));
t0 = 0;
[y0,yp0] = decic(f, t0, [0.98;-0.21; zeros(3,1)], [], zeros(5,1), [], opt)
y0 = 5×1

    0.9777
   -0.2100
         0
         0
         0

yp0 = 5×1

         0
         0
         0
         0
   -9.8100

Протестируйте начальные условия:

f(t0, y0, yp0)
ans = 5×1
10-16 ×

         0
         0
   -0.3469
         0
         0

Теперь можно использовать ode15i, чтобы попытаться решить систему. Когда вы вызываете ode15i, интегрирование сразу останавливается и выдает следующие предупреждения.

Warning: Matrix is singular, close to singular or badly scaled.

Results may be inaccurate. RCOND = NaN.

Warning: Failure at t=0.000000e+00.

Unable to meet integration tolerances without reducing the step

size below the smallest value allowed (0.000000e+00) at time t.

В данном примере ode15i выдает эти предупреждения многократно. Для удобочитаемости отключите предупреждения при помощи warning('off','all') прежде, чем вызвать ode15i и затем включите им снова.

tfinal = 0.5;
s = warning('off','all');
ode15i(f, [t0, tfinal], y0, yp0, opt);

warning(s)

Анализируйте и настройте систему ДАУ

Проверяйте дифференциальный индекс системы ДАУ.

isLowIndexDAE(eqs, vars)
ans = logical
   0

Этот результат объясняет, почему ode15i не может решить эту систему. Эта функция требует, чтобы система входа DAE была дифференциального индекса 0 или 1. Уменьшайте дифференциальный индекс путем расширения модели к эквивалентной большей системе ДАУ, которая включает некоторые скрытые алгебраические ограничения.

[eqs, vars, newVars, index] = reduceDAEIndex(eqs, vars)
eqs = 

(mDxtt(t)-F(t)x(t)rgm+mDytt(t)-F(t)y(t)r-r2+x(t)2+y(t)2Dxt(t)-Dxt1(t)Dyt(t)-Dyt1(t)2Dxt1(t)x(t)+2Dyt1(t)y(t)2y(t)t Dyt1(t)+2Dxt1(t)2+2Dyt1(t)2+2Dxt1t(t)x(t)Dxtt(t)-Dxt1t(t)Dytt(t)-t Dyt1(t)Dyt1(t)-t y(t))

vars = 

(x(t)y(t)F(t)Dxt(t)Dyt(t)Dytt(t)Dxtt(t)Dxt1(t)Dyt1(t)Dxt1t(t))

newVars = 

(Dytt(t)t Dyt(t)Dxtt(t)t Dxt(t)Dxt1(t)t x(t)Dyt1(t)t y(t)Dxt1t(t)2t2 x(t))

index = 3

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

[eqs, vars, S] = reduceRedundancies(eqs, vars)
eqs = 

(-F(t)x(t)-mrDxtt(t)rgmr-F(t)y(t)+mrDytt(t)r-r2+x(t)2+y(t)22Dxt(t)x(t)+2Dyt(t)y(t)2Dxt(t)2+2Dyt(t)2+2Dxtt(t)x(t)+2Dytt(t)y(t)Dytt(t)-t Dyt(t)Dyt(t)-t y(t))

vars = 

(x(t)y(t)F(t)Dxt(t)Dyt(t)Dytt(t)Dxtt(t))

S = struct with fields:
      solvedEquations: [3x1 sym]
    constantVariables: [0x2 sym]
    replacedVariables: [3x2 sym]
       otherEquations: [0x1 sym]

Проверяйте, имеет ли новая система низкий дифференциальный индекс (0 или 1).

isLowIndexDAE(eqs, vars)
ans = logical
   1

Решите систему ДАУ Низкого Индекса

Сгенерируйте указатель функции MATLAB, который заменяет символьные параметры численными значениями.

F = daeFunction(eqs, vars, [m, g, r]) 
F = function_handle with value:
    @(t,in2,in3,in4)[-(in2(3,:).*in2(1,:)-in2(7,:).*in4(:,1).*in4(:,3))./in4(:,3);(-in2(3,:).*in2(2,:)+in2(6,:).*in4(:,1).*in4(:,3)+in4(:,1).*in4(:,2).*in4(:,3))./in4(:,3);-in4(:,3).^2+in2(1,:).^2+in2(2,:).^2;in2(4,:).*in2(1,:).*2.0+in2(5,:).*in2(2,:).*2.0;in2(7,:).*in2(1,:).*2.0+in2(6,:).*in2(2,:).*2.0+in2(4,:).^2.*2.0+in2(5,:).^2.*2.0;in2(6,:)-in3(5,:);in2(5,:)-in3(2,:)]

f = @(t, y, yp)  F(t, y, yp, [1, 9.81, 1])
f = function_handle with value:
    @(t,y,yp)F(t,y,yp,[1,9.81,1])

Вычислите сопоставимые начальные условия для индекса, уменьшаемого функцией decic MATLAB. Здесь, opt является структурой опций, которая устанавливает числовые допуски. Вы уже вычислили его с помощью odeset.

[y0,yp0] = decic(f, t0, [0.98;-0.21; zeros(5,1)], [], zeros(7,1), [], opt)
y0 = 7×1

    0.9779
   -0.2093
   -2.0528
   -0.0000
         0
   -9.3804
   -2.0074

yp0 = 7×1

         0
         0
         0
         0
   -9.3804
         0
         0

Решите систему и постройте решение.

ode15i(f, [t0, tfinal], y0, yp0, opt)