Mass Matrix SWITCH Problem in Matlab
이전 댓글 표시
I'm having a problem with my ODE in Matlab. The code to start the ODE solver is the following:
refine = 4;
options = odeset('Refine', refine,...
'RelTol', 1e-9,'absTol',1e-9*ones(1,length(y_sym)),'Mass',Mss_bend,'MassSingular','no','MstateDependence','strong')
[t_bend_i,y_bend_i] = ode45(@(t,y) ...
bending_DGL(t,y,time_r,dt,ug,vg,Mss_bend,Fss_bend,Sys,flag),time_r_i,IC_bend_i,options);
And the corresponding function file containing the ODE is:
function dy = bending_DGL(t,y,time_r,dt,ug,vg,Mss_bend,Fss_bend,Sys,flag)
r = Sys.r;
roh = Sys.roh;
A = Sys.A;
I = Sys.I;
ne = Sys.ne;
nnode = Sys.nnode;
ndof = Sys.ndof;
Le = Sys.Le;
E = Sys.E;
g = Sys.g;
EI = E*I;
EA = E*A;
%Interpolate Earthquake Excitation
i = floor(t/dt) + 1;
if i < length(time_r)
u = ug(i) + (t-time_r(i))/(time_r(i+1)-time_r(i))*(ug(i+1)-ug(i));
v = vg(i) + (t-time_r(i))/(time_r(i+1)-time_r(i))*(vg(i+1)-vg(i));
else
u = 0;
v = 0;
end
%Load State Space Representation of Problem
switch flag
case ''
dy = Fss_bend;
case 'mass'
dy = Mss_bend;
end
Now I'm trying to solve the ODE where Mss_bend is the mass matrix which is symbolic, because it is statedependent so Mss_bend(y,t) and Fss_bend(y,t) is the right side of the Equation which is state dependent too. So now I wan't to solve the Problem Mss_bend(y,t)*dy = Fss_bend where dy is the derivative of the vector y with respect to time.
When I start the calculation it gives me the
Error: Switch expression must be a scalar or string constant.
Error in bending_DGL (line 31)
switch flag
Error in @(t,y)bending_DGL(t,y,time_r,dt,ug,vg,Mss_bend,Fss_bend,Sys,flag)
Error in odearguments (line 87)
What did i do wrong? Is there a problem because the matrices are symbolic?
Matlab tell's me in the function file that y is unused:
function dy = bending_DGL(t, y,time_r,dt,ug,vg,Mss_bend,Fss_bend,Sys,flag
How do I solve this Problem. y is as symbolics in the Mss_bend and Fss_bend where y(1), y(2) etc is declared as symbols.
Thank you for your answers!
답변 (4개)
Walter Roberson
2016년 4월 7일
We would need to see how you initialized your flag variable to figure out why you are getting the error for switch.
You will need to change your code anyhow. Assuming that your Fss_bend and Mss_bend are expressions rather than functions:
%Load State Space Representation of Problem
switch flag
case ''
dy = double( subs(Fss_bend, {sym('t', sym('y')}, {t, y}) );
case 'mass'
dy = double( subs(Mss_bend, {sym('t', sym('y')}, {t, y}) );
end
However, it seems likely that your Mss_bend and Fss_bend also use some of the variables that you compute, such as u and v. We need to know whether Mss_bend and Fss_bend are functions or expressions, and if they are functions we need to know the order they expect their arguments in. If they are expressions then we need to know which symbolic variables need to be substituted.
댓글 수: 7
Walter Roberson
2016년 4월 8일
In order for your line
[t_bend_i,y_bend_i] = ode45(@(t,y) ...
bending_DGL(t,y,time_r,dt,ug,vg,Mss_bend,Fss_bend,Sys,flag),time_r_i,IC_bend_i,options);
to execute at all, you need to have defined the variables time_r, dt, ug, vg, Mss_bend, Fss_bend, Sys, flag, time_r_i, and IC_bend_i .
I need to see how you initialized the value for flag before you reach that line.
But what I really suspect is that you are handling the mass matrix completely wrong.
MassFun = @(t,y) double(subs(Mss_bend, sym('y'), y));
refine = 4;
options = odeset('Refine', refine,...
'RelTol', 1e-9, 'absTol',1e-9*ones(1,length(y_sym)), 'Mass', MasFun, 'MassSingular', 'no', 'MstateDependence', 'strong');
[t_bend_i,y_bend_i] = ode45(@(t,y) bending_DGL(t, y, time_r, dt, ug, vg, Fss_bend, Sys), time_r_i, IC_bend_i ,options);
together with
function dy = bending_DGL(t, y, time_r, dt, ug, vg, Fss_bend, Sys)
r = Sys.r;
roh = Sys.roh;
A = Sys.A;
I = Sys.I;
ne = Sys.ne;
nnode = Sys.nnode;
ndof = Sys.ndof;
Le = Sys.Le;
E = Sys.E;
g = Sys.g;
EI = E*I;
EA = E*A;
%Interpolate Earthquake Excitation
i = floor(t/dt) + 1;
if i < length(time_r)
u = ug(i) + (t-time_r(i))/(time_r(i+1)-time_r(i))*(ug(i+1)-ug(i));
v = vg(i) + (t-time_r(i))/(time_r(i+1)-time_r(i))*(vg(i+1)-vg(i));
else
u = 0;
v = 0;
end
dy = double( subs(Fss_bend, {sym('u'), sym('v'), sym('y')}, {u, v, y}) );
Marius
2016년 4월 8일
편집: Walter Roberson
2016년 4월 9일
Torsten
2016년 4월 8일
And Fss_bend really is a symbolic column vector of length 16 ?
Best wishes
Torsten.
Torsten
2016년 4월 8일
Can't be true.
If it were the case, the command
dy = double( subs(Fss_bend, {sym('u'), sym('v'), sym('y')}, {u, v, y}) );
would generate a 16x1 vector of doubles, not a 256x1 vector of doubles.
Check the sizes of Fss_bend (before dy is generated) and dy.
Best wishes
Torsten.
Marius
2016년 4월 8일
Torsten
2016년 4월 8일
Maybe
dy = double( subs(Fss_bend, {sym('u'), sym('v'), sym('y')}, {u, v, y'}) );
?
Best wishes
Torsten.
Marius
2016년 4월 21일
0 개 추천
댓글 수: 13
Walter Roberson
2016년 4월 21일
matlabFunction() the symbolic expressions into function handles outside of the objective function, and pass the function handles in to the objective.
Marius
2016년 4월 22일
Walter Roberson
2016년 4월 22일
You could try
y_sym = [sym('y[1]'), sym('y[2]'), ..., sym('y[24]')]
I might be able to test this later today.
Marius
2016년 4월 22일
Walter Roberson
2016년 4월 22일
Sorry, I had an install glitch and cannot test the symbolic toolbox at the moment.
Walter Roberson
2016년 4월 22일
Do not proceed by way of
y_sym = ['y(1)';'y(2)'...;'y(24)']
Instead
y = sym('y', [1, 24]);
which will show up as y1, y2, y3, etc, in your function. Then
matlabFunction(fss, 'vars', {'t', y, 'u', 'v'})
Notice this is y rather than 'y' : when you give a vector of names within {} then all the names are put into a single input argument that is indexed as needed.
Unfortunately the variable name that will be written into the anonymous function will be like 'in2', but since the arguments are positional rather than by name, it will still work.
Marius
2016년 4월 23일
Walter Roberson
2016년 4월 23일
I need to see your Fss, at least part of it.
Marius
2016년 4월 23일
Walter Roberson
2016년 4월 23일
In
function dy = rocking_DGL(t,y,time_r,dt,ug,vg,Fss,Sys,y_sym)
change the Fss to FssFun
Marius
2016년 4월 23일
Walter Roberson
2016년 4월 23일
What is your FssFun reshape()'ing to? It should be reshaping to a column vector.
If you are using matlabFunction(something) to generate FssFun then use matlabFunction(something(:))
카테고리
도움말 센터 및 File Exchange에서 Ordinary Differential Equations에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!