using ode45 to solve a non-linear system of coupled ODE's

30 visualizzazioni (ultimi 30 giorni)
so my code doesn't work. I've looked around and seen that maybe ode45 is not the best ode solver for this problem but it is an assignment and we're told to use that specific one.
So what we have is a system of 3 coupled first-order odes, where dx(1)/dt = vx = x(2), and dx(2)/dt = d(vx)/dt = ax = -Cd*(A/(2*m))*rho0*sqrt(x(2).^2 + y(2).^2 + z(2).^2).*x(2) + Cl*(A/(2*m))*rho0*sqrt(x(2).^2 + y(2).^2 + z(2).^2).*(Sy.*z(2)-Sz.*y(2))
Very complicated function, unfortunately I'm struggling to simplify it but it shouldn't make too much of a difference hopefully!
So I'll post my code and the output, and hopefully someone can point me to a trivial mistake that I'm probably making. Keep in mind the problem I think lies with the fact that the coupled odes all depend on the other variables, so d(vx)/dt depends on vy = dy/dt and vz = dz/dt, for example.
Thanks in advance!
time_length = 25;
g = 9.8; % Acceleration due to gravity (m/s^2)
rho0 = 1.20; % Density of air (kg/m^3)
d = 0.22; % Ball diameter (m)
m = 0.43; % Ball mass (kg)
A = pi*(d/2)^2; % Ball cross-sectional area (m^2)
Cd = 0.3; % Drag coefficient
Cl = 0.3; % Lift coefficient
Sx = 1; % x-component of S
Sy = 1; % y-component of S
Sz = 0; % z-component of S
S = [Sx, Sy, Sz]; % Spin vector
% Coupled ODE's. x = x(1), vx = x(2). Same for y and z
odex = @(t,x) [x(2); -Cd*(A/(2*m))*rho0*sqrt(x(2).^2 + y(2).^2 + z(2).^2).*x(2) + Cl*(A/(2*m))*rho0*sqrt(x(2).^2 + y(2).^2 + z(2).^2).*(Sy.*z(2)-Sz.*y(2))];
odeset('abstol',1e-6);
[t,x] = ode45(odex,[0 time_length],[0,30/sqrt(2)]);
odey = @(t,y) [y(2); -Cd*(A/(2*m))*rho0*sqrt(x(2).^2 + y(2).^2 + z(2).^2).*y(2) + Cl*(A/(2*m))*rho0*sqrt(x(2).^2 + y(2).^2 + z(2).^2).*(Sz.*x(2)-Sx.*z(2))];
odeset('abstol',1e-6);
[t,y] = ode45(odey,[0 time_length],[0,0]);
odez = @(t,z) [z(2); -g-Cd*(A/(2*m))*rho0*sqrt(x(2).^2 + y(2).^2 + z(2).^2).*z(2) + Cl*(A/(2*m))*rho0*sqrt(x(2).^2 + y(2).^2 + z(2).^2).*(Sx.*y(2)-Sy.*x(2))];
odeset('abstol',1e-6);
[t,z] = ode45(odez,[0 time_length],[0,30/sqrt(2)]);
and error output:
Undefined function 'y' for input arguments of type 'double'.
Error in
@(t,x)[x(2);-Cd*(A/(2*m))*rho0*sqrt(x(2).^2+y(2).^2+z(2).^2).*x(2)+Cl*(A/(2*m))*rho0*sqrt(x(2).^2+y(2).^2+z(2).^2).*(Sy.*z(2)-Sz.*y(2))]
Error in odearguments (line 88)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 114)
[neq, tspan, ntspan, next, t0, tfinal, tdir, y0, f0, odeArgs, odeFcn, ...
Error in code (line 24)
[t,x] = ode45(odex,[0 time_length],[0,30/sqrt(2)]);
I suspect I know a bit of what's going wrong, yet I'm at a loss for how to fix it. Any help is much appreciated!

Risposta accettata

Bjorn Gustavsson
Bjorn Gustavsson il 5 Ott 2014
  1. in your definition of W you're mixing doubles and function handles.
  2. write your ode-equations as one m-function - it becomes to messy with function handles.
  3. in that function you'll have something along:
function drdt = myode(t,r,whetever,more,you,need)
code
drdt(1) = vx;
drdr(2) = ax;
drdt(3) = vy;
drdr(4) = ay;
drdt(5) = vz;
drdr(6) = az;
then proceed as above.

Più risposte (1)

Jan
Jan il 28 Set 2014
The error message seems to be clear:
Undefined function 'y' for input arguments of type 'double'.
Error in
@(t,x)[x(2);-Cd*(A/(2*m))*rho0*sqrt(x(2).^2+y(2).^2+z(2).^2).*x(2)+Cl*
(A/(2*m))*rho0*sqrt(x(2).^2+y(2).^2+z(2).^2).*(Sy.*z(2)-Sz.*y(2))]
This is a function of the arguments t and x, but the contents of the function uses the variables x, y and z.
What are y and z?
  5 Commenti
Joshua D'Agostino
Joshua D'Agostino il 30 Set 2014
okay cheers I've gone and done that, but what is this giving me now and why?
odex = @(t,x) -Cd*(A/(2*m))*rho0*sqrt(x(2).^2 + x(4).^2 + x(6).^2).*x(2) + Cl*(A/(2*m))*rho0*sqrt(x(2).^2 + x(4).^2 + x(6).^2).*(Sy.*x(6)-Sz.*x(4));
odey = @(t,x) -Cd*(A/(2*m))*rho0*sqrt(x(2).^2 + x(4).^2 + x(6).^2).*x(4) + Cl*(A/(2*m))*rho0*sqrt(x(2).^2 + x(4).^2 + x(6).^2).*(Sz.*x(2)-Sx.*x(6));
odez = @(t,x) -g-Cd*(A/(2*m))*rho0*sqrt(x(2).^2 + x(4).^2 + x(6).^2).*x(6) + Cl*(A/(2*m))*rho0*sqrt(x(2).^2 + x(4).^2 + x(6).^2).*(Sx.*x(4)-Sy.*x(2));
W = @(t,x) [x(1);x(2);x(3);x(4);x(5);x(6)];
dxyz = @(t,x) [x(2);@out;x(4);odey;x(6);odez];
[T,W] = ode45(dxyz,linspace(0,time_length,1e4),[0,30/sqrt(2),0,0,0,30/sqrt(2)]);
output:
Error using vertcat
The following error occurred converting from double to function_handle:
Error using function_handle
Too many output arguments.
Error in @(t,x)[x(2);@out;x(4);odey;x(6);odez]
Error in odearguments (line 88)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 114)
[neq, tspan, ntspan, next, t0, tfinal, tdir, y0, f0, odeArgs, odeFcn, ...
Error in code (line 35)
[T,W] = ode45(dxyz,linspace(0,time_length,1e4),[0,30/sqrt(2),0,0,0,30/sqrt(2)]);
I don't quite understand why it's giving me these errors, I thought I've taken care of the number of input arguments?
Jan
Jan il 5 Ott 2014
I do not understand your code. What is "@out"? Why do you define W as a function, but overwrite it be the output of the integrator? "odey" is a function handle. If you concatenate it with "[x(2); odey]" what do you expect as result? Which type should this vector have?
I suggest to create a simple function instead of a pile of nested function handles, which are obviously too confusing.

Accedi per commentare.

Categorie

Scopri di più su Programming in Help Center e File Exchange

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by