ode45中出现意外行为

时间:2018-11-27 02:35:22

标签: matlab ode45

我正在尝试使用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

谢谢!

0 个答案:

没有答案