Skip to content

Commit c08e041

Browse files
authored
implement well-balancing with characteristic tracing (#30)
1 parent fc6f047 commit c08e041

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

ppmpy/euler.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def __init__(self, nx, C, *,
8282
gamma=1.4,
8383
init_cond=None, grav_func=None,
8484
params=None,
85-
use_hse_reconstruction=False,
85+
use_hse_reconstruction=False, hse_as_perturbation=False,
8686
use_limiting=True, use_flattening=True):
8787

8888
self.grid = FVGrid(nx, ng=4)
@@ -138,6 +138,8 @@ def __init__(self, nx, C, *,
138138
self.U_init = self.U.copy()
139139

140140
self.use_hse_reconstruction = use_hse_reconstruction
141+
self.hse_as_perturbation = hse_as_perturbation
142+
141143
self.use_flattening = use_flattening
142144
self.use_limiting = use_limiting
143145

@@ -198,7 +200,7 @@ def construct_parabola(self):
198200
for ivar in range(self.v.nvar):
199201
if ivar == self.v.qp and self.use_hse_reconstruction:
200202
self.q_parabola.append(HSEPPMInterpolant(self.grid, q[:, ivar], q[:, self.v.qrho], g,
201-
limit=self.use_limiting, chi_flat=chi))
203+
limit=self.use_limiting, chi_flat=chi, leave_as_perturbation=self.hse_as_perturbation))
202204
else:
203205
self.q_parabola.append(PPMInterpolant(self.grid, q[:, ivar],
204206
limit=self.use_limiting, chi_flat=chi))
@@ -272,13 +274,23 @@ def interface_states(self):
272274
q_ref_m = Im[i, 0, :]
273275

274276
# build eigensystem
275-
ev, lvec, rvec = eigen(q_ref_m[self.v.qrho], q_ref_m[self.v.qu], q_ref_m[self.v.qp], self.gamma)
277+
if self.use_hse_reconstruction and self.hse_as_perturbation:
278+
# we need to make the reference state a pressure again
279+
ev, lvec, rvec = eigen(q_ref_m[self.v.qrho],
280+
q_ref_m[self.v.qu],
281+
self.q_parabola[self.v.qp].p_hse_m[i] + q_ref_m[self.v.qp],
282+
self.gamma)
283+
else:
284+
ev, lvec, rvec = eigen(q_ref_m[self.v.qrho],
285+
q_ref_m[self.v.qu],
286+
q_ref_m[self.v.qp],
287+
self.gamma)
276288

277289
# loop over waves and compute l . (qref - I) for each wave
278290
beta_xm = np.zeros(3)
279291
for iwave in range(3):
280292
dq = q_ref_m - Im[i, iwave, :]
281-
if self.grav_func is not None:
293+
if self.grav_func is not None and not self.hse_as_perturbation:
282294
dq[self.v.qu] -= 0.5 * self.dt * Im_g[i, iwave]
283295
beta_xm[iwave] = lvec[iwave, :] @ dq
284296

@@ -289,19 +301,31 @@ def interface_states(self):
289301
if ev[iwave] <= 0:
290302
q_right[i, :] -= beta_xm[iwave] * rvec[iwave, :]
291303

304+
if self.use_hse_reconstruction and self.hse_as_perturbation:
305+
q_right[i, self.v.qp] += self.q_parabola[self.v.qp].p_hse_m[i]
306+
292307
# left state on interface i+1 -- this uses the "p" reconstructuion
293308

294309
# reference state -- fastest wave moving to the right
295310
q_ref_p = Ip[i, 2, :]
296311

297312
# build eigensystem
298-
ev, lvec, rvec = eigen(q_ref_p[self.v.qrho], q_ref_p[self.v.qu], q_ref_p[self.v.qp], self.gamma)
313+
if self.use_hse_reconstruction and self.hse_as_perturbation:
314+
ev, lvec, rvec = eigen(q_ref_p[self.v.qrho],
315+
q_ref_p[self.v.qu],
316+
self.q_parabola[self.v.qp].p_hse_p[i] + q_ref_p[self.v.qp],
317+
self.gamma)
318+
else:
319+
ev, lvec, rvec = eigen(q_ref_p[self.v.qrho],
320+
q_ref_p[self.v.qu],
321+
q_ref_p[self.v.qp],
322+
self.gamma)
299323

300324
# loop over waves and compute l . (qref - I) for each wave
301325
beta_xp = np.zeros(3)
302326
for iwave in range(3):
303327
dq = q_ref_p - Ip[i, iwave, :]
304-
if self.grav_func is not None:
328+
if self.grav_func is not None and not self.hse_as_perturbation:
305329
dq[self.v.qu] -= 0.5 * self.dt * Ip_g[i, iwave]
306330
beta_xp[iwave] = lvec[iwave, :] @ dq
307331

@@ -312,6 +336,9 @@ def interface_states(self):
312336
if ev[iwave] >= 0:
313337
q_left[i+1, :] -= beta_xp[iwave] * rvec[iwave, :]
314338

339+
if self.use_hse_reconstruction and self.hse_as_perturbation:
340+
q_left[i+1, self.v.qp] += self.q_parabola[self.v.qp].p_hse_p[i]
341+
315342
# enforce reflection
316343
for n in range(self.v.nvar):
317344
if self.bcs_left[n] == "reflect":

ppmpy/reconstruction.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,13 +277,18 @@ class HSEPPMInterpolant(PPMInterpolant):
277277
the flattening coefficient.
278278
"""
279279

280-
def __init__(self, grid, p, rho, g, *, limit=True, chi_flat=None):
280+
def __init__(self, grid, p, rho, g, *, limit=True, chi_flat=None, leave_as_perturbation=False):
281281

282282
super().__init__(grid, p, limit=limit, chi_flat=chi_flat)
283283

284284
self.rho = rho
285285
self.g = g
286286

287+
self.p_hse_m = None
288+
self.p_hse_p = None
289+
290+
self.leave_as_perturbation = leave_as_perturbation
291+
287292
def construct_parabola(self):
288293
"""compute the coefficients of a parabolic interpolant for the
289294
pressure in each zone by subtracting off HSE. This will give
@@ -377,10 +382,19 @@ def construct_parabola(self):
377382
self.am[:] = (1.0 - self.chi_flat[:]) * p_hse[:] + self.chi_flat[:] * self.am[:]
378383
self.ap[:] = (1.0 - self.chi_flat[:]) * p_hse[:] + self.chi_flat[:] * self.ap[:]
379384

380-
# finally, add back in the HSE correction
381-
self.ap[:] += self.a[:] + 0.5 * self.grid.dx * self.rho[:] * self.g[:]
382-
self.am[:] += self.a[:] - 0.5 * self.grid.dx * self.rho[:] * self.g[:]
385+
self.p_hse_p = self.a[:] + 0.5 * self.grid.dx * self.rho[:] * self.g[:]
386+
self.p_hse_m = self.a[:] - 0.5 * self.grid.dx * self.rho[:] * self.g[:]
383387

384-
self.a6 = 6.0 * self.a - 3.0 * (self.am + self.ap)
388+
if not self.leave_as_perturbation:
389+
390+
# finally, add back in the HSE correction
391+
self.ap[:] += self.p_hse_p[:]
392+
self.am[:] += self.p_hse_m[:]
393+
394+
self.a6 = 6.0 * self.a - 3.0 * (self.am + self.ap)
395+
396+
else:
397+
# the cell-center state here is zero, since we subtract off pressur
398+
self.a6 = - 3.0 * (self.am + self.ap)
385399

386400
self.initialized = True

0 commit comments

Comments
 (0)