Project

1D supersonic nozzle flow simulation using macormack method

Matlab code for solving 1D supersonic nozzle flow using macormack method:

clear all 
close all
clc

% grid space
n=31;
x=linspace(0,3,n);
dx=x(2)-x(1);
gamma = 1.4;


%function for non conserved form
tic
[rho,T,v,A,M,P,m,rho_th,T_th,P_th,M_th,rho_res,T_res,v_res,k_n] = supersonic_non_conserved(n,x,dx,gamma);
time_for_non_conservative_solver = toc
%number of cycles for convergence
c_1 = k_n

hold on

%function for conservative form
tic
[rho_c,T_c,v_c,A_c,M_c,P_c,m_c,rho_th_c,T_th_c,P_th_c,M_th_c,rho_res_c,T_res_c,v_res_c,k_c] = supersonic_conserved(n,x,dx,gamma);
time_for_conservative_solver = toc
%number of cycles for convergence
c_2 = k_c


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%--------------------plots for non conservative form----------------------%
%steady state plot
figure(3)
title(\'steady state plot\')
subplot(4,1,1)
plot(x,M,\'linewidth\',1)
xlabel(\'x/Xo\')
ylabel(\'mach number\')
subplot(4,1,2)
plot(x,P,\'k\',\'linewidth\',1)
xlabel(\'x/Xo\')
ylabel(\'pressure ratio\')
subplot(4,1,3)
plot(x,rho,\'r\',\'linewidth\',1)
xlabel(\'x/Xo\')
ylabel(\'density\')
subplot(4,1,4)
plot(x,T,\'g\',\'linewidth\',1)
xlabel(\'x/Xo\')
ylabel(\'temperature\')



%varibles at throat
figure(4)
title(\'variables at throat section\')
subplot(4,1,1)
plot(rho_th,\'b\',\'linewidth\',1)
ylabel(\'rho\')
subplot(4,1,2)
plot(T_th,\'k\',\'linewidth\',1)
ylabel(\'temp\')
subplot(4,1,3)
plot(P_th,\'c\',\'linewidth\',1)
ylabel(\'P\')
subplot(4,1,4)
plot(M_th,\'r\',\'linewidth\',1)
xlabel(\'number of time steps\')
ylabel(\'mach\')

%residual values
figure(5)
plot(rho_res,\'b\',\'linewidth\',1)
hold on
plot(v_res,\'r\',\'linewidth\',1)
hold on
plot(T_res,\'--k\',\'linewidth\',1)
xlabel(\'number of time steps\')
ylabel(\'residual\')
legend(\'density\',\'velocity\',\'temperature\')
%-------------------------------------------------------------------------%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%---------------plots for conservative form-------------------------------%
%steady state plot
figure(6)
title(\'steady state plot\')
subplot(4,1,1)
plot(x,M_c,\'linewidth\',1)
xlabel(\'x/Xo\')
ylabel(\'mach number\')
subplot(4,1,2)
plot(x,P_c,\'k\',\'linewidth\',1)
xlabel(\'x/Xo\')
ylabel(\'pressure ratio\')
subplot(4,1,3)
plot(x,rho_c,\'r\',\'linewidth\',1)
xlabel(\'x/Xo\')
ylabel(\'density\')
subplot(4,1,4)
plot(x,T_c,\'g\',\'linewidth\',1)
xlabel(\'x/Xo\')
ylabel(\'temperature\')


%varibles at throat
figure(7)
title(\'variables at throat section\')
subplot(4,1,1)
plot(rho_th_c,\'b\',\'linewidth\',1)
ylabel(\'rho\')
subplot(4,1,2)
plot(T_th_c,\'k\',\'linewidth\',1)
ylabel(\'temp\')
subplot(4,1,3)
plot(P_th_c,\'c\',\'linewidth\',1)
ylabel(\'P\')
subplot(4,1,4)
plot(M_th_c,\'r\',\'linewidth\',1)
xlabel(\'number of time steps\')
ylabel(\'mach\')

%residual values
figure(8)
plot(rho_res_c,\'b\',\'linewidth\',1)
hold on
plot(v_res_c,\'r\',\'linewidth\',1)
hold on
plot(T_res_c,\'--k\',\'linewidth\',1)
xlabel(\'number of time steps\')
ylabel(\'residual\')
legend(\'density\',\'velocity\',\'temperature\')
%-------------------------------------------------------------------------%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%comparing  mass flow rate 
%non conservative
figure(9)
plot(x,m,\'r\',\'linewidth\',1.5)
hold on
%conservative form
plot(x,m_c,\'k\',\'linewidth\',1.5)
xlabel(\'axial length of nozzle\')
ylabel(\'mass flow\')
legend(\'non conservative\',\'conservative\')

Matlab function for solving non-conservative form:

function [rho,T,v,A,M,P,m,rho_th,T_th,P_th,M_th,rho_res,T_res,v_res,k_n] = supersonic_non_conserved(n,x,dx,gamma)

% grid space
n=31;
x=linspace(0,3,n);
dx=x(2)-x(1);

% initial values
rho = 1-0.3146*x; % density
T = 1-0.2314*x; % temperature
v = (0.1+1.09*x).*((T).^0.5); % velocity
A = 1+(2.2*((x-1.5).^2)); % area
gamma = 1.4;
throat_A = find(A==1);

%defining cfl and time derivative
c=0.5;  % CFL number
tst = (c*dx)./(sqrt(T)+v);
dt_nc = min(tst);


%time loop
nt_nc = 1400;
error_1 = 9e9;
tol = 1e-9;

k_n =0;

while error_1>tol
    
   k_n=k_n+1;
   


  % copy of initial values
  rho_old = rho;
  v_old = v;
  T_old = T;
  M_old = v./sqrt(T);
  m_old = rho_old.*v_old.*A;
  P_old = rho.*T;
  

  
  % prdictor step
  for j=2:n-1
    dvdx = (v(j+1)-v(j))/dx;
    drhodx = (rho(j+1)-rho(j))/dx;
    dlnAdx = (log(A(j+1))-log(A(j)))/dx;
    dTdx = (T(j+1)-T(j))/dx;
    
    %continuity eqn
    drhodt_p(j) = -rho(j)*dvdx -rho(j)*v(j)*dlnAdx -v(j)*drhodx;
    
    %momentum eqn
    dvdt_p(j) = -v(j)*dvdx -(1/gamma)*(dTdx+(T(j)/rho(j))*drhodx);
    
    %energy eqn
    dTdt_p(j) = -v(j)*dTdx -(gamma-1)*T(j)*(dvdx+v(j)*dlnAdx);
    
    % solution update
    rho(j) = rho(j)+(drhodt_p(j))*dt_nc;
    v(j) = v(j)+(dvdt_p(j))*dt_nc;
    T(j) = T(j)+(dTdt_p(j))*dt_nc;
    
  end
  
  %corrector step
  for j =2:n-1
    dvdx = (v(j)-v(j-1))/dx;
    drhodx = (rho(j)-rho(j-1))/dx;
    dlnAdx = (log(A(j))-log(A(j-1)))/dx;
    dTdx = (T(j)-T(j-1))/dx;
    
    %continuity eqn
    drhodt_c(j) =  -rho(j)*dvdx -rho(j)*v(j)*dlnAdx -v(j)*drhodx;
    
    %momentum eqn
    dvdt_c(j) = -v(j)*dvdx -(1/gamma)*(dTdx+(T(j)/rho(j))*drhodx);
    
    %energy eqn
    dTdt_c(j) = -v(j)*dTdx -(gamma-1)*T(j)*(dvdx+v(j)*dlnAdx);
  end
  
  %average values
  drhodt_avg = 0.5*(drhodt_p+drhodt_c);
  dvdt_avg = 0.5*(dvdt_p+dvdt_c);
  dTdt_avg = 0.5*(dTdt_p+dTdt_c);
  
  %final corrected values
  for i= 2:n-1
    rho(i) = rho_old(i)+(drhodt_avg(i))*dt_nc;
    v(i) = v_old(i)+(dvdt_avg(i))*dt_nc;
    T(i) = T_old(i)+(dTdt_avg(i))*dt_nc;
  end
  
  % boundary condition
  
  %inlet
  v(1) = 2*v(2) -v(3);
  rho(1)=1;
  T(1)=1;
  
  %outlet
  v(n) = 2*v(n-1)-v(n-2);
  rho(n) = 2*rho(n-1)-rho(n-2);
  T(n) = 2*T(n-1)-T(n-2);
 
  %mach number 
  M = v./sqrt(T);
  %non dimensional pressure
  P = rho.*T;
  %mass flow 
  m = rho.*v.*A;
  
  % variables at throat
  rho_th(k_n) = rho(throat_A);
  T_th(k_n) = T(throat_A);
  P_th(k_n) = P(throat_A);
  M_th(k_n) = M(throat_A);
  
  %residual values
  rho_res(k_n) = drhodt_avg(throat_A);
  v_res(k_n) = dvdt_avg(throat_A);
  T_res(k_n) = dTdt_avg(throat_A);
  
  %error of mass flow
  error_1 = max(abs(m-m_old));
  
  %mass flow at different time step
  figure(1)
  hold on
  grid on
  if k_n==1
      plot(x,m,\'b\',\'linewidth\',1)
  else if k_n==50
          plot(x,m,\'c\',\'linewidth\',1)
      else if k_n==100
              plot(x,m,\'k\',\'linewidth\',1)
          else if k_n==150
                  plot(x,m,\'g\',\'linewidth\',1)
              else if k_n==200
                      plot(x,m,\'y\',\'linewidth\',1)
                  else if k_n==700
                          plot(x,m,\'r\',\'linewidth\',1)
                          hold on 
                          xlabel(\'x/Xo\')
                          ylabel(\'mass flow rate\')
                          legend(\'dt=0\',\'dt=50\',\'dt=100\',\'dt=150\',\'dt=200\',\'dt=700\')
                          title(\'mass flow through nozzle at different time step\')
                      end
                  end
              end
          end
      end
  end

  
end



end

Matlab function for solving conservative form:

function  [rho_c,T_c,v_c,A_c,M_c,P_c,m_c,rho_th_c,T_th_c,P_th_c,M_th_c,rho_res_c,T_res_c,v_res_c,k_c] = supersonic_conserved(n,x,dx,gamma)

% grid space
n=31;
x=linspace(0,3,n);
dx=x(2)-x(1);
gamma = 1.4;

%initial condition 

% density and temperature
for i=1:n
    
    
    if (x(i)>=0 & x(i)<=0.5 )
        rho_c(i) = 1;
        T_c(i) = 1;
    else if( x(i)>=0.5 & x(i)<=1.5)
            rho_c(i) = 1-((0.366)*(x(i)-0.5));
            T_c(i) = 1-((0.167)*(x(i)-0.5));
        else if (x(i)>=1.5 & x(i)<=3.5)
                rho_c(i) = 0.634-((0.3879)*(x(i)-1.5));
                T_c(i) = 0.833-((0.3507)*(x(i)-1.5));
            end
        end
    end
    
  
    
end

% area
A_c = 1+(2.2*((x-1.5).^2));
%nozzle throat section
throat_c = find(A_c==1);
% initial velocity
v_c = (0.59)./(rho_c.*A_c);

% initial values of u1 u2 u3
u1 = rho_c.*A_c;
u2 = rho_c.*A_c.*v_c;
u3 = rho_c.*((T_c/(gamma-1))+((gamma/2)*((v_c).^2))).*A_c;

% time step calculation
c = 0.5; %CFL number
%tsp = (c*dx)./(sqrt(T_c)+v_c);
%dt = min(tsp);

% time loop
nt =1400;
error = 9e9;
tol = 1e-9;

k_c = 0;

while error>tol
    k_c=k_c+1;
    m_c_old = rho_c.*v_c.*A_c;
    
%for k=1:nt
    
    u1_old = u1 ;
    u2_old = u2 ;
    u3_old = u3 ;
    
    tsp = (c*dx)./(sqrt(T_c)+v_c);
    dt = min(tsp);
    
    f1 = u2;
    term1 = (((gamma-1)/gamma).*(u3-((gamma/2).*(((u2).^2)./u1))));
    f2 = ((u2.^2)./u1)+ term1;
    f3 = (gamma.*(u2.*u3./u1))-((gamma.*(gamma-1)/2).*(((u2).^3)./((u1).^2)));
    
    
    %predictor step 
    for i=2:n-1
        
        df1dx(i) = ((f1(i+1))-(f1(i)))/dx;
        df2dx(i) = ((f2(i+1))-(f2(i)))/dx;
        df3dx(i) = ((f3(i+1))-(f3(i)))/dx;
        dAdx(i) = ((A_c(i+1))-(A_c(i)))/dx; 
        j2(i) = ((1/gamma)*rho_c(i)*T_c(i)*dAdx(i));
        
        %continuity eqn 
        du1dt_p(i) = (-df1dx(i));
        %momentum eqn
        du2dt_p(i) = (-df2dx(i))+j2(i);
        %energy eqn
        du3dt_p(i) = (-df3dx(i));
        
        %solutioin update 
        u1(i) = u1(i)+(du1dt_p(i)*dt);
        u2(i) = u2(i)+(du2dt_p(i)*dt);
        u3(i) = u3(i)+(du3dt_p(i)*dt);
    end
    
    %updating premitive variables
    rho_c = u1./A_c;
    v_c = u2./u1;
    T_c = (gamma-1)*((u3./u1)-((gamma/2)*((v_c).^2)));
    %P_c = rho_c.*T_c;
    
    %predicted flux values
    f1 = u2;
    term1 = (((gamma-1)/gamma).*(u3-((gamma/2).*(((u2).^2)./u1))));
    f2 = ((u2.^2)./u1)+ term1;
    f3 = (gamma.*(u2.*u3./u1))-((gamma.*(gamma-1)/2).*(((u2).^3)./((u1).^2)));
    
    %corrector step
    for j=2:n-1
        
        df1dx(j) = (f1(j)-f1(j-1))/dx;
        df2dx(j) = (f2(j)-f2(j-1))/dx;
        df3dx(j) = (f3(j)-f3(j-1))/dx;
        dAdx(j) = (A_c(j)-A_c(j-1))/dx; 
        j2(j) = (1/gamma)*rho_c(j)*T_c(j)*dAdx(j);
                     
        %continuity eqn 
        du1dt_c(j) = -df1dx(j);
        %momentum eqn
        du2dt_c(j) = -df2dx(j)+j2(j);
        %energy eqn
        du3dt_c(j) = -df3dx(j);
    end
    
    %average time derivatives
    du1dt_avg = 0.5*(du1dt_p+du1dt_c);
    du2dt_avg = 0.5*(du2dt_p+du2dt_c);
    du3dt_avg = 0.5*(du3dt_p+du3dt_c);
    
    %final corrected values
    for j=2:n-1
        u1(j) = u1_old(j)+(du1dt_avg(j))*dt;
        u2(j) = u2_old(j)+(du2dt_avg(j))*dt;
        u3(j) = u3_old(j)+(du3dt_avg(j))*dt;
    end
    
    %boundary conditions
    
    %inlet
    rho_c(1) = 1;
    T_c(1) = 1;
    u1(1) = rho_c(1)*A_c(1);
    u2(1) = 2*u2(2)-u2(3);
    v_c(1) = u2(1)/u1(1);
    u3(1) = u1(1)*((T_c(1)/(gamma-1))+((gamma/2)*(v_c(1)^2)));
    P_c(1) = rho_c(1)*T_c(1);
    %inlet fluxes
    f1(1) = u2(1);
    f2(1) = (((u2(1)).^2)./u1(1))+((gamma-1/gamma)*(u3(1)-((gamma*(u2(1)).^2)./(2*u1(1)))));
    f3(1) = (gamma*(u2(1).*u3(1)./u1(1)))-((gamma*(gamma-1)/2)*(((u2(1)).^3)./((u1(1)).^2)));
    
    %outlet
    u1(n) = 2*u1(n-1)-u1(n-2);
    u2(n) = 2*u2(n-1)-u2(n-2);
    u3(n) = 2*u3(n-1)-u3(n-2);
    %fluxes at outlet
    f1(n) = u2(n);
    f2(n) = (((u2(n))^2)/u1(n))+((gamma-1/gamma)*(u3(n)-((gamma*(u2(n))^2)/(2*u1(n)))));
    f3(n) = (gamma*(u2(n)*u3(n)/u1(n)))-((gamma*(gamma-1)/2)*(((u2(n))^3)/((u1(n))^2)));
    %premitive variables
    rho_c(n) = u1(n)/A_c(n);
    v_c(n) = u2(n)/u1(n);
    T_c(n) = (gamma-1)*((u3(n)/u1(n))-((gamma/2)*((v_c(n))^2)));
    P_c(n) = rho_c(n)*T_c(n);
    
    %mach number 
    M_c = v_c./sqrt(T_c);
    %non dimensional pressure
    P_c = rho_c.*T_c;
    %mass flow 
    m_c = rho_c.*v_c.*A_c;
    
    % variables at throat
    rho_th_c(k_c) = rho_c(throat_c);
    T_th_c(k_c) = T_c(throat_c);
    P_th_c(k_c) = P_c(throat_c);
    M_th_c(k_c) = M_c(throat_c);
    
    %residual at throat
    rho_res_c(k_c) = du1dt_avg(throat_c);
    v_res_c(k_c) = du2dt_avg(throat_c);
    T_res_c(k_c) = du3dt_avg(throat_c);    
 
    
    %error of mass flow
    error = max(abs(m_c-m_c_old));
    
    %mass flow at different time step
    figure(2)
    hold on
    grid on
    if k_c==1
        plot(x,m_c,\'b\',\'linewidth\',1)
        hold on
    else if k_c==100
            plot(x,m_c,\'k\',\'linewidth\',1)
            hold on
        else if k_c==200
                plot(x,m_c,\'y\',\'linewidth\',1)
                hold on
            else if k_c==700
                    plot(x,m_c,\'r\',\'linewidth\',1)
                    hold on 
                    xlabel(\'x/Xo\')
                    ylabel(\'mass flow rate\')
                    legend(\'dt=0\',\'dt=100\',\'dt=200\',\'dt=700\')
                    title(\'mass flow through nozzle at different time step\')
                end
            end
        end
    end

     
     
end



end

In the above program, the function for solving 1D supersonic nozzle flow in non-conservative form and conservative form is written which calculates the premitive variables at different time step and the variation of premitive variables at throat section of the nozzle is observed through the plots and also mass flow at different time step through out the nozzle is observed in the plots.

Number of cycles required for convergence and Time required for solving:

Time take by non-conservative solver = 10.2613s

number of time steps for convergence by non-conservative solver = 1574 time steps

Time taken by conservative solver = 5.5192s

number of time steps for convergence by conservative solver = 2002 time steps

Non-conservative form plots :-

1) steady state profile of non-conservative form

we can observe from the above plot that the variation of density, pressure, temperature and mach number through out the non-dimensional distance of the supersonic nozzle is similar to the analytical solution from the J.D.Anderson book. The mach number increases at the exit of the nozzle, the pressure drops at the exit of the nozzle, the density is high at inlet of the nozzle and drops at exit of nozzle, the temperature also drops at exit of the nozzle.

2) mass flow variation at different time step

The mass flow variation at different time as a function of non-dimensional distance of the nozzle is plotted above. We can see that the mass flow through nozzle at dt=0 is changing largely is not close to the exact solution. The same large variation of mass flow through the nozzle is observed for dt=50, dt=100 and dt=150. But we can observe that the mass flow variation is small and at dt=700 the mass flow does not vary through the nozzle and is constant.

3) Variation with respect to time step at nozzle throat

The variation of density, pressure, temperature and mach number at the throat section of the nozzle is plotted with respect to time step. We can observe that the variation of variables is large at the small time steps and the variation decreases at large time steps and finaly reaches steady state condition.

4) Residual variation with respect to time step

The avereage time derivative is plotted as a function of time steps which is known as residual values. We can see that values of density,temperature and velocity is initialy high and it oscilates upto time step=600 and then reaches steady state and is constant.

Conservative form plots:-

1) steady state profile

The steady state profile of conservative solver and non-conservative solver is similar and it is almost same as the profile given in J.D.Anderson text book.

2) Mass flow variation at different time step

The mass flow variation is large at dt=0 and dt=100 and the variation reduces at dt=200 and finaly the mass flow variation is constant at dt=700.

3) Variation with respect to time steps at nozzle throat

we can see that the variation of density, temperature, pressure and mach number at throat section of the nozzle is fluctuating at initial time steps and after 600 time steps the fluctuation reduces and the values are almost constant.

4) Residual variation with respect to time

The average derivative of density, temperature and velocity are plotted against time steps. We can observe from the plot that the values of variables are high at starting time steps and gradualy the becomes constant at larger time step. When compared to non-conservative form the residuals from conservative form are higher and becomes zero as time step increases.

Mass flow through the nozzle in conservative solver and non-conservative solver:-

The mass flow across the non-dimensional distnace of the nozzle is plotted in above plot. As from the plot we can say that the conservative form solver conserves the mass flow and the non-conservative form does not conserve as the name implies. In non-conservative form solver the mass flow variation across the nozzle is large and in conservative form solver the mass flow variation across the nozzle is small and it is almost close to exact solution.

Conclution:

From the output obtained we can conclude that the conservative form solver takes less time to solve the code with time = 10.26 and the non-conservative form solver takes alittle more time to solve the code withtime = 5.59 and thus the conservative is the fastest solver.

The conservative form solver being the faster solver has more calculation effort than non-conservative form. The residuals from conservative form solver is higher when compared to the non-conservative form. Thus, both conservative and non-conservative solver has its own advantages and disdvantages.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.