forked from burakbayramli/books
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun_sod_roe.py
109 lines (81 loc) · 3.22 KB
/
run_sod_roe.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import numpy as np
from collections import namedtuple
import matplotlib.pyplot as plt
primitive_variables = ('Density', 'Velocity', 'Pressure')
Primitive_State = namedtuple('State', primitive_variables)
def primitive_to_conservative(rho, u, p, gamma=1.4):
mom = rho*u
E = p/(gamma-1.) + 0.5*rho*u**2
return rho, mom, E
def pospart(x):
return np.maximum(1.e-15,x)
def conservative_to_primitive(rho, mom, E, gamma=1.4):
u = mom/pospart(rho)
p = (gamma-1.)*(E - 0.5*rho*u**2)
return rho, u, p
def cons_to_prim(q, gamma=1.4):
return conservative_to_primitive(*q,gamma=1.4)
def roe_averages(q_l, q_r, gamma=1.4):
rho_sqrt_l = np.sqrt(q_l[0])
rho_sqrt_r = np.sqrt(q_r[0])
p_l = (gamma-1.)*(q_l[2]-0.5*(q_l[1]**2)/q_l[0])
p_r = (gamma-1.)*(q_r[2]-0.5*(q_r[1]**2)/q_r[0])
denom = rho_sqrt_l + rho_sqrt_r
u_hat = (q_l[1]/rho_sqrt_l + q_r[1]/rho_sqrt_r)/denom
H_hat = ((q_l[2]+p_l)/rho_sqrt_l + (q_r[2]+p_r)/rho_sqrt_r)/denom
c_hat = np.sqrt((gamma-1)*(H_hat-0.5*u_hat**2))
return u_hat, c_hat, H_hat
def Euler_roe(q_l, q_r, gamma=1.4):
"""
Approximate Roe solver for the Euler equations.
"""
rho_l = q_l[0]
rhou_l = q_l[1]
u_l = rhou_l/rho_l
rho_r = q_r[0]
rhou_r = q_r[1]
u_r = rhou_r/rho_r
u_hat, c_hat, H_hat = roe_averages(q_l, q_r, gamma)
dq = q_r - q_l
s1 = u_hat - c_hat
s2 = u_hat
s3 = u_hat + c_hat
alpha2 = (gamma-1.)/c_hat**2 *((H_hat-u_hat**2)*dq[0]+u_hat*dq[1]-dq[2])
alpha3 = (dq[1] + (c_hat - u_hat)*dq[0] - c_hat*alpha2) / (2.*c_hat)
alpha1 = dq[0] - alpha2 - alpha3
r1 = np.array([1., u_hat-c_hat, H_hat - u_hat*c_hat])
r2 = np.array([1., u_hat, 0.5*u_hat**2])
q_l_star = q_l + alpha1*r1
q_r_star = q_l_star + alpha2*r2
states = np.column_stack([q_l,q_l_star,q_r_star,q_r])
speeds = [s1, s2, s3]
wave_types = ['contact','contact', 'contact']
def reval(xi):
rho = (xi<s1)*states[0,0] + (s1<=xi)*(xi<s2)*states[0,1] + \
(s2<=xi)*(xi<s3)*states[0,2] + (s3<=xi)*states[0,3]
mom = (xi<s1)*states[1,0] + (s1<=xi)*(xi<s2)*states[1,1] + \
(s2<=xi)*(xi<s3)*states[1,2] + (s3<=xi)*states[1,3]
E = (xi<s1)*states[2,0] + (s1<=xi)*(xi<s2)*states[2,1] + \
(s2<=xi)*(xi<s3)*states[2,2] + (s3<=xi)*states[2,3]
return rho, mom, E
xmax = 0.9
x = np.linspace(-xmax, xmax, 100)
t = 0.4 # change this value to see graph at different time points
q = reval(x/(t+1e-10))
q = cons_to_prim(q)
fig, axes = plt.subplots(3, 1, figsize=(5, 6), sharex=True)
axes[0].plot(x,q[0]); axes[0].set_ylim(0,4)
axes[1].plot(x,q[1]); axes[0].set_ylim(0,1)
axes[2].plot(x,q[2]); axes[0].set_ylim(0,4)
plt.savefig('/tmp/sod-out.png')
def compare_solutions():
left = Primitive_State(Density = 3.,
Velocity = 0.,
Pressure = 3.)
right = Primitive_State(Density = 1.,
Velocity = 0.,
Pressure = 1.)
q_l = np.array(primitive_to_conservative(*left))
q_r = np.array(primitive_to_conservative(*right))
Euler_roe(q_l, q_r)
compare_solutions()