How do I pass inputs into external functions from ode45?
Mostra commenti meno recenti
I'm trying to run an ode45 function, but the differential equations are constrained by other equations, which I made functions for, and referenced in the ode function (func) , but I keep getting the error "Not enough input arguments." There may be other errors, but I can't get past this one. I need the domain of the ode45 (pi to 3pi) to be passed into the other functions as input theta. My main goal is to plot theta against pressure/work but I can't get it to intialize. Thanks in advance
global r gamma thetas thetab l S b V0 T1 Tw Qin R
gamma = 1.4;
r = 8.4;
thetas = (3*pi)/2;
thetab = pi;
% meters
l = 0.012;
S = 0.08;
b = 0.09;
% cm squared
V0 = 50;
% Kelvin
T1 = 300;
Tw = 300;
% J/kg
Qin = 2.8e6;
% J/kg/k
R = 287;
% sol = ode45(@func,[pi 3*pi],[1.013e5 0]);
[theta,sol] = ode45(@(theta,y) func,[pi 3*pi],[1.013e5 0]);
function referenced by ode45 and all the dependent functions
function E2 = func(theta,y)
global gamma b Tw Qin R
%y(1)=Pressure
%y(2)=Work
%mass blow by
he = 0;
%heat transfer to cylinder wall
% C = 0;
%instantaneous surface area
Aw =(4*V(theta))/b;
%temperature
T = (y(1)*V(theta))/(mass(theta)*R);
%Pressure and work derivatives, respectively
E2 = [-gamma*(y(1)/V(theta))*(V_prime(theta))+(gamma-1)*((mass(theta)*Qin)/V(theta))*(x_prime(theta))-((gamma-1)*he*Aw*(T-Tw))/(V*w)+((gamma*mass_prime(theta))/mass(theta))*y(1);
y(1)*V_prime(theta);];
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Volume function
function Vtheta = V(theta)
global r l S
sigma = S/(2*l);
Vtheta = 1 + ( (r-1) / (2*sigma) )*( 1+sigma*(1-cos(theta)-sqrt(1-sigma^2*sin(theta)^2)));
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% x derivative function
function dxdtheta = x_prime(theta)
global thetas thetab
if pi <= theta && theta < thetas
dxdtheta = 0;
elseif thetas <= theta && theta <= (thetas+thetab)
dxdtheta = -(pi/( 2* thetab))*cos( ( pi*( theta-thetas ) ) / thetab);
elseif thetas+thetab < theta && theta < 3*pi
dxdtheta = 0;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%mass function
function M = mass(theta)
M0 = 1;%initial mass
C =0 ;%heat transfer to cylinder
omega = 1;%rotational velocity
M = M0*exp( (-C/omega) * (theta-pi) );
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Mass derivative
function dMdTheta = mass_prime(theta)
%constants
omega_prime = 0;%rotational acceleration - zero bc/ angular velocity was zeero
M0 = 1;%initial mass
C =0 ;%heat transfer to cylinder
dMdTheta = ( -(C*omega_prime)-(pi*omega_prime) )*M0*exp( (-C/omega)*(theta-pi) );
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Volume derivative
function dVdTheta = V_prime(theta)
global r l S
sigma = S/(2*l);
dVdTheta = ( 2*r*sqrt( 1-( sigma^2 ) * sin( theta )^2 )* sin( theta ) + r*sigma*sin(2*theta)-2*sqrt( 1-(sigma^2)*( sin(theta) )^2 )*sin( theta ) )/( 4*sqrt( 1 - (sigma^2)*( sin( theta ) )^2 ) );
end
4 Commenti
Walter Roberson
il 28 Apr 2023
See
Note that
[theta,sol] = ode45(@(theta,y) func,[pi 3*pi],[1.013e5 0]);
tells ode45 that it will be operating on a function that accepts two parameters, and ignores them, and returns whatever func() with no parameter would return.
We recommend that you get rid of the global variables and parameterize the functions instead.
Joshua
il 28 Apr 2023
Walter Roberson
il 28 Apr 2023
If you are not going to parameterize to get rid of the globals, then Yes, @func would be faster than @(theta,y)func(theta,y)
Joshua
il 28 Apr 2023
Risposta accettata
Più risposte (1)
This code works without syntax errors, but you should pass all your parameters to "func" and distribute them from there among the other functions called instead of using globals.
Take a look here on how to do this:
global r gamma thetas thetab l S b V0 T1 Tw Qin R
gamma = 1.4;
r = 8.4;
thetas = (3*pi)/2;
thetab = pi;
% meters
l = 0.012;
S = 0.08;
b = 0.09;
% cm squared
V0 = 50;
% Kelvin
T1 = 300;
Tw = 300;
% J/kg
Qin = 2.8e6;
% J/kg/k
R = 287;
% sol = ode45(@func,[pi 3*pi],[1.013e5 0]);
[theta,sol] = ode45(@func,[pi 3*pi],[1.013e5 0]);
plot(theta,sol)
function referenced by ode45 and all the dependent functions
function E2 = func(theta,y)
global gamma b Tw Qin R
%y(1)=Pressure
%y(2)=Work
%mass blow by
he = 0;
%heat transfer to cylinder wall
% C = 0;
%instantaneous surface area
Aw =(4*V(theta))/b;
%temperature
T = (y(1)*V(theta))/(mass(theta)*R);
%Pressure and work derivatives, respectively
E2 = [-gamma*(y(1)/V(theta))*(V_prime(theta))+(gamma-1)*((mass(theta)*Qin)/V(theta))*(x_prime(theta))-((gamma-1)*he*Aw*(T-Tw))/(V(theta)*Aw)+((gamma*mass_prime(theta))/mass(theta))*y(1);
y(1)*V_prime(theta);];
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Volume function
function Vtheta = V(theta)
global r l S
sigma = S/(2*l);
Vtheta = 1 + ( (r-1) / (2*sigma) )*( 1+sigma*(1-cos(theta)-sqrt(1-sigma^2*sin(theta)^2)));
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% x derivative function
function dxdtheta = x_prime(theta)
global thetas thetab
if pi <= theta && theta < thetas
dxdtheta = 0;
elseif thetas <= theta && theta <= (thetas+thetab)
dxdtheta = -(pi/( 2* thetab))*cos( ( pi*( theta-thetas ) ) / thetab);
elseif thetas+thetab < theta && theta < 3*pi
dxdtheta = 0;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%mass function
function M = mass(theta)
M0 = 1;%initial mass
C =0 ;%heat transfer to cylinder
omega = 1;%rotational velocity
M = M0*exp( (-C/omega) * (theta-pi) );
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Mass derivative
function dMdTheta = mass_prime(theta)
%constants
omega_prime = 0;%rotational acceleration - zero bc/ angular velocity was zeero
omega=1;
M0 = 1;%initial mass
C =0 ;%heat transfer to cylinder
dMdTheta = ( -(C*omega_prime)-(pi*omega_prime) )*M0*exp( (-C/omega)*(theta-pi) );
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Volume derivative
function dVdTheta = V_prime(theta)
global r l S
sigma = S/(2*l);
dVdTheta = ( 2*r*sqrt( 1-( sigma^2 ) * sin( theta )^2 )* sin( theta ) + r*sigma*sin(2*theta)-2*sqrt( 1-(sigma^2)*( sin(theta) )^2 )*sin( theta ) )/( 4*sqrt( 1 - (sigma^2)*( sin( theta ) )^2 ) );
end
4 Commenti
Joshua
il 28 Apr 2023
Walter Roberson
il 29 Apr 2023
Modificato: Walter Roberson
il 29 Apr 2023
You have
E2 = [-gamma*(y(1)/V(theta))*(V_prime(theta))+(gamma-1)*((mass(theta)*Qin)/V(theta))*(x_prime(theta))-((gamma-1)*he*Aw*(T-Tw))/(V*w)+((gamma*mass_prime(theta))/mass(theta))*y(1);
y(1)*V_prime(theta);];
Notice the
/(V*w)
That is a problem in that statement because V is not a variable: it is a function of theta.
Also, there is no w anywhere in your code -- only Tw
Joshua
il 29 Apr 2023
Categorie
Scopri di più su Mathematics in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
