Challenge

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

Program:

clear all;
close all;
clc;



tic;
nx_nc = 31;        %No. of nodes
l_nc = 3;          %Length of the domain
x_nc = linspace(0,l_nc,nx_nc);   %Mesh generation
dx_nc = l_nc/(nx_nc-1);

t_nc = 1400;  %time
A_throat_nc = 1;
gamma_nc = 1.4;
C_nc = 0.2;       % Courant Number

%Initial conditions based on shape of the nozzle
A_nc = 1+2.2*(x_nc-1.5).^2;
rho_nc = 1-0.3146*x_nc;
T_nc = 1-0.2314*x_nc;
V_nc = (0.1+1.09*x_nc).*T_nc.^0.5;


for k = 1:t_nc        %time marching
    rho_old_nc = rho_nc;
    V_old_nc = V_nc;
    T_old_nc = T_nc;
    A_old_nc = A_nc;

    dt_nc = C_nc*dx_nc./((T_nc.^0.5)+V_nc);     %Courant number criterion
    dt_nc = min(dt_nc);              % taking time step as minimun value after calculating at each node
    for i = 2: nx_nc-1     %space marching

        % predictor step , forward differencing of space terms
        dV_dx_nc = (V_nc(i+1)-V_nc(i))/dx_nc;
        dlogA_dx_nc = (log(A_nc(i+1))-log(A_nc(i)))/dx_nc;
        drho_dx_nc = (rho_nc(i+1)-rho_nc(i))/dx_nc;
        dT_dx_nc = (T_nc(i+1)-T_nc(i))/dx_nc;

        drho_dt_p_nc(i) = -rho_nc(i)*(dV_dx_nc)-(rho_nc(i).*V_nc(i)*dlogA_dx_nc)-(V_nc(i)*drho_dx_nc);
        dV_dt_p_nc(i) = (-V_nc(i)*dV_dx_nc)-((1/gamma_nc)*(dT_dx_nc+(T_nc(i)/rho_nc(i))*drho_dx_nc));
        dT_dt_p_nc(i) = -V_nc(i)*(dT_dx_nc)-(gamma_nc-1)*T_nc(i)*(dV_dx_nc+(V_nc(i)*dlogA_dx_nc));


        %Solution update
        rho_nc(i) = rho_old_nc(i) + drho_dt_p_nc(i)*dt_nc;
        V_nc(i) = V_old_nc(i) + dV_dt_p_nc(i)*dt_nc;
        T_nc(i) = T_old_nc(i) + dT_dt_p_nc(i)*dt_nc;

    end

    for i = 2: nx_nc-1     %space marching

        % corrector step , backward differencing of space terms
        dV_dx_nc = (V_nc(i)-V_nc(i-1))/dx_nc;
        dlogA_dx_nc = (log(A_nc(i))-log(A_nc(i-1)))/dx_nc;
        drho_dx_nc = (rho_nc(i)-rho_nc(i-1))/dx_nc;
        dT_dx_nc = (T_nc(i)-T_nc(i-1))/dx_nc;

        drho_dt_c_nc(i) = -rho_nc(i)*(dV_dx_nc)-(rho_nc(i).*V_nc(i)*dlogA_dx_nc)-(V_nc(i)*drho_dx_nc);
        dV_dt_c_nc(i) = (-V_nc(i)*dV_dx_nc)-((1/gamma_nc)*(dT_dx_nc+(T_nc(i)/rho_nc(i))*drho_dx_nc));
        dT_dt_c_nc(i) = -V_nc(i)*(dT_dx_nc)-(gamma_nc-1)*T_nc(i)*(dV_dx_nc+(V_nc(i)*dlogA_dx_nc));

    end
    %computing the average
    drho_dt_avg_nc = 0.5*(drho_dt_p_nc + drho_dt_c_nc);
    dV_dt_avg_nc = 0.5*(dV_dt_p_nc + dV_dt_c_nc);
    dT_dt_avg_nc = 0.5*(dT_dt_p_nc + dT_dt_c_nc);

    %final solution update

    for i = 2:nx_nc-1
        rho_nc(i) = rho_old_nc(i) + drho_dt_avg_nc(i)*dt_nc;
        V_nc(i) = V_old_nc(i) + dV_dt_avg_nc(i)*dt_nc;
        T_nc(i) = T_old_nc(i) + dT_dt_avg_nc(i)*dt_nc;
    end

    %boundary conditions

    %Boundary condition at node-1(Reservior)
    V_nc(1) = 2*V_nc(2)-V_nc(3);
    rho_nc(1) = 1;
    T_nc(1) = 1;
    %Boundary condition at end node(outlet)
    V_nc(nx_nc) = 2*V_nc(nx_nc-1)-V_nc(nx_nc-2);
    rho_nc(nx_nc) = 2*rho_nc(nx_nc-1)-rho_nc(nx_nc-2);
    T_nc(nx_nc) = 2*T_nc(nx_nc-1)-T_nc(nx_nc-2);

    % Calculating solutions
    % Mass flow rate
    m_nc = rho_nc.*A_nc.*V_nc;
    % pressure
    P_nc = rho_nc.*T_nc;
    % Mach number
    M_nc = V_nc./((T_nc).^0.5);

    %Non-conservative solution plot

    figure(1)
    subplot(2,3,1)
    plot(x_nc,P_nc)
    xlabel('Length of domain')
    ylabel('Pressure ratio : P/P_0')
    title('Pressure ratio V/S length of domain')

    subplot(2,3,2)
    plot(x_nc,rho_nc)
    xlabel('Length of domain')
    ylabel('Density ratio : rho/rho_0')
    title('Density ratio V/S length of domain')


    subplot(2,3,3)
    plot(x_nc,T_nc)
    xlabel('Length of domain')
    ylabel('Temperature ratio : T/T_0')
    title('Temp. ratio V/S length of domain')


    subplot(2,3,4)
    plot(x_nc,M_nc)
    xlabel('Length of domain')
    ylabel('Mach Number : M')
    title('Mach Number V/S length of domain')


    subplot(2,3,5)
    plot(x_nc,m_nc)
    xlabel('Length of domain')
    ylabel('Mass flow rate')
    title('mass flow rate V/S length of domain')
    pause(0.003)

    sgtitle(sprintf('Time step %d',k))
   

end
simulation_time_nc = toc;

tic;
%Conservative
gamma = 1.4;
C = 0.8;
l = 3;
nx = 31;
x = linspace(0,3,nx);
A = 1+2.2*(x-1.5).^2;
t = 1400;
dx = x(2) - x(1);

for i = 1:nx
    if x(i)>=0 && x(i)<=0.5
        rho(i) = 1;
        T(i) = 1;
    else if 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);
    else if x(i)>=1.5 && x(i)<=3
            rho(i) = 0.634-0.3879*(x(i)-1.5);
            T(i) = 0.833-0.3507*(x(i)-1.5);
    end
    end
    end
end
V = 0.59./(rho.*A);
P = rho.*T;
U1 = rho.*A;
U2 = rho.*A.*V;
U3 = rho.*((T./(gamma-1))+((gamma/2).*(V.^2))).*A;
dt = C*dx./((T.^0.5)+V);     %Courant number criterion
dt = min(dt);              % taking time step as minimum value after calculating at each node

for k = 1:t
    U1_old = U1;
    U2_old = U2;
    U3_old = U3;

    %Flux variables
    F1 = U2;
    F2 = ((U2.^2)./U1) + ((gamma-1)/gamma)*(U3-(((gamma/2)*U2.^2)./U1));
    F3 = ((gamma*U2.*U3)./U1) - (gamma*(gamma-1)/2)*((U2.^3)./(U1.^2));

    % predictor step , forward differencing of space terms
    for j = 2:nx-1
        dF1_dx = (F1(j+1)-F1(j))/dx;
        dF2_dx = (F2(j+1)-F2(j))/dx;
        dF3_dx = (F3(j+1)-F3(j))/dx;
        dlogA_dx = (log(A(j+1))-log(A(j)))/dx;
        dA_dx = (A(j+1)-A(j))/dx;
        J2 = (1/gamma).*rho(j).*T(j).*dA_dx;

        % continuity equation
        dU1_dt_p(j) = -dF1_dx;
        % Momentum equation
        dU2_dt_p(j) = -dF2_dx + J2;
        % Energy equation
        dU3_dt_p(j) = -dF3_dx;

        % Solution update
        U1(j) = U1(j) + dU1_dt_p(j)*dt;
        U2(j) = U2(j) + dU2_dt_p(j)*dt;
        U3(j) = U3(j) + dU3_dt_p(j)*dt;

    end

    % Primitive terms for corrector step
    rho = U1./A;
    v = U2./U1;
    t = (gamma-1)*((U3./U1)-((gamma/2)*((U2./U1).^2)));
    P = rho.*t;
    F1 = U2;
    F2 = ((U2.^2)./U1) + ((gamma-1)/gamma)*(U3-(((gamma/2)*U2.^2)./U1));
    F3 = ((gamma*U2.*U3)./U1)-(gamma*(gamma-1)/2)*((U2.^3)./(U1.^2));

    % corrector step, backward differencing of space terms
    for j=2:nx-1
        dF1_dx = (F1(j)-F1(j-1))/dx;
        dF2_dx = (F2(j)-F2(j-1))/dx;
        dF3_dx = (F3(j)-F3(j-1))/dx;
        dlogAdx = (log(A(j))-log(A(j-1)))/dx;
        dA_dx = (A(j)-A(j-1))/dx;
        J2 = (1/gamma).*rho(j).*t(j).*dA_dx;

        % continuity equation
        dU1_dt_c(j) = -dF1_dx;
        % Momentum equation
        dU2_dt_c(j) = -dF2_dx + J2;
        % Energy equation
        dU3_dt_c(j) = -dF3_dx;
    end
    % Average derivatives
    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);

    % Final solution update
    for i = 2:nx-1
        U1(i) = U1_old(i) + dU1_dt(i)*dt;
        U2(i) = U2_old(i) + dU2_dt(i)*dt;
        U3(i) = U3_old(i) + dU3_dt(i)*dt;
    end
    % Applying the Boundary conditions
    % Inlet
    U1(1)=rho(1)*A(1);
    U2(1)= 2*U2(2)-U2(3);
    v(1)= U2(1)/U1(1);
    t(1) = 1;
    U3(1) = U1(1)*((t(1)/(gamma-1))+((gamma/2)*(v(1)^2)));

    % caculating solutions
    % Mass flow rate
    m = rho.*V.*A;
    % pressure
    P = rho.*t;
    % Mach number
    M= V./((T).^0.5);

    % Conservative solution plot

    figure(2)
    subplot(2,3,1)
    plot(x,P)
    xlabel('Length of domain')
    ylabel('Pressure ratio : P/P_0')
    title('Pressure ratio V/S length of domain')


    subplot(2,3,2)
    plot(x,rho)
    xlabel('Length of domain')
    ylabel('Density ratio : rho/rho_0')
    title('Density ratio V/S length of domain')


    subplot(2,3,3)
    plot(x,T)
    xlabel('Length of domain')
    ylabel('Temperature ratio : T/T_0')
    title('Temp. ratio V/S length of domain')


    subplot(2,3,4)
    plot(x,M)
    xlabel('Length of domain')
    ylabel('Mach Number : M')
    title('Mach Number V/S length of domain')


    subplot(2,3,5)
    plot(x,m)
    xlabel('Length of domain')
    ylabel('Mass flow rate')
    title('mass flow rate V/S length of domain')
    pause(0.003)

    sgtitle(sprintf('Time step %d',k))



end
simulation_time_c = toc;

%comparison plots

figure(3)
plot(x_nc,m_nc)
hold on
plot(x,m)
xlabel('Length of domain')
ylabel('Mass flow rate')
legend('non_conservative mass flow','Conservative mass flow')
title('mass flow rate V/S length of domain')

figure(4)
X = categorical({'Simulation time (Non-Conservative)','Simulation time (Conservative)'});
Y = [simulation_time_nc,simulation_time_c];
bar(X,Y)


Code Explanation

1. Code started with close all, clear all & clc command.

2. tic & toc commands are used for both non-conservative & conservative equations to keep the track of simulation time.

3. Variable having 'nc' in its name belong to the non-conservative flow field.

4. Now certain terms are defined like No. of nodes, length of domain, total time, area of throat, gamma , and Courant number.

5. Initial conditions are specified containing governing equations of area, density, temperature & velocity based on shape of the nozzle.

6. Time & space marching loop is initiated and copy of variables are made ( rho, Temp, vel).

7. The Courant number criterion for the time step is stated in which 'dt' is taken minimum of the value calculated at each node at a given time.

8. Now MacCormack method is used to calculate the final solution for continuity, momentum, and energy equations.

9. Steps in MacCormack's method are as follows-

a) Predicter step: calculated by forward differencing of differential equations.

b) Solution update

c) corrector step: calculated by backward differencing of differential equations.

d) Solution update

e) Taking the average of both predictor & corrector.

f) Final solution update.

10. Boundary conditions are defined.

a) At inlet: velocity is calculated by interpolation , rho = 1 , T =1

b) At outlet: V, rho, T all are interpolated.

11. The governing equations for mass flow rate, pressure, Mach No. are written.

12. 5 subplots are created in a single figure showing the graphs.

13. Similarly the continuity, momentum & energy equations are solved for the conservative flow field.

14. For comparison, a figure is plotted showing the mass flow rate of conservative & non-conservative flow fields.

15. A bar graph is plotted showing the simulation time of both the flow fields.

Graphs

1) Non- Conservative plot

> Pressure ratio, density ratio & temperature ratio decrease along the length of the nozzle.

> Mach No. increases along the length of the nozzle & Mach No = 1 at the throat section.

> Mass flow rate is more in the convergent region as compared to the divergent region.

2) Conservative plot

> Pressure ratio, density ratio & temperature ratio decrease along the length of the nozzle.

> Mach No. increases along the length of the nozzle & Mach No ~ 1 at the throat section.

> Mass flow rate increases along the length of the domain (but by a small factor i.e negligible as compared to non-conservative flow field)

3) Mass flow rate comparison

> Comparing the mass flow rate of conservative & non- conservative flow fields. We can say that it remains fairly constant for non-conservative case & varying in the case of the conservative flow field.

4) Simulation time comparison

> Simulation time for conservative flow field is greater than non-conservative flow field.

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.