Skip to content

Commit 56ed664

Browse files
committed
Merge branch 'master' of ssh://github.com:/zingale/hydro_examples
2 parents fd54256 + 55b7750 commit 56ed664

2 files changed

Lines changed: 86 additions & 60 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ https://open-astrophysics-bookshelf.github.io/numerical_exercises/
1111

1212
and with the pyro2 code:
1313

14-
https://github.com/zingale/pyro2
14+
https://github.com/python-hydro/pyro2
1515

1616

1717

compressible/riemann.py

Lines changed: 85 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
1-
# solve the Riemann problem for a gamma-law gas
1+
"""An exact Riemann solver for the Euler equations with a gamma-law
2+
gas. The left and right states are stored as State objects. We then
3+
create a RiemannProblem object with the left and right state:
24
3-
from __future__ import print_function
5+
> rp = RiemannProblem(left_state, right_state)
6+
7+
Next we solve for the star state:
8+
9+
> rp.find_star_state()
10+
11+
Finally, we sample the solution to find the interface state, which
12+
is returned as a State object:
13+
14+
> q_int = rp.sample_solution()
15+
"""
416

517
import matplotlib.pyplot as plt
618
import numpy as np
719
import scipy.optimize as optimize
820

9-
class State(object):
21+
class State:
1022
""" a simple object to hold a primitive variable state """
1123

1224
def __init__(self, p=1.0, u=0.0, rho=1.0):
@@ -15,9 +27,9 @@ def __init__(self, p=1.0, u=0.0, rho=1.0):
1527
self.rho = rho
1628

1729
def __str__(self):
18-
return "rho: {}; u: {}; p: {}".format(self.rho, self.u, self.p)
30+
return f"rho: {self.rho}; u: {self.u}; p: {self.p}"
1931

20-
class RiemannProblem(object):
32+
class RiemannProblem:
2133
""" a class to define a Riemann problem. It takes a left
2234
and right state. Note: we assume a constant gamma """
2335

@@ -29,6 +41,9 @@ def __init__(self, left_state, right_state, gamma=1.4):
2941
self.ustar = None
3042
self.pstar = None
3143

44+
def __str__(self):
45+
return f"pstar = {self.pstar}, ustar = {self.ustar}"
46+
3247
def u_hugoniot(self, p, side, shock=False):
3348
"""define the Hugoniot curve, u(p). If shock=True, we do a 2-shock
3449
solution"""
@@ -80,11 +95,67 @@ def find_2shock_star_state(self, p_min=0.001, p_max=1000.0):
8095
p_min, p_max)
8196
self.ustar = self.u_hugoniot(self.pstar, "left", shock=True)
8297

98+
def shock_solution(self, sgn, xi, state):
99+
"""return the interface solution considering a shock"""
100+
101+
p_ratio = self.pstar/state.p
102+
c = np.sqrt(self.gamma*state.p/state.rho)
103+
104+
# Toro, eq. 4.52 / 4.59
105+
S = state.u + sgn*c*np.sqrt(0.5*(self.gamma + 1.0)/self.gamma*p_ratio +
106+
0.5*(self.gamma - 1.0)/self.gamma)
107+
108+
# are we to the left or right of the shock?
109+
if (sgn > 0 and xi > S) or (sgn < 0 and xi < S):
110+
# R/L region
111+
solution = state
112+
else:
113+
# * region -- get rhostar from Toro, eq. 4.50 / 4.57
114+
gam_fac = (self.gamma - 1.0)/(self.gamma + 1.0)
115+
rhostar = state.rho * (p_ratio + gam_fac)/(gam_fac * p_ratio + 1.0)
116+
solution = State(rho=rhostar, u=self.ustar, p=self.pstar)
117+
118+
return solution
119+
120+
def rarefaction_solution(self, sgn, xi, state):
121+
"""return the interface solution considering a rarefaction wave"""
122+
123+
# find the speed of the head and tail of the rarefaction fan
124+
125+
# isentropic (Toro eq. 4.54 / 4.61)
126+
p_ratio = self.pstar/state.p
127+
c = np.sqrt(self.gamma*state.p/state.rho)
128+
cstar = c*p_ratio**((self.gamma-1.0)/(2*self.gamma))
129+
130+
lambda_head = state.u + sgn*c
131+
lambda_tail = self.ustar + sgn*cstar
132+
133+
gam_fac = (self.gamma - 1.0)/(self.gamma + 1.0)
134+
135+
if (sgn > 0 and xi > lambda_head) or (sgn < 0 and xi < lambda_head):
136+
# R/L region
137+
solution = state
138+
139+
elif (sgn > 0 and xi < lambda_tail) or (sgn < 0 and xi > lambda_tail):
140+
# * region, we use the isentropic density (Toro 4.53 / 4.60)
141+
solution = State(rho = state.rho*p_ratio**(1.0/self.gamma),
142+
u = self.ustar, p = self.pstar)
143+
144+
else:
145+
# we are in the fan -- Toro 4.56 / 4.63
146+
rho = state.rho * (2/(self.gamma + 1.0) -
147+
sgn*gam_fac*(state.u - xi)/c)**(2.0/(self.gamma-1.0))
148+
u = 2.0/(self.gamma + 1.0) * ( -sgn*c + 0.5*(self.gamma - 1.0)*state.u + xi)
149+
p = state.p * (2/(self.gamma + 1.0) -
150+
sgn*gam_fac*(state.u - xi)/c)**(2.0*self.gamma/(self.gamma-1.0))
151+
solution = State(rho=rho, u=u, p=p)
152+
153+
return solution
83154

84155
def sample_solution(self, time, npts, xmin=0.0, xmax=1.0):
85156
"""given the star state (ustar, pstar), sample the solution for npts
86157
points between xmin and xmax at the given time.
87-
158+
88159
this is a similarity solution in xi = x/t """
89160

90161
# we write it all explicitly out here -- this could be vectorized
@@ -117,65 +188,20 @@ def sample_solution(self, time, npts, xmin=0.0, xmax=1.0):
117188
state = self.left
118189
sgn = -1.0
119190

120-
p_ratio = self.pstar/state.p
121-
122-
c = np.sqrt(gam*state.p/state.rho)
123-
124-
# isentropic (Toro eq. 4.54 / 4.61)
125-
cstar = c*p_ratio**((gam-1.0)/(2*gam))
126-
127-
# is the right wave in our a shock or rarefaction?
191+
# is non-contact wave a shock or rarefaction?
128192
if self.pstar > state.p:
129-
# shock
130-
131-
# Toro, eq. 4.50 / 4.57
132-
rhostar = state.rho * (p_ratio + gam_fac)/(gam_fac * p_ratio + 1.0)
133-
134-
# Toro, eq. 4.52 / 4.59
135-
S = state.u + sgn*c*np.sqrt(0.5*(gam + 1.0)/gam*p_ratio + 0.5*(gam - 1.0)/gam)
136-
137-
# are we to the left or right of the shock?
138-
if (sgn > 0 and xi[n] > S) or (sgn < 0 and xi[n] < S):
139-
# R/L region
140-
rho = state.rho
141-
u = state.u
142-
p = state.p
143-
else:
144-
# * region
145-
rho = rhostar
146-
u = self.ustar
147-
p = self.pstar
193+
# compression! we are a shock
194+
solution = self.shock_solution(sgn, xi[n], state)
148195

149196
else:
150-
# rarefaction -- the rarefaction is spread out, so
151-
# find the speed of the head and tail of the rarefaction fan
152-
lambda_head = state.u + sgn*c
153-
lambda_tail = self.ustar + sgn*cstar
154-
155-
if (sgn > 0 and xi[n] > lambda_head) or (sgn < 0 and xi[n] < lambda_head):
156-
# R/L region
157-
rho = state.rho
158-
u = state.u
159-
p = state.p
160-
161-
elif (sgn > 0 and xi[n] < lambda_tail) or (sgn < 0 and xi[n] > lambda_tail):
162-
# * region
163-
# isentropic density (Toro 4.53 / 4.60)
164-
rho = state.rho*p_ratio**(1.0/gam)
165-
u = self.ustar
166-
p = self.pstar
167-
168-
else:
169-
# we are in the fan -- Toro 4.56 / 4.63
170-
rho = state.rho * (2/(gam + 1.0) - sgn*gam_fac*(state.u - xi[n])/c)**(2.0/(gam-1.0))
171-
u = 2.0/(gam + 1.0) * ( -sgn*c + 0.5*(gam - 1.0)*state.u + xi[n])
172-
p = state.p * (2/(gam + 1.0) - sgn*gam_fac*(state.u - xi[n])/c)**(2.0*gam/(gam-1.0))
197+
# rarefaction
198+
solution = self.rarefaction_solution(sgn, xi[n], state)
173199

174200

175201
# store
176-
rho_v.append(rho)
177-
u_v.append(u)
178-
p_v.append(p)
202+
rho_v.append(solution.rho)
203+
u_v.append(solution.u)
204+
p_v.append(solution.p)
179205

180206
return x, np.array(rho_v), np.array(u_v), np.array(p_v)
181207

0 commit comments

Comments
 (0)