Challenge

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

Nozzle - nozzle is used to control the velocity of fluid flow flowing through nozzle.

As area of the nozzle decreases, speed of fluid flow increases because when area decreases,
the pressure also decreases and the fluid flows fast due to decrease in pressure (Convergent type nozzle )

When area of the nozzle increases the fluid get more space to stay in the increased area,this causes increase in pressure at that area, therefore fluid flow velocity decreases when area increase(Divergent type nozzle)

In our case, the nozzle is convergent-divergent.(subsonic-supersonic)
In subsonic part, the mach number is less than 1(appropriately 0.65) and in supersonic part,the mach number is greater than 1 (appropriately 1.35)

In this project, our main objective is to perform the simulation of fluid flowing through convergent-divergent nozzle

For this,we are going to solve the quasi 1-Dimensional nozzle flow equation in matlab.

Conservative and non conservative forms of governing eqaution.

Governing pde's can be shown by different means

Conservative forms

Non-conservative form

Dimensional form

Non dimensional form

Conservative and non conservative forms are different in numerical discretization

Conservative and non conservative forms are meaningful when we solve them computationally,

Analytically they are menaning less.

The conservative form is more accurate than non conservative form.
It tends to work well with shocks or discontinuities exist in the domain.



About PDE.

Convert the integral form of governing equations into partial derivative form and also to follow quasi-one-dimensional assumption while doing this.

We will get pde's set of eqaution
(i.e continuity equation, momentum equation, energy equation)

Continuity equation



Momentum equation



Energy equation in terms of temperature

non dimensional temperature,density, area, time, velocity.

, , ,

The above equations are the most convinient for time marching solution of quasi one dimensional flow and it is in non conservation and in dimensionless form.

Mostly the nozzle flow variables are expressed in non dimensional form
But to take dimensional form is also fine.
It depends completely on cfd engineer to which form to take for solving
There is no real difference as per the numerics are concerned.

Firstly, we are going to perform simulation by Non conservative form

The steps of the cfd are

Meshing
Descretization
Solving


In meshing

To mesh the 1-Dimensional domain of nozzle
(x direction) into number of grid points

In reality the flowfield variation in nozzle is in both x and y direction but we assumed that these variation is going to held in x direction only.

To solve the governing equations which are made appropriate for nozzle flow equations in matlab for each and every grid point of domain but excluding the boundary grid points because the initial and final values of variables are known there.

Discretization

The LHS of the governing equation has time derivatives
So the solution will be the time marching solutions
We are going to solve these equations explicitly.

Explicit scheme - The current solution for a variable is fully dependent on parameters at previous time.

MacCormack's technique

In this technique,we are going to split the time marching in two phase

Predicted step
corrector step

Predictor step

We start with the initial condition to calculate the value at next time step but it is not the complete time step, it is only the prediction step

Forward difference scheme is applied on RHS space terms

Solution update

In this step,with the help of predicted time derivative,the updated time marching term is been computed

Corrector step

In this step we find corrected value of time marching term.

Backward difference scheme is applied on space terms

Then the Average of predicted and corrected terms is calculated.

As we are solving this explicitly, the courant number stability criteria should get followed.
C should be less than 1.

Predictor step equation

(∂ρ/∂t)predicted = -ρiN[vNi+1 _ v­iN/Δx] ­­– ρiN viN [ln(Ai+1) – ln(Ai)/Δx] – viN[ρi+1N – ρiN/Δx]

(∂v/∂t)predicted = ­­-viN[vNi+1 _ v­iN/Δx] ­­– (1/ϒ)[Ti+1N – TiN /Δx + T­i/ρiN(ρi+1N – ρiN/Δx)]

(∂v/∂t)predicted = ­­-viN [Ti+1N – TiN /Δx] – (ϒ-1)TiN [vNi+1 _ v­iN/Δx + v­iN[ln(Ai+1) – ln(Ai)/Δx]

Updated solution

ρupdated = ρinitial condition + (∂ρ/∂t)predictedΔt

vupdated = vinitial condition + (∂v/∂t)predictedΔt

Tupdated = Tinitial condition + (∂v/∂t)predictedΔt

Corrector step

(∂ρ/∂t)corrector = -ρiN[vui _ v­i-1u/Δx] ­­- ρiu viu [ln(Ai) – ln(Ai-1)/Δx] – viu[ρiu – ρi-1u/Δx]

(∂v/∂t)corrector = ­­-viu[vui _ v­i-1u/Δx] ­­– (1/ϒ)[Tiu – Ti-1u /Δx + T­i/ρiu(ρiu – ρi-1u/Δx)]

(∂T/∂t)corrector = ­­-viu [Tiu – Ti-1u /Δx] – (ϒ-1)Tiu [vui _ v­i-1u/Δx + v­iu[ln(Ai) – ln(Ai-1)/Δx]

Average of predicted and corrected

(∂ρ/∂t)average = 0.5 [ (∂ρ/∂t)predicted + (∂ρ/∂t)corrector ]

(∂v/∂t)average = 0.5 [ (∂v/∂t)predicted + (∂v/∂t)corrector ]

(∂T/∂t)average = 0.5 [ (∂T/∂t)predicted + (∂T/∂t)corrector ]

We considered steady, isentropic flow through convergent divergent nozzle

The flow at inlet to the nozzle comes from a reserviour where the pressure and temperature are denoted by Po and To respectively

The flow expands to supersonic speed at the exit of nozzle

At throat (M = 1)

We made assumption that the flow properties varies only with respect to x

Such flow is quasi one dimensional flow.

The flow field variables changes from one time step to next

As the time step proceeds ,the flow field variables approaches to zero(i.e the steady state gets achieved)

MATLAB CODING FOR NON-CONSERVATION

FUNCTION FOR PREDICTOR STEP

% function for predictor method

function [Continuity,Momentum,Energy] = non_conservation_pr(rho,v,t,a,j,dx,gamma)

drhodx = (rho(j+1)-rho(j))/dx;
dvdx = (v(j+1)-v(j))/dx;
dtdx = (t(j+1)-t(j))/dx;
dlog_adx = (log(a(j+1))-log(a(j)))/dx;

% continuity equation

Continuity = -rho(j)*dvdx - rho(j)*v(j)*dlog_adx - v(j)*drhodx;

% Momentum equation

Momentum = -v(j)*dvdx - (1/gamma)*(dtdx + (t(j)/rho(j))*drhodx);

% Energy equation in terms of temperature

Energy = -v(j)*dtdx - (gamma-1)*t(j)*(dvdx + v(j)*dlog_adx);

end

FUNCTION FOR CORRECTOR STEP

 function for corrector method

function [Continuity,Momentum,Energy] = non_conservation_cr(rho,v,t,a,j,dx,gamma)

drhodx = (rho(j)-rho(j-1))/dx;
dvdx = (v(j)-v(j-1))/dx;
dtdx = (t(j)-t(j-1))/dx;
dlog_adx = (log(a(j))-log(a(j-1)))/dx;

% continuity equation

Continuity = -rho(j)*dvdx - rho(j)*v(j)*dlog_adx - v(j)*drhodx;

% Momentum equation

Momentum = -v(j)*dvdx - (1/gamma)*(dtdx + (t(j)/rho(j))*drhodx);


% Energy equation in terms of temperature

Energy = -v(j)*dtdx - (gamma-1)*t(j)*(dvdx + v(j)*dlog_adx);

end

For both corrector and predictor, the name of a function should be the name of the file.

main code

% The program for macCormak technique

clear 
close all
clc

% giving inputs

n = 31; % Number of grid points/Nodes 
L = 3;
x = linspace(0,L,n);
dx = x(2)-x(1);
gamma = 1.4;

% Initial Conditions

rho = 1 - 0.3146*x;
t   = 1 - 0.2314*x;   % t = temperature
v   = (0.1 + 1.09*x).*t.^0.5;

% area 
 a = 1+2.2*(x - 1.5).^2;
 
 % Time step
 
 nt = 800;
 
 % C = to assign the courant number which stabilizes the solution 
 C = 0.5;
 dt = min((C.*dx)./(sqrt(t)+v));   % a = squareroot of t (t = temperature)
 
 % time loop
 tic;
 for k = 1:nt
     
     rho_old = rho;
     v_old = v;
     t_old = t;
     
     
     % predictor step
     
     for j = 2:n-1
         
     [drho_dt_pr(j),dvdt_pr(j),dtdt_pr(j)] = non_conservation_pr(rho,v,t,a,j,dx,gamma);
         
     
     % solution update step
     
     rho(j) = rho(j) + drho_dt_pr(j)*dt;
     v(j)   = v(j) + dvdt_pr(j)*dt;
     t(j)   = t(j) + dtdt_pr(j)*dt;
    
     end   
    % Corrector step 
    for j = 2:n-1
        
        [drho_dt_cr(j),dvdt_cr(j),dtdt_cr(j)] = non_conservation_cr(rho,v,t,a,j,dx,gamma);
         
    end    
        
    % average of predicted and corrector terms
    
    drhodt = 0.5*(drho_dt_pr + drho_dt_cr);
    dvdt =   0.5*(dvdt_pr + dvdt_cr);
    dtdt =   0.5*(dtdt_pr +dtdt_cr);
    
    % 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
    
    % boundary conditions
    
    
   % Inlet BC 
   v(1) = 2*v(2) - v(3);
    
    % Outlet BC
    
    rho(n) = 2*rho(n-1)-rho(n-2);
    v(n) = 2*v(n-1) - v(n-2);
    t(n) = 2*t(n-1) - t(n-2);
    
    m = rho.*a.*v;      % mass flow rate
    mach = v./(sqrt(t));
    P = rho.*t;        % t = temperature
    
    % Solution Update at Throat 
    
    rho_throat(k) = rho(16);
    temp_throat(k) = t(16);
    P_throat(k) = P(16);
    mach_th(k)  = mach(16);
    v_throat(k) = v(16);
    m_throat(k) = m(16);
    k_throat = 1:nt;
    
    toc
    
    
    % Variation of mass flow rate distribution inside the nozzle at
    % different time steps
    
      figure(1)
      hold on
      if k == 50
      plot(x,m);
      elseif k==200
      plot(x,m,'o')
      elseif k == 300
      plot(x,m);
      elseif k == 500
      plot(x,m,'r')
      grid on
      title('Mass flow rate at different time steps','Fontsize',15)
      xlabel('Non dimensional distance through nozzle','Fontsize',15)
      ylabel('non dimensional mass flow rate','Fontsize',15)
      end
 end
 
 
 % Steady state distribution of primitive variables inside the nozzle
 
 figure(2)
 subplot(2,3,1)
 plot(x,v,'Linewidth',2)
 title('velocity profile','Fontsize',15)
 xlabel ('x/L')
 ylabel('velocity ratio')
 grid on
 
 subplot(2,3,2)
 plot(x,rho,'Linewidth',2)
 title('density profile','Fontsize',15)
 xlabel('x/L')
 ylabel('density ratio')
 grid on
 
 subplot(2,3,3)
 plot(x,t,'Linewidth',2)
 title('   temp profile','Fontsize',15)
 xlabel('x/L')
 ylabel('temperature ratio')
 grid on
 
 subplot(2,3,4)
 plot(x,mach,'Linewidth',2)
 title('Mach number','Fontsize',15)
 xlabel('x/L')
 ylabel('Mach number')
 grid on
 
 subplot(2,3,5)
 plot(x,P,'Linewidth',2)
 title('pressure profile','Fontsize',15)
 xlabel('x/L')
 ylabel('Pressure ratio')
 grid on 
 
 
 
     
 % time wise variation of primitive variations    
  figure(3)
  subplot(2,2,1)
  plot(rho_throat,'Linewidth',2)
  title('density profile at throat','Fontsize',15)
  xlabel('time step')
  ylabel('density ratio')
  
  subplot(2,2,2)
  plot(temp_throat,'Linewidth',2)
  title('temp profile at throat','Fontsize',15)
  xlabel('time step')
  ylabel('temperature ratio')
  
  subplot(2,2,3)
  plot(P_throat,'Linewidth',2)
  title('pressure profile at throat','Fontsize',15)
  xlabel('time step')
  ylabel('pressure ratio')
  
  subplot(2,2,4)
  plot(m_throat,'Linewidth',2)
  title(' Mach no profile at throat','Fontsize',15)
  xlabel('time step')
  ylabel('M')
  
  
 % NORMALIZED MASS FLOW RATE
 
 figure(4)
 plot(x,m,'Linewidth',2)
 title('Normalized mass flow rate','Fontsize',15)
 xlabel('x/L')
 ylabel('mass flow rate')
 grid on
 
 
 
 

output

(Diagram 1) variation of primitive variables with nozzle length. (Diagram 2) variation of primitive variables with time step

(Diagram 3) Mass flow rate at different time steps

(Diagram 4) Normalized mass flow rate

simulation time for Non-Conservation form is 3.67 seconds for 31 grid points and at 800 time steps

CONSERVATION FORM

Continuity equation

∂(ρ’A’)/∂t’ + ∂(ρ’A’v’)/∂x’ = 0

Momentum equation

∂(ρ’A’v’)/∂t’ + ∂[(ρ’A’v’2) + (1/ϒ)p’A’]/∂x’ = (1/ϒ)p’(∂A’/∂x’)

Energy equation

∂[ρ’(e’/ϒ-1 + (ϒ/2)v’2)A’]/∂t’ + ∂[ρ’(e’/ϒ-1 + (ϒ/2)v’2)A’v’ +p’A’v’]/∂x’ = 0

MATLAB CODING FOR CONSERVATION FORM

FUNCTION FOR PREDICTOR STEP

% CONSERVATION FORM

% function for Predictor step

function [Continuity,Momentum,Energy] = conservation_pr(t,a,i,dx,gamma,f1,f2,f3,rho)
         
     dadx  = (a(i+1)-a(i))/dx;
     df1dx = (f1(i+1)-f1(i))/dx;
     df2dx = (f2(i+1)-f2(i))/dx;
     df3dx = (f3(i+1)-f3(i))/dx;
     
     
     j2 = (rho.*t.*dadx)./gamma;    %%% p = rho.*t
     
     % continuity Equation
     
      Continuity = -df1dx;
     
     % Momentum Equation
     
       Momentum = -df2dx + j2(i);
     
     % Energy Equation
     
       Energy = -df3dx;
     
end     
     
     

FUNCTION FOR CORRECTOR STEP

% FUNCTION FOR CORRECTOR STEP
% CONSERVATION FORM


function [Continuity,Momentum,Energy]= conservation_cr(t,a,i,dx,gamma,f1,f2,f3,rho)

     dadx  = (a(i)-a(i-1))/dx;
     df1dx = (f1(i)-f1(i-1))/dx;
     df2dx = (f2(i)-f2(i-1))/dx;
     df3dx = (f3(i)-f3(i-1))/dx;

     
 j2 = (rho.*t.*dadx)./gamma;     %%% p = rho.*t
     
     % continuity Equation
     
      Continuity = -df1dx;
     
     % Momentum Equation
     
       Momentum = -df2dx + j2(i);
     
     % Energy Equation
     
       Energy = -df3dx;
     
end     

MAIN CODE

% MAIN PROGRAM FOR CONSERVATION BY MACCORMACK'S TECHNIQUE
% CONSERVATION FORM

clear
close all
clc

% giving Inputs

n = 31;
L = 3;
x = linspace(0,L,n);
dx = x(2) - x(1);
gamma = 1.4;

% Initial Condition

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

% density and temperature initial condition

rho = zeros(1,n);
t = zeros(1,n);
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       

% Velocity Condition

v = 0.59./(rho.*a);
 
% initial Condition for Solution

e = t;
p = rho.*t;
u1 = rho.*a;
u2 = rho.*a.*v;
u3 = rho.*a.*((e/(gamma-1)) + ((gamma/2)*v.^2));


%time steps

nt = 800;
C = 0.5;     % courant number stablity criteria  
dt = min((C.*dx)./(sqrt(t)+v));   % a = squareroot of t (t = temperature)


% time loop
tic;
for k = 1:nt
    
    
    u1_old = u1;
    u2_old = u2;
    u3_old = u3;
    
    %flux terms in pure form
    
    f1 = u2;
    term1 = (u3./u1) - ((gamma/2)*((u2./u1).^2));
    f2 = ((u2.^2)./u1)+(u1.*term1.*(gamma-1))./(gamma);
    term2 = (gamma*(gamma-1)*(u2.^3))./(2*u1.^2);
    f3 =((gamma*u2.*u3)./u1)-term2;
    
    % Predictor method
     
    for i = 2:n-1
    
    % GOVERNING PDES
    
    [du1_dt_pr(i),du2_dt_pr(i),du3_dt_pr(i)] = conservation_pr(t,a,i,dx,gamma,f1,f2,f3,rho);
    
    % SOLUTION UPDATE
    
    u1(i)= u1(i) + du1_dt_pr(i)*dt;
    u2(i)= u2(i) + du2_dt_pr(i)*dt;
    u3(i)= u3(i) + du3_dt_pr(i)*dt;
    
    end
    
rho = u1./a;
v = u2./u1;
t = (gamma-1)*((u3./u1)- ((gamma*v.^2)/2));

    
 % update flux term in pure form

    f1 = u2;
    term1 = (u3./u1) - ((gamma/2)*((u2./u1).^2));
    f2 = ((u2.^2)./u1)+(u1.*term1.*(gamma-1))./(gamma);
    term2 = (gamma*(gamma-1)*(u2.^3))./(2*u1.^2);
    f3 =((gamma*u2.*u3)./u1)-term2;
    

% Corrector method

for i = 2:n-1
    
 [du1_dt_cr(i),du2_dt_cr(i),du3_dt_cr(i)] = conservation_cr(t,a,i,dx,gamma,f1,f2,f3,rho);
    
end

%calculating the average value

du1_dt = 0.5*(du1_dt_pr + du1_dt_cr);
du2_dt = 0.5*(du2_dt_pr + du2_dt_cr);   
du3_dt = 0.5*(du3_dt_pr + du3_dt_cr);

%SOLUTION UPDATE

    for j = 2:n-1
        
    u1(j)= u1_old(j) + du1_dt(j)*dt;
    u2(j)= u2_old(j) + du2_dt(j)*dt;
    u3(j)= u3_old(j) + du3_dt(j)*dt;
    end
    
   % apply boundary coditions
   
   % INLET BC
   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));
   
   
   % outlet bc
   
   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);
   
   % Obtaining primitive varibles
   rho = u1./a;
   v = u2./u1;
   t = (gamma-1)*((u3./u1)- ((gamma*v.^2)/2));
   p = rho.*t;
   mach = v./(sqrt(t)); 
   m = rho.*a.*v;
   
   % Solution Update at Throat 
    
    rho_throat(k) = rho(16);
    temp_throat(k) = t(16);
    p_throat(k) = p(16);
    mach_th(k)  = mach(16);
    v_throat(k) = v(16);
    m_throat(k) = m(16);
    k_throat = 1:nt; 
    
    toc
    
    
    % Variation of mass low rate distribution inside the nozzle at
    % different time steps
    
      figure(1)
      hold on
      if k == 50
      plot(x,m);
      elseif k==200
      plot(x,m,'o')
      elseif k == 300
      plot(x,m,'y','Linewidth',2)
      elseif k == 500
      plot(x,m,'r','Linewidth',2)
      grid on
      title('Mass flow rate at different time steps','Fontsize',15)
      xlabel('Non dimensional distance through nozzle','Fontsize',15)
      ylabel('non dimensional mass flow rate','Fontsize',15)
      end
    
end 
   



   
% Steady state distribution of primitive variables inside the nozzle
 
 figure(2)
 subplot(2,3,1)
 plot(x,v,'Linewidth',2)
 title('velocity profile','Fontsize',15)
 xlabel ('x/L')
 ylabel('velocity ratio')
 grid on
 
 subplot(2,3,2)
 plot(x,rho,'Linewidth',2)
 title('density profile','Fontsize',15)
 xlabel('x/L')
 ylabel('density ratio')
 grid on
 
 subplot(2,3,3)
 plot(x,t,'Linewidth',2)
 title('   temp profile','Fontsize',15)
 xlabel('x/L')
 ylabel('temperature ratio')
 grid on
 
 subplot(2,3,4)
 plot(x,mach,'Linewidth',2)
 title('Mach number','Fontsize',15)
 xlabel('x/L')
 ylabel('Mach number')
 grid on
 
 subplot(2,3,5)
 plot(x,p,'Linewidth',2)
 title('pressure profile','Fontsize',15)
 xlabel('x/L')
 ylabel('Pressure ratio')
 grid on    
 
 
     
  % Time wise variation of primitive variables
  
  figure(3)
  
  subplot(2,2,1)
  plot(rho_throat,'Linewidth',2)
  title('density profile at throat','Fontsize',15)
  xlabel('time step')
  ylabel('density ratio')
  
  subplot(2,2,2)
  plot(temp_throat,'Linewidth',2)
  title('temp profile at throat','Fontsize',15)
  xlabel('time step')
  ylabel('temperature ratio')
  
  subplot(2,2,3)
  plot(p_throat,'Linewidth',2)
  title('pressure profile at throat','Fontsize',15)
  xlabel('time step')
  ylabel('pressure ratio')
  
  subplot(2,2,4)
  plot(mach_th,'Linewidth',2)
  title('  Mach no profile at throat','Fontsize',15)
  xlabel('time step')
  ylabel('M')
  
   
 % NORMALIZED MASS FLOW RATE
 
 figure(4)
 plot(x,m,'Linewidth',2)
 title('Normalized mass flow rate','Fontsize',15)
 xlabel('x/L')
 ylabel('mass flow rate')
 grid on 
   
   

OUTPUT

(diagram 1) variation of primitive variables with nozzle length. (diagram 2) variation of primitive variables with time step

(diagram 3) Mass flow rate at different time step

(Diagram 4) Normalized mass low rate.

For both conservative and non conservative form

The (diagram 1) are the distribution of primitive variables inside the nozzle for quasi 1D nozzle flow equation for 800 time step at 31 grid points

The variables changes as the nozzle length varies

(diagram 2)

the diagram 2 is the variation of primitive variables at throat where mach number is one

for both Non-conservative and conservative forms,at the initial time step there are much more variation but later as the time step increases the solution achieves steady state.

diagram (3)

mass flow rate at different time steps

for both Non-conservative and Conservative forms, we checked the mass flow rate at 50,200, 300,500 time steps and it shows that, as the time step proceeds, the solution achieves steadyness.

At 500 time step, it starts achieving steady state which is represented by red line in diagram 3

diagram(4)

Normalized mass flow rate

in non-conservation form,mass flow rate first increases then decreases at throat, then again increases in diverging section as per the convergent - divergent nozzle is concerned

In Conservation form, at nearer to throat, the mass flow rate is higher as compare to mass flow rate at throat in non conservation form,and it is true because as area decreases mass flow rate should increase

Simulation time

The simulation time for non conservation form is less than the simulation time for conservation form.This is because,the coding of non conservation form is not so complex as compare to conservaion form, also there are no flux terms present in it.

we conclude that for both forms, all the results are same excluding the results of mass flow rate distribution

grid point test

The velocity, mach number ,density, pressure, temperature does not have any major variation in graphs as number of nodes increases or we can say 'changes'.

but the mass flow rate have smooth changes because as number of nodes increases, we get the more information about mass flow rate in 3m length of nozzle.

non conservation form mass flow rate, at n = 61

conservation form mass flow rate at n = 61

The mass flow rate graph is very much different at n = 31 and at n = 61

so appropriate number of nodes should be taken for the required mass flow rate and also the courant number stability criteria should get followed while choosing number of nodes

As number of grid points increases, simulation time also increases for both the cases

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.