Project

Simulation of 1 Dimensional super-sonic nozzle flow

Objective

To write a code to solve the 1D supersonic nozzle flow equations using MacCormack method.

Problem Definition

The above image shows the different sections of the convergent divergent nozzle. The fluid flow is considered to be at steady state and Isentropic.

Governing Equations

The governing equations are solved in both conservative and Non-conservative form.

Non-conservative form

Mass conservation

`(delrho^')/(delt^')=-rho^'*(delv^')/(delx^')-rho^'*v^'*(dellnA')/(delx^')-v^'*(delrho^')/(delx^')`

Momentum conservation

`(delv^')/(delt^')=-v^'*(delv^')/(delx^')-1/gamma*((delT^')/(delx^')+T^'/rho^'*(delrho^')/(delx^'))`

Energy conservation

`(delT^')/(delt^')=-v^'*(delT^')/(delx^')-(gamma-1)*T^'((delv^')/(delx^')+v^'*(dellnA^')/(delx^'))`

Conservative form

Mass conservation

`(del(rho^'A^'))/(delt^')+(del(rho^'A^'v^'))/(delx^')=0`

Momentum conservation

`(del(rho^'A^'v^'))/(delt^')+(del[rho^'A^'v^('^2)+1/gamma*p^'A^'])/(delx^')=1/gamma*p^'*(delA^')/(delx^')`

Energy conservation

`(del[rho^'(e^'/(gamma-1)+gamma/2*v^('^2))*A^'])/(delt^')+(del[rho^'*(e^'/(gamma-1)+gamma/2*v^('^2))*v^'*A^'+p^'*A^'*v^'])/(delx^')=0`

solution vectors are defined as:

`u1=rho^'*A^', u2=rho^'*A^'*v^', u3=rho^'((T^')/(gamma-1)+gamma/2v^('^2))A^'`

Flux vectors are defines as:

`f1=u2`

`f2=(u2^2)/(u1)+1/gammau1(gamma-1)[(u3)/(u1)-gamma/2((u2)/(u1))^2]`

`f3=gamma(u2u3)/(u1)-(gamma(gamma-1))/2(u2^3)/(u1^2)`

The source term is defined by:

`j2=1/gammarho^'T^'(delA)/(delx)`

All the above equations are in dimensionless form.

MATLAB PROGRAM

Main program

% Quasi 1-D NOZZLE flow
clear all
close all
clc

% inputs
L=3; % length of the nozzle
n=31; % number of grid points
c=0.5; % Courant number
throat=(n-1)/2;
x=linspace(0,L,n); % Creating 1D grid
dx=x(2)-x(1); % grid space
gamma=1.4; % specific heat ratio
A=1+2.2*(x-1.5).^2; % Nozzle cross sectional area(function of x)
tic
nt=1400; % Number of time steps (Non-conservative form)
% Calling the function (Non-conservative form)
[rho,v,T,mach,mf,p]=non_conserv(x,dx,A,nt,gamma,c,n,throat);
sim_t_nc=toc;
tic
nt=550; % Number of time steps (Conservative form)
% Calling the function (Conservative form)
[rho2,v2,T2,mach_c,m_c,p_c]=conserv(A,x,nt,n,gamma,c,dx,throat);
sim_t_c=toc;

% Mass flow rate comparison between conservative and Non-conservative forms

figure(7)
plot(x,mf,'linewidth',2)
hold on
plot(x,m_c,'linewidth',2)
hold on
line([0 3],[0.579 0.579],'linewidth',2)
title('Mass flow rate comparison')
xlabel('Distance along Nozzle (Non-Dimensional)');
ylabel('Mass flow rate-(Non-Dimensional)');
legend('Non-conservative','conservative','exact solution')

Non-Conservative form

1) Predictor step

function [d_rho_dt_p,d_v_dt_p,d_T_dt_p]=pred(rho,v,T,n,A,gamma,dx)
d_rho_dt_p=ones(1,31);
d_v_dt_p=ones(1,31);
d_T_dt_p=ones(1,31);
% Pre-allocating the array size
a=ones(1,31);
b=ones(1,31);
c=ones(1,31);
d=ones(1,31);
for i=2:n-1
    a(i)=(v(i+1)-v(i))/dx;
    b(i)=(log(A(i+1))-log(A(i)))/dx;
    c(i)=(rho(i+1)-rho(i))/dx;
    d(i)=(T(i+1)-T(i))/dx;
    
    d_rho_dt_p(i)=-rho(i)*a(i)-rho(i)*v(i)*b(i)-v(i)*c(i); 
    d_v_dt_p(i)=-v(i)*a(i)-(1/gamma)*(d(i)+(T(i)/rho(i))*c(i));
    d_T_dt_p(i)=-v(i)*d(i)-(gamma-1)*T(i)*(a(i)+v(i)*b(i));
end

2) Corrector step

function [drho_dt_c,dv_dt_c,dT_dt_c]=corr(rho,v,T,n,A,gamma,dx)
drho_dt_c=ones(1,31);
dv_dt_c=ones(1,31);
dT_dt_c=ones(1,31);
% Pre-allocating the array size
a=ones(1,31);
b=ones(1,31);
c=ones(1,31);
d=ones(1,31);
for i=2:n-1
    a(i)=(v(i)-v(i-1))/dx;
    b(i)=(log(A(i))-log(A(i-1)))/dx;
    c(i)=(rho(i)-rho(i-1))/dx;
    d(i)=(T(i)-T(i-1))/dx;
    
    drho_dt_c(i)=-rho(i)*a(i)-rho(i)*v(i)*b(i)-v(i)*c(i); 
    dv_dt_c(i)=-v(i)*a(i)-(1/gamma)*(d(i)+(T(i)/rho(i))*c(i));
    dT_dt_c(i)=-v(i)*d(i)-(gamma-1)*T(i)*(a(i)+v(i)*b(i));
end

3) Solving Non-Conservative equations

function[rho,v,T,mach,mf,p]=non_conserv(x,dx,A,nt,gamma,c,n,throat)
% Initial conditions
rho=1-(0.3146*x);
T=1-(0.2314*x);
v=(0.1+1.09*x).*T.^0.5;
% Pre-allocating the array size
p_throat=ones(1,nt);
rho_throat=ones(1,nt);
temp_throat=ones(1,nt);
mach_throat=ones(1,nt);
X=linspace(1,nt,nt);

% Iteration loop
for k=1:nt
    
  % updating previous time_step values
  rho_old=rho;
  T_old=T;
  v_old=v; 
  % time step calculation
  sl=(sqrt(T)); % local velocity of sound
  dt=c.*(dx./((sl)+v));
  dt=min(dt);
  
  % function for predictor step
  [drho_dt_p,dv_dt_p,dT_dt_p]=pred(rho,v,T,n,A,gamma,dx);
  for i=2:n-1
      % next time step values
      rho(i)=rho(i)+drho_dt_p(i)*dt; 
      v(i)=v(i)+dv_dt_p(i)*dt;
      T(i)=T(i)+dT_dt_p(i)*dt;
  end
  % function for corrector step
  [drho_dt_c,dv_dt_c,dT_dt_c]=corr(rho,v,T,n,A,gamma,dx);
  
  % computing average values
  d_rho_dt=0.5.*(drho_dt_p+drho_dt_c);
  d_v_dt=0.5.*(dv_dt_p+dv_dt_c);
  d_T_dt=0.5.*(dT_dt_p+dT_dt_c);
  
  % Updating next time step values
  for j=2:n-1
      rho(j)=rho_old(j)+d_rho_dt(j)*dt;
      v(j)=v_old(j)+d_v_dt(j)*dt;
      T(j)=T_old(j)+d_T_dt(j)*dt;
  end
  
% Boundary conditions (inlet)
v(1)=2*v(2)-v(3);
% Boundary conditions (exit)
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);

% Calculating state variables
mf=rho.*A.*v;
mach=v./(sqrt(T));
p=rho.*T;

% Calculating throat values
p_throat(k)=p(throat);
rho_throat(k)=rho(throat);
temp_throat(k)=T(throat);
mach_throat(k)=mach(throat);

figure(1)
if k==50
    plot(x,mf,'color','r','linewidth',2)
    hold on
elseif k==100
    plot(x,mf,'color','g','linewidth',2)
    hold on
elseif k==150
    plot(x,mf,'color','b','linewidth',2)
    hold on
elseif k==200
    plot(x,mf,'color','bla','linewidth',2)
    hold on
elseif k==700
    plot(x,mf,'color','m','linewidth',2)
    hold on
elseif k==1400
    plot(x,mf,'y--o','linewidth',2)
    legend('50-dt','100-dt','150-dt','200-dt','700-dt','1400-dt')
xlabel('Distance along Nozzle (Non-Dimensional)');
ylabel('Mass flow rate-(Non-Dimensional)')
title('Non-conservative form - Mass flow rate at different time steps')
    hold on
end

end
figure(2)
subplot(2,1,1)
plot(X,rho_throat)
title('Non-conservative form - variation of density and temperature with time-steps at nozzle throat')
xlabel('No of time steps')
ylabel('Density')
subplot(2,1,2)
plot(X,temp_throat)
xlabel('No of time steps')
ylabel('Temperature')

figure(3)
subplot(2,1,1)
plot(X,p_throat)
title('Non-conservative form - variation of pressure and Mach number with time-steps at nozzle throat')
xlabel('No of time steps')
ylabel('Pressure')
subplot(2,1,2)
plot(X,mach_throat)
xlabel('No of time steps')
ylabel('Mach Number')

end

Conservative form

1) Forward Difference

function f1=fd_dx(f,dx,i)
% This function calculates the forward difference for a given function 
f1=(f(i+1)-f(i))/dx;
end

2) Backward Difference

function f1=rd_dx(f,dx,i)
% This function calculates the rearward difference for a given function 
f1=(f(i)-f(i-1))/dx;
end

3) Solving Conservative equations

function [rho,v,T,mach_c,m_c,p_c]=conserv(A,x,nt,n,gamma,c,dx,throat)
% Pre-allocating the array size 
rho=ones(1,n);
T=ones(1,n);

% Pre-allocating the array size
p_throat=ones(1,nt);
rho_throat=ones(1,nt);
temp_throat=ones(1,nt);
mach_throat=ones(1,nt);
X=linspace(1,nt,nt);

% Initial conditions
for i=1:n
    if x(i)>=0&&x(i)<=0.5
        rho(i)=1;
        T(i)=1;
    elseif x(i)>=0.5&&x(i)<=1.5
        rho(i)=1-0.366*(x(i)-0.5);
        T(i)=1-0.167*(x(i)-0.5);
    elseif  x(i)>=1.5&&x(i)<=3.5
        rho(i)=0.634-0.3879*(x(i)-1.5);
        T(i)=0.833-0.3507*(x(i)-1.5);     
    end
end
% Defining velocity 
v=0.59./(rho.*A);


% Defining Solution vector
 u1=rho.*A;
 u2=rho.*A.*v;
 u3=rho.*A.*(T/(gamma-1)+gamma/2*v.^2);
 
 % Iteration loop 
 for k=1:nt
    
% previous time step update
    u1_old=u1;
    u2_old=u2;
    u3_old=u3;
    
% time step calculation
  dt=min(c*dx./(sqrt(T)+v));
  
% Flux vectors 
 f1=u2;
 f2=(u2.^2./u1)+((gamma-1)/gamma)*(u3-(gamma*u2.^2)./(2*u1));
 f3=(gamma*u2.*u3./u1)-(gamma*(gamma-1)/2)*(u2.^3./u1.^2);

    % Pre-allocating the array size
    du1_dt_p=ones(1,n);
    du2_dt_p=ones(1,n);
    du3_dt_p=ones(1,n);
    j2=ones(1,n);
    
% PREDICTOR STEP
    for i=2:n-1
        j2(i)=1/gamma*rho(i).*T(i)*fd_dx(A,dx,i);
        du1_dt_p(i)=-fd_dx(f1,dx,i);
        du2_dt_p(i)=-fd_dx(f2,dx,i)+j2(i);
        du3_dt_p(i)=-fd_dx(f3,dx,i);
        
        % solution update
      u1(i)=u1(i)+du1_dt_p(i)*dt;  
      u2(i)=u2(i)+du2_dt_p(i)*dt; 
      u3(i)=u3(i)+du3_dt_p(i)*dt; 
    end
     
    du1_dt_c=ones(1,n);
    du2_dt_c=ones(1,n);
    du3_dt_c=ones(1,n);
    
    % updating primitive variables and flux vectors
    rho=u1./A;
    T=(gamma-1)*(u3./u1-(gamma/2)*(u2./u1).^2);
    f1=u2;
    f2=(u2.^2./u1)+((gamma-1)/gamma)*(u3-(gamma*u2.^2)./(2*u1));
    f3=(gamma*u2.*u3./u1)-(gamma*(gamma-1)/2)*(u2.^3./u1.^2);
    
  % CORRECTOR STEP
    for j=2:n-1
        j2(j)=1/gamma*rho(j).*T(j)*rd_dx(A,dx,j);
        du1_dt_c(j)=-rd_dx(f1,dx,j);
        du2_dt_c(j)=-rd_dx(f2,dx,j)+j2(j);
        du3_dt_c(j)=-rd_dx(f3,dx,j);
    end
    
    % COMPUTING AVERAGE
    du1_dt=0.5*(du1_dt_p+du1_dt_c);
    du2_dt=0.5*(du2_dt_p+du2_dt_c);
    du3_dt=0.5*(du3_dt_p+du3_dt_c);
    
    % COMPUTING FINAL VALUES
    for l=2:n-1
        u1(l)=u1_old(l)+du1_dt(l)*dt;
        u2(l)=u2_old(l)+du2_dt(l)*dt;
        u3(l)=u3_old(l)+du3_dt(l)*dt;
    end

% INLET BOUNDARY CONDITIONS
u2(1)=2*u2(2)-u2(3);

% OUTLET BOUNDARY CONDITION
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);

% Final update of variables
 rho=u1./A;
 v=u2./u1;
 T=(gamma-1)*(u3./u1-(gamma/2)*(u2./u1).^2);

% Calculating non-dimensional physical quantities
mach_c=v./sqrt(T);
m_c=rho.*A.*v;
p_c=rho.*T;

% Calculating throat values
p_throat(k)=p_c(throat);
rho_throat(k)=rho(throat);
temp_throat(k)=T(throat);
mach_throat(k)=mach_c(throat);

figure(4)
if k==50
    plot(x,m_c,'color','r','linewidth',2)
    hold on
elseif k==100
    plot(x,m_c,'color','g','linewidth',2)
    hold on
elseif k==150
    plot(x,m_c,'color','b','linewidth',2)
    hold on
elseif k==200
    plot(x,m_c,'color','bla','linewidth',2)
    hold on
elseif k==500
    plot(x,m_c,'color','m','linewidth',2)
    hold on
elseif k==550
    plot(x,m_c,'y--o','linewidth',2)
    legend('50-dt','100-dt','150-dt','200-dt','500-dt','600-dt')
    xlabel('Distance along Nozzle (Non-Dimensional)');
    ylabel('Mass flow rate-(Non-Dimensional)')
    title('conservative form - Mass flow rate at different time steps')
    hold on
end

end
figure(5)
subplot(2,1,1)
plot(X,rho_throat)
title('conservative form - variation of density and temperature with time-steps at nozzle throat')
xlabel('No of time steps')
ylabel('Density')
subplot(2,1,2)
plot(X,temp_throat)
xlabel('No of time steps')
ylabel('Temperature')

figure(6)
subplot(2,1,1)
plot(X,p_throat)
title('conservative form - variation of pressure and Mach number with time-steps at nozzle throat')
xlabel('No of time steps')
ylabel('Pressure')
subplot(2,1,2)
plot(X,mach_throat)
xlabel('No of time steps')
ylabel('Mach Number')

end

Results

Minimum number of cycles for Convergence- (No of grid points=31)

The Non-conservative form takes more number of cycles for Convergence compared to Conservative form.

Mass Flow rate comparison between Conservative and Non-Conservative form (Grid points=31)

The Non-Conservative form has so many fluctuations compared to Conservative form in matching the exact solution.

Solution time

The time taken for calculation is the number of cycles to converge

31 Grid points

Solution time for conservative form is 0.572 sec

Solution time for Non-conservative form is 0.596 sec

61 Grid points

Solution time for conservative form is 1.100 sec

Solution time for Non-conservative form is 1.594 sec



The conservative form takes comparatively less number of cycles to converge but contains a lot of calculations while the Non-conservative form takes more number of cycles to converge but contains less calculations. However it depends on the code efficiency which depends on the structure of the code.

Grid dependence study

The fluctuations are less in the solution when the number of grid points is increased as seen in the above image.

Inference

The Conservative form of governing equations yield results closer to the exact solution compared to the Non-Conservative form of governing equations. A lot of fluctuations are also seen close to the inlet and outlet boundaries in the Non-conservative form of governing equation.

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.