我正在尝试使用ode45模拟一个简单的瓶装火箭,但是空气质量一直在间歇性地增加,因此我无法一生找出原因。我的代码始终将负的“空气质量变化”(dmair)传递回给ode45,但是在下一个步骤中,我的质量有时将输入较高的函数,有时是函数的3-4倍。同样,质量应该只会减少,但是我的功能是创建多个临界点而不是一条平滑曲线。我已经在这个问题上停留了几天,所以任何见识都会受到赞赏!
Here's a graph的空气质量及其变化率。显然,空气质量应该总是随着时间而减少,但是我对ode45的行为表现出如此不一致的观点感到困惑。有人可以帮我吗?
这是我的主要功能:
%% Set up constants
global p_i
global v_i
global t_i
global v_bottle
global water_density
global p_atmosphere
global area_throat
global area_bottle
global discharge_coeff
global gas_const
global mass_rocket
global mass_air
global p_end
global t_end
global g
global air_density
global drag_coeff
global vel_i
global theta_i
global x_i
global z_i
global test_stand
global Thrust_vector
global water_exhausted
water_exhausted = 0;
t_span = [0 5];
v_bottle = 0.002; %m^3,
p_i = convpres(12.1+50,'psi','Pa');
v_i = 0.001; %Total in m^3
t_i = 300; %kelvin
water_density = 998.2; %kg/m^3 from wolframalpha
p_atmosphere = convpres(12.5,'psi','Pa'); %Pascals,
area_throat = 0.000346361; %m^2, from an estimate of d = 2.1cm
area_bottle = 0.008659015; %m&2, from d = 10.5cm
gas_const = 287; %J/KgK
p_end = p_i * ((v_i/v_bottle)^1.4); %pressure when all the water has been ejected
t_end = t_i * ((v_i/v_bottle)^0.4); %temperature when all the water has been ejected
g = 9.81; %m/s^2
air_density = 0.961; %kg/m^3
drag_coeff = 0.5;
discharge_coeff = 0.8;
vel_i = 0; %m/s
theta_i = pi/4; %radians (45 degrees)
x_i = 0; %m
z_i = 0.25; %m above the ground
test_stand = 0.5; %m
%determine initial mass of the system
mass_bottle = 0.15; %kg
mass_water = water_density * (v_bottle - v_i);
mass_air = v_i * (p_i/(gas_const * t_i));
mass_rocket = mass_bottle + mass_water + mass_air;
rocket_parameters = [v_i; mass_rocket; mass_air; vel_i; theta_i; x_i; z_i;];
%% Call ODE45
[t, rocket_values] = `ode45(@rocket_ode_rework,t_span,rocket_parameters);`
这是ode45调用的函数:
function time_values = rocket_ode_rework(t,rocket_par)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
v_air = rocket_par(1,1);
m_rocket = rocket_par(2,1);
m_air = rocket_par(3,1);
velocity = rocket_par(4,1);
theta = rocket_par(5,1);
x = rocket_par(6,1);
z = rocket_par(7,1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
global p_i
global v_i
global t_i
global v_bottle
global water_density
global p_atmosphere
global area_throat
global area_bottle
global discharge_coeff
global gas_const
global mass_rocket
global mass_air
global p_end
global t_end
global g
global air_density
global drag_coeff
global vel_i
global theta_i
global x_i
global z_i
global test_stand
global Thrust_vector
global water_exhausted
gam = 1.4;
if water_exhausted == 1
v_air = v_bottle;
end
% Water Propellant Phase
if v_air < v_bottle && water_exhausted == 0
bottle_pressure = p_i*((v_i/v_air)^gam);
dvolume = discharge_coeff * area_throat * sqrt((2 / water_density) * (bottle_pressure - p_atmosphere));
dmrocket = -discharge_coeff * area_throat * sqrt(2 * water_density * (bottle_pressure - p_atmosphere));
T = 2 * discharge_coeff * area_throat * (bottle_pressure - p_atmosphere);
dmair = 0;
% Air Propellant Phase
elseif v_air >= v_bottle || water_exhausted == 1
water_exhausted = 1;
bottle_pressure = p_end * (m_air / mass_air)^gam;
bottle_density = m_air / v_bottle;
bottle_temp = bottle_pressure / (gas_const * bottle_density);
if bottle_pressure > p_atmosphere
critical_pressure = bottle_pressure * (2/(gam + 1))^(gam / (gam - 1));
if critical_pressure > p_atmosphere %choked flow
p_exit = critical_pressure;
t_exit = bottle_temp * (2 / (gam + 1));
vel_exit = sqrt(gam * gas_const * t_exit);
density_exit = (critical_pressure / (gas_const * t_exit));
else %unchoked flow
p_exit = p_atmosphere;
Mach = sqrt((-1 + (bottle_pressure / p_atmosphere)^((gam-1)/gam))*(2/(gam-1)));
t_exit = bottle_temp * (1 + ((gam-1)/2) * Mach^2);
density_exit = p_atmosphere / (gas_const * t_exit);
vel_exit = Mach * sqrt(gam * gas_const * t_exit);
end
dmair = -discharge_coeff * density_exit * area_throat * vel_exit;
dmrocket = dmair;
T = -dmair * vel_exit + (p_exit - p_atmosphere) * area_throat;
dvolume = 0; %for each non-water propellant phase, there should be no change in volume
% Ballistic Phase
else
dmrocket = 0;
dmair = 0;
T = 0;
dvolume = 0;
end
end
D = (0.5 * air_density * (velocity^2)) * drag_coeff * area_bottle;
dvel = (T - D - (m_rocket * g * sin(theta)))/m_rocket;
if velocity <= test_stand %rocket has not left the test stand
dtheta = 0;
else
dtheta = (-g * cos(theta)) / velocity;
end
dx = velocity * cos(theta);
dz = velocity * sin(theta);
Thrust_vector = [Thrust_vector; T];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
time_values(1,1) = dvolume; %volume integral
time_values(2,1) = dmrocket; %mass integral
time_values(3,1) = dmair; %air integral
time_values(4,1) = dvel;
time_values(5,1) = dtheta;
time_values(6,1) = dx;
time_values(7,1) = dz;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
谢谢!