コード例 #1
0
def prim_to_cons(q, gamma, ivars, myg):
    """ convert an input vector of primitive variables to conserved variables """

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

    u = q[:, :, ivars.iu]
    v = q[:, :, ivars.iv]

    try:
        W = 1 / np.sqrt(1 - u**2 - v**2)
    except FloatingPointError:
        u[np.isnan(u)] = 0
        v[np.isnan(v)] = 0
        W = np.ones_like(u)

    rhoh = eos.rhoh_from_rho_p(gamma, q[:, :, ivars.irho], q[:, :, ivars.ip])

    U[:, :, ivars.idens] = q[:, :, ivars.irho] * W
    U[:, :, ivars.ixmom] = u * rhoh * W**2
    U[:, :, ivars.iymom] = v * rhoh * W**2

    U[:, :, ivars.iener] = rhoh * W**2 - q[:, :, ivars.ip] - U[:, :, ivars.idens]

    if ivars.naux > 0:
        for nq, nu in zip(range(ivars.ix, ivars.ix+ivars.naux),
                          range(ivars.irhox, ivars.irhox+ivars.naux)):
            U[:, :, nu] = q[:, :, nq]*q[:, :, ivars.irho]*W

    return U
コード例 #2
0
def init_data(my_data, rp):
    """ an init routine for unit testing """

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ERROR: patch invalid in sedov.py")
        print(my_data.__class__)
        sys.exit()

    # 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[:, :] = 1.0
    xmom[:, :] = 0.0
    ymom[:, :] = 0.0
    # ener[:, :] = 2.5

    p = 1.0

    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)
    # print(f'rhoh = {rhoh}')

    # u, v = 0 so W = 1

    ener[:, :] = rhoh[:, :] - p - dens[:, :]
コード例 #3
0
ファイル: hse.py プロジェクト: priesbr1/CMSE401_pyro2_project
def init_data(my_data, rp):
    """ initialize the HSE problem """

    msg.bold("initializing the HSE problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ERROR: patch invalid in hse.py")
        print(my_data.__class__)
        sys.exit()

    # 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")

    dens0 = rp.get_param("hse.dens0")
    print("dens0 = ", dens0)
    H = rp.get_param("hse.h")

    # isothermal sound speed (squared)
    cs2 = H * abs(grav)

    # 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[:, :] = 0.0

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

    p = myg.scratch_array()

    for j in range(myg.jlo, myg.jhi + 1):
        dens[:, j] = dens0 * np.exp(-myg.y[j] / H)
        if j == myg.jlo:
            p[:, j] = dens[:, j] * cs2
        else:
            p[:,
              j] = p[:, j -
                     1] + 0.5 * myg.dy * (dens[:, j] + dens[:, j - 1]) * grav

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

    # W = 1
    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)
    ener[:, :] = rhoh - p - dens
コード例 #4
0
def init_data(my_data, rp):
    """ initialize a smooth advection problem for testing convergence """

    msg.bold("initializing the advect problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ERROR: patch invalid in advect.py")
        print(my_data.__class__)
        sys.exit()

    # 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")

    # 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[:, :] = 0.2
    xmom[:, :] = 0.0
    ymom[:, :] = 0.0

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

    xmin = rp.get_param("mesh.xmin")
    xmax = rp.get_param("mesh.xmax")

    ymin = rp.get_param("mesh.ymin")
    ymax = rp.get_param("mesh.ymax")

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

    # this is identical to the advection/smooth problem
    dens[:, :] = 0.2 * (1 + np.exp(-60.0 * ((my_data.grid.x2d - xctr)**2 +
                                            (my_data.grid.y2d - yctr)**2)))

    # velocity is diagonal
    u = 0.4
    v = 0.4

    # pressure is constant
    p = 0.2

    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)

    W = 1. / np.sqrt(1 - u**2 - v**2)
    dens[:, :] *= W
    xmom[:, :] = rhoh[:, :] * u * W**2
    ymom[:, :] = rhoh[:, :] * v * W**2

    ener[:, :] = rhoh[:, :] * W**2 - p - dens[:, :]
コード例 #5
0
def init_data(myd, rp):
    """initialize the acoustic_pulse problem.  This comes from
    McCourquodale & Coella 2011"""

    msg.bold("initializing the acoustic pulse problem...")

    # make sure that we are passed a valid patch object
    # if not isinstance(myd, fv.FV2d):
    #     print("ERROR: patch invalid in acoustic_pulse.py")
    #     print(myd.__class__)
    #     sys.exit()

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

    # 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

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

    rho0 = rp.get_param("acoustic_pulse.rho0")
    drho0 = rp.get_param("acoustic_pulse.drho0")

    xmin = rp.get_param("mesh.xmin")
    xmax = rp.get_param("mesh.xmax")

    ymin = rp.get_param("mesh.ymin")
    ymax = rp.get_param("mesh.ymax")

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

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

    dens[:, :] = rho0
    idx = dist <= 0.5
    dens[idx] = rho0 + drho0 * np.exp(-16 * dist[idx]**2) * np.cos(
        np.pi * dist[idx])**6

    p = (dens / rho0)**gamma
    ener[:, :] = p / (gamma - 1)

    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)

    ener[:, :] = rhoh[:, :] - p - dens[:, :]
コード例 #6
0
def test_eos_consistency():

    dens = 1.0
    eint = 1.0
    gamma = 1.4

    p = eos.pres(gamma, dens, eint)

    dens_eos = eos.dens(gamma, p, eint)

    assert dens == dens_eos

    rhoe_eos = eos.rhoe(gamma, p)

    assert dens*eint == rhoe_eos

    h = eos.h_from_eps(gamma, eint)

    assert (1 + gamma*eint) == h

    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)

    assert dens*h == rhoh
コード例 #7
0
def init_data(my_data, rp):
    """ initialize the bubble problem """

    msg.bold("initializing the bubble problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ERROR: patch invalid in bubble.py")
        print(my_data.__class__)
        sys.exit()

    # 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("bubble.scale_height")
    dens_base = rp.get_param("bubble.dens_base")
    dens_cutoff = rp.get_param("bubble.dens_cutoff")

    x_pert = rp.get_param("bubble.x_pert")
    y_pert = rp.get_param("bubble.y_pert")
    r_pert = rp.get_param("bubble.r_pert")
    pert_amplitude_factor = rp.get_param("bubble.pert_amplitude_factor")

    # 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()

    cs2 = scale_height * abs(grav)

    for j in range(myg.jlo, myg.jhi + 1):
        dens[:, j] = max(dens_base * np.exp(-myg.y[j] / scale_height),
                         dens_cutoff)
        if j == myg.jlo:
            p[:, j] = dens[:, j] * cs2
        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[:, :]

    r = np.sqrt((myg.x2d - x_pert)**2 + (myg.y2d - y_pert)**2)
    idx = r <= r_pert

    # boost the specific internal energy, keeping the pressure
    # constant, by dropping the density
    eint = (ener[idx] - 0.5 *
            (xmom[idx]**2 - ymom[idx]**2) / dens[idx]) / dens[idx]

    pres = dens[idx] * eint * (gamma - 1.0)

    eint = eint * pert_amplitude_factor
    dens[idx] = pres / (eint * (gamma - 1.0))

    ener[idx] = dens[idx] * eint + 0.5 * (xmom[idx]**2 +
                                          ymom[idx]**2) / dens[idx]

    # p[idx] = pres

    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)

    W = 1 / (np.sqrt(1 - (xmom**2 - ymom**2) / dens))

    dens[:, :] *= W
    xmom[:, :] *= rhoh[:, :] / dens * W**2
    ymom[:, :] *= rhoh[:, :] / dens * W**2

    # HACK: didn't work but W = 1 so shall cheat
    ener[:, :] = rhoh[:, :] * W**2 - p - dens[:, :]
コード例 #8
0
def init_data(my_data, rp):
    """ initialize the sedov problem """

    msg.bold("initializing the logo problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ERROR: patch invalid in sedov.py")
        print(my_data.__class__)
        sys.exit()

    # create the logo
    myg = my_data.grid

    fig = plt.figure(2, (0.64, 0.64), dpi=100 * myg.nx / 64)
    fig.add_subplot(111)

    fig.text(0.5,
             0.5,
             "pyro",
             transform=fig.transFigure,
             fontsize="16",
             horizontalalignment="center",
             verticalalignment="center")

    plt.axis("off")

    fig.canvas.draw()
    data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
    data = data.reshape(fig.canvas.get_width_height()[::-1] + (3, ))

    logo = np.rot90(np.rot90(np.rot90((256 - data[:, :, 1]) / 255.0)))

    # 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")

    myg = my_data.grid

    # 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

    # set the density in the logo zones to be really large
    logo_dens = 0.1

    dens[:, :] = logo_dens * (0.5 + logo[0, 0])

    dens.v()[:, :] = (0.5 + logo[:, :]) * logo_dens

    # pressure equilibrium
    gamma = rp.get_param("eos.gamma")

    p_ambient = 1.e-1
    p = myg.scratch_array(nvar=1)
    p[:, :] = p_ambient * (0.8 + logo[0, 0])
    p.v()[:, :] *= (0.8 + logo[:, :])
    # ener[:, :] = p/(gamma - 1.0)
    # ener.v()[:, :] *= (0.2 + logo[:, :])
    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)

    u = xmom / dens
    v = ymom / dens
    W = 1. / np.sqrt(1 - u**2 - v**2)
    dens[:, :] *= W
    xmom[:, :] = rhoh[:, :] * u * W**2
    ymom[:, :] = rhoh[:, :] * v * W**2

    ener[:, :] = rhoh[:, :] * W**2 - p - dens[:, :]
コード例 #9
0
def init_data(my_data, rp):
    """ initialize the sedov problem """

    msg.bold("initializing the sedov problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ERROR: patch invalid in sedov.py")
        print(my_data.__class__)
        sys.exit()

    # 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")

    # 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[:, :] = 1.0
    xmom[:, :] = 0.0
    ymom[:, :] = 0.0

    E_sedov = 2.0e-3

    r_init = rp.get_param("sedov.r_init")

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

    xmin = rp.get_param("mesh.xmin")
    xmax = rp.get_param("mesh.xmax")

    ymin = rp.get_param("mesh.ymin")
    ymax = rp.get_param("mesh.ymax")

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

    # initialize the pressure by putting the explosion energy into a
    # volume of constant pressure.  Then compute the energy in a zone
    # from this.
    nsub = rp.get_param("sedov.nsub")

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

    p = 1.e-5
    ener[:, :] = p / (gamma - 1.0)

    for i, j in np.transpose(np.nonzero(dist < 2.0 * r_init)):

        xsub = my_data.grid.xl[i] + (my_data.grid.dx /
                                     nsub) * (np.arange(nsub) + 0.5)
        ysub = my_data.grid.yl[j] + (my_data.grid.dy /
                                     nsub) * (np.arange(nsub) + 0.5)

        xx, yy = np.meshgrid(xsub, ysub, indexing="ij")

        dist = np.sqrt((xx - xctr)**2 + (yy - yctr)**2)

        n_in_pert = np.count_nonzero(dist <= r_init)

        p = n_in_pert*(gamma - 1.0)*E_sedov/(pi*r_init*r_init) + \
            (nsub*nsub - n_in_pert)*1.e-5

        p = p / (nsub * nsub)
        #
        # ener[i, j] = p/(gamma - 1.0)

        # W = 1
        rhoh = eos.rhoh_from_rho_p(gamma, dens[i, j], p)
        ener[i, j] = rhoh - p - dens[i, j]
コード例 #10
0
def init_data(my_data, rp):
    """ initialize the Gresho vortex problem """

    msg.bold("initializing the Gresho vortex problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ErrrrOrr: patch invalid in bubble.py")
        print(my_data.__class__)
        sys.exit()

    # get the density and velocities
    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")

    dens_base = rp.get_param("gresho.dens_base")

    rr = rp.get_param("gresho.r")
    u0 = rp.get_param("gresho.u0")
    p0 = rp.get_param("gresho.p0")

    # initialize the components -- we'll get a psure too
    # but that is used only to initialize the base state
    xmom[:, :] = 0.0
    ymom[:, :] = 0.0

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

    dens[:, :] = dens_base

    pres[:, :] = p0

    x_centre = 0.5 * (myg.x[0] + myg.x[-1])
    y_centre = 0.5 * (myg.y[0] + myg.y[-1])

    rad = np.sqrt((myg.x2d - x_centre)**2 + (myg.y2d - y_centre)**2)

    pres[rad <= rr] += 0.5 * (u0 * rad[rad <= rr] / rr)**2
    pres[(rad > rr) & (rad <= 2*rr)] += u0**2 * \
        (0.5 * (rad[(rad > rr) & (rad <= 2*rr)]/rr)**2 +
        4 * (1 - rad[(rad > rr) & (rad <= 2*rr)]/rr +
        np.log(rad[(rad > rr) & (rad <= 2*rr)]/rr)))
    pres[rad > 2 * rr] += u0**2 * (4 * np.log(2) - 2)
    # print(p[rad > 2*rr])
    #
    uphi = np.zeros_like(pres)
    uphi[rad <= rr] = u0 * rad[rad <= rr] / rr
    uphi[(rad > rr)
         & (rad <= 2 * rr)] = u0 * (2 - rad[(rad > rr) & (rad <= 2 * rr)] / rr)

    xmom[:, :] = -uphi[:, :] * (myg.y2d - y_centre) / rad[:, :]
    ymom[:, :] = uphi[:, :] * (myg.x2d - x_centre) / rad[:, :]

    # rhoe
    # enerad[:, :] = p[:, :]/(gamma - 1.0) + \
    #             0.5*(xmom[:, :]**2 + ymom[:, :]**2)/dens[:, :]

    # dens[:, :] = p[:, :]/(eint[:, :]*(gamma - 1.0))

    rhoh = eos.rhoh_from_rho_p(gamma, dens, pres)

    w_lor = 1. / np.sqrt(1. - xmom**2 - ymom**2)
    dens[:, :] *= w_lor
    xmom[:, :] *= rhoh * w_lor**2
    ymom[:, :] *= rhoh * w_lor**2

    ener[:, :] = rhoh * w_lor**2 - pres - dens
コード例 #11
0
def init_data(my_data, rp):
    """ initialize the sod problem """

    msg.bold("initializing the sod problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ERROR: patch invalid in sod.py")
        print(my_data.__class__)
        sys.exit()

    # get the sod parameters
    dens_left = rp.get_param("sod.dens_left")
    dens_right = rp.get_param("sod.dens_right")

    u_left = rp.get_param("sod.u_left")
    u_right = rp.get_param("sod.u_right")

    p_left = rp.get_param("sod.p_left")
    p_right = rp.get_param("sod.p_right")

    # 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")

    # initialize the components, remember, that ener here is rho*eint
    # + 0.5*rho*v**2, where eint is the specific internal energy
    # (erg/g)
    xmin = rp.get_param("mesh.xmin")
    xmax = rp.get_param("mesh.xmax")

    ymin = rp.get_param("mesh.ymin")
    ymax = rp.get_param("mesh.ymax")

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

    direction = rp.get_param("sod.direction")

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

    myg = my_data.grid

    p = np.ones_like(dens) * p_left
    dens[:, :] = dens_left

    if direction == "x":

        # left
        idxl = myg.x2d <= xctr

        dens[idxl] = dens_left
        xmom[idxl] = u_left
        ymom[idxl] = 0.0
        # ener[idxl] = p_left/(gamma - 1.0) + 0.5*xmom[idxl]*u_left

        p[idxl] = p_left

        # right
        idxr = myg.x2d > xctr

        dens[idxr] = dens_right
        xmom[idxr] = u_right
        ymom[idxr] = 0.0
        # ener[idxr] = p_right/(gamma - 1.0) + 0.5*xmom[idxr]*u_right

        p[idxr] = p_right

    else:

        # bottom
        idxb = myg.y2d <= yctr

        dens[idxb] = dens_left
        xmom[idxb] = 0.0
        ymom[idxb] = u_left
        # ener[idxb] = p_left/(gamma - 1.0) + 0.5*ymom[idxb]*u_left

        p[idxb] = p_left

        # top
        idxt = myg.y2d > yctr

        dens[idxt] = dens_right
        xmom[idxt] = 0.0
        ymom[idxt] = u_right
        # ener[idxt] = p_right/(gamma - 1.0) + 0.5*ymom[idxt]*u_right

        p[idxt] = p_right

    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)

    W = 1. / np.sqrt(1 - xmom**2 - ymom**2)
    dens[:, :] *= W
    xmom[:, :] *= rhoh * W**2
    ymom[:, :] *= rhoh * W**2

    ener[:, :] = rhoh * W**2 - p - dens
コード例 #12
0
def init_data(my_data, rp):
    """ initialize the Kelvin-Helmholtz problem """

    msg.bold("initializing the Kelvin-Helmholtz problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print(my_data.__class__)
        msg.fail("ERROR: patch invalid in kh.py")

    # 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")

    # 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[:, :] = 1.0
    xmom[:, :] = 0.0
    ymom[:, :] = 0.0

    rho_1 = rp.get_param("kh.rho_1")
    v_1 = rp.get_param("kh.v_1")
    rho_2 = rp.get_param("kh.rho_2")
    v_2 = rp.get_param("kh.v_2")

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

    myg = my_data.grid

    dy = 0.025
    w0 = 0.01
    vm = 0.5 * (v_1 - v_2)
    rhom = 0.5 * (rho_1 - rho_2)

    idx1 = myg.y2d < 0.25
    idx2 = np.logical_and(myg.y2d >= 0.25, myg.y2d < 0.5)
    idx3 = np.logical_and(myg.y2d >= 0.5, myg.y2d < 0.75)
    idx4 = myg.y2d >= 0.75

    # we will initialize momemum as velocity for now

    # lower quarter
    dens[idx1] = rho_1 - rhom * np.exp((myg.y2d[idx1] - 0.25) / dy)
    xmom[idx1] = v_1 - vm * np.exp((myg.y2d[idx1] - 0.25) / dy)

    # second quarter
    dens[idx2] = rho_2 + rhom * np.exp((0.25 - myg.y2d[idx2]) / dy)
    xmom[idx2] = v_2 + vm * np.exp((0.25 - myg.y2d[idx2]) / dy)

    # third quarter
    dens[idx3] = rho_2 + rhom * np.exp((myg.y2d[idx3] - 0.75) / dy)
    xmom[idx3] = v_2 + vm * np.exp((myg.y2d[idx3] - 0.75) / dy)

    # fourth quarter
    dens[idx4] = rho_1 - rhom * np.exp((0.75 - myg.y2d[idx4]) / dy)
    xmom[idx4] = v_1 - vm * np.exp((0.75 - myg.y2d[idx4]) / dy)

    # upper half
    xmom[:, :] *= dens
    ymom[:, :] = dens * w0 * np.sin(4 * np.pi * myg.x2d)

    p = 2.5
    ener[:, :] = p / (gamma - 1.0) + 0.5 * (xmom[:, :]**2 +
                                            ymom[:, :]**2) / dens[:, :]

    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)

    u = xmom / dens
    v = ymom / dens
    W = 1. / np.sqrt(1 - u**2 - v**2)
    dens[:, :] *= W
    xmom[:, :] = rhoh[:, :] * u * W**2
    ymom[:, :] = rhoh[:, :] * v * W**2

    ener[:, :] = rhoh[:, :] * W**2 - p - dens[:, :]
コード例 #13
0
def user(bc_name, bc_edge, variable, ccdata, ivars):
    """
    A hydrostatic boundary.  This integrates the equation of HSE into
    the ghost cells to get the pressure and density under the assumption
    that the specific internal energy is constant.

    Upon exit, the ghost cells for the input variable will be set

    Parameters
    ----------
    bc_name : {'hse'}
        The descriptive name for the boundary condition -- this allows
        for pyro to have multiple types of user-supplied boundary
        conditions.  For this module, it needs to be 'hse'.
    bc_edge : {'ylb', 'yrb'}
        The boundary to update: ylb = lower y boundary; yrb = upper y
        boundary.
    variable : {'density', 'x-momentum', 'y-momentum', 'energy'}
        The variable whose ghost cells we are filling
    ccdata : CellCenterData2d object
        The data object

    """

    myg = ccdata.grid

    if bc_name == "hse":

        if bc_edge == "ylb":

            # lower y boundary

            # we will take the density to be constant, the velocity to
            # be outflow, and the pressure to be in HSE
            if variable in [
                    "density", "x-momentum", "y-momentum", "ymom_src", "E_src",
                    "fuel", "ash"
            ]:
                v = ccdata.get_var(variable)
                j = myg.jlo - 1
                while j >= 0:
                    v[:, j] = v[:, myg.jlo]
                    j -= 1

            elif variable == "energy":
                # dens = ccdata.get_var("density")
                # xmom = ccdata.get_var("x-momentum")
                # ymom = ccdata.get_var("y-momentum")
                ener = ccdata.get_var("energy")

                grav = ccdata.get_aux("grav")
                gamma = ccdata.get_aux("gamma")

                q = flx.cons_to_prim_wrapper(ccdata.data, gamma, ivars, myg)

                rho = q[:, :, ivars.irho]
                u = q[:, myg.jlo, ivars.iu]
                v = q[:, myg.jlo, ivars.iv]
                p = q[:, :, ivars.ip]

                dens_base = rho[:, myg.jlo]
                # ke_base = 0.5*(u[:, myg.jlo]**2 + v[:, myg.jlo]**2) * rho[:, myg.jlo]

                # eint_base = (ener[:, myg.jlo] - ke_base)/dens[:, myg.jlo]
                # pres_base = eos.pres(gamma, dens_base, eint_base)
                pres_base = p[:, myg.jlo]

                # we are assuming that the density is constant in this
                # formulation of HSE, so the pressure comes simply from
                # differencing the HSE equation
                W = np.sqrt(1 - u**2 - v**2)
                j = myg.jlo - 1
                while j >= 0:
                    pres_below = pres_base - grav * dens_base * myg.dy
                    rhoh = eos.rhoh_from_rho_p(gamma, dens_base, pres_below)

                    ener[:, j] = rhoh * W**2 - pres_below - dens_base

                    pres_base = pres_below.copy()

                    j -= 1

            else:
                raise NotImplementedError("variable not defined")

        elif bc_edge == "yrb":

            # upper y boundary

            # we will take the density to be constant, the velocity to
            # be outflow, and the pressure to be in HSE
            if variable in [
                    "density", "x-momentum", "y-momentum", "ymom_src", "E_src",
                    "fuel", "ash"
            ]:
                v = ccdata.get_var(variable)
                for j in range(myg.jhi + 1, myg.jhi + myg.ng + 1):
                    v[:, j] = v[:, myg.jhi]

            elif variable == "energy":
                # dens = ccdata.get_var("density")
                # xmom = ccdata.get_var("x-momentum")
                # ymom = ccdata.get_var("y-momentum")
                ener = ccdata.get_var("energy")

                grav = ccdata.get_aux("grav")
                gamma = ccdata.get_aux("gamma")

                q = flx.cons_to_prim_wrapper(ccdata.data, gamma, ivars, myg)

                rho = q[:, :, ivars.irho]
                u = q[:, myg.jhi, ivars.iu]
                v = q[:, myg.jhi, ivars.iv]
                p = q[:, :, ivars.ip]

                dens_base = rho[:, myg.jhi]
                # ke_base = 0.5*(xmom[:, myg.jhi]**2 + ymom[:, myg.jhi]**2) / \
                #   dens[:, myg.jhi]

                # eint_base = (ener[:, myg.jhi] - ke_base)/dens[:, myg.jhi]
                # pres_base = eos.pres(gamma, dens_base, eint_base)
                pres_base = p[:, myg.jhi]

                # we are assuming that the density is constant in this
                # formulation of HSE, so the pressure comes simply from
                # differencing the HSE equation
                W = np.sqrt(1 - u**2 - v**2)
                for j in range(myg.jhi + 1, myg.jhi + myg.ng + 1):
                    pres_above = pres_base + grav * dens_base * myg.dy
                    # rhoe = eos.rhoe(gamma, pres_above)
                    rhoh = eos.rhoh_from_rho_p(gamma, dens_base, pres_above)

                    # ener[:, j] = rhoe + ke_base
                    ener[:, j] = rhoh * W**2 - pres_above - dens_base

                    pres_base = pres_above.copy()

            else:
                raise NotImplementedError("variable not defined")

        else:
            msg.fail("error: hse BC not supported for xlb or xrb")

    elif bc_name == "ramp":
        # Boundary conditions for double Mach reflection problem

        gamma = ccdata.get_aux("gamma")

        if bc_edge == "xlb":
            # lower x boundary
            # inflow condition with post shock setup

            v = ccdata.get_var(variable)
            i = myg.ilo - 1
            if variable in ["density", "x-momentum", "y-momentum", "energy"]:
                val = inflow_post_bc(variable, gamma)
                while i >= 0:
                    v[i, :] = val
                    i = i - 1
            else:
                v[:, :] = 0.0  # no source term

        elif bc_edge == "ylb":
            # lower y boundary
            # for x > 1./6., reflective boundary
            # for x < 1./6., inflow with post shock setup

            if variable in ["density", "x-momentum", "y-momentum", "energy"]:
                v = ccdata.get_var(variable)
                j = myg.jlo - 1
                jj = 0
                while j >= 0:
                    xcen_l = myg.x < 1.0 / 6.0
                    xcen_r = myg.x >= 1.0 / 6.0
                    v[xcen_l, j] = inflow_post_bc(variable, gamma)

                    if variable == "y-momentum":
                        v[xcen_r, j] = -1.0 * v[xcen_r, myg.jlo + jj]
                    else:
                        v[xcen_r, j] = v[xcen_r, myg.jlo + jj]
                    j = j - 1
                    jj = jj + 1
            else:
                v = ccdata.get_var(variable)
                v[:, :] = 0.0  # no source term

        elif bc_edge == "yrb":
            # upper y boundary
            # time-dependent boundary, the shockfront moves with a 10 mach velocity forming an angle
            # to the x-axis of 30 degrees clockwise.
            # x coordinate of the grid is used to judge whether the cell belongs to pure post shock area,
            # the pure pre shock area or the mixed area.

            if variable in ["density", "x-momentum", "y-momentum", "energy"]:
                v = ccdata.get_var(variable)
                for j in range(myg.jhi + 1, myg.jhi + myg.ng + 1):
                    shockfront_up = 1.0/6.0 + (myg.y[j] + 0.5*myg.dy*math.sqrt(3))/math.tan(math.pi/3.0) \
                                    + (10.0/math.sin(math.pi/3.0))*ccdata.t
                    shockfront_down = 1.0/6.0 + (myg.y[j] - 0.5*myg.dy*math.sqrt(3))/math.tan(math.pi/3.0) \
                                    + (10.0/math.sin(math.pi/3.0))*ccdata.t
                    shockfront = np.array([shockfront_down, shockfront_up])
                    for i in range(myg.ihi + myg.ng + 1):
                        v[i, j] = 0.0
                        cx_down = myg.x[i] - 0.5 * myg.dx * math.sqrt(3)
                        cx_up = myg.x[i] + 0.5 * myg.dx * math.sqrt(3)
                        cx = np.array([cx_down, cx_up])

                        for sf in shockfront:
                            for x in cx:
                                if x < sf:
                                    v[i, j] = v[i, j] + 0.25 * inflow_post_bc(
                                        variable, gamma)
                                else:
                                    v[i, j] = v[i, j] + 0.25 * inflow_pre_bc(
                                        variable, gamma)
            else:
                v = ccdata.get_var(variable)
                v[:, :] = 0.0  # no source term

    else:
        msg.fail("error: bc type %s not supported" % (bc_name))
コード例 #14
0
def init_data(my_data, rp):
    """ initialize the rt problem """

    msg.bold("initializing the rt problem...")

    # make sure that we are passed a valid patch object
    if not isinstance(my_data, patch.CellCenterData2d):
        print("ERROR: patch invalid in rt.py")
        print(my_data.__class__)
        sys.exit()

    # 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")

    dens1 = rp.get_param("rt.dens1")
    dens2 = rp.get_param("rt.dens2")
    p0 = rp.get_param("rt.p0")
    amp = rp.get_param("rt.amp")
    sigma = rp.get_param("rt.sigma")

    # 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[:, :] = 0.0

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

    ycenter = 0.5 * (myg.ymin + myg.ymax)

    p = myg.scratch_array()

    p[:, :] = p0
    dens[:, :] = dens1

    for j in range(myg.jlo, myg.jhi + 1):
        if (myg.y[j] < ycenter):
            dens[:, j] = dens1
            p[:, j] = p0 + dens1 * grav * myg.y[j]

        else:
            dens[:, j] = dens2
            p[:, j] = p0 + dens1 * grav * ycenter + dens2 * grav * (myg.y[j] -
                                                                    ycenter)

    ymom[:, :] = amp * np.cos(2.0 * np.pi * myg.x2d /
                              (myg.xmax - myg.xmin)) * np.exp(
                                  -(myg.y2d - ycenter)**2 / sigma**2)

    rhoh = eos.rhoh_from_rho_p(gamma, dens, p)

    u = xmom
    v = ymom
    W = 1. / np.sqrt(1 - u**2 - v**2)
    dens[:, :] *= W
    xmom[:, :] *= rhoh[:, :] * W**2
    ymom[:, :] *= rhoh[:, :] * W**2

    ener[:, :] = rhoh[:, :] * W**2 - p - dens[:, :]