Challenge

Week 7 - Simulation of a 1D Super-sonic nozzle flow simulation using Macormack Method

Objective: To simulate the isentropic flow through a quasi 1D subsonic-supersonic nozzle.

To plot:
1. Steady-state distribution of primitive variables inside the nozzle
2. Time-wise variation of the primitive variables
3. Variation of Mass flow rate distribution inside the nozzle at different time steps during the time-marching process
4. Comparison of Normalized mass flow rate distributions of both forms

Non-Dimensionalising the values:
First, we going to non-dimensionalize the flow field variable for the aesthetic advantage of presenting results. The non-dimensionalized
variables are given by,
`x' = x/L`


`rho' = rho/rho^o`


`T' = T/T^o`


`V' = V/a_o`


`t'= t/(L/a_o)`


`P=P/P^0`


`A'= A/A^"*"`


where,
L = Length of the nozzle
`T^o , rho^o , P^o` = temperature, density and pressure at stagnation condition respectevely
`a_o = sqrt(gamma R T_o)`
and `A^"*"` = throat area

MacCormack Method
MacCormack method is a discretization technique which is an explicit finite difference technique that is second-order accurate in space and time. The techniques make use of two first-order accurate schemes namely predictor step and corrector step and effectively make them second-order accurate.

Step 1: Predictor Step

In this step, we use foreward differencing schemes for spatial derivatives and calculate the solution
`((delf)/(dt))_p = (f(i+1) - f(i))/(Deltax)`

Solution update (Intermediate solution)

Step 2: Corrector Step

In this step, we use backward differencing schemes for spatial derivatives and calculate the solution gradient by which we reach an corrected
solution.
`((delf_p)/(dt))_c = (f(i) - f(i-1))/(Deltax)`.

Step 3: Final Solution
With use of two computed solution gradients ( predictor and colllector), we take the average of both and reach final solution.

`((delf)/(dt))_(avg) = 0.5(((delf)/(dt))_p +((delf_p)/(dt))_c )`

Final solution updated by adding the average to the initial state.
`f_(sol) = f_(Initial) + ((delf)/(delt))_(avg) * Deltat`
`f_(sol)`= Final solution of the flow field variable for the first time step

Matlab Code:

Main Code:

clear all
close all
clc


%heat capacity ratio
    gamma = 1.4;
%length
    L = 3;
%length of nozzle
    X = linspace(0,L,31);
    dx = X(2)-X(1);
    
%Calling function to save values of mass flow     
    [m_nonconservative] = non_conservative(gamma,X,dx);
    [ m_Conservative] = Conservative(gamma,X,dx);
%To compare steady state mass flow for conservative and non conservative form
    figure(7)
    plot(X,m_nonconservative,'linewidth',2)
    hold on
    plot(X,m_Conservative,'linewidth',2) 
    xlabel('Nozzle length')
    ylabel('Mass flow rate')
    legend('Non Conservative','Conservative');
    title('Massflow conservative and Non conservative form')
           




Function Code:(NON CONSERVATIVE)

function [m_plot] = non_conservative(gamma,X,dx) 
%Initial condition
    rho = (1-0.3146*X);
    T = (1-0.2314*X);
    V = (0.1+1.09*X).*T.^0.5;
    A = 1+2.2*(X-1.5).^2;

%Speedof sound
a_initial = T.^0.5; 
%Courant number
C = 0.5;
%time step calculation
delt = min(C*dx./(T.^0.5+V));


nt = 1400;
plot_no = 1;    
iterno = 200;
for i = 1:nt
    %time step calculation
    delt = min(C*dx./(T.^0.5+V));
    
    for j = 2:length(X)-1

    
    term_a = (V(j+1)-V(j))/dx;
    term_b = (log(A(j+1))-log(A(j)))/dx;
    term_c = (rho(j+1)-rho(j))/dx;
    term_d = (T(j+1)-T(j))/dx;
%predictor  
    %density
    drho_dt_predict(j) = -rho(j)*term_a- rho(j)*V(j)*term_b-V(j)*term_c;
    %Velocity
    dv_dt_predict(j) = -V(j)*term_a-(1/gamma)*(term_d+(T(j)/rho(j))*term_c);
    %Temperature
    dT_dt_predict(j) = -V(j)*(term_d)-(gamma-1)*T(j)*(term_a+V(j)*term_b);
%New predicted 
    %rho
    rho_predict(j) = rho(j)+ drho_dt_predict(j)*delt; 
    %Velocity
    V_predict(j) = V(j) + dv_dt_predict(j)*delt;
    %Temperature
    T_predict(j) = T(j) + dT_dt_predict(j)*delt;
    end 
    rho_predict(1) = rho(1);
    V_predict(1) = V(1);
    T_predict(1) = T(1);
    
    
%<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Corrector>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
for j = 2:length(X)-1
    term_a = (V_predict(j)-V_predict(j-1))/dx;
    term_b = (log(A(j))-log(A(j-1)))/dx;
    term_c = (rho_predict(j)-rho_predict(j-1))/dx;
    term_d = (T_predict(j)-T_predict(j-1))/dx;
    
    %density
    drho_dt_correct(j) = -rho_predict(j)*term_a-rho_predict(j)*V_predict(j)*term_b-V_predict(j)*term_c;
    %Velocity
    dv_dt_correct(j) = -V_predict(j)*term_a-(1/gamma)*(term_d+(T_predict(j)/ rho_predict(j))*term_c);
    %Temperature
    dT_dt_correct(j) = -V_predict(j)*(term_d)-(gamma-1)*T_predict(j)*(term_a+V_predict(j)*term_b);    
end
%<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<New time step value computing>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
for j = 2:length(X)-1

    rho_new(j-1) = rho(j)+ ((drho_dt_predict(j) + drho_dt_correct(j))/2)*delt;
    V_new(j-1) = V(j) + ((dv_dt_predict(j) + dv_dt_correct(j))/2)*delt;
    T_new(j-1) = T(j) + ((dT_dt_predict(j) + dT_dt_correct(j))/2)*delt;
    
end
%Assigning values of old timestep to new one
    rho(2:length(X)-1) = rho_new;
    V(2:length(X)-1) = V_new;
    T(2:length(X)-1) = T_new;
%Assigning boundary conditions    
    %Inlet
    rho(1) = rho(1);
    V(1) = 2*V(2)-V(3);
    T(1) = T(1);
    %Outlet
    rho(length(X)) = 2*rho(length(X)-1)-rho(length(X)-2);
    V(length(X)) = 2*V(length(X)-1)-V(length(X)-2);
    T(length(X)) = 2*T(length(X)-1)-T(length(X)-2);
%<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<savnig the throat velocity>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   plot_rho(i) = rho(16);
   plot_V(i) = V(16);
   plot_T(i) = V(16);
%To compute the mass flow rate at intermediate iterations     
   if i == iterno
   m(plot_no,:) = rho.*A.*V;
   iterno = iterno+300;
   plot_no = plot_no+1;
   end
  
end

%Mass flow rate calculation
m_plot = rho.*A.*V;
%Mach number calculation
M = V./T.^0.5;

 figure(1)
 plot(X,m,'linewidth',2)
 xlabel('Nozzle length')
 ylabel('Mass flow rate')
 legend('Iteration NO: 200','Iteration NO: 500'...
            ,'Iteration NO: 800','Iteration NO: 1100','Iteration NO: 1400')
title('Massflow Non conservative form at different iteration')
%Iteration vs throat properties
figure(2)
subplot(3,1,1)
plot(plot_V);
title('Velocity')
xlabel('Number of time step')
ylabel('\bf{\it{V/a_0}}')
subplot(3,1,2)
plot(plot_T);
title('Temperature')
xlabel('Number of time step')
ylabel('\bf{\it{T/T_0}}')
subplot(3,1,3)
plot(plot_rho);
title('Density')
xlabel('Number of time step')
ylabel('\bf{\rho/\rho_0}')

%Variation of properties with nozzle distance
figure(3)
subplot(4,1,1)
plot(X,V);
title('Velocity')
xlabel('Non dimensional nozzle distance')
ylabel('\bf{\it{V/a_0}}')
subplot(4,1,2)
plot(X,T);
title('Temperature')
xlabel('Non dimensional nozzle distance')
ylabel('\bf{\it{T/T_0}}')
subplot(4,1,3)
plot(X,rho);
title('Density')
xlabel('Non dimensional nozzle distance')
ylabel('\bf{\rho/\rho_0}')
subplot(4,1,4)
plot(X,M);
title('Mach No.')
xlabel('Non dimensional nozzle distance')
ylabel('\bf{M}')

end

Function Code:(CONSERVATIVE)

function [ m_steadystate] = Conservative(gamma,X,dx) 
%Initial conditions
for i = 1:length(X)
    if (0<=X(i) && X(i)<=0.5)
    rho(i) = 1; 
    T(i) = 1;
    elseif (0.5<=X(i) && X(i)<=1.5)
    rho(i) = 1-0.366*(X(i)-0.5);
    T(i) = 1-0.167*(X(i)-0.5);
    elseif(1.5<=X(i) && 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

%Area variation
    A = 1+2.2*(X-1.5).^2;
%Velocity VRItion
    V = 0.59./(rho.*A);
    %Courant number
    C = 0.5;
%time step calculation
    delt = min(C*dx./(T.^0.5+V));  
plot_no = 1;    
iterno = 200;    
 for i = 1:1400
%%
%Updating value of time step   
   delt = min(C*dx./(T.^0.5+V));  
   
%Solution Vector    
    U_1 = rho.*A;
    U_2 = rho.*A.*V;
    U_3 = rho.*A.*((T./(gamma-1))+(gamma/2*V.^2));
%Flux Vector
    F_1 = U_2;
    F_2 = U_2.^2./U_1+((gamma-1)/gamma)*(U_3-(gamma/2)*(U_2.^2./U_1));
    F_3 = ((gamma*U_2.*U_3)./U_1)-((gamma*(gamma-1)/2)*(U_2.^3./U_1.^2));
    
%Updating value of predicted U_1,U_2and U_3
    U_1_predict = U_1;
    U_2_predict = U_2;
    U_3_predict = U_3;
% Space loop  
    for j = 2:length(X)-1
%%
%<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Predictor Step>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       
%Source term
        J(j) = (1/gamma)*rho(j)*T(j)*(A(j+1)-A(j))/dx;
       
%Predictor values        
        dU_1_dt_predict(j) = -(F_1(j+1)-F_1(j))/dx;
        dU_2_dt_predict(j) = -(F_2(j+1)-F_2(j))/dx+J(j);
        dU_3_dt_predict(j) = -(F_3(j+1)-F_3(j))/dx ;

        U_1_predict(j) = U_1(j)+ dU_1_dt_predict(j)*delt;
        U_2_predict(j) = U_2(j)+ dU_2_dt_predict(j)*delt;
        U_3_predict(j) = U_3(j)+ dU_3_dt_predict(j)*delt;
        
    end    
%%
%Finding Predicted velocity density and temperature
    %density
    rho = U_1_predict./A;
    %Velocity
    V = U_2_predict./U_1_predict;
    %Temperature
    T = (gamma-1)*((U_3_predict./U_1_predict)-(gamma/2)*(V).^2);
    
%Updating values of F_1 F_2 and  F_3
    F_1 = U_2_predict;
    F_2 = U_2_predict.^2./U_1_predict+((gamma-1)/gamma)*(U_3_predict-(gamma/2)*(U_2_predict.^2./U_1_predict));
    F_3 = ((gamma*U_2_predict.*U_3_predict)./U_1_predict)-((gamma*(gamma-1)/2)*(U_2_predict.^3./U_1_predict.^2));    
      
%%
%<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Corrector Step>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>       
 for j = 2:(length(X)-1)
    J(j) = (1/gamma)*rho(j)*T(j)*(A(j)-A(j-1))/dx;
    dU_1_dt_correct(j) = -(F_1(j)-F_1(j-1))/dx;
    dU_2_dt_correct(j) = -(F_2(j)-F_2(j-1))/dx+ J(j);
    dU_3_dt_correct(j) = -(F_3(j)-F_3(j-1))/dx ;
end
%Averaging Step
    dU_1_dt = 0.5*(dU_1_dt_predict+dU_1_dt_correct);
    dU_2_dt = 0.5*(dU_2_dt_predict+dU_2_dt_correct);
    dU_3_dt = 0.5*(dU_3_dt_predict+dU_3_dt_correct);
%%
%new value of solution vector
for j = 2:(length(X)-1)   
%Final step
    U_1_new(j) = U_1(j)+ dU_1_dt(j)*delt;
    U_2_new(j) = U_2(j)+ dU_2_dt(j)*delt;
    U_3_new(j) = U_3(j)+ dU_3_dt(j)*delt;
end

% Boundary condition-inlet
    U_1_new(1)=rho(1)*A(1);
    U_2_new(1)=(2*U_2_new(2))-U_2_new(3);
    U_3_new(1)=U_1_new(1)*(T(1)/(gamma-1)+(gamma/2)*V(1)^2); 
% Boundary condition-outlet
    U_1_new(length(X))=2*U_1_new(length(X)-1)-U_1_new(length(X)-2);
    U_2_new(length(X))=2*U_2_new(length(X)-1)-U_2_new(length(X)-2);
    U_3_new(length(X))=2*U_3_new(length(X)-1)-U_3_new(length(X)-2);
    
%%
%New Value of Primitive variables 
    rho = U_1_new./A;
    V = U_2_new./U_1_new;
    T = (gamma-1)*((U_3_new./U_1_new)-(gamma/2)*V.^2);
    M = V./T.^0.5;
    
%To compute the mass flow rate at intermediate iterations    
    if i == iterno
    m(plot_no,:) = rho.*A.*V;
    iterno = iterno+300;
    plot_no = plot_no+1;
    end
    plot_rho(i) = rho(16);
    plot_V(i) = V(16);
    plot_T(i) = V(16);
 end
 m_steadystate = rho.*A.*V;
 %Plotting
 figure(4)
 plot(X,m,'linewidth',2)
 xlabel('Nozzle length')
 ylabel('Mass flow rate')
 legend('Iteration NO: 200','Iteration NO: 500'...
            ,'Iteration NO: 800','Iteration NO: 1100','Iteration NO: 1400')
 title('Massflow title Conservative form at different time step')
 

 %Iteration vs throat properties
figure(5)
subplot(3,1,1)
plot(plot_V);
title('Velocity')
xlabel('Number of time step')
ylabel('\bf{\it{V/a_0}}')
subplot(3,1,2)
plot(plot_T);
title('Temperature')
xlabel('Number of time step')
ylabel('\bf{\it{T/T_0}}')
subplot(3,1,3)
plot(plot_rho);
title('Density')
xlabel('Number of time step')
ylabel('\bf{\rho/\rho_0}')
%Variation of properties with nozzle distance
figure(6)
subplot(4,1,1)
plot(X,V);
title('Velocity')
xlabel('Non dimensional nozzle distance')
ylabel('\bf{\it{V/a_0}}')
subplot(4,1,2)
plot(X,T);
title('Temperature')
xlabel('Non dimensional nozzle distance')
ylabel('\bf{\it{T/T_0}}')
subplot(4,1,3)
plot(X,rho);
title('Density')
xlabel('Non dimensional nozzle distance')
ylabel('\bf{\rho/\rho_0}')
subplot(4,1,4)
plot(X,M);
title('Mach No.')
xlabel('Non dimensional nozzle distance')
ylabel('\bf{M}')
 
end 

Results and Discussion
The steady-state distribution of primitive variables inside the nozzle:

The steady-state distribution of primitive variables shows how the variables change along the span of the nozzle from the convergent part to the divergent part for non-conservative and conservative forms of
the governing equations.

Non-Conservative Form:

Conservative Form:

Time-wise variation of the primitive variables:

The time-wise variation of the primitive variables from the initial condition to the 1400 time step is shown in the figures. It can be seen that the variation is maximum in early timesteps for both cases. But in comparison, in the nonconservative form, these die down around the 300th timestep while for the conservative form the changes are prominent around 400th-time
step.

Non-Conservative Form:

Conservative Form:

Variation of Mass flow rate distribution inside the nozzle at different time steps during the time-marching process:
Here the non-dimensional mass flow is plotted as the function of the non-dimensional distance through the nozzle. Five different curves are
shown. Initially, the curves show huge variation and as time passes the variation is diminished and finally comes to a constant value.

Comparison of Normalized mass flow rate distributions of both forms:

Now, we compare the steady-state variations of the mass flow obtained with the non-conservative and conservative Steady-state variation of the conservative form was compared to that of the non-conservative form. Here we can see that the conservative form has a satisfactory value compared to the value obtained from the non-conservative form. in conservation form preserving the mass throughout the flowfield as it is a dependent variable in the equation. But in non-conservation form, the dependent variables are primary flow variables and mass flow is obtained as a secondary result. The steady-state mass flow results obtained with the conservation form are hence closer to the exact analytical value of 0.549.

The grid independence test

`frac{rho^ast}
{rho_0^ast}`
`frac{T^ast}
{T_0^ast}`
Mach
Number M
Exact analytical
solution
0.634 0.833 1.000
Conservation
form, numerical
results (31
points)
0.650 0.840 0.981
Non-Conservation
form, numerical
results (31
points)
0.721 0.836 0.999
Nonconservation
form, numerical
results (61
points)
0.637 0.835 0.999
Conservation
form, numerical
results (61
points)
0.638 0.835 0.991

Conclusions
The conservative form gives a better mass flow distribution compared to the non-conservative form

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.