Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] add a compressible convection problem #293

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1ca7ccb
compressible: add the ability for a problem-dependent external source
zingale Oct 18, 2024
6e05e62
compressible: add a get_external_sources method
zingale Oct 18, 2024
47b5eb2
fix linting
zingale Oct 18, 2024
bb483b0
create a U_old
zingale Oct 18, 2024
b8ab28b
fix typo
zingale Oct 18, 2024
59a1921
fix
zingale Oct 18, 2024
b476e6f
fix stack
zingale Oct 18, 2024
110d7dc
do the corrector for the source
zingale Oct 18, 2024
275bb46
fix pylint
zingale Oct 18, 2024
4baf3cc
Merge branch 'external_sources' into energy_source
zingale Oct 18, 2024
f5d6a84
this works now
zingale Oct 18, 2024
cdea66d
update classes
zingale Oct 18, 2024
22cefac
update modules
zingale Oct 18, 2024
4352ef0
update source
zingale Oct 18, 2024
c8ef31b
add the plume problem
zingale Oct 18, 2024
9bce42a
add more doc
zingale Oct 18, 2024
012a9e5
fix spherical grav
zingale Oct 18, 2024
3ab90fe
update coord
zingale Oct 18, 2024
71a0224
fix flake8
zingale Oct 18, 2024
26ffe6f
fix pylint
zingale Oct 18, 2024
0bde429
fix p gradient sign
zingale Oct 21, 2024
3c33c36
Merge branch 'external_sources' into energy_source
zingale Oct 21, 2024
d75ab08
Merge branch 'main' into external_sources
zingale Oct 21, 2024
078cb2f
Merge branch 'external_sources' into energy_source
zingale Oct 21, 2024
4ce2545
use the same compressible external source function for RK and SDC sol…
zingale Nov 1, 2024
f40525f
fix flake8
zingale Nov 1, 2024
e3e2ad7
fix crash
zingale Nov 1, 2024
f3cbca1
fix stage data
zingale Nov 1, 2024
37a072d
Merge branch 'rk_sources' into energy_source
zingale Nov 1, 2024
87d148f
hook problem sources into RK
zingale Nov 1, 2024
baf26f8
Merge branch 'main' into rk_sources
zingale Nov 1, 2024
c01f5f8
Merge branch 'rk_sources' into energy_source
zingale Nov 1, 2024
d4a1486
add source to the predictor
zingale Nov 1, 2024
5ef5194
add a convection problem
zingale Nov 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions pyro/compressible/problems/convection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""A heat source in a layer at some height above the bottom will drive
convection in an adiabatically stratified atmosphere."""

import numpy as np

from pyro.util import msg

DEFAULT_INPUTS = "inputs.convection"

PROBLEM_PARAMS = {"convection.dens_base": 10.0, # density at the base of the atmosphere
"convection.scale_height": 4.0, # scale height of the isothermal atmosphere
"convection.y_height": 2.0,
"convection.thickness": 0.25,
"convection.e_rate": 0.1,
"convection.dens_cutoff": 0.01}


def init_data(my_data, rp):
""" initialize the bubble problem """

if rp.get_param("driver.verbose"):
msg.bold("initializing the bubble problem...")

# get the density, momenta, and energy as separate variables
dens = my_data.get_var("density")
xmom = my_data.get_var("x-momentum")
ymom = my_data.get_var("y-momentum")
ener = my_data.get_var("energy")

gamma = rp.get_param("eos.gamma")

grav = rp.get_param("compressible.grav")

scale_height = rp.get_param("convection.scale_height")
dens_base = rp.get_param("convection.dens_base")
dens_cutoff = rp.get_param("convection.dens_cutoff")

# initialize the components, remember, that ener here is
# rho*eint + 0.5*rho*v**2, where eint is the specific
# internal energy (erg/g)
xmom[:, :] = 0.0
ymom[:, :] = 0.0
dens[:, :] = dens_cutoff

# set the density to be stratified in the y-direction
myg = my_data.grid

p = myg.scratch_array()

pres_base = scale_height*dens_base*abs(grav)

for j in range(myg.jlo, myg.jhi+1):
profile = 1.0 - (gamma-1.0)/gamma * myg.y[j]/scale_height
if profile > 0.0:
dens[:, j] = max(dens_base*(profile)**(1.0/(gamma-1.0)),
dens_cutoff)
else:
dens[:, j] = dens_cutoff

if j == myg.jlo:
p[:, j] = pres_base
elif dens[0, j] <= dens_cutoff + 1.e-30:
p[:, j] = p[:, j-1]
else:
p[:, j] = p[:, j-1] + 0.5*myg.dy*(dens[:, j] + dens[:, j-1])*grav

# set the energy (P = cs2*dens)
ener[:, :] = p[:, :]/(gamma - 1.0) + \
0.5*(xmom[:, :]**2 + ymom[:, :]**2)/dens[:, :]

# pairs of random numbers between [-1, 1]
vel_pert = 2.0 * np.random.random_sample((myg.qx, myg.qy, 2)) - 1

cs = np.sqrt(gamma * p / dens)

# make vel_pert have M < 0.05
vel_pert[:, :, 0] *= 0.05 * cs
vel_pert[:, :, 1] *= 0.05 * cs

idx = dens > 2 * dens_cutoff
xmom[idx] = dens[idx] * vel_pert[idx, 0]
ymom[idx] = dens[idx] * vel_pert[idx, 1]

ener[:, :] += 0.5 * (xmom[:, :]**2 + ymom[:, :]**2) / dens[:, :]


def source_terms(myg, U, ivars, rp):
"""source terms to be added to the evolution"""

S = myg.scratch_array(nvar=ivars.nvar)

y_height = rp.get_param("convection.y_height")

dist = np.abs(myg.y2d - y_height)

e_rate = rp.get_param("convection.e_rate")
thick = rp.get_param("convection.thickness")

S[:, :, ivars.iener] = U[:, :, ivars.idens] * e_rate * np.exp(-(dist / thick)**2)
return S


def finalize():
""" print out any information to the user at the end of the run """
65 changes: 65 additions & 0 deletions pyro/compressible/problems/heating.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""A test of the energy sources. This uses a uniform domain and
slowly adds heat to the center over time."""

import numpy as np

from pyro.util import msg

DEFAULT_INPUTS = "inputs.heating"

PROBLEM_PARAMS = {"heating.rho_ambient": 1.0, # ambient density
"heating.p_ambient": 10.0, # ambient pressure
"heating.r_src": 0.1, # physical size of the heating src
"heating.e_rate": 0.1} # energy generation rate (energy / mass / time)


def init_data(my_data, rp):
""" initialize the heating problem """

if rp.get_param("driver.verbose"):
msg.bold("initializing the heating problem...")

# get the density, momenta, and energy as separate variables
dens = my_data.get_var("density")
xmom = my_data.get_var("x-momentum")
ymom = my_data.get_var("y-momentum")
ener = my_data.get_var("energy")

gamma = rp.get_param("eos.gamma")

# initialize the components, remember, that ener here is rho*eint
# + 0.5*rho*v**2, where eint is the specific internal energy
# (erg/g)
dens[:, :] = rp.get_param("heating.rho_ambient")
xmom[:, :] = 0.0
ymom[:, :] = 0.0
ener[:, :] = rp.get_param("heating.p_ambient") / (gamma - 1.0)


def source_terms(myg, U, ivars, rp):
"""source terms to be added to the evolution"""

S = myg.scratch_array(nvar=ivars.nvar)

xctr = 0.5 * (myg.xmin + myg.xmax)
yctr = 0.5 * (myg.ymin + myg.ymax)

dist = np.sqrt((myg.x2d - xctr)**2 +
(myg.y2d - yctr)**2)

e_rate = rp.get_param("heating.e_rate")
r_src = rp.get_param("heating.r_src")

S[:, :, ivars.iener] = U[:, :, ivars.idens] * e_rate * np.exp(-(dist / r_src)**2)
return S


def finalize():
""" print out any information to the user at the end of the run """

print("""
The script analysis/sedov_compare.py can be used to analyze these
results. That will perform an average at constant radius and
compare the radial profiles to the exact solution. Sample exact
data is provided as analysis/cylindrical-sedov.out
""")
39 changes: 39 additions & 0 deletions pyro/compressible/problems/inputs.convection
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# simple inputs files for the four-corner problem.

[driver]
max_steps = 10000
tmax = 10.0


[io]
basename = convection_
n_out = 100


[mesh]
nx = 128
ny = 256
xmax = 4.0
ymax = 8.0

xlboundary = outflow
xrboundary = outflow

ylboundary = reflect
yrboundary = outflow


[convection]
scale_height = 2.0
dens_base = 1000.0

x_pert = 2.0
y_pert = 2.0
r_pert = 0.25
e_rate = 0.5


[compressible]
grav = -2.0

limiter = 2
41 changes: 41 additions & 0 deletions pyro/compressible/problems/inputs.heating
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[driver]
max_steps = 5000
tmax = 1.0


[compressible]
limiter = 2
cvisc = 0.1


[io]
basename = heating_
dt_out = 0.1


[eos]
gamma = 1.4


[mesh]
nx = 64
ny = 64
xmax = 1.0
ymax = 1.0

xlboundary = outflow
xrboundary = outflow

ylboundary = outflow
yrboundary = outflow


[heating]
rho_ambient = 1.0
p_ambient = 10.0
r_src = 0.05
e_rate = 0.1


[vis]
dovis = 1
39 changes: 39 additions & 0 deletions pyro/compressible/problems/inputs.plume
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# simple inputs files for the four-corner problem.

[driver]
max_steps = 10000
tmax = 10.0


[io]
basename = plume_
n_out = 100


[mesh]
nx = 128
ny = 256
xmax = 4.0
ymax = 8.0

xlboundary = outflow
xrboundary = outflow

ylboundary = hse
yrboundary = hse


[plume]
scale_height = 3.0
dens_base = 1000.0

x_pert = 2.0
y_pert = 2.0
r_pert = 0.25
e_rate = 0.5


[compressible]
grav = -2.0

limiter = 2
90 changes: 90 additions & 0 deletions pyro/compressible/problems/plume.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""A heat source at a point creates a plume that buoynantly rises in
an adiabatically stratified atmosphere."""

import numpy as np

from pyro.util import msg

DEFAULT_INPUTS = "inputs.plume"

PROBLEM_PARAMS = {"plume.dens_base": 10.0, # density at the base of the atmosphere
"plume.scale_height": 4.0, # scale height of the isothermal atmosphere
"plume.x_pert": 2.0,
"plume.y_pert": 2.0,
"plume.r_pert": 0.25,
"plume.e_rate": 0.1,
"plume.dens_cutoff": 0.01}


def init_data(my_data, rp):
""" initialize the bubble problem """

if rp.get_param("driver.verbose"):
msg.bold("initializing the bubble problem...")

# get the density, momenta, and energy as separate variables
dens = my_data.get_var("density")
xmom = my_data.get_var("x-momentum")
ymom = my_data.get_var("y-momentum")
ener = my_data.get_var("energy")

gamma = rp.get_param("eos.gamma")

grav = rp.get_param("compressible.grav")

scale_height = rp.get_param("plume.scale_height")
dens_base = rp.get_param("plume.dens_base")
dens_cutoff = rp.get_param("plume.dens_cutoff")

# initialize the components, remember, that ener here is
# rho*eint + 0.5*rho*v**2, where eint is the specific
# internal energy (erg/g)
xmom[:, :] = 0.0
ymom[:, :] = 0.0
dens[:, :] = dens_cutoff

# set the density to be stratified in the y-direction
myg = my_data.grid

p = myg.scratch_array()

pres_base = scale_height*dens_base*abs(grav)

for j in range(myg.jlo, myg.jhi+1):
profile = 1.0 - (gamma-1.0)/gamma * myg.y[j]/scale_height
if profile > 0.0:
dens[:, j] = max(dens_base*(profile)**(1.0/(gamma-1.0)),
dens_cutoff)
else:
dens[:, j] = dens_cutoff

if j == myg.jlo:
p[:, j] = pres_base
else:
p[:, j] = p[:, j-1] + 0.5*myg.dy*(dens[:, j] + dens[:, j-1])*grav

# set the energy (P = cs2*dens)
ener[:, :] = p[:, :]/(gamma - 1.0) + \
0.5*(xmom[:, :]**2 + ymom[:, :]**2)/dens[:, :]


def source_terms(myg, U, ivars, rp):
"""source terms to be added to the evolution"""

S = myg.scratch_array(nvar=ivars.nvar)

x_pert = rp.get_param("plume.x_pert")
y_pert = rp.get_param("plume.y_pert")

dist = np.sqrt((myg.x2d - x_pert)**2 +
(myg.y2d - y_pert)**2)

e_rate = rp.get_param("plume.e_rate")
r_pert = rp.get_param("plume.r_pert")

S[:, :, ivars.iener] = U[:, :, ivars.idens] * e_rate * np.exp(-(dist / r_pert)**2)
return S


def finalize():
""" print out any information to the user at the end of the run """
Loading