How can I pass a large function into ODE45?
Ältere Kommentare anzeigen
I have a large ODE function that I need to evaluate the system response time for. My function is a second order differential
. In the code, theta_2 refers to the position of my link bar 2.
My problem is that my ODE is huge. Like really big.
and
and
, -->
, -->
, -->
-->
,
-->
And
is a peicewsie function of 
What is the best way to pass my ODE into ODE45. Or any other ODE solver. My boundary conditions are
clc
clear
% Find time-response plots for theta2dot and theta
% ----------- Knows -----------
R_2 = 2 ; %inches
R_3 = 6 ; %inches
diam = 3.5;
radius = diam./2;
% ----------- Pressure Stuff ----------
n = 1.37 ; % Gas R-value
P_atm = 14.7;
P1 = 13; %psi
P2 = P1; %psi
P3 = P2.*8.^n; %psi
P4 = 600; %psi
P5 = P4./(8.^n); %psi
P6 = 18; %psi
P7 = P6; %psi
% ------------- Input -------------
% theta_2 = 0:1:720;
% theta_2 = theta_2';
% Let theta_dot be omega
% Let theta_2dot be alpha
R_4 = @(theta_2) R_2.*cosd(theta_2) + sqrt((R_3.^2)-(R_2*sind(theta_2)));
%R_4 = Get_R_4(theta_2);
theta_3 = @(theta_2) atan2d((-R_2).*sind(theta_2),(R_4-R_2.*cosd(theta_2)));
h_3 = @(theta_2) (-R_2.*cosd(theta_2))./(R_3.*cosd(theta_3));
h_3_prime = @(theta_2)(R_2.*sind(theta_2))./(R_3.*cosd(theta_3)) + tand(theta_3).*(h_3.^2);
f_4 = @(theta_2) -R_2.*sind(theta_2) + R_2.*cosd(theta_2).*tand(theta_3);
f_4_prime = @(theta_2) -R_2.*cosd(theta_2) - R_3.*cosd(theta_3).*(h_3.^2) - R_3.*sind(theta_3).*h_3_prime;
R_4_prime = f_4;
R_4_2prime = f_4_prime;
% [pressure] = Get_pressure(theta_2);
R4_atBDC = R_4(180);
R4_atTDC = R_4(0);
d = 0.57142857;
BDC_Volume = (R4_atTDC-R4_atBDC+d).*pi.*radius.^2;
TDC_Volume = (d).*pi.*radius.^2;
Int_Volume = @(theta_2) ((R4_atTDC-R4_atBDC)-(R4(theta_2)-R4_atBDC)+d).*pi.*radius.^2;
Compression_Pressure = @(theta_2) P2.*(BDC_Volume).^1.37./(Int_Volume).^1.37;
Expansion_Pressure = @(theta_2) P4.*(TDC_Volume).^1.37./(Int_Volume).^1.37;
pressure = @(theta_2) piecewise( theta_2<180, P1, theta_2>180 & theta_2<360, ...
Compression_Pressure, theta_2 == 360, P4, theta_2>360 & theta_2<540, ...
Expansion_Pressure, theta_2>540 & theta_2<720, P6);
force = @(theta_2)(pressure(theta_2)-P_atm).*(radius.^2).*(pi);
Power = @(theta_2) f_4.*force;
Power_ODE = @(omega_2, alpha_2) Power == (0.02072+1.5+0.01166.*(R_4_prime.^2)).*(omega_2).*(alpha_2)+0.01166.*(R_4_prime).*(R_4_2prime).*(omega_2.^3)+0.005.*(omega_2.^3)+8.*cosd(theta_2).*(omega_2);
a = @(theta_2) (force(theta_2).*f_4(theta_2))./(0.02072+1.5+0.01.*R_4_prime(theta_2).^2);
b = @(theta_2) (-0.01166.*R_4_prime(theta_2).*R_4_2prime(theta_2))./(0.02072+1.5+0.01.*R_4_prime(theta_2).^2);
c = @(theta_2) (0.005)./(0.02072+1.5+0.01.*R_4_prime(theta_2).^2);
d = @(theta_2) 8./(0.02072+1.5+0.01.*R_4_prime(theta_2).^2);
odeFUNC = @(t,theta) [theta(2); a(theta(1)) - b(theta(1))*(theta(2)) - c(theta(1))*((theta(2))^2) - d(theta(1))*cosd(theta(1))];
tspan = [0 10];
theta0 = [180 400];
[ts,ys] = ode45(@(t,theta) odeFUNC,tspan,theta0);
Akzeptierte Antwort
Weitere Antworten (1)
Write your function as an m file and pass a handle to it; don't try to do stuff in scripts or complicated stuff as anonymous functions. Amongst other benefits, you can then much more easily test that it does as you expect at any point in time by calling it standalone with any input time and whatever auxiliary parameters are needed and debug it.
If you need additional parameters beyond the time and y' vector, see the section on <Parameterizing ODE Functions>
Kategorien
Mehr zu Programming finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
