The quasi-one-dimensional model describing the flow of compressible gas in rocket nozzles is very common. The corresponding equations have a divergent non dimensional form
$ \frac{\partial \mathbf{U}}{\partial t}+\frac{\partial \mathbf{F}}{\partial x}=\mathbf{J}$
where
$ U_1=\rho A, U_2=\rho A V, U_3=\rho A (\frac{e}{\gamma -1}+\frac{\gamma}{2}V^2)$
$ F_1=\rho A V, F_2=\rho A V^2 +\frac{1}{\gamma}p A, F_3=\rho V A (\frac{e}{\gamma -1}+\frac{\gamma}{2}V^2)$
$ J_1=J_3=0, J_2=\frac{1}{\gamma}p\frac{\partial A}{\partial x}, p=\rho T.$
Here $e=T$ is an internal energy, $T$ is a temperature, $\rho$ is a density, $V$ is velocity, and $A$ is an area of nozzle cross section.
There are 7 repository results on GitHub for quasi 1D nozzle flows with 3 codes in MATLAB, 2 in Python, 1 in C++, and 1 in Java:
To simulate quasi-one-dimensional compressible Euler equations C++
CFD solution of quasi-1D nozzle flows using finite difference approach (MATLAB)
MATLAB code for computing quasi-1D nozzle flow and sensitivities using CSA
Numerical Solutions of quasi-1d nozzle flows (Python)
But there is nothing for Mathematica. In this post, we demonstrate codes translated for Mathematica and testing using data from the NASA portal. First code translated from here is given by
(*# Global variables*)
gamma = 1.4(* # Specific heat ratio*);
c = 0.5 (*# Courant number*);
(*# Grid generation*)
dx = 0.2 (*# Grid size*);
xstart = 0.0 (* # Starting x-position*);
xstop = 10.0 (* # Stopping x-position*);
x = Range[xstart, xstop, dx];
n = Length[x](* # Number of grid points*);
(*# Nozzle area distribution*)
A0[x_] := 1 + 2.2*((x - 1.5)^2)(* # Anderson Appendix B*);
half = Round[n/2];
A = Table[If[i <= half, 1.75 - 0.75*Cos[(0.2*x[[i]] - 1.0) Pi],
1.25 - 0.25*Cos[(0.2*x[[i]] - 1.0)*Pi]], {i, n}]; ListPlot[A]
(*# Flow field variables
# Note that these are dimensionless*)
rho = 0.9608492 -
0.07526785000260212`*
x (*# Density normalized by reservoir density,rho0 in case of \
Pout/Pin=.16; *);
T = 1 - 0.02314*
x (*# Temperature normalized by reservoir temperature,T0*);
V = (0.1 + 0.1*x)*
Sqrt[T](* # Velocity normalized by stagnation acoustic speed,a0*);
ListPlot[{rho, T, V}]
(*# Time history data*)maxt = 600 (*# Maximum number of time-steps*);
hd = Table[0., {n}, {maxt}];
rho1 = hd; V1 = hd; T1 = hd; p1 = hd; M1 = hd;
zeros = Table[0., {n}];
ddtrho = zeros;
ddtV = zeros;
ddtT = zeros;
ddtrhobar = zeros;
ddtVbar = zeros;
ddtTbar = zeros;
ddtrhoavg = zeros;
ddtVavg = zeros;
ddtTavg = zeros;
dtn = c*dx/(Sqrt[T] + V);
dt = Min[dtn](*# Time-step size determination*);
Do[
(*# Prediction step*)
Do[ddtrho[[i]] = -rho[[i]]*((V[[i + 1]] - V[[i]])/dx) -
rho[[i]]*V[[i]]*(Log[A[[i + 1]]] - Log[A[[i]]])/dx -
V[[i]]*(rho[[i + 1]] - rho[[i]])/dx;
ddtV[[
i]] = -V[[i]]*(V[[i + 1]] - V[[i]])/
dx - (1/gamma)*(((T[[i + 1]] - T[[i]])/
dx) + (T[[i]]/rho[[i]])*((rho[[i + 1]] - rho[[i]])/dx));
ddtT[[
i]] = (-V[[i]]*(T[[i + 1]] - T[[i]])/dx) - ((gamma - 1)*
T[[i]]*(((V[[i + 1]] - V[[i]])/
dx) + (V[[i]]*(Log[A[[i + 1]]] - Log[A[[i]]])/dx)));, {i,
2, n - 1}];
(*# Predicted values at next time-step*)
rhobar = rho + (ddtrho*dt);
Vbar = V + (ddtV*dt);
Tbar = T + (ddtT*dt);
(*# Correction step*)
Do[ddtrhobar[[i]] = -rhobar[[i]]*((Vbar[[i]] - Vbar[[i - 1]])/dx) -
rhobar[[i]]*Vbar[[i]]*(Log[A[[i]]] - Log[A[[i - 1]]])/dx -
Vbar[[i]]*(rhobar[[i]] - rhobar[[i - 1]])/dx;
ddtVbar[[
i]] = (-Vbar[[i]]*(Vbar[[i]] - Vbar[[i - 1]])/dx) - (1/
gamma)*(((Tbar[[i]] - Tbar[[i - 1]])/
dx) + (Tbar[[i]]/
rhobar[[i]])*((rhobar[[i]] - rhobar[[i - 1]])/dx));
ddtTbar[[
i]] = (-Vbar[[i]]*(Tbar[[i]] - Tbar[[i - 1]])/dx) - ((gamma - 1)*
Tbar[[i]]*(((Vbar[[i]] - Vbar[[i - 1]])/
dx) + (Vbar[[i]]*(Log[A[[i]]] - Log[A[[i - 1]]])/
dx)));, {i, 2, n - 1}];
ddtrhoavg = 0.5*(ddtrho + ddtrhobar);
ddtVavg = 0.5*(ddtV + ddtVbar);
ddtTavg = 0.5*(ddtT + ddtTbar);
(*# Update flow field variables*)
rho = rho + ddtrhoavg*dt;
V = V + ddtVavg*dt;
T = T + ddtTavg*dt;
(*# Compute pressure from the equation of state*)
p = rho*T;
(*# Compute boundary points*)
(*# Subsonic inflow*)
V[[1]] = (2*V[[2]]) - V[[3]];
(*# Supersonic outflow*)
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]];
(*# Compute Mach number*)
M = V/Sqrt[T];
(*# Data collection*)
rho1[[All, j]] = rho;
V1[[All, j]] = V;
T1[[All, j]] = T;
p1[[All, j]] = p;
M1[[All, j]] = M;, {j, 1, 600}];
To test this code we use data
data = Drop[
Import["https://www.grc.nasa.gov/www/wind/valid/cdv/axial.Pex.p16.\
gen", "List"], 7];
p016=Interpreter[DelimitedSequence["Number"]][#] & /@ data;
data1 = Drop[
Import["https://www.grc.nasa.gov/www/wind/valid/cdv/axial.Mex.p16.\
gen", "List"], 7];
M016=Interpreter[DelimitedSequence["Number"]][#] & /@ data1;
Finally, we show computation results (solid lines) together with p016, M016
(red points) for the Mach number (left) and pressure (right)
{Show[ListLinePlot[Transpose[{x, M}], PlotRange -> {All, {0, 2}},
Frame -> True, ImageSize -> 300, PlotLabel -> "Pin/Pout=0.16",
PlotStyle -> Blue, FrameLabel -> {"x", "M"}],
ListPlot[M016, PlotStyle -> Red]],
Show[ListLinePlot[Transpose[{x, p}], PlotRange -> {All, {0, 1}},
Frame -> True, ImageSize -> 300, PlotLabel -> "Pin/Pout=0.16",
PlotStyle -> Blue, FrameLabel -> {"x", "p"}],
ListPlot[p016, PlotStyle -> Red]]}
As we can see this is a good correlation for this simple case of supersonic outflow. The problem comes when we test flow with a shock wave in the diffuser. The corresponding data are given by
data = Import[
"https://www.grc.nasa.gov/www/wind/valid/cdv/axial.Mex.p75.gen",
"List"];
M075=Interpreter[DelimitedSequence["Number"]][#] & /@ Drop[data, 7];
data1 = Import[
"https://www.grc.nasa.gov/www/wind/valid/cdv/axial.Pex.p75.gen",
"List"];
p075=Interpreter[DelimitedSequence["Number"]][#] & /@ Drop[data1, 7];
For this problem, we need code with shock capturing method implementation like here. Therefore we translated this code as well for Mathematica users:
(*Note: All parameters are nondimensionalized.*)
dx = 0.2;(*grid size*)
c = 0.5;(*courant number*)
gamma = 1.4;(*Ratio of specific heats*)
(*Discretization of nondimensional distance along the nozzle*)
x = Range[0, 10., dx];
k = Length[x]; nth = Round[k/2];
jmax = 200;
Cx = .05;(*% artificial viscosity arbitrary parameter*)
(*% Parabolic area distribution along the nozzle*)
n = Length[x](* # Number of grid points*);
(*# Nozzle area distribution*)
half = Round[n/2];
A = Table[If[i <= half, 1.75 - 0.75*Cos[(0.2*x[[i]] - 1.0) Pi],
1.25 - 0.25*Cos[(0.2*x[[i]] - 1.0)*Pi]], {i, k}]; ListPlot[A]
(*% Initial Condition*)
P = p075[[All, 2]];(*pressure,p/p0*)
rho = P^(1/gamma);
T = P/rho;
V = M075[[All, 2]]*Sqrt[T];(*Velocity,V/a0*)
mf0 = rho*A*V;(*mass flow rate@t=0*)
ListPlot[{rho, P, T, V, mf0}]
gamma1 = 1/gamma;
gamma2 = gamma - 1;
(* Initial condition of solution vectors*)
U1 = rho*A;
U2 = rho*A*V;
uu3 = T/gamma2 + 0.5 gamma V^2;
U3 = rho*A;
U3 = U3*uu3;
(*% Initial condition of flux vectors*)
F1 = U2;
F2 = (U2^2/U1) + (1 - gamma1)*(U3 - 0.5*gamma*U2^2/U1);
F3 = (gamma*U2*U3/U1) - 0.5*gamma*gamma2*U2^3/U1^2;
{ListPlot[{U1, U2, U3}, PlotRange -> All], ListPlot[{F1, F2, F3}]}
dta = (c*dx)/(V + Abs[T]^0.5);
dt = Min[dta];
resmax = 10^-3;(*% maximum error*)
res = 1;
t = 0;
nstep = 0; M = Table[0, {k}]; rho1 =
P1 = Table[0, {k}, {jmax}]; M1 = P1; V1 = P1; T1 = P1;
Do[If[res <= resmax, Break[]];
nstep = nstep + 1;
(*% Predictor Step*)
Do[
J2p[i] = gamma1*rho[[i]]*T[[i]]*((A[[i + 1]] - A[[i]])/dx);
dU1dtp[i] = -(F1[[i + 1]] - F1[[i]])/dx;
dU2dtp[i] = -(F2[[i + 1]] - F2[[i]])/dx + J2p[i];
dU3dtp[i] = -(F3[[i + 1]] - F3[[i]])/dx;, {i, 2, k - 1}];
Do[num = Abs[P[[i + 1]] - 2*P[[i]] + P[[i - 1]]];
den = P[[i + 1]] + 2*P[[i]] + P[[i - 1]];
S1p[i] = (Cx*num*(U1[[i + 1]] - 2*U1[[i]] + U1[[i - 1]]))/den;
S2p[i] = (Cx*num*(U2[[i + 1]] - 2*U2[[i]] + U2[[i - 1]]))/den;
S3p[i] = (Cx*num*(U3[[i + 1]] - 2*U3[[i]] + U3[[i - 1]]))/den;, {i,
2, k - 1}];
Do[
U1p[i] = U1[[i]] + (dU1dtp[i]*dt) + S1p[i];
U2p[i] = U2[[i]] + (dU2dtp[i]*dt) + S2p[i];
U3p[i] = U3[[i]] + (dU3dtp[i]*dt) + S3p[i];, {i, 2, k - 1}];
U1p[1] = U1[[1]];
U2p[1] = U2[[1]];
U3p[1] = U3[[1]];
U1p[k] = U1[[k]];
U2p[k] = U2[[k]];
U3p[k] = U3[[k]];
Do[
rhop[i] = U1p[i]/A[[i]];
Vp[i] = U2p[i]/U1p[i];
Tp[i] = gamma2*(U3p[i]/U1p[i]) - 0.5*gamma*Vp[i]^2;
Pp[i] = rhop[i]*Tp[i];
F1p[i] = U2p[i];
F2p[i] = (U2p[i]^2/
U1p[i]) + (1 - gamma1)*(U3p[i] - 0.5*gamma*U2p[i]^2/U1p[i]);
F3p[i] = (gamma*U2p[i]*U3p[i]/U1p[i]) - (0.5*gamma*gamma2*
U2p[i]^3/U1p[i]^2);, {i, 1, k}];
(*% corrector Step*)
Do[
J2c = gamma1*rhop[i]*Tp[i]*((A[[i]] - A[[i - 1]])/dx);
dU1dtc[i] = -(F1p[i] - F1p[i - 1])/dx;
dU2dtc[i] = -(F2p[i] - F2p[i - 1])/dx + J2c;
dU3dtc[i] = -(F3p[i] - F3p[i - 1])/dx;, {i, 1, k - 1}];
Do[
num = Abs[(Pp[i + 1] - 2*Pp[i] + Pp[i - 1])];
den = Pp[i + 1] + 2*Pp[i] + Pp[i - 1];
S1c[i] = (Cx*num*(U1p[i + 1] - 2*U1p[i] + U1p[i - 1]))/den;
S2c[i] = (Cx*num*(U2p[i + 1] - 2*U2p[i] + U2p[i - 1]))/den;
S3c[i] = (Cx*num*(U3p[i + 1] - 2*U3p[i] + U3p[i - 1]))/den;, {i, 2,
k - 1}];
(*% Average time derivatives*)
Do[
dU1dtav[i] = 0.5*(dU1dtp[i] + dU1dtc[i]);
dU2dtav[i] = 0.5*(dU2dtp[i] + dU2dtc[i]);
dU3dtav[i] = 0.5*(dU3dtp[i] + dU3dtc[i]);, {i, 2, k - 1}];
Do[
U1[[i]] = U1[[i]] + (dU1dtav[i]*dt) + S1c[i];
U2[[i]] = U2[[i]] + (dU2dtav[i]*dt) + S2c[i];
U3[[i]] = U3[[i]] + (dU3dtav[i]*dt) + S3c[i];, {i, 2, k - 1}];
(*% Boundary condition@first node*)
(*U1[[2]]=A[[2]];
U2[[2]]=2*U2[[3]]-U2[[4]];
ve=U2[[2]]/U1[[2]];
U3[[2]]=U1[[2]]*((1/gamma2)+0.5*gamma*ve^2);
(*% Boundary condition@last node*)
U1[[k-1]]=2*U1[[k-2]]-U1[[k-3]];
U2[[k-1]]=2*U2[[k-2]]-U2[[k-3]];
U3[[k-1]]=2*U3[[k-2]]-U3[[k-3]];(*(0.6784*A[[k]]/gamma2)+(0.5*gamma*
U2[[k]]^2/U1[[k]]);*)*)
Do[
F1[[i]] = U2[[i]];
F2[[i]] = (U2[[i]]^2/
U1[[i]]) + (1 - gamma1)*(U3[[i]] - 0.5*gamma*U2[[i]]^2/U1[[i]]);
F3[[i]] = (gamma*U2[[i]]*U3[[i]]/U1[[i]]) -
0.5*gamma*gamma2*U2[[i]]^3/U1[[i]]^2;, {i, 1, k}];
(*% corrected values of primitive variables*)
Do[
rho[[i]] = U1[[i]]/A[[i]];
V[[i]] = U2[[i]]/U1[[i]];
T[[i]] = gamma2*((U3[[i]]/U1[[i]]) - 0.5*gamma*V[[i]]^2);
M[[i]] = V[[i]]*T[[i]]^-0.5;
P[[i]] = rho[[i]]*T[[i]];, {i, 1, k}];
(*% mass flow rate after t+dt*)
mf = rho*A*V;
res1 = Abs[dU1dtav[nth]];
res2 = Abs[dU2dtav[nth]];
res = If[ res1 > res2,
res1,
res2];
Do[
rho1[[i, j]] = rho[[i]];
T1[[i, j]] = T[[i]];
P1[[i, j]] = P[[i]];
M1[[i, j]] = M[[i]];
V1[[i, j]] = V[[i]];, {i, 1, k}];
, {j, 1, jmax}];
Finally, we check this numerical solution using the exact solution M075,p075
{Show[ListLinePlot[Transpose[{x, M}], PlotRange -> {All, {0, 2}},
Frame -> True, ImageSize -> 300, PlotLabel -> "Pin/Pout=0.75",
PlotStyle -> Blue], ListPlot[M075, PlotStyle -> Red]],
Show[ListLinePlot[Transpose[{x, P}], PlotRange -> {All, {0, 1.2}},
Frame -> True, ImageSize -> 300, PlotLabel -> "Pin/Pout=0.75",
PlotStyle -> Blue], ListPlot[p075, PlotStyle -> Red]]}
As we can see the correlation is not so good even if we start from the exact solution. The question is how we can solve this problem using maybe code written for Mathematica from scratch and with NDSolve
?
Update 1 To make research with variable dx
in the last code we use initial conditions in a form
pi = Interpolation[p075, InterpolationOrder -> 1];
mi = Interpolation[M075, InterpolationOrder -> 1];
(*% Initial Condition*)
P = pi[x];(*pressure,p/p0*)
rho = P[[1]]^(1/gamma) - (P[[1]]^(1/gamma) - P[[k]]^(1/gamma))/10*x ;
T = P[[1]]/rho[[1]] - (P[[1]]/rho[[1]] - P[[k]]/rho[[k]])/10*x; M =
mi[x];
V = M[[1]]*
Sqrt[T[[1]]] - (M[[1]]*Sqrt[T[[1]]] - M[[k]]*Sqrt[T[[k]]])/10*
x;(*Velocity,V/a0*)
mf0 = rho*A*V;(*mass flow rate@t=0*)
Then for dx=0.1, Cx=0.0005, jmax=1200
we have pictures below
Update 2. In a case of subsonic flow we retrieve data from
data = Drop[
Import["https://www.grc.nasa.gov/www/wind/valid/cdv/axial.Pex.p89.\
gen", "List"], 7];
p089=Interpreter[DelimitedSequence["Number"]][#] & /@ data;
data1 = Drop[
Import["https://www.grc.nasa.gov/www/wind/valid/cdv/axial.Mex.p89.\
gen", "List"], 7];
M089=Interpreter[DelimitedSequence["Number"]][#] & /@ data1;
Input data for the last code
pi = Interpolation[p089, InterpolationOrder -> 1];
mi = Interpolation[M089, InterpolationOrder -> 1];
(*% Initial Condition*)
P = pi[x];(*pressure,p/p0*)
rho = P[[1]]^(1/gamma) - (P[[1]]^(1/gamma) - P[[k]]^(1/gamma))/10*x ;
T = P[[1]]/rho[[1]] - (P[[1]]/rho[[1]] - P[[k]]/rho[[k]])/10*x; M =
mi[x];
V = M[[1]]*
Sqrt[T[[1]]] - (M[[1]]*Sqrt[T[[1]]] - M[[k]]*Sqrt[T[[k]]])/10*
x;(*Velocity,V/a0*)
mf0 = rho*A*V;(*mass flow rate@t=0*)
Final results after 690 iteration
Taken into account that we solve quasi 1D problem using McCormack's method this correlation is not bad. But we need something better, since for supersonic outflow we have nice correlation.
Update 3. Third code we translated from here. It is good working for supersonic outflow, and for subsonic outflow as well
(*#setting up initial conditions*)
gamma = 1.4; dx = 0.2;
X = Range[0, 10,
dx]; M016 = {{0.0000000, 0.2395428}, {0.2000000,
0.2401525}, {0.4000000, 0.2419912}, {0.6000000,
0.2450882}, {0.8000000, 0.2494931}, {1.000000,
0.2552769}, {1.200000, 0.2625332}, {1.400000,
0.2713805}, {1.600000, 0.2819642}, {1.800000,
0.2944594}, {2.000000, 0.3090735}, {2.200000,
0.3260485}, {2.400000, 0.3456640}, {2.600000,
0.3682380}, {2.800000, 0.3941266}, {3.000000,
0.4237210}, {3.200000, 0.4574398}, {3.400000,
0.4957166}, {3.600000, 0.5389794}, {3.800000,
0.5876219}, {4.000000, 0.6419665}, {4.200000,
0.7022194}, {4.400000, 0.7684249}, {4.600000,
0.8404243}, {4.800000, 0.9178230}, {5.000000,
0.9997698}, {5.200000, 1.049278}, {5.400000, 1.099540}, {5.600000,
1.150450}, {5.800000, 1.201643}, {6.000000, 1.252754}, {6.200000,
1.303419}, {6.400000, 1.353288}, {6.600000, 1.402030}, {6.800000,
1.449334}, {7.000000, 1.494914}, {7.200000, 1.538515}, {7.400000,
1.579906}, {7.600000, 1.618885}, {7.800000, 1.655275}, {8.000000,
1.688924}, {8.200000, 1.719701}, {8.400000, 1.747494}, {8.600000,
1.772210}, {8.800000, 1.793771}, {9.000000, 1.812114}, {9.200000,
1.827187}, {9.400000, 1.838950}, {9.600000, 1.847373}, {9.800000,
1.852435}, {10.00000, 1.854124}}; p016 = {{0.`, 0.9608492`}, {0.2`,
0.9606546`}, {0.4`, 0.9600656`}, {0.6`, 0.9590641`}, {0.8`,
0.9576204`}, {1.`, 0.95569`}, {1.2`, 0.9532128`}, {1.4`,
0.9501103`}, {1.6`, 0.946282`}, {1.8`, 0.9416005`}, {2.`,
0.9359082`}, {2.2`, 0.9290103`}, {2.4`, 0.920669`}, {2.6`,
0.9105966`}, {2.8`, 0.8984537`}, {3.`, 0.8838449`}, {3.2`,
0.8663263`}, {3.4`, 0.8454205`}, {3.6`, 0.8206479`}, {3.8`,
0.7915765`}, {4.`, 0.7578946`}, {4.2`, 0.7194992`}, {4.4`,
0.6765875`}, {4.6`, 0.6297246`}, {4.8`, 0.5798628`}, {5.`,
0.5286468`}, {5.2`, 0.4983042`}, {5.4`, 0.4686222`}, {5.6`,
0.4395775`}, {5.8`, 0.4114938`}, {6.`, 0.3846425`}, {6.2`,
0.3592383`}, {6.4`, 0.3354384`}, {6.6`, 0.3133435`}, {6.8`,
0.2930009`}, {7.`, 0.2744158`}, {7.2`, 0.2575561`}, {7.4`,
0.2423654`}, {7.6`, 0.2287681`}, {7.8`, 0.2166777`}, {8.`,
0.2060031`}, {8.2`, 0.1966533`}, {8.4`, 0.1885405`}, {8.6`,
0.1815824`}, {8.8`, 0.1757052`}, {9.`, 0.1708438`}, {9.2`,
0.1669425`}, {9.4`, 0.1639555`}, {9.6`, 0.1618473`}, {9.8`,
0.1605926`}, {10.`, 0.1601759`}};
k = Length[p016]; gamma = 1.4;
nx = Length[X];
(*% Parabolic area distrubition along the nozzle*)
(*# Nozzle area distribution*)
half = Round[nx/2];
A = Table[If[i <= half, 1.75 - 0.75*Cos[(0.2*X[[i]] - 1.0) Pi],
1.25 - 0.25*Cos[(0.2*X[[i]] - 1.0)*Pi]], {i, nx}];
pi = Interpolation[p016, InterpolationOrder -> 1];
mi = Interpolation[M016, InterpolationOrder -> 1];
(*% Initial Condition*)
P = pi[X];(*pressure,p/p0*)k = nx;
rho = P[[1]]^(1/gamma) - (P[[1]]^(1/gamma) - P[[k]]^(1/gamma))/10*X ;
T = P[[1]]/rho[[1]] - (P[[1]]/rho[[1]] - P[[k]]/rho[[k]])/10*X; M =
mi[X];
V = M[[1]]*
Sqrt[T[[1]]] - (M[[1]]*Sqrt[T[[1]]] - M[[k]]*Sqrt[T[[k]]])/10*
X;(*Velocity,V/a0*)
mf0 = rho*A*V;(*mass flow rate@t=0*)
dt = Min[0.5*dx/(T^0.5 + V)];
nt = 1200;
(*#Variable preDef*)
ini0 = Table[0., {nx}]; (*#predicted values*)
drhodtp = rhop = ini0;
Vp = ini0;
dVdtp = ini0;
Tp = ini0;
dTdtp = ini0;
drhodtc = ini0; (*#Corrected Values*)
dVdtc = ini0;
dTdtc = ini0;
TinTime = XTP = Table[0., {nx}, {nt}] ; (*#Used for plotting *)
rhoinTime = XTP;
VinTime = XTP;
PinTime = XTP;
MinTime = XTP;
err = 1;
iterNo = 0;
Do[If[ err <= 10^-4, Break[]];
iterNo = iterNo + 1;
rhon = rho;
Vn = V;
Tn = T;
Mn = M;
Do[
drhodtp[[i - 1]] = -rho[[i - 1]]*(V[[i]] - V[[i - 1]])/dx -
rho[[i - 1]]*V[[i - 1]]*(Log[A[[i]]] - Log[A[[i - 1]]])/dx -
V[[i - 1]]*(rho[[i]] - rho[[i - 1]])/dx;
dVdtp[[i -
1]] = -V[[i - 1]]*(V[[i]] - V[[i - 1]])/
dx - (1/gamma)*((T[[i]] - T[[i - 1]])/
dx + (T[[i - 1]]/rho[[i - 1]])*(rho[[i]] - rho[[i - 1]])/
dx); dTdtp[[
i - 1]] = -V[[i - 1]]*(T[[i]] - T[[i - 1]])/dx - (gamma - 1)*
T[[i - 1]]*( (V[[i]] - V[[i - 1]])/dx +
V[[i - 1]]*(Log[A[[i]]] - Log[A[[i - 1]]])/dx);, {i, 3, nx}];
rhop = rho + drhodtp*dt;
Vp = V + dVdtp*dt;
Tp = T + dTdtp*dt;
Do[
drhodtc[[i]] = -rhop[[i]]*(Vp[[i]] - Vp[[i - 1]])/dx -
rhop[[i]]*Vp[[i]]*(Log[A[[i]]] - Log[A[[i - 1]]])/dx -
Vp[[i]]*(rhop[[i]] - rhop[[i - 1]])/dx;
dVdtc[[i]] = -Vp[[i]]*(Vp[[i]] - Vp[[i - 1]])/
dx - (1/gamma)*((Tp[[i]] - Tp[[i - 1]])/
dx + (Tp[[i]]/rhop[[i]])*(rhop[[i]] - rhop[[i - 1]])/dx);
dTdtp[[i]] = -Vp[[i]]*(Tp[[i]] - Tp[[i - 1]])/dx - (gamma - 1)*
Tp[[i]]*( (Vp[[i]] - Vp[[i - 1]])/dx +
Vp[[i]]*(Log[A[[i]]] - Log[A[[i - 1]]])/dx);, {i, 2,
nx - 1}];
rho = rho + .5 (drhodtp + drhodtc)*dt;
V = V + .5 (dVdtp + dVdtc)*dt;
T = T + .5 (dTdtp + dTdtc)*dt;
(*rho[[1]]=1; T[[1]]=1;*)
(*V[[1]]=2*V[[2]]-V[[3]];
V[[-1]]=2*V[[-2]]-V[[-3]];*)
(*T[[-1]]=2*T[[-2]]-T[[-3]]; rho[[-1]]=2*rho[[-2]]-rho[[-3]];*)
P = rho*T;
PinTime[[All, j]] = P;
M = V/Abs[T]^0.5;
MinTime[[All, j]] = M;
rhoinTime[[All, j]] = rho; VinTime[[All, j]] = V;
TinTime[[All, j]] = T;
err = Total[Abs[M - Mn]];, {j, nt}];
{err, iterNo}
{Show[ListLinePlot[Transpose[{X, M}], PlotRange -> {All, {0, 2}},
Frame -> True, ImageSize -> 300, PlotLabel -> "Pin/Pout=0.16",
PlotStyle -> Blue, FrameLabel -> {"x", "M"}],
ListPlot[M016, PlotStyle -> Red]],
Show[ListLinePlot[Transpose[{X, P}], PlotRange -> {All, {0., 1.2}},
Frame -> True, ImageSize -> 300, PlotLabel -> "Pin/Pout=0.16",
PlotStyle -> Blue, FrameLabel -> {"x", "p"}],
ListPlot[p016, PlotStyle -> Red]]}
If we put in the last code dt = Min[0.75*dx/(T^0.5 + V)]
(it looks like 0.75 is special Courant number for subsonic flow) and use p089, M089
from above, then we have nice fit with exact solution with error of $10^{-4}$ - see picture below