% Start timer
tic;

% Check if restart flag exists
if (exist('Q1D_restart') == 0),
  Q1D_restart = 0;
end

% CFL number
CFL = 0.90;

if (Q1D_restart == 0),
  
  % Gas properties
  gamma = 1.4;
  Rgas  = 287.06;
  cv    = Rgas/(gamma - 1);
  cp    = cv*gamma;
  
  % Inlet total pressure and temperature
  P0inlet = 101327;
  T0inlet = 288.15;
  poutlet = P0inlet*0.9;
  
  % Maximum number of iterations
  maxiter = 100000;

  % Number of iterations per plot
  nplot = 1;

  % Set grid size and geometry info
  Nx = 40;
  x  = linspace(0,4,Nx+1);
  xc = 0.5*(x(1:Nx) + x(2:Nx+1));
  dx = x(2) - x(1);

  A0 = 10.0;
  A1 =  8.0;
  A2 = 12.0;

  A = zeros(size(x));

  for j = 1:Nx+1,
    xl = x(j);
    if (xl <= 1),
      A(j) = A0;
    elseif (xl <= 2),
      A(j) = A0 + 0.5*(A1-A0)*(1 - cos(pi*(xl-1)));
    elseif (xl <= 3),
      A(j) = A1 + 0.5*(A2-A1)*(1 - cos(pi*(xl-2)));
    else,
      A(j) = A2;
    end
  end
  
  for j = 1:Nx,
    dA(j) = A(j+1) - A(j);
    Vol(1,j) = 1.0/(0.5*(A(j+1)+A(j))*dx);
    Vol(2,j) = 1.0/(0.5*(A(j+1)+A(j))*dx);
    Vol(3,j) = 1.0/(0.5*(A(j+1)+A(j))*dx);
  end
  
  % Allocate space solution and residual vectors
  U  = zeros(3,Nx);
  R  = zeros(3,Nx);
  Fh = zeros(3,1);

  % Initialize flow to stagnation conditions
  pinit   = P0inlet;
  Tinit   = T0inlet;
  uinit   = 0;
  rhoinit = pinit/(Rgas*Tinit);
  
  U(1,:) = rhoinit;
  U(2,:) = rhoinit*uinit;
  U(3,:) = pinit/(gamma-1) + 0.5*rhoinit*uinit^2;
  
  % Initialize niter, restol, curres, and maxres
  niter = 0;
  restol = 1e-4;
  maxres = 0;
  curres = 1;
end

while ((niter < maxiter) & (curres > maxres*restol)),
  % Zero residual
  R(:,:) = 0;
  
  % Set inlet states as follows (we assume a subsonic inlet condition):
  % 
  % P0 = P0inlet (i.e. prescribed)
  % T0 = T0inlet (i.e. prescribed)
  % u  = u(2)    (i.e. set velocity equal to velocity in 2nd cell)
  %
  % Given these three pieces of information, the flux at the inlet
  % can be calculated.

  j = 2;
  P0I  = P0inlet;
  T0I  = T0inlet;
  uI   = U(2,j)/U(1,j);
  a2I  = gamma*Rgas*T0I - 0.5*(gamma-1)*uI^2;
  M2I  = uI^2/a2I;
  pI   = P0I*(1+0.5*(gamma-1)*M2I)^(-gamma/(gamma-1));
  rhoI = gamma*pI/a2I;
  
  U(1,1) = rhoI;
  U(2,1) = rhoI*uI;
  U(3,1) = rhoI*(cp*T0I - pI/rhoI);
  
  % Set outlet states as follows (we assume a subsonic outlet condition):
  % Calculate flux at outlet face and distribute to cell residual
  % To do this, we will assume that the states at the inlet are
  % given as follows:
  % 
  % P0 = P0(Nx-1) (i.e. set equal to total pressure in last cell)
  % T0 = T0(Nx-1) (i.e. set equal to total temperature in last cell)
  % p  = poutlet  (i.e. prescribed)
  %
  % Given these three pieces of information, the flux at the outlet
  % can be calculated.
  
  j   = Nx-1;
  pj  = (gamma-1)*(U(3,j) - 0.5*U(2,j)^2/U(1,j));
  a2j = gamma*pj/U(1,j);
  uj  = U(2,j)/U(1,j);
  JpF = uj + 2*sqrt(a2j)/(gamma-1);
  sF  = pj/U(1,j)^(gamma);
  
  pF  = poutlet;
  
  rhoF = (pF/sF)^(1/gamma);
  a2F  = gamma*pF/rhoF;
  uF   = JpF - 2*sqrt(a2F)/(gamma-1);
  HF   = a2F/(gamma-1) + 0.5*uF^2;

  U(1,Nx) = rhoF;
  U(2,Nx) = rhoF*uF;
  U(3,Nx) = rhoF*(HF - pF/rhoF);

  % Calculate flux at interior faces and distribute to cell residuals
  for j = 2:Nx,
    Fh = Fupwind(U(:,j-1),U(:,j),gamma);
    R(:,j-1) = R(:,j-1) + Fh*A(j);
    R(:,j  ) = R(:,j  ) - Fh*A(j);
  end
  
  % Add source term to each cell residual  
  pvec   = (gamma-1)*(U(3,:) - 0.5*U(2,:).^2./U(1,:));
  R(2,:) = R(2,:) - pvec.*dA;
  
  % Assign timestep
  cvec = sqrt(gamma*pvec./U(1,:));
  lambdamax = max(abs(U(2,:)./U(1,:)) + cvec);  
  dt = CFL*dx/lambdamax;
  niter = niter + 1;
  curres = sqrt(sum((Vol(1,2:Nx-1).*R(1,2:Nx-1)).^2)*dx);
  Res(niter) = curres;  
  if (curres > maxres),
    maxres = curres;
  end
  
  % Update U using Forward Euler (ignoring update to first and last cells)
  U(:,2:Nx-1) = U(:,2:Nx-1) - dt*R(:,2:Nx-1).*Vol(:,2:Nx-1);

  p     = (gamma-1)*(U(3,:) - 0.5*U(2,:).^2/U(1,:));
  rho   = U(1,:);
  u     = U(2,:)./rho;
  a     = sqrt(gamma*p./rho);
  M     = u./a;
  P0    = p.*(1 + 0.5*(gamma-1)*M.^2).^(gamma/(gamma-1));
  Fout  = Fupwind(U(:,Nx-1),U(:,Nx),gamma);

  P0out(niter) = P0(Nx);
  mdot(niter)  = Fout(1)*A(Nx);

  if (mod(niter,nplot) == 0),
    subplot(221);
    plot(xc,M);
    xlabel('x');ylabel('M');
    
    subplot(222);
    plot(log10(Res(min(niter,max(2,niter-199)):niter)));
    xlabel('iters');ylabel('log10 Res');

    subplot(223);
    plot(P0out(min(niter,max(2,niter-199)):niter));
    xlabel('iters');ylabel('P0outlet');

    subplot(224);
    plot(mdot(min(niter,max(2,niter-199)):niter));
    xlabel('iters');ylabel('mdot outlet');
    
    drawnow;
  end
  
end

% Stop timer 
fprintf('Elapsed time = %f\n',toc);
fprintf('Iters        = %i\n',niter);

% Final plot
subplot(221);
plot(xc,M);
xlabel('x');ylabel('M');

subplot(222);
plot(log10(Res));
xlabel('iters');ylabel('log10 RMSres');

subplot(223);
plot(P0out);
xlabel('iters');ylabel('P0outlet');

subplot(224);
plot(mdot);
xlabel('iters');ylabel('mdot outlet');

fprintf('Outlet P0    = %f\n',P0out(niter));
fprintf('Outlet mdot  = %f\n',mdot(niter));










