Skip to content

Commit 425d037

Browse files
authored
simplified the initial conditions interface (#39)
1 parent 7e7dd5c commit 425d037

4 files changed

Lines changed: 81 additions & 98 deletions

File tree

examples/euler.ipynb

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -190,32 +190,32 @@
190190
},
191191
{
192192
"cell_type": "code",
193-
"execution_count": 15,
193+
"execution_count": 10,
194194
"id": "047dc02b-b5f1-45c0-a41a-af0251834cc7",
195195
"metadata": {},
196196
"outputs": [],
197197
"source": [
198-
"def shock_tube(g, v, U, params):\n",
198+
"def shock_tube(euler):\n",
199199
"\n",
200-
" gamma = params[\"gamma\"]\n",
200+
" gamma = euler.params[\"gamma\"]\n",
201201
" \n",
202-
" rho_l = params[\"rho_l\"]\n",
203-
" u_l = params[\"u_l\"]\n",
204-
" p_l = params[\"p_l\"]\n",
205-
" rho_r = params[\"rho_r\"]\n",
206-
" u_r = params[\"u_r\"]\n",
207-
" p_r = params[\"p_r\"]\n",
202+
" rho_l = euler.params[\"rho_l\"]\n",
203+
" u_l = euler.params[\"u_l\"]\n",
204+
" p_l = euler.params[\"p_l\"]\n",
205+
" rho_r = euler.params[\"rho_r\"]\n",
206+
" u_r = euler.params[\"u_r\"]\n",
207+
" p_r = euler.params[\"p_r\"]\n",
208208
"\n",
209-
" idx_l = g.x < 0.5\n",
210-
" idx_r = g.x >= 0.5\n",
209+
" idx_l = euler.grid.x < 0.5\n",
210+
" idx_r = euler.grid.x >= 0.5\n",
211211
"\n",
212-
" U[idx_l, v.urho] = rho_l\n",
213-
" U[idx_l, v.umx] = rho_l * u_l\n",
214-
" U[idx_l, v.uener] = p_l/(gamma - 1.0) + 0.5 * rho_l * u_l**2\n",
212+
" euler.U[idx_l, euler.v.urho] = rho_l\n",
213+
" euler.U[idx_l, euler.v.umx] = rho_l * u_l\n",
214+
" euler.U[idx_l, euler.v.uener] = p_l/(gamma - 1.0) + 0.5 * rho_l * u_l**2\n",
215215
"\n",
216-
" U[idx_r, v.urho] = rho_r\n",
217-
" U[idx_r, v.umx] = rho_r * u_r\n",
218-
" U[idx_r, v.uener] = p_r/(gamma - 1.0) + 0.5 * rho_r * u_r**2"
216+
" euler.U[idx_r, euler.v.urho] = rho_r\n",
217+
" euler.U[idx_r, euler.v.umx] = rho_r * u_r\n",
218+
" euler.U[idx_r, euler.v.uener] = p_r/(gamma - 1.0) + 0.5 * rho_r * u_r**2"
219219
]
220220
},
221221
{
@@ -228,7 +228,7 @@
228228
},
229229
{
230230
"cell_type": "code",
231-
"execution_count": 16,
231+
"execution_count": 11,
232232
"id": "017682fe-b0d8-48a9-88d5-19b2d96398d0",
233233
"metadata": {},
234234
"outputs": [],
@@ -241,7 +241,7 @@
241241
},
242242
{
243243
"cell_type": "code",
244-
"execution_count": 17,
244+
"execution_count": 12,
245245
"id": "64489150-696b-4b9b-a879-3d70a5cedb18",
246246
"metadata": {},
247247
"outputs": [

examples/hse.ipynb

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@
9292
"cell_type": "code",
9393
"execution_count": 5,
9494
"id": "6935138d-852d-4d56-ac43-4960cd4f4b6b",
95-
"metadata": {},
95+
"metadata": {
96+
"scrolled": true
97+
},
9698
"outputs": [
9799
{
98100
"name": "stdout",
@@ -122,7 +124,7 @@
122124
},
123125
{
124126
"cell_type": "code",
125-
"execution_count": 7,
127+
"execution_count": 6,
126128
"id": "66950c33-44e4-4975-9e96-c569396b8f5c",
127129
"metadata": {},
128130
"outputs": [
@@ -140,9 +142,7 @@
140142
],
141143
"source": [
142144
"for s in simulations:\n",
143-
" init = s.grid.scratch_array(nc=3)\n",
144-
" hse(s.grid, s.v, init, s.params)\n",
145-
" print(f\"{s.grid.nx:3d} : {s.grid.norm(init[:, ivar] - s.U[:, ivar]) }\")"
145+
" print(f\"{s.grid.nx:3d} : {s.grid.norm(s.U_init[:, ivar] - s.U[:, ivar]) }\")"
146146
]
147147
},
148148
{
@@ -155,17 +155,17 @@
155155
},
156156
{
157157
"cell_type": "code",
158-
"execution_count": 10,
158+
"execution_count": 7,
159159
"id": "d4e9df43-d976-4e00-b99b-213f52b60839",
160160
"metadata": {},
161161
"outputs": [
162162
{
163163
"data": {
164164
"text/plain": [
165-
"[<matplotlib.lines.Line2D at 0x7ff5d0149880>]"
165+
"[<matplotlib.lines.Line2D at 0x7fe7d0d9b800>]"
166166
]
167167
},
168-
"execution_count": 10,
168+
"execution_count": 7,
169169
"metadata": {},
170170
"output_type": "execute_result"
171171
},
@@ -182,11 +182,9 @@
182182
],
183183
"source": [
184184
"s = simulations[0]\n",
185-
"init = s.grid.scratch_array(nc=3)\n",
186-
"hse(s.grid, s.v, init, s.params)\n",
187185
"\n",
188186
"fig, ax = plt.subplots()\n",
189-
"ax.plot(s.grid.x[s.grid.lo:s.grid.hi+1], init[s.grid.lo:s.grid.hi+1, ivar], marker=\"o\")\n",
187+
"ax.plot(s.grid.x[s.grid.lo:s.grid.hi+1], s.U_init[s.grid.lo:s.grid.hi+1, ivar], marker=\"o\")\n",
190188
"ax.plot(s.grid.x[s.grid.lo:s.grid.hi+1], s.U[s.grid.lo:s.grid.hi+1, ivar], marker=\"x\")"
191189
]
192190
}

ppmpy/euler.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,8 @@ class Euler:
5656
are: "reflect", "outflow", "periodic"
5757
init_cond : function
5858
the function to call to initialize the conserved state.
59-
This has the signature `init_cond(grid, v, gamma, U, params)`
60-
where `grid` is a `FVGrid`, `v` is a `FluidVars`, and `params`
61-
is a `dict` with any optional parameters needed for
62-
initialization.
59+
This has the signature `init_cond(euler)`
60+
where `euler` is an `Euler` object.
6361
grav_func : function
6462
the function to call to compute the gravitational acceleration.
6563
This has the signature: `g = grav_func(grid, rho, params)`, where
@@ -130,12 +128,15 @@ def __init__(self, nx, C, *,
130128
self.g_parabola = None
131129

132130
# initialize
133-
init_cond(self.grid, self.v, self.U, self.params)
131+
init_cond(self)
134132
for n in range(self.v.nvar):
135133
self.grid.ghost_fill(self.U[:, n],
136134
bc_left_type=self.bcs_left[n],
137135
bc_right_type=self.bcs_right[n])
138136

137+
# save ICs for later diagnostics
138+
self.U_init = self.U.copy()
139+
139140
self.use_hse_reconstruction = use_hse_reconstruction
140141
self.use_flattening = use_flattening
141142
self.use_limiting = use_limiting

ppmpy/initial_conditions.py

Lines changed: 47 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,21 @@
44
import numpy as np
55

66

7-
def sod(g, v, U, params): # pylint: disable=W0613
7+
def sod(euler):
88
"""Initial conditions for the classic Sod shock tube problem
99
1010
Parameters
1111
----------
12-
grid : FVGrid
13-
the grid object
14-
v : FluidVars
15-
the fluid variables object
16-
U : ndarray
17-
the conserved state array
18-
params : dict
19-
a dictionary of parameters.
20-
We expect gamma to be provided here
12+
euler : Euler
13+
the Euler simulation object
2114
2215
Returns
2316
-------
2417
None
2518
"""
2619

27-
gamma = params["gamma"]
20+
gamma = euler.params["gamma"]
21+
g = euler.grid
2822

2923
# setup initial conditions -- this is Sod's problem
3024
rho_l = 1.0
@@ -37,82 +31,72 @@ def sod(g, v, U, params): # pylint: disable=W0613
3731
idx_l = g.x < 0.5
3832
idx_r = g.x >= 0.5
3933

40-
U[idx_l, v.urho] = rho_l
41-
U[idx_l, v.umx] = rho_l * u_l
42-
U[idx_l, v.uener] = p_l/(gamma - 1.0) + 0.5 * rho_l * u_l**2
34+
euler.U[idx_l, euler.v.urho] = rho_l
35+
euler.U[idx_l, euler.v.umx] = rho_l * u_l
36+
euler.U[idx_l, euler.v.uener] = p_l/(gamma - 1.0) + 0.5 * rho_l * u_l**2
4337

44-
U[idx_r, v.urho] = rho_r
45-
U[idx_r, v.umx] = rho_r * u_r
46-
U[idx_r, v.uener] = p_r/(gamma - 1.0) + 0.5 * rho_r * u_r**2
38+
euler.U[idx_r, euler.v.urho] = rho_r
39+
euler.U[idx_r, euler.v.umx] = rho_r * u_r
40+
euler.U[idx_r, euler.v.uener] = p_r/(gamma - 1.0) + 0.5 * rho_r * u_r**2
4741

4842

49-
def acoustic_pulse(g, v, U, params): # pylint: disable=W0613
43+
def acoustic_pulse(euler):
5044
"""The acoustic pulse problem from McCorquodale & Colella 2011
5145
5246
Parameters
5347
----------
54-
grid : FVGrid
55-
the grid object
56-
v : FluidVars
57-
the fluid variables object
58-
U : ndarray
59-
the conserved state array
60-
params : dict
61-
a dictionary of parameters (not used)
62-
We expect gamma to be provided here
48+
euler : Euler
49+
the Euler simulation object
6350
6451
Returns
6552
-------
6653
None
6754
"""
6855

69-
gamma = params["gamma"]
56+
gamma = euler.params["gamma"]
7057

71-
xcenter = 0.5 * (g.xmin + g.xmax)
58+
xcenter = 0.5 * (euler.grid.xmin + euler.grid.xmax)
7259

7360
rho0 = 1.4
7461
delta_rho = 0.14
7562

76-
r = np.abs(g.x - xcenter)
63+
r = np.abs(euler.grid.x - xcenter)
7764

7865
rho = np.where(r <= 0.5, rho0 + delta_rho * np.exp(-16.0 * r**2) * np.cos(np.pi * r)**6, rho0)
7966
p = (rho / rho0)**gamma
8067
u = 0.0
8168

82-
U[:, v.urho] = rho
83-
U[:, v.umx] = rho * u
84-
U[:, v.uener] = p / (gamma - 1.0) + 0.5 * rho * u**2
69+
euler.U[:, euler.v.urho] = rho
70+
euler.U[:, euler.v.umx] = rho * u
71+
euler.U[:, euler.v.uener] = p / (gamma - 1.0) + 0.5 * rho * u**2
8572

8673

87-
def hse(grid, v, U, params):
74+
def hse(euler):
8875
"""An isothermal hydrostatic atmosphere.
76+
77+
The following parameters should be set in the Euler initialization:
78+
79+
* `base_density` : the density at the lower boundary
80+
* `base_pressure` : the pressure at the lower boundary
81+
* `g_const` : the gravitational acceleration
82+
* `verbose` : output the HSE error
83+
8984
Parameters
9085
----------
91-
grid : FVGrid
92-
the grid object
93-
v : FluidVars
94-
the fluid variables object
95-
U : ndarray
96-
the conserved state array
97-
params : dict
98-
a dictionary of parameters
99-
100-
* `base_density` : the density at the lower boundary
101-
* `base_pressure` : the pressure at the lower boundary
102-
* `g_const` : the gravitational acceleration
103-
* `gamma` : the ratio of specific heats
86+
euler : Euler
87+
the Euler simulation object
10488
10589
Returns
10690
-------
10791
None
10892
"""
10993

110-
rho_base = params["base_density"]
111-
pres_base = params["base_pressure"]
112-
g = params["g_const"]
113-
gamma = params["gamma"]
94+
rho_base = euler.params["base_density"]
95+
pres_base = euler.params["base_pressure"]
96+
g = euler.params["g_const"]
97+
gamma = euler.params["gamma"]
11498

115-
verbose = params.get("verbose", False)
99+
verbose = euler.params.get("verbose", False)
116100

117101
# we will assume we are isothermal and constant composition. In that case,
118102
# p/rho = constant
@@ -122,34 +106,34 @@ def hse(grid, v, U, params):
122106
# p_{i+1} = p_i + dx / 2 (rho_i + rho_{i+1} g
123107
# but we can write p_{i+1} = A rho_{i+1} and solve for rho_{i+1}
124108

125-
p = grid.scratch_array()
126-
rho = grid.scratch_array()
109+
p = euler.grid.scratch_array()
110+
rho = euler.grid.scratch_array()
127111

128112
# we want the base conditions to be at the lower boundary. We will
129113
# set the conditions in the first zone center from the analytic expression:
130114
# P = P_base e^{-z/H}
131115

132116
H = pres_base / rho_base / np.abs(g)
133117

134-
p[grid.lo] = pres_base * np.exp(-grid.x[grid.lo] / H)
135-
rho[grid.lo] = rho_base * np.exp(-grid.x[grid.lo] / H)
118+
p[euler.grid.lo] = pres_base * np.exp(-euler.grid.x[euler.grid.lo] / H)
119+
rho[euler.grid.lo] = rho_base * np.exp(-euler.grid.x[euler.grid.lo] / H)
136120

137-
for i in range(grid.lo+1, grid.hi+1):
138-
rho[i] = (p[i-1] + 0.5 * grid.dx * rho[i-1] * g) / (A - 0.5 * grid.dx * g)
121+
for i in range(euler.grid.lo+1, euler.grid.hi+1):
122+
rho[i] = (p[i-1] + 0.5 * euler.grid.dx * rho[i-1] * g) / (A - 0.5 * euler.grid.dx * g)
139123
p[i] = A * rho[i]
140124

141125
# now check HSE
142126
if verbose:
143127
max_err = 0.0
144-
for i in range(grid.lo+1, grid.hi+1):
145-
dpdr = (p[i] - p[i-1])/grid.dx
128+
for i in range(euler.grid.lo+1, euler.grid.hi+1):
129+
dpdr = (p[i] - p[i-1]) / euler.grid.dx
146130
rhog = 0.5 * (rho[i] + rho[i-1]) * g
147131
err = np.abs(dpdr - rhog) / np.abs(rhog)
148132
max_err = max(max_err, err)
149133

150134
print(f"max err = {max_err}")
151135

152136
# now fill the conserved variables
153-
U[:, v.urho] = rho[:]
154-
U[:, v.umx] = 0.0
155-
U[:, v.uener] = p[:] / (gamma - 1.0)
137+
euler.U[:, euler.v.urho] = rho[:]
138+
euler.U[:, euler.v.umx] = 0.0
139+
euler.U[:, euler.v.uener] = p[:] / (gamma - 1.0)

0 commit comments

Comments
 (0)