Project

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

Matlab Code for Conservative Form:

%Conservative form
clear all;
clc all;
close all;

n=61;
x=linspace(0,3,n);
dx=x(2)-x(1);
gaamma=1.4;
c=0.5; %cfl number
e=10e9;
tol=10e-4; %convergence criterion
a=1+2.2*(x-1.5).^2;

%Initial conditions

for i=1:n

    if (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

end

v=0.59./(rho.*a);

U1=rho.*a;
U2=rho.*a.*v;
U3=rho.*(t*(1/(gaamma-1))+(0.5*gaamma*v.^2)).*a;

%time steps
nt=1400;

%loop to calculate from courant number
for z=1:n
dt_x(z)=c*dx/(t(z)^0.5+v(z));
dt=min(dt_x);
end
iter=0;
tic;

%outer time loop
%while e>tol
for k=1:nt 

    U1_old=U1;
    U2_old=U2;
    U3_old=U3;
    rho_old=U1_old./a;
    v_old=U2_old./U1_old;
    t_old=(gaamma-1)*((U3_old./U1_old)-(0.5*gaamma*(v_old.^2)));
    F1=U2;
    F2=((U2.^2)./U1)+(((gaamma-1)/gaamma).*(U3-((0.5*gaamma)*(U2.^2)./U1)));
    %F2=(rho.*a.*v.^2)+(1/gaamma)*rho.*a.*t;
    F3=((gaamma*U2.*U3)./U1)-((gaamma*(gaamma-1)*0.5)*((U2.^3)./(U1.^2)));
    %F3=(rho.*a.*v).*((t/(gaamma-1))+(0.5*gaamma*v.^2))+rho.*a.*v;
    
    %predictor step
   for j=2:n-1
      J2(j)=(1/gaamma)*rho(j)*t(j)*((a(j+1)-a(j))/dx);
      %continuity eqn
      dU1dt_p(j)=-(F1(j+1)-F1(j))/dx;
      %momentum eqn
      dU2dt_p(j)=J2(j)-(F2(j+1)-F2(j))/dx;
      %energy eqn
      dU3dt_p(j)=-(F3(j+1)-F3(j))/dx;
      
      %solution update
      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
   
    rho=U1./a;
    v=U2./U1;
    t=(gaamma-1)*((U3./U1)-(0.5*gaamma*(v.^2)));
    F1=U2;
    F2=((U2.^2)./U1)+(((gaamma-1)/gaamma).*(U3-((0.5*gaamma)*(U2.^2)./U1)));
    %F2=(rho.*a.*v.^2)+(1/gaamma)*rho.*a.*t;
    F3=((gaamma*U2.*U3)./U1)-((gaamma*(gaamma-1)*0.5)*((U2.^3)./(U1.^2)));
    %F3=(rho.*a.*v).*((t/(gaamma-1))+(0.5*gaamma*v.^2))+rho.*a.*v;
    
   
    %corrector step
    
    for i=2:n-1
      J2(i)=(1/gaamma)*rho(i)*t(i)*((a(i)-a(i-1))/dx);
      %continuity eqn
      dU1dt_c(i)=-(F1(i)-F1(i-1))/dx;
      %momentum eqn
      dU2dt_c(i)=J2(i)-(F2(i)-F2(i-1))/dx;
      %energy eqn
      dU3dt_c(i)=-(F3(i)-F3(i-1))/dx;
      
      %solution update
      U1(i)=U1(i)+dU1dt_c(i)*dt;
      U2(i)=U2(i)+dU2dt_c(i)*dt;
      U3(i)=U3(i)+dU3dt_c(i)*dt;
   end
   
   %calculate average time derivative
   dU1dt=0.5*(dU1dt_p+dU1dt_c);
   dU2dt=0.5*(dU2dt_p+dU2dt_c);
   dU3dt=0.5*(dU3dt_p+dU3dt_c);
   
   %final solution update
    for k=2:n-1
    U1(k)=U1_old(k)+dU1dt(k)*dt;
    U2(k)=U2_old(k)+dU2dt(k)*dt;
    U3(k)=U3_old(k)+dU3dt(k)*dt;    
    end
    
    %apply boundary conditions
    %inlet
    rho(1)=U1(1)./a(1);
    v(1)=U2(1)./(rho(1).*a(1));
    U2(1)=2*U2(2)-U2(3);
    U3(1)=U1(1).*(t(1)*(1/(gaamma-1))+(0.5*gaamma*v(1).^2));
    
    
    %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);
    
    %updating values
    rho=U1./a;
    v=U2./U1;
    t=(gaamma-1)*((U3./U1)-(0.5*gaamma*(v.^2)));
    
    
    e_rho=max(abs(rho-rho_old));
    e_v=max(abs(v-v_old));
    e_t=max(abs(t-t_old));
    error_matrix=[e_rho e_v e_t];
    e=max(error_matrix);
    iter=iter+1;
end
toc;
simulation_time=toc;
    %plot(x,v);
    %title(sprintf(\'Time step=%d\',k))
    %pause(0.03)
    %mass flow rate
   m=(rho.*v.*a);
   plot(x,m);

Matlab Code Non-Conservative Form:

%Non-Conservative form
clear all;
clc all;
close all;

n=61;
x=linspace(0,3,n);
dx=x(2)-x(1);
gaamma=1.4;
c=0.5; %cfl number
e=10e9;
tol=10e-4; %convergence criterion

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


%time steps
nt=1400;

%loop to calcualate from courant number
for z=1:n
dt_x(z)=c*dx/(t(z)^0.5+v(z));
dt=min(dt_x);
end
iter=0;
tic;
%outer time loop
%while e>tol
for k=1:nt 
    
    rho_old=rho;
    v_old=v;
    t_old=t;
    
    %predictor step
    
   for j=2:n-1
    
      dvdx=(v(j+1)-v(j))/dx;
      drhodx=(rho(j+1)-rho(j))/dx;
      dtdx=(t(j+1)-t(j))/dx;
      dlogadx=(log(a(j+1))-log(a(j)))/dx;
    
      %continuity eqn
      drhodt_p(j)=(-rho(j)*dvdx)-(rho(j)*v(j)*dlogadx)-(v(j)*drhodx);
    
      %momentum eqn
      dvdt_p(j)=-v(j)*dvdx-(1/gaamma)*(dtdx+(t(j)/rho(j))*drhodx);
    
      %energy eqn
      dtdt_p(j)=(-v(j)*dtdx)-(gaamma-1)*t(j)*(dvdx+v(j)*dlogadx);
    
      %solution update
      rho(j)=rho(j)+drhodt_p(j)*dt;
      v(j)=v(j)+dvdt_p(j)*dt;
      t(j)=t(j)+dtdt_p(j)*dt;
     
   end
   
   
    %corrector step
    
   for j=2:n-1
    
      dvdx=(v(j)-v(j-1))/dx;
      drhodx=(rho(j)-rho(j-1))/dx;
      dtdx=(t(j)-t(j-1))/dx;
      dlogadx=(log(a(j))-log(a(j-1)))/dx;
    
      %continuity eqn
      drhodt_c(j)=-rho(j)*dvdx-rho(j)*v(j)*dlogadx-v(j)*drhodx;
    
      %momentum eqn
      dvdt_c(j)=-v(j)*dvdx-(1/gaamma)*(dtdx+(t(j)/rho(j))*drhodx);
    
      %energy eqn
      dtdt_c(j)=(-v(j)*dtdx)-(gaamma-1)*t(j)*(dvdx+v(j)*dlogadx);
    
   end
      
   %calculate 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(i)=rho_old(i)+drhodt(i)*dt;
    v(i)=v_old(i)+dvdt(i)*dt;
    t(i)=t_old(i)+dtdt(i)*dt;
    end
    
    %apply boundary conditions
    %inlet
    v(1)=2*v(2)-v(3);
    
    %outlet
    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);
    e_rho=max(abs(rho-rho_old));
    e_v=max(abs(v-v_old));
    e_t=max(abs(t-t_old));
    error_matrix=[e_rho e_v e_t];
    e=max(error_matrix);
    iter=iter+1;
    
    %plot(x,v);
    %title(sprintf(\'Time step=%d\',k))
    %pause(0.03)
    
%end
end
toc;
simulation_time=toc;
 %mass flow rate
      m=(rho.*v.*a);
      plot(x,m);

Normalized Mass Flow Rates:

Conservative Form:

Non-Conservative Form:

Conclusion:

From the above results, it can be concluded that the results corresponding to conservative form is near to the analytical results and shows good agreement with the actual results

Number of iterations for Convergence:

Conservative form: For a residual of 10e-4, the number of iterations required to reach convergence is 182

Non-Conservative form:For a residual of 10e-4, number of iterations required to reach convergence is 276

Simulation Time:

Conservative form:12.074 sec

Non-Conservative form:14.6266 sec

This shows that for 1400 timesteps Solution by Conservative form is faster than Non-Conservative form

Grid Dependency Test:

Conservative form:

Results @ throat for a grid size of 31:

rho_throat:0.65238 temp_throat:0.84107 vel_throat:0.89692

Results @ throat for a grid size of 61:

rho_throat:0.63899 temp_throat:0.83566 vel_throat:0.91216

Non-Conservative form:

Results @ throat for a grid size of 31:

rho_throat:0.6386 temp_throat:0.83645 vel_throat:0.91402

Results @ throat for a grid size of 61:

rho_throat:0.63766 temp_throat:0.91382 vel_throat:0.83544

From the results, it can be seen that there is not much difference in the results for 31 grid points and 61 grid points for both conservative & non-conservative form. This confirms the grid dependency test i.e. in order to save computation time and cost, a grid with 31 nodes will do the same work as that of a grid with 61 nodes.

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.