Maverick
Maverick

Reputation: 440

Solve matrix DAE system in matlab

The equations can be found here. As you can see it is set of 8 scalar equations closed to 3 matrix ones. In order to let Matlab know that equations are matrix - wise, I declare variable time dependent vector functions as:

syms t p1(t) p2(t) p3(t)
p(t) = symfun([p1(t);p2(t);p3(t)], t);
p = formula(p(t));  % allows indexing for vector p
% same goes for w(t) and m(t)...

Known matrices are declared as follows:

A = sym('A%d%d',[3 3]);
Fq = sym('Fq%d%d',[2 3]);
Im = diag(sym('Im%d%d',[1 3]));

The system is now ready to be modeled according to guide:

eqs = [diff(p) == A*w + Fq'*m,...
       diff(w) == -Im*p,...
       Fq*w == 0];
vars = [p; w; m];

At this point, when I try to reduce index (since it equals 2), I receive following error:

[DAEs,DAEvars] = reduceDAEIndex(eqs,vars);

Error using sym/reduceDAEIndex (line 95)
Expecting as many equations as variables.

The error would not arise if we had declared all variables as scalars:

syms A Im Fq real p(t) w(t) m(t)

Quoting symfun documentation (tips section):

Symbolic functions are always scalars, therefore, you cannot index into a function.

However it is hard for me to believe that it's not possible to solve these equations matrix - wise. Obviously, one can expand it to 8 scalar equations, but the multi body system concerned here is very simple and the aim is to be able to solve complex ones - hence the question: is it possible to solve matrix DAE in Matlab, and if so - what has to be fixed in order for this to work?


Ps. I have another issue with Matlab DAE solver: input variables (known coefficient functions) for my model are time variant. As far as example is concerned, they are constant in all domain, however for my problem they change in time. This problem has been brought out here. I would be grateful if you referred to it, should you have any solution.

Upvotes: 1

Views: 1204

Answers (1)

Maverick
Maverick

Reputation: 440

Finally, I managed to find correct syntax for this problem. I made a mistake of treating matrix variables (such as A, Fq) as a single entity. Below I present code that utilizes matrix approach and solves this particular DAE:

% Define symbolic variables.
q = sym('q%d',[3 1]);        % state variables
a = sym('a'); k = sym('k');  % constant parameters
t = sym('t','real');         % independent variable

% Define system variables and group them in vectors:
p1(t) = sym('p1(t)'); p2(t) = sym('p2(t)'); p3(t) = sym('p3(t)');
w1(t) = sym('w1(t)'); w2(t) = sym('w2(t)'); w3(t) = sym('w3(t)');
m1(t) = sym('m1(t)'); m2(t) = sym('m2(t)');
pvect = [p1(t); p2(t); p3(t)];
wvect = [w1(t); w2(t); w3(t)];
mvect = [m1(t); m2(t)];

% Define matrices:
mass = diag(sym('ms%d',[1 3]));
Fq = [0 -1 a;
      0  0 1];
A = [1  0  0;
     0  1  a;
     0  a -q(1)*a] * k;

% Define sets of equations and aggregate them into one set: 
set1 = diff(pvect,t) == A*wvect + Fq'*mvect;
set2 = mass*diff(wvect,t) == -pvect;
set3 = Fq*wvect == 0;
eqs = [set1; set2; set3];
% Close all system variables in one vector:
vars = [pvect; wvect; mvect];

% Reduce index of the system and remove redundnat equations:
[DAEs,DAEvars] = reduceDAEIndex(eqs,vars);
[DAEs,DAEvars] = reduceRedundancies(DAEs,DAEvars);
[M,F] = massMatrixForm(DAEs,DAEvars);

We receive very simple 2x2 ODE for two variables p1(t) and w1(t). Keep in mind that after reducing redundancies we got rid of all elements from state vector q. This means that all left variables (k and mass(1,1)) are not time dependent. If there had been time dependency of some variables within the system, the case would have been much harder to solve.

% Replace symbolic variables with numeric ones:
M = odeFunction(M, DAEvars,mass(1,1));
F = odeFunction(F, DAEvars, k);
k = 2000; numericMass = 4;
F = @(t, Y) F(t, Y, k);
M = @(t, Y) M(t, Y, numericMass);

% set the solver:
opt = odeset('Mass', M); % Mass matrix of the system
TIME = [1; 0];           % Time boundaries of the simulation (backwards in time)
y0 = [1 0]';             % Initial conditions for left variables p1(t) and w1(t)

% Call the solver
[T, solution] = ode15s(F, TIME, y0, opt);
% Plot results
plot(T,solution(:,1),T,solution(:,2))

Upvotes: 0

Related Questions