Challenge

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

Objective: To simulate the isentropic flow through quasi 1D flow through subsonic-supersonic nozzle, by deriving conservation and non conservation forms of governing equations and solve them by using MacCormack’s technique.

Expected Results:

1.Determine the steady state temperature distribution of the flow field variables.

2.Variation of primitive variables w.r.t timesteps and along the length of nozzle.

3.Mass flow rate distribution inside the nozzle at different timesteps.

4.Compare normalized mass flow rate distribution of both forms.

Theory:

Here we consider the steady isentropic flow through the nozzle. The one end of the nozzle is attached to the reservoir,hence the entering velocity at inlet of the nozzle is assumed to be nearly equal to zero (as compared to outlet velocity and throat velocity). The area of nozzle is varying w.r.t to nozzle,hence it becomes a 2D flow problem.But we assume that flow properties do not vary in the y direction,i.e we neglect the effect of variation of flow properties in y direction. This type of problem is known as quasi 1D flow. This assumption leads to uniform flow properties across any given cross section.

As the one end of the nozzle is attached to the reservoir, the area,A tends to infinity hence velocity is nearly equal to 0. The properties at this point are known as stagnation properties, which are denoted as P0, T0 and ⍴0 as denoted in below figure. The flow expands isentropically towards exit with value as Pe, Te and ⍴e .

Figure(1): schematic diag of nozzle.

A. Governing flow equation:

I. Non-dimensional primitive variables:

 

  II. Non-conservation equation:

  III. Conservation equation:

To write the conservation equation in general form,

Let   Solution vector= U ,Flux vector= F and Source  vector= J. 

        

With the above equations, conservation equation can be written as;

As the above equations are conservative form, here dependent variables are not primitive variables. After solving the above equation, we will get value for U1,U2 and U3. So we define define primitive variables in terms of U1,U2,U3 .

 B. MATLAB CODE TO SOLVE THE GOVERNING EQUATIONS USING MacCormack's technique.

Now to solve the non-conservation and conservation equation numerically we will use MacCormack’s technique    

The code to solve the above equations is divided into 3 parts, 

Part 1: function for non conservation equation.

Part 2: function for conservation equation.

Part 3: Main code to solve above functions.

PART 1: MATLAB CODE FOR FUNCTION OF NON CONSERVATION EQUATION.

function[mass_flow_nonc,rho_nonc,v_nonc,T_nonc,M_nonc,P_nonc,rho_t_nonc,T_t_nonc,P_t_nonc,M_t_nonc]=non_conservation(n,x,dx,gamma,A,C,nt)


%defining domain
n=31;
x=linspace(0,3,n);
dx=x(2)-x(1);

%boundary conditions
rho_nonc=1-0.3146.*x;                    %density
T_nonc=1-0.2314.*x;                      %temperature
v_nonc=(0.1+1.09*x).*T_nonc.^0.5;        %velocity
gamma=1.4;

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

figure(2)
plot(A)
throat=find(A==1);

nt=1400;


for k=1:nt
    
    
    rho_old=rho_nonc;
    v_old=v_nonc;
    T_old=T_nonc;
    
    %time step
    B=(T_nonc.^0.5);
    dt=C.*(dx./((B)+v_nonc));
    dt=min(dt);
    
    %predictor method
    for j=2:n-1
        dvdx=(v_nonc(j+1)-v_nonc(j))/dx;
        drhodx=(rho_nonc(j+1)-rho_nonc(j))/dx;
        dTdx=(T_nonc(j+1)-T_nonc(j))/dx;
        dlogAdx=(log(A(j+1))-log(A(j)))/dx;
        
        %continuity equation
        drhodt_p(j)=-rho_nonc(j)*(dvdx)-rho_nonc(j)*v_nonc(j)*dlogAdx-v_nonc(j)*drhodx;
        
        %momentum equation
        dvdt_p(j)=-v_nonc(j)*(dvdx)-(1/gamma)*(dTdx+(T_nonc(j)/rho_nonc(j))*drhodx);
        
        %energy equation
        dTdt_p(j)=-v_nonc(j)*(dTdx) - (gamma-1)*T_nonc(j)*(dvdx + v_nonc(j)*dlogAdx);
       
        %solution update
         rho_nonc(j)=rho_nonc(j) + drhodt_p(j)*dt;
         v_nonc(j)=v_nonc(j) + dvdt_p(j)*dt;
         T_nonc(j)=T_nonc(j) + dTdt_p(j)*dt;
        
    end
    
    %corrector method
    for j=2:n-1
        dvdx=(v_nonc(j)-v_nonc(j-1))/dx;
        drhodx=(rho_nonc(j)-rho_nonc(j-1))/dx;
        dTdx=(T_nonc(j)-T_nonc(j-1))/dx;
        dlogAdx=(log(A(j))-log(A(j-1)))/dx;
        
        %continuity equation
        drhodt_c(j)=-rho_nonc(j)*(dvdx)-rho_nonc(j)*v_nonc(j)*(dlogAdx)- v_nonc(j)*drhodx;
        
        %momentum equation
        dvdt_c(j)=-v_nonc(j)*(dvdx)-(1/gamma)*((dTdx)+(T_nonc(j)/rho_nonc(j))*drhodx);
        
        %energy equation
        dTdt_c(j)=-v_nonc(j)*(dTdx) - (gamma-1)*T_nonc(j)*(dvdx + v_nonc(j)*dlogAdx);
          
    end
        %computing the average time derivative
        drhodt = 0.5*(drhodt_p + drhodt_c);
        dvdt   = 0.5*(dvdt_p + dvdt_c);
        dTdt  = 0.5*(dTdt_p+ dTdt_c);
        
        %final solution update

        for i = 2:n-1
            rho_nonc(i)= rho_old(i)+drhodt(i)*dt;
            v_nonc(i)=  v_old(i)+dvdt(i)*dt;
            T_nonc(i)=  T_old(i)+dTdt(i)*dt;
        end


        %apply the boundary conditions

        %inlet
        v_nonc(1)=2*v_nonc(2)-v_nonc(3);
        
        %outlet
        v_nonc(n)=2*v_nonc(n-1)-v_nonc(n-2);
        rho_nonc(n)=2*rho_nonc(n-1)-rho_nonc(n-2);
        T_nonc(n)=2*T_nonc(n-1)-T_nonc(n-2);
        
        M_nonc=v_nonc./(T_nonc.^0.5);
        P_nonc=rho_nonc.*T_nonc;
        mass_flow_nonc=rho_nonc.*v_nonc.*A;
        
        %PLOTTING MASS FLOW RATE
        
    rho_t_nonc(k)=rho_nonc(throat);
    T_t_nonc(k)=T_nonc(throat);
    v_t_nonc(k)=v_nonc(throat);
    mass_flow_t_nonc(k)=mass_flow_nonc(throat);
    P_t_nonc(k)=P_nonc(throat);
    M_t_nonc(k)=M_nonc(throat);
        
        figure(3)
        
        if k==50
            plot(x,mass_flow_nonc,'color','g','linewidth',1.5)
            hold on
        elseif k==100
            plot(x,mass_flow_nonc,'color','yellow','linewidth',1.5)
            hold on
        elseif k==200
            plot(x,mass_flow_nonc,'color','blue','linewidth',1.5)
            hold on
        elseif k==400
            plot(x,mass_flow_nonc,'color','magenta','linewidth',1.5)
            hold on
        elseif k==800
            plot(x,mass_flow_nonc,'color','red','linewidth',1.5)
            hold on
        elseif k==1400
            plot(x,mass_flow_nonc,'color','k','linewidth',1.5)
            hold on
        end
        
    title('MASS FLOW RATES AT DIFFERENT TIMESTEPS-NON CONSERVATION FORM')
    xlabel('Distance')
    ylabel('Mass flow rate')   
    legend("50th timestep","100th timestep","200th timestep","400th timestep","800th timestep","1400th timestep")
    grid on
        
    end

Code explaination:

1. The function is defined by the name non_conservation with output variables as mass flow rate , velocity , density , temperature, pressure and Mach number in the nozzle and at throat (t).

2. The domain is defined with grid points ,n=31 ,divided over the length of 3m. Also the boundary condition and area profile of nozzle is defined. This values are taken from CFD book by John D. Anderson.

3. To make our soultion stable , a stability criteria is used, which is CFL<=0.5. From these value min time step value is defined, min(dt).

4. Next predictor step is used to get the predicted values of our primitive variables.

5. Similarly corrector step is used to get the corrected values. Atlast average time derivative value is calculated from predictor and corrector step. And finally the values for primitive variables are calculated for internal grid points;            2 to n-1.

6. Now we apply the boundary at inlet and outlet.

PART 2: MATLAB CODE FOR FUNCTION OF CONSERVATION EQUATION.

function[U1,U2,U3,mass_flow_con,rho,v,T,M,P,rho_t,T_t,v_t,P_t,M_t]=conservation(n,x,dx,gamma,A,C,nt)

n=31;
nt=1400;

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


%initial profile for area,velocity and pressure

A=1+2.2*(x-1.5).^2;
throat_c=find(A==1);
v=0.59./(rho.*A);
P=rho.*T;

%Initial solution vectors
U1=rho.*A;
U2=rho.*A.*v;
U3=rho.*A.*(T./(gamma-1))+((gamma/2)*v.^2);



for k=1:nt
    
    dt=min(C.*dx./(sqrt(T)+v));
    
    U1_old=U1;
    U2_old=U2;
    U3_old=U3;
    
    %calculating flux vectors
    F1=U2;
    F2=((U2.^2)./U1)+((gamma-1)/gamma)*(U3-(gamma/2)*(U2.^2)./U1);
    F3=((gamma*U2.*U3)./U1)-(gamma*(gamma-1)*((U2.^3)./(2*U1.^2)));
    
    %PREDICTOR METHOD
    
    for j=2:n-1
        
        J2(j)=(1/gamma)*rho(j)*T(j)*(A(j+1)-A(j))/(dx);
        
        %continuity equation
        dU1dt_p(j)=-(F1(j+1)-F1(j))/dx;
        
        %momentum equation
        dU2dt_p(j)=-((F2(j+1)-F2(j))/(dx))+J2(j);
        
        %energy equation
        dU3dt_p(j)=-((F3(j+1)-F3(j))/dx);
        
        %Updating new values
        
        U1(j)=U1(j)+dU1dt_p(j)*dt;
        U2(j)=U2(j)+dU2dt_p(j)*dt;
        U3(j)=U3(j)+dU3dt_p(j)*dt;
    end
    
    %updating flux vectors
    F1=U2;
    F2=((U2.^2)./U1)+((gamma-1)/gamma)*(U3-(gamma/2)*(U2.^2)./U1);
    F3=((gamma*U2.*U3)./U1)-(gamma*(gamma-1)*((U2.^3)./(2*U1.^2)));
    
    
    %CORRECTOR METHOD
    
    rho=U1./A;
    v=U2./U1;
    T=(gamma-1)*((U3./U1-(gamma/2)*(v).^2));
    
    for j=2:n-1
        
        J2(j)=(1/gamma)*rho(j)*T(j)*(A(j)-A(j-1))/(dx);
        
        %continuity equation
        dU1dt_c(j)=-(F1(j)-F1(j-1))/dx;
        
        %momentum equation
        dU2dt_c(j)=-((F2(j)-F2(j-1))/dx)+J2(j);
        
        %energy equation
        dU3dt_c(j)=-((F3(j)-F3(j-1))/dx);
    end
    
    %computing average time derivatives
    dU1dt=0.5*(dU1dt_p+dU1dt_c);
    dU2dt=0.5*(dU2dt_p+dU2dt_c);
    dU3dt=0.5*(dU3dt_p+dU3dt_c);
        
    %Final solution matrix

    for i=2:n-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

    %At inlet
    
    U1(1)=rho(1)*A(1);
    U2(1)=2*U2(2)-U2(3);
    v(1)=U2(1)./U1(1);
    U3(1)=U1(1)*((T(1)/(gamma-1))+((gamma/2)*(v(1)).^2));
    
    %At Outlet
    
    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 Primitive value update
    
    rho=U1./A;
    v=U2./U1;
    T=(gamma-1)*((U3./U1-(gamma/2)*(v).^2));
    
    
    %mass flow rate 
    %M=mach number
    
    mass_flow_con=rho.*A.*v;
    P=rho.*T;
    M=(v./sqrt(T));
    
    %THROAT VARIABLES
    
    rho_t(k)=rho(throat_c);
    T_t(k)=T(throat_c);
    v_t(k)=v(throat_c);
    mass_flow_con_t(k)=mass_flow_con(throat_c);
    P_t(k)=P(throat_c);
    M_t(k)=M(throat_c);
    
    %PLOT
    figure(3)
    
    if k==50
        plot(x,mass_flow_con,'k','linewidth',2);
        hold on
    elseif k==100
        plot(x,mass_flow_con,'g','linewidth',2);
        hold on
    elseif k==200
        plot(x,mass_flow_con,'r','linewidth',2);
        hold on
    elseif k==400
        plot(x,mass_flow_con,'m','linewidth',2);
        hold on
    elseif k==800
        plot(x,mass_flow_con,'y','linewidth',2);
        hold on
    elseif k==1400
        plot(x,mass_flow_con,'y','linewidth',2);
        hold on
    end
    
    title('MASS FLOW RATES AT DIFFERENT TIMESTEPS-CONSERVATION FORM')
    xlabel('Distance')
    ylabel('Mass flow rate')
    legend("50th timestep","100th timestep","200th timestep","400th timestep","800th timestep","1400th timestep")
end
end

Code explaination:

1. The function is defined by the name non_conservation with output variables as mass flow rate , velocity , density , temperature, pressure and Mach number in the nozzle and at throat (t).

2. The domain is defined with grid points ,n=31 ,divided over the length of 3m. Also the boundary condition and area profile of nozzle is defined. This values are taken from CFD book by John D. Anderson.

3. To make our soultion stable , a stability criteria is used, which is CFL<=0.5. From these value min time step value is defined, min(dt).

4. As  the dependent variable in the conservation equation are U1,U2 and U3, there values are synthesized from initial conditions of density and temperature (non-dimensional).

5. Next we define the solution vectors and flux vectors. Here flux vectors are defined in terms of U1,U2 and U3.

6. After defining the boundary conditions, we use similar technique of predictor and corrector step for conservation equation.

PART 3: MAIN CODE

n=31;
gamma=1.4;
x=linspace(0,3,n);
dx=x(2)-x(1);
A=1+2.2*(x-1.5).^2;
nt=1400;
throat=find(A==1);


C=0.5; %courant number

%Calling non conservation function

tic;
[mass_flow_nonc,rho_nonc,v_nonc,T_nonc,M_nonc,P_nonc,rho_t_nonc,T_t_nonc,P_t_nonc,M_t_nonc]=non_conservation(n,x,dx,gamma,A,C,nt);
Time_taken_nonc=toc;
hold on

%PLOTTING Variation of properties at throat with number of timesteps
figure(4)

%DENSITY
subplot(4,1,1)
plot(linspace(1,nt,nt),rho_t_nonc,'k')
ylabel('DENSITY')
legend("DENSITY AT THROAT")
axis([0 1400 0 1.3])
title('Timestep variation at throat-NON CONSERVATION FORM')

%TEMPERATURE
subplot(4,1,2)
plot(linspace(1,nt,nt),T_t_nonc,'m')
ylabel('TEMPERATURE')
legend("TEMPERATURE AT THROAT")

%PRESSURE
subplot(4,1,3)
plot(linspace(1,nt,nt),P_t_nonc,'y')
ylabel('PRESSURE')
legend("PRESSURE AT THROAT")


%MACH NUMBER
subplot(4,1,4)
plot(linspace(1,nt,nt),M_t_nonc,'g')
ylabel('MACH NUMBER')
legend("MACH NUMBER AT THROAT")

%plotting variation of primitive variable with nozzle length
figure(5)

%DENSITY
subplot(4,1,1)
plot(x,rho_nonc,'k')
ylabel('Density')
legend("DENSITY")
axis([0 3 0 1])
grid on
title("PROPERTY VARIATION ALONG THE LENGTH OF NOZZLE")

%TEMPERATURE
subplot(4,1,2)
plot(x,T_nonc,'b')
ylabel('TEMPERATURE')
legend("TEMPERATURE")
axis([0 3 0 1])


%PRESSURE
subplot(4,1,3)
plot(x,P_nonc,'r')
ylabel('PRESSURE')
legend("PRESSURE")
axis([0 3 0 1])


%MACH NUMBER
subplot(4,1,4)
plot(x,M_nonc,'m')
ylabel('MACH NUMBER')
legend("MACH NUMBER")
axis([0 3 0 5])






%Calling conservation function
tic;
[U1,U2,U3,mass_flow_con,rho,v,T,M,P,rho_t,T_t,v_t,P_t,M_t]=conservation(n,x,dx,gamma,A,C,nt);
Time_taken_c=toc;
hold on


%PLOTTING Variation of properties at throat with number of timesteps
 figure(6)
Z=linspace(1,nt,nt);
%DENSITY
subplot(4,1,1)
plot(Z,rho_t,'k')
ylabel('DENSITY')
legend("DENSITY AT THROAT")
axis([0 1400 0 3])
title('Timestep variation at throat- CONSERVATION FORM')

%TEMPERATURE
subplot(4,1,2)
plot(Z,T_t,'m')
ylabel('TEMPERATURE')
legend("TEMPERATURE AT THROAT -CONSERVATION")
 
%PRESSURE
subplot(4,1,3)
plot(Z,P_t,'y')
ylabel('PRESSURE')
legend("PRESSURE AT THROAT -CONSERVATION")


%MACH NUMBER
subplot(4,1,4)
plot(Z,M_t,'g')
ylabel('MACH NUMBER')
legend("MACH NUMBER AT THROAT -CONSERVATION")

%plotting variation of primitive variable with nozzle length
figure(7)

%DENSITY
subplot(4,1,1)
plot(x,rho,'k')
ylabel('Density')
legend("DENSITY -CONSERVATION")
axis([0 3 0 1])
grid on
title("PROPERTY VARIATION ALONG THE LENGTH OF NOZZLE-CONSERVATION")

%TEMPERATURE
subplot(4,1,2)
plot(x,T,'b')
ylabel('TEMPERATURE')
legend("TEMPERATURE -CONSERVATION")
axis([0 3 0 1])


%PRESSURE
subplot(4,1,3)
plot(x,P,'r')
ylabel('PRESSURE')
legend("PRESSURE -CONSERVATION")
axis([0 3 0 1])


%MACH NUMBER
subplot(4,1,4)
plot(x,M,'m')
ylabel('MACH NUMBER')
legend("MACH NUMBER -CONSERVATION")
axis([0 3 0 5])



%COMPARISON OF MASS FLOW RATES 
figure(8)

plot(x,mass_flow_nonc,'r','linewidth',1.2)
hold on
plot(x,mass_flow_con,'k','linewidth',1.25)
hold off

grid on

Results:

I. Mass flow rate variation inside the nozzle at different time steps.

Observation:

In both of the forms of equation we can see that mass flow rate becomes steady after 400 timesteps. 

II. Variation of properties at throat with number of time steps.

    

Observation:

Here we see that the value of primitive variables in non conservation equation becomes steady after a while as compared to conservation equation. This can be inferred from the above figure.

III. Variation of properties along the length of nozzle

IV.  Comparison of mass flow rate in both forms of equation

Observation

The graph for non-conservation oscillates more than the conservation graph. Here the mass flow rate is constant with a value of around 0.579. The conservation graph being more closer to being constant matches the exact solution. Although the distribution in above figure have been magnified for more clarity. We can see that the variation in non-conservation comes at inlet and outlet of nozzle.

Grid dependence test:

After changing the grid points from n=31 to 61 we see that at the end of 1400th timestep; the values of primitive variable do not change much. Here we can infere that given problem is grid independent. This test helps us to decrease the simulation time by keeping the values of the variables same.

Conclusion:

1. From the comparison of mass flow rate figure , we conclude that conservation equation gives value closer to exact    value. Here conservation equation does better job.

2. The result for primitive variables by non conservation equation are more accurate than its counter part. However the values for flux terms are slightly more accurate by conservation form.

3. To write the code for conservation form requires more  effort, first we have to define solution vectors in terms of primitive variables ,then define flux vectors in terms of solution vector and then finally solve the equation. This all is not required in non-conservation form. 

4. Although both th form of equation can be used inter dependent on one another, and one can be derived from other. But while solving the problem each one of them has there own pros and cons. Here conservation equation yields faster result as compared to non conservation . In terms of values of primitive variables non conservation does better job. And in terms of complexity of solution , conservation equation is more complex than non conservation.

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.