Challenge

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

AIM: To study the flow in a quasi-1D supersonic nozzle using Macormack's method and comparing the observations obtained from using conservative and non conservative governing equations.

THEORY:

Nozzle :-

A nozzle is a device which increases the kinetic energy of a fluid at the cost of its pressure. It most daily life applications, the Mach number(M; ratio of speed of fluid in the medium at a point to the speed of sound in that medium at that point) is less than 1, thereby bringing about an increase in velocity through a decrease in area (resulting in convergent structure). However when M > 1, then an increase in velocity can be obtained only through an increase in area ( resulting in divergent structutre). This is the basis for supersonic flow.

`(dA)/A = (dV)/V(M^2 - 1)`; area velocity relation for compressive flow.

Fluid flow in a nozzle is not a true one dimensional flow because area of crossection changes as a function of x. Hence it is supposed to be a 2 dimensional flow, with properties varying along both x and y axis. However we assume that the properties are uniform across a cross section, thereby making the flow quasi 1 dimensional.

Governing equations:-

The three governing equations considered are those of continuity, momentum and energy conversation. These equations can be expressed in both conservative (fixed control volume) and non conservative (moving control volume) depending on the system being considered.

ρ = Density ; P = Pressure ; V = Velocity ; A = Area ; T = Temperature ; γ = specific heat ratio; Cv = Specific heat at constant volume; a = speed of sound in the reservoir; L = length of the nozzle

Non dimensionalising of the variables are also done, mainly in order to add an aesthetic advanatge in terms of data representation. It is done as follows:

x' = `x/L`; P' = `P/(Po)`; V' = `V/(Vo)`; t' = `t/(L/a)`; ρ' = `ρ/(ρo)`; T' = `T/(To)`

Equation of continuity-

`(∂(ρA))/(∂t) + (∂(ρAV))/(∂x) = 0`

  • expanding the differential

`A(∂ρ)/(∂t) = -AV(∂ρ)/(∂x) - ρV(∂A)/(∂x) -ρA(∂V)/(∂x)`

  • dividing by A

`(∂ρ)/(∂t) = -V(∂ρ)/(∂x) - (ρV)/A(∂A)/(∂x) -ρ(∂V)/(∂x)`

`(∂ρ)/(∂t) = -V(∂ρ)/(∂x) - ρV(∂lnA)/(∂x) -ρ(∂V)/(∂x)`

  • In non dimensional form

`(∂ρ')/(∂t') = -V'(∂ρ')/(∂x') - ρ'V'(∂lnA')/(∂x') -ρ'(∂V')/(∂x')`

Equation of momentum conservation-

`ρ(∂V)/(∂t) + ρV(∂V)/(∂x) = -(∂P)/(∂x)`

  • dividing by ρ

`(∂V)/(∂t) = -V(∂V)/(∂x) -1/ρ(∂P)/(∂x)`

  • putting P = ρRT based on ideal gas equation

`(∂V)/(∂t) = -V(∂V)/(∂x) -R((∂T)/(∂x) - T/ρ(∂ρ)/(∂x))`

  • In non dimensional form

`(∂V')/(∂t') = -V'(∂V')/(∂x') -(1/γ)((∂T')/(∂x') - T'/ρ'(∂ρ')/(∂x'))`

Equation of energy conservation-

`ρA(∂e)/(∂t) + ρAV(∂e)/(∂x) = -P(∂(AV))/(∂x)`

  • dividing by ρA and putting e = CvT

`C_v(∂T)/(∂t) + C_vV(∂T)/(∂x) = -P/(ρA)(V(∂A)/(∂x)+ A(∂V)/(∂x))`

`C_v(∂T)/(∂t) + C_vV(∂T)/(∂x) = -P/ρ(V(∂lnA)/(∂x)+ (∂V)/(∂x))`

  • dividing by Cv and equating P = ρRT

`(∂T)/(∂t) = - V(∂T)/(∂x) -(RT)/(C_v)(V(∂lnA)/(∂x)+ (∂V)/(∂x))`

  • since R/Cv = γ-1

`(∂T)/(∂t) = - V(∂T)/(∂x) -(γ-1)T(V(∂lnA)/(∂x)+ (∂V)/(∂x))`

  • In non dimensional form

`(∂T')/(∂t') = - V'(∂T')/(∂x') -(γ-1)T'(V'(∂lnA')/(∂x')+ (∂V')/(∂x'))`

Code for non conservative flow:

close all
clear
clc
dx = 0.1;
x = 0:dx:3;
% initial conditions
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;
P = rho.*T; % non dimensional pressure obtained from real gas equation

% time step
C = 0.35; % steady state ontained at around t = 800
% Time marching pre requisites
V_o = V;rho_o = rho;T_o = T;
drdt = zeros(size(x));
drdt_p = drdt; drdt_c = drdt; %initialising predictor and corrector values for all nodes
dvdt = zeros(size(V));
dvdt_p = dvdt; dvdt_c = dvdt;
dTdt = zeros(size(T));
dTdt_p = dTdt; dTdt_c = dTdt;
n = length(x);
n1 = 0;
%while err > 1e-4

for t = 1:900
    %n1 = n1 +1;
    V_o = V;rho_o = rho;T_o = T; % updating the old values with the new ones
    a = (T).^0.5; % non dimensional speed of sound in the medium 
    dt = C*dx./(a+V); % time step calculation
    dt = min(dt); % taking uniform time step as the minimum time step
    
    for i = 2:length(x)-1 %loop for predictor step
        dvdx_p(i) = (V_o(i+1)-V_o(i))/dx;dAdx_p(i) = (log(A(i+1))-log(A(i)))/dx;drdx_p(i) = (rho_o(i+1)-rho_o(i))/dx;
        dtdx_p(i) = (T_o(i+1)-T_o(i))/dx;

        drdt_p(i) =  -(rho_o(i) * dvdx_p(i)) - (rho_o(i) * V_o(i) * dAdx_p(i)) - (V_o(i) * drdx_p(i));
        rho(i) = rho_o(i) + drdt_p(i) * dt;
        dvdt_p(i) = -(V_o(i) * dvdx_p(i)) -(1/1.4) * (dtdx_p(i) + (T_o(i)/rho_o(i)) * drdx_p(i));
        V(i) = V(i) + dvdt_p(i)* dt;
        dTdt_p(i) = -(V_o(i) * dtdx_p(i)) -(1.4 - 1) * T_o(i) * (dvdx_p(i) + V_o(i) * dAdx_p(i));
        T(i) = T_o(i) + dTdt(i) * dt;
    end

    for i = 2:length(x) - 1 % loop for corrector step
        dvdx_c(i) = (V(i)-V(i-1))/dx; dAdx_c(i) = (log(A(i))-log(A(i-1)))/dx; drdx_c(i) = (rho(i)-rho(i-1))/dx;
        dtdx_c(i) = (T(i)-T(i-1))/dx;

        drdt_c(i) =  -(rho(i) * dvdx_c(i)) - (rho(i) * V(i) * dAdx_c(i)) - (V(i) * drdx_c(i));
        dvdt_c(i) = -(V(i) * dvdx_c(i)) -(1/1.4) * (dtdx_c(i) + (T(i)/rho(i)) * drdx_c(i));
        dTdt_c(i) = -(V(i) * dtdx_c(i)) -(1.4 - 1) * T(i) * (dvdx_c(i) + V(i) * dAdx_c(i));
    end

    drdt = 0.5 * (drdt_p + drdt_c);
    dvdt = 0.5 * (dvdt_p + dvdt_c);
    dTdt = 0.5 * (dTdt_p + dTdt_c);

    for i = 2:length(x)-1 %loop for finally updating flow variables
        rho(i) = rho_o(i) + drdt(i) * dt;
        V(i) = V_o(i) + dvdt(i) * dt;
        T(i) = T_o(i) + dTdt(i) * dt;
        P(i) = rho(i) * T (i); % non dimensional pressure obtained from real gas equation
    end
    % inlet boundary conditions
    V(1) = 2*V(2) - V(3);
    % outlet boundary conditions
    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);
    


   subplot(4,1,1)
   plot(x,V,'Marker','o')
   title(sprintf('Time %d',t))
   ylabel("Velocity");xlabel("Distance");
   pause(0.00001)
   subplot(4,1,2)
   plot(x,T,'Marker','o')
   title(sprintf('Time %d',t))
   ylabel("Temperature");xlabel("Distance");
   subplot(4,1,3)
   plot(x,rho,'Marker','o')
   title(sprintf('Time %d',t))
   ylabel("Density");xlabel("Distance");
   subplot(4,1,4)
   plot(x,P,'Marker','o')
   title(sprintf('Time %d',t))
   ylabel("Pressure");xlabel("Distance");

end

Conseravtive form:

Equation of continuity-

`(∂(ρA))/(∂t) + (∂(ρAV))/(∂x) = 0`

  • In non dimensional form

`(∂(ρ'A'))/(∂t') + (∂(ρ'A'V'))/(∂x') = 0`

Equation of momentum conservation-

`(∂(ρAV))/(∂t) + (∂(ρAV^2))/(∂x) = -A(∂P)/(∂x)`

  • using `(∂(PA))/(∂x) - P(∂A)/(∂x)= A(∂P)/(∂x)`

`(∂(ρAV))/(∂t) + (∂(ρAV^2) + ∂(PA))/(∂x) = P(∂A)/(∂x)`

  • In non dimensional form

`(∂(ρ'A'V'))/(∂t') + (∂(ρ'A'V' ^ 2) + 1/γ∂(P'A'))/(∂x') = 1/γP'(∂A')/(∂x')`

Equation for energy conservation

`(∂(ρ(e+V^2/2)A))/(∂t) + (∂(ρ(e+V^2/2)AV+PAV))/(∂x) =0`

  • In non dimensional form

`(∂(ρ'((e' )/(γ-1)+γ/2V'^2))A')/(∂t') + (∂(ρ'((e')/(γ-1)+γ/2V'^2)A'V'+P'A'V'))/(∂x') =0`

In terms of dependent variables,U1,U2,U3, the above equations can be written as

`(∂U_1)/(∂t) = -(∂F_1)/(∂x)`

`(∂U_2)/(∂t) = -(∂F_2)/(∂x) +J_2`

`(∂U_3)/(∂t) = -(∂F_3)/(∂x)`

where

`F1 = U2`

`F2 = (U_2^2)/U_1+((γ-1)/γ)*(U_3-γ/2*U_2^2/U_1)`

`F3 = γ(U_3 * U_2)/U_1+(γ(γ-1))/2 * U_2^3 / U_1^2`

`J2 = 1/γ ρ T(∂A)/(∂x)`
Code for conservative flow
close all
clear
clc

dx = 0.1;
x = 0:dx:3; n = length(x);
A = 1 + 2.2*(x - 1.5).^2;
C = 0.5;

%initial conditions
rho = zeros(size(x)); T = zeros(size(x)); V = zeros(size(x));

for i=1:length(x)
    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
        rho(i) = 0.634 - 0.3879*(x(i)-1.5);
        T(i) = 0.833 - 0.3507*(x(i)-1.5);
    end
    V(i) = 0.59/(rho(i)*A(i));
end

% rho = 1 - 0.3146 * x;
% T = 1 - 0.2314 * x;
% V = (0.1 + 1.09 * x).*(T.^0.5);
% V = 0.59./(rho.*A);
% P = rho.*T;


%dependent variables
U1 = rho.*A;
U2 = (rho.*A).*V;
U3 = rho.*(T/(1.4-1)+(1.4/2) * V.^2).*A;
du1dt = zeros(size(x)); du2dt = zeros(size(x)); du3dt = zeros(size(x));
du1dt_p = zeros(size(x)); du2dt_p = zeros(size(x)); du3dt_p = zeros(size(x));
du1dt_c = zeros(size(x)); du2dt_c = zeros(size(x)); du3dt_c = zeros(size(x));



for t = 1:950
    U1_o = U1; U2_o = U2; U3_o = U3;
    F1 = U2;
    F2 = (U2.^2)./U1+((1.4-1)/1.4)*(U3 - (1.4/2)*(U2.^2)./U1);
    F3 = 1.4*(U3 .* U2)./U1 - (1.4*0.4)/2 * (U2.^3) ./ (U1.^2);
    J2 = (1/1.4) * rho .* T;
    
    %time step calculation
    a = T.^0.5;
    dt = C * dx./(a+V);
    dt = min(dt);
    
    for i = 2:length(x)-1
        df1dx_p(i) = (F1(i+1) - F1(i))/dx; df2dx_p(i) = (F2(i+1) - F2(i))/dx; df3dx_p(i) = (F3(i+1) - F3(i))/dx;
        dj2dx_p(i) = J2(i) * (A(i+1)-A(i))/dx;

        du1dt_p(i) = -df1dx_p(i); du2dt_p(i) = -df2dx_p(i) + dj2dx_p(i); du3dt_p(i) = -df3dx_p(i);
        U1(i) = U1_o(i) + du1dt_p(i)*dt;
        U2(i) = U2_o(i) + du2dt_p(i)*dt;
        U3(i) = U3_o(i) + du3dt_p(i)*dt;
    end

    V = U2./U1;
    rho = U1./A;
    T = 0.4 * (U3./U1 - 1.4/2 * V.^2);
    P = rho .* T;

    %updating boundary conditions before corrector step
    U1(1) = rho(1)*A(1);
    U2(1) = 2*U2(2) - U2(3);
    U3(1) = rho(1)*(T(1)/(1.4-1)+1.4/2 * V(1)^2)*A(1);

    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);

    F1 = U2;
    F2 = (U2.^2)./U1+((1.4-1)/1.4)*(U3-(1.4/2)*(U2.^2)./U1);
    F3 = 1.4*(U3 .* U2)./U1 - ((1.4*0.4)/2) * (U2.^3) ./ (U1.^2);
    J2 = (rho.*T)/1.4;

    for i = 2:length(x)-1
        df1dx_c(i) = (F1(i) - F1(i-1))/dx; df2dx_c(i) = (F2(i) - F2(i-1))/dx; df3dx_c(i) = (F3(i) - F3(i-1))/dx;
        dj2dx_c(i) = J2(i) * (A(i)-A(i-1))/dx;

        du1dt_c(i) = -df1dx_c(i); du2dt_c(i) = -df2dx_c(i) + dj2dx_c(i); du3dt_c(i) = -df3dx_c(i);
    end

    du1dt = 0.5*(du1dt_p+du1dt_c);
    du2dt = 0.5*(du2dt_p+du2dt_c);
    du3dt = 0.5*(du3dt_p+du3dt_c);

    for i = 2:length(x)-1
        U1(i) = U1_o(i) + du1dt(i)*dt;
        U2(i) = U2_o(i) + du2dt(i)*dt;
        U3(i) = U3_o(i) + du3dt(i)*dt;
    end

    U1(1) = rho(1)*A(1);
    U2(1) = 2*U2(2) - U2(3);
    U3(1) = rho(1)*(T(1)/(1.4-1)+1.4/2 * V(1)^2)*A(1);

    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);

    V = U2./U1;
    rho = U1./A;
    T = 0.4 * (U3./U1 - 1.4/2 * V.^2);
    P = rho .* T;
    mfr = mfr_co(rho,A,V); %mass flow rate

    subplot(4,1,1)
    plot(x,V,'Marker','o')
    title(sprintf('Time %d',t))
    ylabel("Velocity");xlabel("Distance");
    pause(0.00001)
    subplot(4,1,2)
    plot(x,T,'Marker','o')
    title(sprintf('Time %d',t))
    ylabel("Temperature");xlabel("Distance");
    subplot(4,1,3)
    plot(x,rho,'Marker','o')
    title(sprintf('Time %d',t))
    ylabel("Density");xlabel("Distance");
    subplot(4,1,4)
    plot(x,P,'Marker','o')
    title(sprintf('Time %d',t))
    ylabel("Pressure");xlabel("Distance");

    plot(x,mfr,'Marker','o')
    title(sprintf('Time %d',t))
    ylabel("Pressure");xlabel("Distance");
    

end
Observations:
1) The steady state distribution of the flow under non conservative governing equations
The steady state distribution of the flow under conservative governing equations
The steady state distribution of the primitive variables are nearly identical. This clearly shows that the conservative and non conservtive forms are simply slight modifications of one another which will eventually yoeld the same answer.
2) Time wise distribution of primtive variables under non conservative governing equations
Velocity
Temperature
Density
Pressure

Time wise distribution of primtive variables under conservative governing equations

Velocity

Temperature

Density

Pressure

It is evidently seen that the conservative form reaches a steady state at around 200 time steps in comparison to the non conservative form which stabalises around 300 time steps

3) Mass flow rate of at different time steps

Non conservative form:

Conservative form:

While the end result is same in both the forms, The mass flow rate remains more consistent in the conservative form as compared to the non conservative form.

4) Comparison of Normalised mass flow rate

There are small variations in the mass flow rate in between nodes in the non conservative form while it is nearly uniform in the conservative.

5) Mach number distribution from subsonic to supersonic state

Inference:

While result wise, both non conservative and conservative form yields the same result, the Non conservative form is more susceptable to shocks. The conservative form provides a more stable result on the other hand.

Grid independence test

Velocity at index at which x = 1.5

In the non conservative form:

for dx = 0.1 V = 0.91 ; dx = 0.01 V = 0.96, dx = 0.001 V = 1.36

Here the % increase is greater than 5%

In the conservative form:

for dx = 0.1 V = 0.9 ; dx = 0.01 V = 0.93, dx = 0.001 V = 1.89

Here the percentage change is less than 4%, thus making it much more acceptable.

Inference: Largely both the models are grid independent, but the conservative model shows greater levels ofgrid independence.

Design of code:

The variables used have been explained in the theory

Most other explanations have been given alongside inn the form of comments

Mass flow rate has been obtained using the functions

function mfr = mfr_co(rho,A,V)
% A function which accepts the density, area and velocity of flow
% in order to calculate the mass flow rate
mfr = (rho.*A).*V;
end
function mfr = mfr_nonco(rho,A,V)
% A function which accepts the density, area and velocity of flow
% in order to calculate the mass flow rate
mfr = (rho.*A).*V;
end
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.