Challenge

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

Program:

%Main program

clear all
close all 
clc

% Domain initialization

L=3;
nx=31;
x=linspace(0,L,nx);
dx=x(2)-x(1);
C=0.5;
nt=1400;
gamma=1.4;

%Nozzle area

A=1+2.2*(x-1.5).^2;

%Computing the flow variable through conservative and non-conservative
%forms

[rho1, V1, T1, p1, M1, m1, rho_t1, V_t1, p_t1, T_t1, M_t1, residual1] = non_conservative_sh(x, dx, A, C, nt, gamma);
[rho2, V2, T2, p2, M2, m2, rho_t2, V_t2, p_t2, T_t2, M_t2, residual2] = conservative_sh(x, dx, A, C, nt, gamma);

%Plotting of results

figure(1)
subplot(4,1,1)
plot(x,M1)
grid on; ylim([0 4.5]); yticks(0:1.5:4.5);
ylabel('Mach Number')
title('Flow parameter (non-conservative form of governing equation)')
subplot(4,1,2)
plot(x,p1)
grid on; yticks(0:0.2:1);
ylabel('Pressure ratio')
subplot(4,1,3)
plot(x,rho1)
grid on; yticks(0:0.2:1);
ylabel('Density Ratio')
subplot(4,1,4)
plot(x,T1)
grid on; ylim([0 1]); yticks(0:0.2:1);
ylabel('Temperature Ratio')
xlabel('X/L')

figure(2)
subplot(4,1,1)
plot(x,M2)
grid on; ylim([0 4.5]); yticks(0:1.5:4.5);
ylabel('Mach Number')
title('Flow parameter (conservative form of governing equation)')
subplot(4,1,2)
plot(x,p2)
grid on; yticks(0:0.2:1);
ylabel('Pressure ratio')
subplot(4,1,3)
plot(x,rho2)
grid on; yticks(0:0.2:1);
ylabel('Density Ratio')
subplot(4,1,4)
plot(x,T2)
grid on; ylim([0 1]); yticks(0:0.2:1);
ylabel('Temperature Ratio')
xlabel('X/L')

figure(3)
subplot(4,1,1)
plot(1:nt,rho_t1)
hold on
plot(1:nt,rho_t2)
grid on; ylim([0 1]); yticks(0:0.2:1);
ylabel('rho/rho_0')
title('Flow parameter variation with time at the nozzle throat');
legend('Non-conservative', 'Conservative');
subplot(4,1,2)
plot(1:nt,T_t1)
hold on
plot(1:nt,T_t2)
grid on; yticks(0:0.2:1);
ylabel('T/T_0')
legend('Non-conservative', 'Conservative');
subplot(4,1,3)
plot(1:nt, p_t1)
hold on
plot(1:nt,p_t2)
grid on; yticks(0:0.2:1);
ylabel('p/p_0')
legend('Non-conservative', 'Conservative');
subplot(4,1,4)
plot(1:nt,M_t1)
hold on
plot(1:nt, M_t2)
grid on; yticks(0:0.2:2);
ylabel('Mach No.')
xlabel('Time steps')
legend('Non-conservative', 'Conservative');

figure(4)
subplot(2,1,1)
plot(1:nt,residual1)
grid on
xlabel('Time Steps')
ylabel('Residuals')
legend('|drho/dt|_{av}', '|dV/dt|_{av}', '|dT/dt|_{av}')
title('Residuals: Non-conservative form')
subplot(2,1,2)
plot(1:nt,residual2)
grid on
xlabel('Time steps')
ylabel('Residuals'); yticks(0:0.5:4);
legend('|dU_1/dt|_{av}', '|dU_2/dt|_{av}', '|dU_3/dt|_{av}')
title('Residuals: Conservative form')

figure(5)
hold on; grid on;
plot(x,m1(50,:),'-x')
plot(x,m1(100,:),'-d')
plot(x,m1(150,:),'-s')
plot(x,m1(200,:),'-*')
plot(x,m1(700,:),'-o')
xlabel('X/L')
ylabel('rhoAV/rho_0A_0V_0')
legend('t=50/t', 't=100/t', 't=150/t', 't=200/t', 't=700/t' )
title('Variation of non-dimensional mass flow rate (Non-conservative form)')

figure(6)
hold on; grid on;
plot(x,m2(100,:), 'x')
plot(x,m2(150,:), 'd')
plot(x,m2(200,:), '*')
plot(x,m2(700,:), 'o')
xlabel('X/L')
ylabel('rhoV/rho_0A_0V_0')
legend('t=100/t', 't=150/t', 't=200/t', 't=700/t' )
title('Variation of non-dimensional mass flow rate (Conservative form)')

figure(7)
hold on; grid on;
plot(x,m1(end,:), 'Linewidth', 3)
plot(x,m2(end,:), 'Linewidth', 3)
plot(x,0.579*ones(length(x),1),'--k')
xlabel('X/L')
ylabel('rhoV/rho_0A_0V_0')
legend('Non-conservative', 'Conservative', 'Exact')
title('Variation of non-dimensional mass flow rate (Steady state)')


% Solver for conservative form of governing equation

function [rho2, V2, T2, p2, M2, m2, rho_t2, V_t2, p_t2, T_t2, M_t2, residual2] = conservative_sh(x, dx, A, C, nt, gamma)

%Initial conditions

rho_0=zeros(1,length(x));
T_0=rho_0;
V_0=T_0;
for i=1:length(x)
    if x(i)>=0 && x(i)<0.5
        rho_0(i)=1;
         T_0(i)=1;

    elseif x(i)>=0.5 && x(i)<1.5
        rho_0(i)=1-0.366*(x(i)-0.5);
        T_0(i)=1-0.167*(x(i)-0.5);

    elseif x(i)>=1.5 && x(i)<=3
        rho_0(i)=0.634-0.3879*(x(i)-1.5);
        T_0(i)=0.833-0.3507*(x(i)-1.5);
    end
    V_0(i)=0.59/(rho_0(i)*A(i));
end

throat=find(A==1);
rho=rho_0;
T=T_0;
V=V_0;
m=zeros(nt,length(x));
U1=rho.*A;
U2=rho.*A.*V;
U3=rho.*(T./(gamma-1)+(0.5*gamma)*(V.^2)).*A;
rho_t=zeros(nt,1);
T_t=rho_t;
V_t=T_t;
p_t=V_t;
M_t=p_t;
residual=zeros(nt,3);
for k=1:nt
    U1_old=U1;
    U2_old=U2;
    U3_old=U3;
    dt=min(C*dx./(T.^0.5+V));
    F1=U2;
    F2=(U2.^2)./U1+(gamma-1)/(gamma)*(U3-0.5*gamma*(U2.^2)./U1);
    F3=gamma*U2.*U3./U1-0.5*gamma*(gamma-1)*(U2.^3)./(U1.^2);
    
    % Predictor Loop
    for i=2:length(x)-1
        dF1dx=(F1(i+1)-F1(i))/dx;
        dF2dx=(F2(i+1)-F2(i))/dx;
        dF3dx=(F3(i+1)-F3(i))/dx;
        dAdx=(A(i+1)-A(i))/dx;
        J2=(1/gamma)*rho(i)*T(i)*dAdx;
        
        dU1dt_p(i)=-dF1dx;
        dU2dt_p(i)=-dF2dx+J2;
        dU3dt_p(i)=-dF3dx;
        
        % Intermediate 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
    rho=U1./A;
    V=U2./U1;
    T=(gamma-1)*((U3./U1)-0.5*gamma*V.^2);
    F1=U2;
    F2=((U2.^2)./U1)+(((gamma-1)/gamma)*(U3-((0.5*gamma)*(U2.^2)./U1)));
    F3=(gamma*((U2.*U3)./U1))-((0.5*gamma*(gamma-1))*((U2.^3)./U1.^2));
    
    % Corrector Loop
    for i=2:length(x)-1
        dF1dx=(F1(i)-F1(i-1))/dx;
        dF2dx=(F2(i)-F2(i-1))/dx;
        dF3dx=(F3(i)-F3(i-1))/dx;
        dAdx=(A(i)-A(i-1))/dx;
        J2=(1/gamma)*rho(i)*T(i)*dAdx;
        
        dU1dt_c(i)=-dF1dx;
        dU2dt_c(i)=-dF2dx+J2;
        dU3dt_c(i)=-dF3dx;
    end
    
    % Average of predictor and corrector step
    
    dU1dt=0.5*(dU1dt_p+dU1dt_c);
    dU2dt=0.5*(dU2dt_p+dU2dt_c);
    dU3dt=0.5*(dU3dt_p+dU3dt_c);

    residual(k,1)=max(abs(dU1dt));
    residual(k,2)=max(abs(dU2dt));
    residual(k,3)=max(abs(dU3dt));
    
    % Final solution update

    for i=2:length(x)-1
        U1(i)=U1_old(i)+dU1dt(i)*dt;
        U2(i)=U2_old(i)+dU2dt(i)*dt;
        U3(i)=U3_old(i)+dU3dt(i)*dt;
    end
    
    % Boundary Conditions
    U1(1)=rho(1)*A(1);
    U1(end)=2*U1(end-1)-U1(end-2);
    U2(1)=2*U2(2)-U2(3);
    U2(end)=2*U2(end-1)-U2(end-2);
    U3(1)=U1(1)*((T(1)/(gamma-1))+0.5*gamma*V(1)^2);
    U3(end)=2*U3(end-1)-U3(end-2);
    rho=U1./A;
    V=U2./U1;
    T=(gamma-1)*((U3./U1)-((0.5*gamma)*V.^2));
    M=V./(T.^0.5);
    p=rho.*T;
    m(k,:)=rho.*A.*V;
    rho_t(k)=rho(throat);
    V_t(k)=V(throat);
    T_t(k)=T(throat);
    p_t(k)=p(throat);
    M_t(k)=M(throat);
end
rho2=rho;
V2= V;
T2= T;
p2= p;
M2= M;
m2 = m;
rho_t2= rho_t;
V_t2= V_t;
p_t2= p_t; 
T_t2= T_t;
M_t2= M_t;
residual2= residual;
end

        
        
      
% Solver for Non-conservative form of governing equation

function [rho1, V1, T1, p1, M1, m1, rho_t1, V_t1, p_t1, T_t1, M_t1, residual1] = non_conservative_sh(x, dx, A, C, nt, gamma)

%Initial conditions
rho_0 = 1 - 0.3146*x;
T_0 = 1- 0.2314*x;
V_0 = (0.1 + 1.09*x).*T_0.^0.5;
throat = find(A==1);
rho = rho_0;
T = T_0;
V = V_0; 
m = zeros(nt,length(x));
rho_t = zeros(nt,1);
T_t = rho_t;
V_t = T_t; 
p_t= V_t;
M_t = p_t;
residual = zeros(nt,3);
for k=1:nt
    rho_old = rho; 
    T_old = T; 
    V_old = V;
    dt = min(C*dx./(T.^0.5+V));

    %Predictor loop

    for i=2:length(x)-1
        dVdx= (V(i+1) - V(i))/dx;
        dlogAdx = (log(A(i+1)) - log(A(i)))/dx;
        drhodx = (rho(i+1) - rho(i))/dx;
        dTdx = (T(i+1) - T(i))/dx;

        drhodt_p(i) = -rho(i)*dVdx - rho(i)*V(i)*dlogAdx - V(i)*drhodx;
        dVdt_p(i) = -V(i)*dVdx - (1/gamma)*(dTdx + ((T(i)/rho(i))*drhodx));
        dTdt_p(i) = -V(i)*dTdx - (gamma-1)*T(i)*(dVdx +V(i)*dlogAdx);

        %Intermediate step

        rho(i) = rho(i) + drhodt_p(i)*dt;
        V(i) = V(i) + dVdt_p(i)*dt;
        T(i) = T(i) + dTdt_p(i)*dt;

    end

    % Corrector loop

    for i=2:length(x)-1
        dVdx = (V(i) - V(i-1))/dx;
        dlogAdx = (log(A(i)) - log(A(i-1)))/dx;
        drhodx = (rho(i) - rho(i-1))/dx;
        dTdx = (T(i) - T(i-1))/dx;

        drhodt_c(i) = -rho(i)*dVdx - rho(i)*V(i)*dlogAdx - V(i)*drhodx;
        dVdt_c(i) = -V(i)*dVdx - ((1/gamma)*(dTdx + ((T(i)/rho(i))*drhodx)));
        dTdt_c(i) = -V(i)*dTdx - (gamma-1)*T(i)*(dVdx + V(i)*dlogAdx);

    end

    %Average of predictor and corrector step

    drhodt = 0.5*(drhodt_p + drhodt_c);
    dVdt = 0.5*(dVdt_p + dVdt_c);
    dTdt = 0.5*(dTdt_p + dTdt_c);
    residual(k,1) = max(abs(drhodt));
    residual(k,2) = max(abs(dVdt));
    residual(k,3) = max(abs(dTdt));

    %FInal solution update

    for i=2:length(x) - 1
        rho(i) = rho_old(i) + drhodt(i)*dt;
        V(i) = V_old(i) + dVdt(i)*dt;
        T(i) = T_old(i) + dTdt(i)*dt;
    end

    %Boundary conditions
    rho(end) = 2*rho(end-1) - rho(end-2);
    V(1) = 2*V(2) - V(3); 
    V(end) = 2*V(end-1) - V(end-2);
    T(end) = 2*T(end-1) - T(end-2);
    M = V./(T.^0.5);
    p = rho.*T;
    m(k,:) = rho.*A.*V;
    rho_t(k) = rho(throat);
    V_t(k) = V(throat); 
    T_t(k) = T(throat);
    p_t(k) = p(throat);
    M_t(k) = M(throat);
end
rho1=rho;
V1= V;
T1= T;
p1= p;
M1= M;
m1 = m;
rho_t1= rho_t;
V_t1= V_t;
p_t1= p_t; 
T_t1= T_t;
M_t1= M_t;
residual1= residual;
end

Theory:

Results:

Theory:

We have considered a steady isentropic flow through a convergent-divergent nozzle.

The flow to the inlet comes from a reservoir is large. Po and To are stagrnation pressure and temperature. In this case, the flow expands isentropically to supersonic speeds at the exit of the nozzle. The exit pressure, temperature and other conditions are denoted with a subscript 'e'.

Mackormack method setup -

In CFD, the Mackormack scheme is the most widely used discretization technique for obtaining solutions for hyperbolic partial differential equations.

It is an explicit method that gives second order accuracy without the involovement of second order derivative thus reducing the complexity of calculating it.

From the text book, we have considered the conservation equations to be,

The reservoir temperature and density are denoted by T0 and `rho0` and we define non-dimensional temperature and density as `T' = T/(T0) and rho' = rho/(rho0)`with x'=x/L as the non-dimensional length.

After similar substitiution, we arrive at (image taken from the text)

The FDM setup with the node points is as follows -

The flow field variables are as follows.

Calculation of time step -

where C, Courant number(Stability indicator) lesser than or eqaul to 1 for explicit case

Taking the grid point consideration for the 'i' th node,

For the 'i+1'th node,

Initial conditions are as follows -

The further process for solving can be inferred from the program.

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.