Exemple #1
0
    def dovis(self):
        """
        Do runtime visualization.
        """

        plt.clf()

        plt.rc("font", size=10)

        # we do this even though ivars is in self, so this works when
        # we are plotting from a file
        ivars = Variables(self.cc_data)

        # access gamma from the cc_data object so we can use dovis
        # outside of a running simulation.
        gamma = self.cc_data.get_aux("gamma")

        q = cons_to_prim(self.cc_data.data, gamma, ivars, self.cc_data.grid)

        rho = q[:, :, ivars.irho]
        u = q[:, :, ivars.iu]
        v = q[:, :, ivars.iv]
        p = q[:, :, ivars.ip]
        e = eos.rhoe(gamma, p) / rho

        magvel = np.sqrt(u**2 + v**2)

        myg = self.cc_data.grid

        fields = [rho, magvel, p, e]
        field_names = [r"$\rho$", r"U", "p", "e"]

        f, axes, cbar_title = plot_tools.setup_axes(myg, len(fields))

        for n, ax in enumerate(axes):
            v = fields[n]

            img = ax.imshow(np.transpose(v.v()),
                            interpolation="nearest",
                            origin="lower",
                            extent=[myg.xmin, myg.xmax, myg.ymin, myg.ymax],
                            cmap=self.cm)

            ax.set_xlabel("x")
            ax.set_ylabel("y")

            # needed for PDF rendering
            cb = axes.cbar_axes[n].colorbar(img)
            cb.solids.set_rasterized(True)
            cb.solids.set_edgecolor("face")

            if cbar_title:
                cb.ax.set_title(field_names[n])
            else:
                ax.set_title(field_names[n])

        plt.figtext(0.05, 0.0125, "t = {:10.5g}".format(self.cc_data.t))

        plt.pause(0.001)
        plt.draw()
Exemple #2
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_equal(dens, dens_eos)

    rhoe_eos = eos.rhoe(gamma, p)

    assert_equal(dens * eint, rhoe_eos)
Exemple #3
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
Exemple #4
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
Exemple #5
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[:, :, ivars.idens] = q[:, :, ivars.irho]
    U[:, :, ivars.ixmom] = q[:, :, ivars.iu] * U[:, :, ivars.idens]
    U[:, :, ivars.iymom] = q[:, :, ivars.iv] * U[:, :, ivars.idens]

    rhoe = eos.rhoe(gamma, q[:, :, ivars.ip])

    U[:, :,
      ivars.iener] = rhoe + 0.5 * q[:, :, ivars.irho] * (q[:, :, ivars.iu]**2 +
                                                         q[:, :, ivars.iv]**2)

    if ivars.naux > 0:
        U[:, :, ivars.irhox] = q[:, :, ivars.ix] * q[:, :, ivars.irho]

    return U
Exemple #6
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[:, :, ivars.idens] = q[:, :, ivars.irho]
    U[:, :, ivars.ixmom] = q[:, :, ivars.iu]*U[:, :, ivars.idens]
    U[:, :, ivars.iymom] = q[:, :, ivars.iv]*U[:, :, ivars.idens]

    rhoe = eos.rhoe(gamma, q[:, :, ivars.ip])

    U[:, :, ivars.iener] = rhoe + 0.5*q[:, :, ivars.irho]*(q[:, :, ivars.iu]**2 +
                                                           q[:, :, ivars.iv]**2)

    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]

    return U
Exemple #7
0
def unsplitFluxes(my_data, my_aux, rp, vars, solid, tc, dt):
    """
    unsplitFluxes returns the fluxes through the x and y interfaces by
    doing an unsplit reconstruction of the interface values and then
    solving the Riemann problem through all the interfaces at once

    currently we assume a gamma-law EOS

    The runtime parameter grav is assumed to be the gravitational
    acceleration in the y-direction

    Parameters
    ----------
    my_data : CellCenterData2d object
        The data object containing the grid and advective scalar that
        we are advecting.
    rp : RuntimeParameters object
        The runtime parameters for the simulation
    vars : Variables object
        The Variables object that tells us which indices refer to which
        variables
    tc : TimerCollection object
        The timers we are using to profile
    dt : float
        The timestep we are advancing through.

    Returns
    -------
    out : ndarray, ndarray
        The fluxes on the x- and y-interfaces

    """

    tm_flux = tc.timer("unsplitFluxes")
    tm_flux.begin()

    myg = my_data.grid

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

    #=========================================================================
    # compute the primitive variables
    #=========================================================================
    # Q = (rho, u, v, p)

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

    r = dens

    # get the velocities
    u = xmom/dens
    v = ymom/dens

    # get the pressure
    e = (ener - 0.5*(xmom**2 + ymom**2)/dens)/dens

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

    smallp = 1.e-10
    p.d = p.d.clip(smallp)   # apply a floor to the pressure


    #=========================================================================
    # compute the flattening coefficients
    #=========================================================================

    # there is a single flattening coefficient (xi) for all directions
    use_flattening = rp.get_param("compressible.use_flattening")

    if use_flattening:
        delta = rp.get_param("compressible.delta")
        z0 = rp.get_param("compressible.z0")
        z1 = rp.get_param("compressible.z1")

        xi_x = reconstruction_f.flatten(1, p.d, u.d, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1)
        xi_y = reconstruction_f.flatten(2, p.d, v.d, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1)

        xi = reconstruction_f.flatten_multid(xi_x, xi_y, p.d, myg.qx, myg.qy, myg.ng)
    else:
        xi = 1.0


    # monotonized central differences in x-direction
    tm_limit = tc.timer("limiting")
    tm_limit.begin()

    limiter = rp.get_param("compressible.limiter")
    if limiter == 0:
        limitFunc = reconstruction_f.nolimit
    elif limiter == 1:
        limitFunc = reconstruction_f.limit2
    else:
        limitFunc = reconstruction_f.limit4

    ldelta_rx = xi*limitFunc(1, r.d, myg.qx, myg.qy, myg.ng)
    ldelta_ux = xi*limitFunc(1, u.d, myg.qx, myg.qy, myg.ng)
    ldelta_vx = xi*limitFunc(1, v.d, myg.qx, myg.qy, myg.ng)
    ldelta_px = xi*limitFunc(1, p.d, myg.qx, myg.qy, myg.ng)

    # monotonized central differences in y-direction
    ldelta_ry = xi*limitFunc(2, r.d, myg.qx, myg.qy, myg.ng)
    ldelta_uy = xi*limitFunc(2, u.d, myg.qx, myg.qy, myg.ng)
    ldelta_vy = xi*limitFunc(2, v.d, myg.qx, myg.qy, myg.ng)
    ldelta_py = xi*limitFunc(2, p.d, myg.qx, myg.qy, myg.ng)

    tm_limit.end()


    #=========================================================================
    # x-direction
    #=========================================================================

    # left and right primitive variable states
    tm_states = tc.timer("interfaceStates")
    tm_states.begin()

    V_l, V_r = interface_f.states(1, myg.qx, myg.qy, myg.ng, myg.dx, dt,
                                  vars.nvar,
                                  gamma,
                                  r.d, u.d, v.d, p.d,
                                  ldelta_rx, ldelta_ux, ldelta_vx, ldelta_px)

    tm_states.end()


    # transform interface states back into conserved variables
    U_xl = myg.scratch_array(vars.nvar)
    U_xr = myg.scratch_array(vars.nvar)

    U_xl.d[:,:,vars.idens] = V_l[:,:,vars.irho]
    U_xl.d[:,:,vars.ixmom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iu]
    U_xl.d[:,:,vars.iymom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iv]
    U_xl.d[:,:,vars.iener] = eos.rhoe(gamma, V_l[:,:,vars.ip]) + \
        0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2)

    U_xr.d[:,:,vars.idens] = V_r[:,:,vars.irho]
    U_xr.d[:,:,vars.ixmom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iu]
    U_xr.d[:,:,vars.iymom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iv]
    U_xr.d[:,:,vars.iener] = eos.rhoe(gamma, V_r[:,:,vars.ip]) + \
        0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2)



    #=========================================================================
    # y-direction
    #=========================================================================


    # left and right primitive variable states
    tm_states.begin()

    V_l, V_r = interface_f.states(2, myg.qx, myg.qy, myg.ng, myg.dy, dt,
                                  vars.nvar,
                                  gamma,
                                  r.d, u.d, v.d, p.d,
                                  ldelta_ry, ldelta_uy, ldelta_vy, ldelta_py)

    tm_states.end()


    # transform interface states back into conserved variables
    U_yl = myg.scratch_array(vars.nvar)
    U_yr = myg.scratch_array(vars.nvar)

    U_yl.d[:,:,vars.idens] = V_l[:,:,vars.irho]
    U_yl.d[:,:,vars.ixmom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iu]
    U_yl.d[:,:,vars.iymom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iv]
    U_yl.d[:,:,vars.iener] = eos.rhoe(gamma, V_l[:,:,vars.ip]) + \
        0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2)

    U_yr.d[:,:,vars.idens] = V_r[:,:,vars.irho]
    U_yr.d[:,:,vars.ixmom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iu]
    U_yr.d[:,:,vars.iymom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iv]
    U_yr.d[:,:,vars.iener] = eos.rhoe(gamma, V_r[:,:,vars.ip]) + \
        0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2)


    #=========================================================================
    # apply source terms
    #=========================================================================
    grav = rp.get_param("compressible.grav")

    ymom_src = my_aux.get_var("ymom_src")
    ymom_src.v()[:,:] = dens.v()*grav
    my_aux.fill_BC("ymom_src")

    E_src = my_aux.get_var("E_src")
    E_src.v()[:,:] = ymom.v()*grav
    my_aux.fill_BC("E_src")

    # ymom_xl[i,j] += 0.5*dt*dens[i-1,j]*grav
    U_xl.v(buf=1, n=vars.iymom)[:,:] += 0.5*dt*ymom_src.ip(-1, buf=1)
    U_xl.v(buf=1, n=vars.iener)[:,:] += 0.5*dt*E_src.ip(-1, buf=1)

    # ymom_xr[i,j] += 0.5*dt*dens[i,j]*grav
    U_xr.v(buf=1, n=vars.iymom)[:,:] += 0.5*dt*ymom_src.v(buf=1)
    U_xr.v(buf=1, n=vars.iener)[:,:] += 0.5*dt*E_src.v(buf=1)

    # ymom_yl[i,j] += 0.5*dt*dens[i,j-1]*grav
    U_yl.v(buf=1, n=vars.iymom)[:,:] += 0.5*dt*ymom_src.jp(-1, buf=1)
    U_yl.v(buf=1, n=vars.iener)[:,:] += 0.5*dt*E_src.jp(-1, buf=1)

    # ymom_yr[i,j] += 0.5*dt*dens[i,j]*grav
    U_yr.v(buf=1, n=vars.iymom)[:,:] += 0.5*dt*ymom_src.v(buf=1)
    U_yr.v(buf=1, n=vars.iener)[:,:] += 0.5*dt*E_src.v(buf=1)


    #=========================================================================
    # compute transverse fluxes
    #=========================================================================
    tm_riem = tc.timer("riemann")
    tm_riem.begin()

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

    if riemann == "HLLC":
        riemannFunc = interface_f.riemann_hllc
    elif riemann == "CGF":
        riemannFunc = interface_f.riemann_cgf
    else:
        msg.fail("ERROR: Riemann solver undefined")


    _fx = riemannFunc(1, myg.qx, myg.qy, myg.ng,
                      vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener,
                      solid.xl, solid.xr,
                      gamma, U_xl.d, U_xr.d)

    _fy = riemannFunc(2, myg.qx, myg.qy, myg.ng,
                      vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener,
                      solid.yl, solid.yr,
                      gamma, U_yl.d, U_yr.d)

    F_x = patch.ArrayIndexer(d=_fx, grid=myg)
    F_y = patch.ArrayIndexer(d=_fy, grid=myg)    
    
    tm_riem.end()

    #=========================================================================
    # construct the interface values of U now
    #=========================================================================

    """
    finally, we can construct the state perpendicular to the interface
    by adding the central difference part to the trasverse flux
    difference.

    The states that we represent by indices i,j are shown below
    (1,2,3,4):


      j+3/2--+----------+----------+----------+
             |          |          |          |
             |          |          |          |
        j+1 -+          |          |          |
             |          |          |          |
             |          |          |          |    1: U_xl[i,j,:] = U
      j+1/2--+----------XXXXXXXXXXXX----------+                      i-1/2,j,L
             |          X          X          |
             |          X          X          |
          j -+        1 X 2        X          |    2: U_xr[i,j,:] = U
             |          X          X          |                      i-1/2,j,R
             |          X    4     X          |
      j-1/2--+----------XXXXXXXXXXXX----------+
             |          |    3     |          |    3: U_yl[i,j,:] = U
             |          |          |          |                      i,j-1/2,L
        j-1 -+          |          |          |
             |          |          |          |
             |          |          |          |    4: U_yr[i,j,:] = U
      j-3/2--+----------+----------+----------+                      i,j-1/2,R
             |    |     |    |     |    |     |
                 i-1         i         i+1
           i-3/2      i-1/2      i+1/2      i+3/2


    remember that the fluxes are stored on the left edge, so

    F_x[i,j,:] = F_x
                    i-1/2, j

    F_y[i,j,:] = F_y
                    i, j-1/2

    """

    tm_transverse = tc.timer("transverse flux addition")
    tm_transverse.begin()

    dtdx = dt/myg.dx
    dtdy = dt/myg.dy
    
    b = (2,1)

    for n in range(vars.nvar):
            
        # U_xl[i,j,:] = U_xl[i,j,:] - 0.5*dt/dy * (F_y[i-1,j+1,:] - F_y[i-1,j,:])
        U_xl.v(buf=b, n=n)[:,:] += \
            - 0.5*dtdy*(F_y.ip_jp(-1, 1, buf=b, n=n) - F_y.ip(-1, buf=b, n=n))

        # U_xr[i,j,:] = U_xr[i,j,:] - 0.5*dt/dy * (F_y[i,j+1,:] - F_y[i,j,:])
        U_xr.v(buf=b, n=n)[:,:] += \
            - 0.5*dtdy*(F_y.jp(1, buf=b, n=n) - F_y.v(buf=b, n=n))

        # U_yl[i,j,:] = U_yl[i,j,:] - 0.5*dt/dx * (F_x[i+1,j-1,:] - F_x[i,j-1,:])
        U_yl.v(buf=b, n=n)[:,:] += \
            - 0.5*dtdx*(F_x.ip_jp(1, -1, buf=b, n=n) - F_x.jp(-1, buf=b, n=n))

        # U_yr[i,j,:] = U_yr[i,j,:] - 0.5*dt/dx * (F_x[i+1,j,:] - F_x[i,j,:])
        U_yr.v(buf=b, n=n)[:,:] += \
            - 0.5*dtdx*(F_x.ip(1, buf=b, n=n) - F_x.v(buf=b, n=n))
        
    tm_transverse.end()


    #=========================================================================
    # construct the fluxes normal to the interfaces
    #=========================================================================

    # up until now, F_x and F_y stored the transverse fluxes, now we
    # overwrite with the fluxes normal to the interfaces

    tm_riem.begin()

    _fx = riemannFunc(1, myg.qx, myg.qy, myg.ng,
                      vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener,
                      solid.xl, solid.xr,
                      gamma, U_xl.d, U_xr.d)

    _fy = riemannFunc(2, myg.qx, myg.qy, myg.ng,
                      vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener,
                      solid.yl, solid.yr,
                      gamma, U_yl.d, U_yr.d)

    F_x = patch.ArrayIndexer(d=_fx, grid=myg)
    F_y = patch.ArrayIndexer(d=_fy, grid=myg)
    
    tm_riem.end()

    #=========================================================================
    # apply artificial viscosity
    #=========================================================================
    cvisc = rp.get_param("compressible.cvisc")

    _ax, _ay = interface_f.artificial_viscosity( 
        myg.qx, myg.qy, myg.ng, myg.dx, myg.dy, 
        cvisc, u.d, v.d)

    avisco_x = patch.ArrayIndexer(d=_ax, grid=myg)
    avisco_y = patch.ArrayIndexer(d=_ay, grid=myg)    
    
    
    b = (2,1)
    
    # F_x = F_x + avisco_x * (U(i-1,j) - U(i,j))
    F_x.v(buf=b, n=vars.idens)[:,:] += \
        avisco_x.v(buf=b)*(dens.ip(-1, buf=b) - dens.v(buf=b))

    F_x.v(buf=b, n=vars.ixmom)[:,:] += \
        avisco_x.v(buf=b)*(xmom.ip(-1, buf=b) - xmom.v(buf=b))

    F_x.v(buf=b, n=vars.iymom)[:,:] += \
        avisco_x.v(buf=b)*(ymom.ip(-1, buf=b) - ymom.v(buf=b))

    F_x.v(buf=b, n=vars.iener)[:,:] += \
        avisco_x.v(buf=b)*(ener.ip(-1, buf=b) - ener.v(buf=b))

    # F_y = F_y + avisco_y * (U(i,j-1) - U(i,j))
    F_y.v(buf=b, n=vars.idens)[:,:] += \
        avisco_y.v(buf=b)*(dens.jp(-1, buf=b) - dens.v(buf=b))

    F_y.v(buf=b, n=vars.ixmom)[:,:] += \
        avisco_y.v(buf=b)*(xmom.jp(-1, buf=b) - xmom.v(buf=b))

    F_y.v(buf=b, n=vars.iymom)[:,:] += \
        avisco_y.v(buf=b)*(ymom.jp(-1, buf=b) - ymom.v(buf=b))

    F_y.v(buf=b, n=vars.iener)[:,:] += \
        avisco_y.v(buf=b)*(ener.jp(-1, buf=b) - ener.v(buf=b))

    tm_flux.end()

    return F_x, F_y
Exemple #8
0
    def dovis(self):
        """
        Do runtime visualization.
        """

        plt.clf()

        plt.rc("font", size=10)

        # we do this even though ivars is in self, so this works when
        # we are plotting from a file
        ivars = Variables(self.cc_data)

        # access gamma from the cc_data object so we can use dovis
        # outside of a running simulation.
        gamma = self.cc_data.get_aux("gamma")

        q = cons_to_prim(self.cc_data.data, gamma, ivars, self.cc_data.grid)

        rho = q[:, :, ivars.irho]
        u = q[:, :, ivars.iu]
        v = q[:, :, ivars.iv]
        p = q[:, :, ivars.ip]
        e = eos.rhoe(gamma, p)/rho

        magvel = np.sqrt(u**2 + v**2)

        myg = self.cc_data.grid

        fields = [rho, magvel, p, e]
        field_names = [r"$\rho$", r"U", "p", "e"]

        _, axes, cbar_title = plot_tools.setup_axes(myg, len(fields))

        for n, ax in enumerate(axes):
            v = fields[n]

            img = ax.imshow(np.transpose(v.v()),
                            interpolation="nearest", origin="lower",
                            extent=[myg.xmin, myg.xmax, myg.ymin, myg.ymax],
                            cmap=self.cm)

            ax.set_xlabel("x")
            ax.set_ylabel("y")

            # needed for PDF rendering
            cb = axes.cbar_axes[n].colorbar(img)
            cb.solids.set_rasterized(True)
            cb.solids.set_edgecolor("face")

            if cbar_title:
                cb.ax.set_title(field_names[n])
            else:
                ax.set_title(field_names[n])

        if self.particles is not None:
            ax = axes[0]
            particle_positions = self.particles.get_positions()
            # dye particles
            colors = self.particles.get_init_positions()[:, 0]

            # plot particles
            ax.scatter(particle_positions[:, 0],
                particle_positions[:, 1], s=5, c=colors, alpha=0.8, cmap="Greys")
            ax.set_xlim([myg.xmin, myg.xmax])
            ax.set_ylim([myg.ymin, myg.ymax])

        plt.figtext(0.05, 0.0125, "t = {:10.5g}".format(self.cc_data.t))

        plt.pause(0.001)
        plt.draw()
Exemple #9
0
def user(bc_name, bc_edge, variable, my_data):
    """
    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
    my_data : CellCenterData2d object
        The data object

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

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

    myg = my_data.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 == "density":
                j = myg.jlo - 1
                while j >= 0:
                    dens[:, j] = dens[:, myg.jlo]
                    j -= 1

            elif variable == "x-momentum":
                j = myg.jlo - 1
                while j >= 0:
                    xmom[:, j] = xmom[:, myg.jlo]
                    j -= 1

            elif variable == "y-momentum":
                j = myg.jlo - 1
                while j >= 0:
                    ymom[:, j] = ymom[:, myg.jlo]
                    j -= 1

            elif variable == "energy":
                dens_base = dens[:, myg.jlo]
                ke_base = 0.5 * (xmom[:, myg.jlo] ** 2 + ymom[:, myg.jlo] ** 2) / dens[:, myg.jlo]

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

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

                    ener[:, j] = rhoe + ke_base

                    pres_base = pres_below.copy()

                    j -= 1

            else:
                msg.fail("error: 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 == "density":
                j = myg.jhi + 1
                while j <= myg.jhi + myg.ng:
                    dens[:, j] = dens[:, myg.jhi]
                    j += 1

            elif variable == "x-momentum":
                j = myg.jhi + 1
                while j <= myg.jhi + myg.ng:
                    xmom[:, j] = xmom[:, myg.jhi]
                    j += 1

            elif variable == "y-momentum":
                j = myg.jhi + 1
                while j <= myg.jhi + myg.ng:
                    ymom[:, j] = ymom[:, myg.jhi]
                    j += 1

            elif variable == "energy":
                dens_base = dens[:, 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)

                # we are assuming that the density is constant in this
                # formulation of HSE, so the pressure comes simply from
                # differencing the HSE equation
                j = myg.jhi + 1
                while j <= myg.jhi + myg.ng:
                    pres_above = pres_base + grav * dens_base * myg.dy
                    rhoe = eos.rhoe(gamma, pres_above)

                    ener[:, j] = rhoe + ke_base

                    pres_base = pres_above.copy()

                    j += 1

            else:
                msg.fail("error: variable not defined")

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

    else:
        msg.fail("error: bc type %s not supported" % (bc_name))
Exemple #10
0
    def dovis(self):
        """
        Do runtime visualization.
        """

        plt.clf()

        plt.rc("font", size=10)

        # we do this even though ivars is in self, so this works when
        # we are plotting from a file
        ivars = Variables(self.cc_data)

        # access gamma from the cc_data object so we can use dovis
        # outside of a running simulation.
        gamma = self.cc_data.get_aux("gamma")

        q = cons_to_prim(self.cc_data.data, gamma, ivars, self.cc_data.grid)

        rho = q[:, :, ivars.irho]
        u = q[:, :, ivars.iu]
        v = q[:, :, ivars.iv]
        p = q[:, :, ivars.ip]
        e = eos.rhoe(gamma, p) / rho

        magvel = np.sqrt(u**2 + v**2)

        myg = self.cc_data.grid

        # figure out the geometry
        L_x = self.cc_data.grid.xmax - self.cc_data.grid.xmin
        L_y = self.cc_data.grid.ymax - self.cc_data.grid.ymin

        f = plt.figure(1)

        cbar_title = False

        if L_x > 2 * L_y:
            # we want 4 rows:
            axes = AxesGrid(f,
                            111,
                            nrows_ncols=(4, 1),
                            share_all=True,
                            cbar_mode="each",
                            cbar_location="top",
                            cbar_pad="10%",
                            cbar_size="25%",
                            axes_pad=(0.25, 0.65),
                            add_all=True,
                            label_mode="L")
            cbar_title = True

        elif L_y > 2 * L_x:
            # we want 4 columns:  rho  |U|  p  e
            axes = AxesGrid(f,
                            111,
                            nrows_ncols=(1, 4),
                            share_all=True,
                            cbar_mode="each",
                            cbar_location="right",
                            cbar_pad="10%",
                            cbar_size="25%",
                            axes_pad=(0.65, 0.25),
                            add_all=True,
                            label_mode="L")

        else:
            # 2x2 grid of plots
            axes = AxesGrid(f,
                            111,
                            nrows_ncols=(2, 2),
                            share_all=True,
                            cbar_mode="each",
                            cbar_location="right",
                            cbar_pad="2%",
                            axes_pad=(0.65, 0.25),
                            add_all=True,
                            label_mode="L")

        fields = [rho, magvel, p, e]
        field_names = [r"$\rho$", r"U", "p", "e"]

        for n in range(4):
            ax = axes[n]

            v = fields[n]

            img = ax.imshow(np.transpose(v.v()),
                            interpolation="nearest",
                            origin="lower",
                            extent=[myg.xmin, myg.xmax, myg.ymin, myg.ymax],
                            cmap=self.cm)

            ax.set_xlabel("x")
            ax.set_ylabel("y")

            cb = axes.cbar_axes[n].colorbar(img)
            if cbar_title:
                cb.ax.set_title(field_names[n])
            else:
                ax.set_title(field_names[n])

        plt.figtext(0.05, 0.0125, "t = {:10.5g}".format(self.cc_data.t))

        plt.pause(0.001)
        plt.draw()
Exemple #11
0
def init_data(my_data, rp):
    """ initialize the shu-osher 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 shu_osher.py")
        print(my_data.__class__)
        sys.exit()

    # get the shu_osher parameters

    dens_left = rp.get_param("shu_osher.dens_left")

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

    p_left = rp.get_param("shu_osher.p_left")
    p_right = rp.get_param("shu_osher.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("shu_osher.direction")

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

    myg = my_data.grid

    if direction == "x":

        # left
        idxl = myg.x2d <= xctr

        dens[idxl] = dens_left
        xmom[idxl] = dens_left * u_left
        ymom[idxl] = 0.0
        ener[idxl] = eos.rhoe(dens[idxl], p_left *
                              np.ones(np.shape(dens[idxl])))  #/ dens[idxl]
        #ener[idxl] = p_left/(gamma - 1.0) + 0.5*xmom[idxl]*u_left

        # right
        idxr = myg.x2d > xctr

        xdat = idxr[:, 0]
        xall = myg.x2d[:, 0]
        rhocrit = dens_left / 3.857

        for i in range(xdat.shape[0]):
            if idxr[i].all() == True:
                dens[i] = (1.0 +
                           0.2 * np.sin(5.0 * xall[i])) * rhocrit * np.ones(18)
                xmom[i] = (1.0 + 0.2 * np.sin(5.0 * xall[i])
                           ) * rhocrit * np.ones(18) * u_right
                ymom[i] = np.ones(18) * 0.0
                ener[i] = eos.rhoe((1.0 + 0.2 * np.sin(5.0 * xall[i])) *
                                   rhocrit * np.ones(18),
                                   p_right * np.ones(18))

        keyboard()
        #dens[idxr] = 1.0 + 0.2*np.sin(5.0*xall[xdat])
        #xmom[idxr] = dens_right*u_right
        #ymom[idxr] = 0.0
        #ener[idxr] = eos.rhoe(dens[idxr], p_right*np.ones(np.shape(dens[idxr]))) #/ dens[idxr]
        #ener[idxr] = p_right/(gamma - 1.0) + 0.5*xmom[idxr]*u_right

    else:

        # bottom
        idxb = myg.y2d <= yctr

        dens[idxb] = dens_left
        xmom[idxb] = 0.0
        ymom[idxb] = dens_left * u_left
        ener[idxb] = eos.rhoe(dens[idxb], p_left *
                              np.ones(np.shape(dens[idxb])))  #/ dens[idxb]
        #ener[idxb] = p_left/(gamma - 1.0) + 0.5*ymom[idxb]*u_left

        # top
        idxt = myg.y2d > yctr

        dens[idxt] = dens_right
        xmom[idxt] = 0.0
        ymom[idxt] = dens_right * u_right
        ener[idxt] = eos.rhoe(dens[idxt],
                              p_right *
                              np.ones(np.shape(dens[idxt])))  #/ dens[idxt]
Exemple #12
0
def init_data(my_data, rp):
    """ initialize the Kelvin-Helmholtz 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(my_data.__class__)
        msg.fail("ERROR: patch invalid in sedov.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")

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

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

    yctr = 0.5 * (ymin + ymax)

    L_x = xmax - xmin

    myg = my_data.grid

    idx_l = myg.y2d < yctr + 0.01 * np.sin(10.0 * np.pi * myg.x2d / L_x)
    idx_h = myg.y2d >= yctr + 0.01 * np.sin(10.0 * np.pi * myg.x2d / L_x)

    # lower half
    dens[idx_l] = rho_1
    xmom[idx_l] = rho_1 * v_1
    ymom[idx_l] = 0.0

    # upper half
    dens[idx_h] = rho_2
    xmom[idx_h] = rho_2 * v_2
    ymom[idx_h] = 0.0

    #p = 1.0
    p = 6.9E06 * np.ones(np.shape(dens))
    #ener[:,:] = p/(gamma - 1.0) + 0.5*(xmom[:,:]**2 + ymom[:,:]**2)/dens[:,:]
    ener[:, :] = eos.rhoe(
        dens[:, :], p) + 0.5 * (xmom[:, :]**2 + ymom[:, :]**2) / dens[:, :]
    keyboard()
Exemple #13
0
def fluxes(my_data, rp, vars, solid, tc):
    """
    unsplitFluxes returns the fluxes through the x and y interfaces by
    doing an unsplit reconstruction of the interface values and then
    solving the Riemann problem through all the interfaces at once

    currently we assume a gamma-law EOS

    Parameters
    ----------
    my_data : CellCenterData2d object
        The data object containing the grid and advective scalar that
        we are advecting.
    rp : RuntimeParameters object
        The runtime parameters for the simulation
    vars : Variables object
        The Variables object that tells us which indices refer to which
        variables
    tc : TimerCollection object
        The timers we are using to profile

    Returns
    -------
    out : ndarray, ndarray
        The fluxes on the x- and y-interfaces

    """

    tm_flux = tc.timer("unsplitFluxes")
    tm_flux.begin()

    myg = my_data.grid

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

    #=========================================================================
    # compute the primitive variables
    #=========================================================================
    # Q = (rho, u, v, p)

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

    r = dens

    # get the velocities
    u = xmom / dens
    v = ymom / dens

    # get the pressure
    e = (ener - 0.5 * (xmom**2 + ymom**2) / dens) / dens

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

    smallp = 1.e-10
    p = p.clip(smallp)  # apply a floor to the pressure

    #=========================================================================
    # compute the flattening coefficients
    #=========================================================================

    # there is a single flattening coefficient (xi) for all directions
    use_flattening = rp.get_param("compressible.use_flattening")

    if use_flattening:
        delta = rp.get_param("compressible.delta")
        z0 = rp.get_param("compressible.z0")
        z1 = rp.get_param("compressible.z1")

        xi_x = reconstruction_f.flatten(1, p, u, myg.qx, myg.qy, myg.ng,
                                        smallp, delta, z0, z1)
        xi_y = reconstruction_f.flatten(2, p, v, myg.qx, myg.qy, myg.ng,
                                        smallp, delta, z0, z1)

        xi = reconstruction_f.flatten_multid(xi_x, xi_y, p, myg.qx, myg.qy,
                                             myg.ng)
    else:
        xi = 1.0

    # monotonized central differences in x-direction
    tm_limit = tc.timer("limiting")
    tm_limit.begin()

    limiter = rp.get_param("compressible.limiter")
    if limiter == 0:
        limitFunc = reconstruction_f.nolimit
    elif limiter == 1:
        limitFunc = reconstruction_f.limit2
    else:
        limitFunc = reconstruction_f.limit4

    _ldelta_rx = xi * limitFunc(1, r, myg.qx, myg.qy, myg.ng)
    _ldelta_ux = xi * limitFunc(1, u, myg.qx, myg.qy, myg.ng)
    _ldelta_vx = xi * limitFunc(1, v, myg.qx, myg.qy, myg.ng)
    _ldelta_px = xi * limitFunc(1, p, myg.qx, myg.qy, myg.ng)

    # wrap these in ArrayIndexer objects
    ldelta_rx = ai.ArrayIndexer(d=_ldelta_rx, grid=myg)
    ldelta_ux = ai.ArrayIndexer(d=_ldelta_ux, grid=myg)
    ldelta_vx = ai.ArrayIndexer(d=_ldelta_vx, grid=myg)
    ldelta_px = ai.ArrayIndexer(d=_ldelta_px, grid=myg)

    # monotonized central differences in y-direction
    _ldelta_ry = xi * limitFunc(2, r, myg.qx, myg.qy, myg.ng)
    _ldelta_uy = xi * limitFunc(2, u, myg.qx, myg.qy, myg.ng)
    _ldelta_vy = xi * limitFunc(2, v, myg.qx, myg.qy, myg.ng)
    _ldelta_py = xi * limitFunc(2, p, myg.qx, myg.qy, myg.ng)

    ldelta_ry = ai.ArrayIndexer(d=_ldelta_ry, grid=myg)
    ldelta_uy = ai.ArrayIndexer(d=_ldelta_uy, grid=myg)
    ldelta_vy = ai.ArrayIndexer(d=_ldelta_vy, grid=myg)
    ldelta_py = ai.ArrayIndexer(d=_ldelta_py, grid=myg)

    tm_limit.end()

    #=========================================================================
    # x-direction
    #=========================================================================

    # left and right primitive variable states
    tm_states = tc.timer("interfaceStates")
    tm_states.begin()

    V_l = myg.scratch_array(vars.nvar)
    V_r = myg.scratch_array(vars.nvar)

    V_l.ip(1, n=vars.irho, buf=2)[:, :] = r.v(buf=2) + 0.5 * ldelta_rx.v(buf=2)
    V_r.v(n=vars.irho, buf=2)[:, :] = r.v(buf=2) - 0.5 * ldelta_rx.v(buf=2)

    V_l.ip(1, n=vars.iu, buf=2)[:, :] = u.v(buf=2) + 0.5 * ldelta_ux.v(buf=2)
    V_r.v(n=vars.iu, buf=2)[:, :] = u.v(buf=2) - 0.5 * ldelta_ux.v(buf=2)

    V_l.ip(1, n=vars.iv, buf=2)[:, :] = v.v(buf=2) + 0.5 * ldelta_vx.v(buf=2)
    V_r.v(n=vars.iv, buf=2)[:, :] = v.v(buf=2) - 0.5 * ldelta_vx.v(buf=2)

    V_l.ip(1, n=vars.ip, buf=2)[:, :] = p.v(buf=2) + 0.5 * ldelta_px.v(buf=2)
    V_r.v(n=vars.ip, buf=2)[:, :] = p.v(buf=2) - 0.5 * ldelta_px.v(buf=2)

    tm_states.end()

    # transform interface states back into conserved variables
    U_xl = myg.scratch_array(vars.nvar)
    U_xr = myg.scratch_array(vars.nvar)

    U_xl[:, :, vars.idens] = V_l[:, :, vars.irho]
    U_xl[:, :, vars.ixmom] = V_l[:, :, vars.irho] * V_l[:, :, vars.iu]
    U_xl[:, :, vars.iymom] = V_l[:, :, vars.irho] * V_l[:, :, vars.iv]
    U_xl[:,:,vars.iener] = eos.rhoe(gamma, V_l[:,:,vars.ip]) + \
        0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2)

    U_xr[:, :, vars.idens] = V_r[:, :, vars.irho]
    U_xr[:, :, vars.ixmom] = V_r[:, :, vars.irho] * V_r[:, :, vars.iu]
    U_xr[:, :, vars.iymom] = V_r[:, :, vars.irho] * V_r[:, :, vars.iv]
    U_xr[:,:,vars.iener] = eos.rhoe(gamma, V_r[:,:,vars.ip]) + \
        0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2)

    #=========================================================================
    # y-direction
    #=========================================================================

    # left and right primitive variable states
    tm_states.begin()

    V_l.jp(1, n=vars.irho, buf=2)[:, :] = r.v(buf=2) + 0.5 * ldelta_ry.v(buf=2)
    V_r.v(n=vars.irho, buf=2)[:, :] = r.v(buf=2) - 0.5 * ldelta_ry.v(buf=2)

    V_l.jp(1, n=vars.iu, buf=2)[:, :] = u.v(buf=2) + 0.5 * ldelta_uy.v(buf=2)
    V_r.v(n=vars.iu, buf=2)[:, :] = u.v(buf=2) - 0.5 * ldelta_uy.v(buf=2)

    V_l.jp(1, n=vars.iv, buf=2)[:, :] = v.v(buf=2) + 0.5 * ldelta_vy.v(buf=2)
    V_r.v(n=vars.iv, buf=2)[:, :] = v.v(buf=2) - 0.5 * ldelta_vy.v(buf=2)

    V_l.jp(1, n=vars.ip, buf=2)[:, :] = p.v(buf=2) + 0.5 * ldelta_py.v(buf=2)
    V_r.v(n=vars.ip, buf=2)[:, :] = p.v(buf=2) - 0.5 * ldelta_py.v(buf=2)

    tm_states.end()

    # transform interface states back into conserved variables
    U_yl = myg.scratch_array(vars.nvar)
    U_yr = myg.scratch_array(vars.nvar)

    U_yl[:, :, vars.idens] = V_l[:, :, vars.irho]
    U_yl[:, :, vars.ixmom] = V_l[:, :, vars.irho] * V_l[:, :, vars.iu]
    U_yl[:, :, vars.iymom] = V_l[:, :, vars.irho] * V_l[:, :, vars.iv]
    U_yl[:,:,vars.iener] = eos.rhoe(gamma, V_l[:,:,vars.ip]) + \
        0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2)

    U_yr[:, :, vars.idens] = V_r[:, :, vars.irho]
    U_yr[:, :, vars.ixmom] = V_r[:, :, vars.irho] * V_r[:, :, vars.iu]
    U_yr[:, :, vars.iymom] = V_r[:, :, vars.irho] * V_r[:, :, vars.iv]
    U_yr[:,:,vars.iener] = eos.rhoe(gamma, V_r[:,:,vars.ip]) + \
        0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2)

    #=========================================================================
    # construct the fluxes normal to the interfaces
    #=========================================================================
    tm_riem = tc.timer("Riemann")
    tm_riem.begin()

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

    if riemann == "HLLC":
        riemannFunc = interface_f.riemann_hllc
    elif riemann == "CGF":
        riemannFunc = interface_f.riemann_cgf
    else:
        msg.fail("ERROR: Riemann solver undefined")

    _fx = riemannFunc(1, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens,
                      vars.ixmom, vars.iymom, vars.iener, solid.xl, solid.xr,
                      gamma, U_xl, U_xr)

    _fy = riemannFunc(2, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens,
                      vars.ixmom, vars.iymom, vars.iener, solid.yl, solid.yr,
                      gamma, U_yl, U_yr)

    F_x = ai.ArrayIndexer(d=_fx, grid=myg)
    F_y = ai.ArrayIndexer(d=_fy, grid=myg)

    tm_riem.end()

    #=========================================================================
    # apply artificial viscosity
    #=========================================================================
    cvisc = rp.get_param("compressible.cvisc")

    _ax, _ay = interface_f.artificial_viscosity(myg.qx, myg.qy, myg.ng, myg.dx,
                                                myg.dy, cvisc, u, v)

    avisco_x = ai.ArrayIndexer(d=_ax, grid=myg)
    avisco_y = ai.ArrayIndexer(d=_ay, grid=myg)

    b = (2, 1)

    # F_x = F_x + avisco_x * (U(i-1,j) - U(i,j))
    F_x.v(buf=b, n=vars.idens)[:,:] += \
        avisco_x.v(buf=b)*(dens.ip(-1, buf=b) - dens.v(buf=b))

    F_x.v(buf=b, n=vars.ixmom)[:,:] += \
        avisco_x.v(buf=b)*(xmom.ip(-1, buf=b) - xmom.v(buf=b))

    F_x.v(buf=b, n=vars.iymom)[:,:] += \
        avisco_x.v(buf=b)*(ymom.ip(-1, buf=b) - ymom.v(buf=b))

    F_x.v(buf=b, n=vars.iener)[:,:] += \
        avisco_x.v(buf=b)*(ener.ip(-1, buf=b) - ener.v(buf=b))

    # F_y = F_y + avisco_y * (U(i,j-1) - U(i,j))
    F_y.v(buf=b, n=vars.idens)[:,:] += \
        avisco_y.v(buf=b)*(dens.jp(-1, buf=b) - dens.v(buf=b))

    F_y.v(buf=b, n=vars.ixmom)[:,:] += \
        avisco_y.v(buf=b)*(xmom.jp(-1, buf=b) - xmom.v(buf=b))

    F_y.v(buf=b, n=vars.iymom)[:,:] += \
        avisco_y.v(buf=b)*(ymom.jp(-1, buf=b) - ymom.v(buf=b))

    F_y.v(buf=b, n=vars.iener)[:,:] += \
        avisco_y.v(buf=b)*(ener.jp(-1, buf=b) - ener.v(buf=b))

    tm_flux.end()

    return F_x, F_y
Exemple #14
0
def user(bc_name, bc_edge, variable, ccdata):
    """
    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")

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

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

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

                    ener[:, j] = rhoe + ke_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")

                dens_base = dens[:, 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)

                # we are assuming that the density is constant in this
                # formulation of HSE, so the pressure comes simply from
                # differencing the HSE equation
                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)

                    ener[:, j] = rhoe + ke_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))
Exemple #15
0
def user(bc_name, bc_edge, variable, ccdata):
    """
    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")

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

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

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

                    ener[:, j] = rhoe + ke_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")

                dens_base = dens[:, 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)

                # we are assuming that the density is constant in this
                # formulation of HSE, so the pressure comes simply from
                # differencing the HSE equation
                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)

                    ener[:, j] = rhoe + ke_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))
Exemple #16
0
def user(bc_name, bc_edge, variable, my_data):
    """
    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
    my_data : CellCenterData2d object
        The data object

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

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

    myg = my_data.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 == "density":
                j = myg.jlo - 1
                while j >= 0:
                    dens.d[:, j] = dens.d[:, myg.jlo]
                    j -= 1

            elif variable == "x-momentum":
                j = myg.jlo - 1
                while j >= 0:
                    xmom.d[:, j] = xmom.d[:, myg.jlo]
                    j -= 1

            elif variable == "y-momentum":
                j = myg.jlo - 1
                while j >= 0:
                    ymom.d[:, j] = ymom.d[:, myg.jlo]
                    j -= 1

            elif variable == "energy":
                dens_base = dens.d[:, myg.jlo]
                ke_base = 0.5*(xmom.d[:,myg.jlo]**2 + ymom.d[:,myg.jlo]**2) / \
                    dens.d[:,myg.jlo]

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

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

                    ener.d[:, j] = rhoe + ke_base

                    pres_base = pres_below.copy()

                    j -= 1

            else:
                msg.fail("error: 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 == "density":
                for j in range(myg.jhi + 1, myg.jhi + myg.ng + 1):
                    dens.d[:, j] = dens.d[:, myg.jhi]

            elif variable == "x-momentum":
                for j in range(myg.jhi + 1, myg.jhi + myg.ng + 1):
                    xmom.d[:, j] = xmom.d[:, myg.jhi]

            elif variable == "y-momentum":
                for j in range(myg.jhi + 1, myg.jhi + myg.ng + 1):
                    ymom.d[:, j] = ymom.d[:, myg.jhi]

            elif variable == "energy":
                dens_base = dens.d[:, myg.jhi]
                ke_base = 0.5*(xmom.d[:,myg.jhi]**2 + ymom.d[:,myg.jhi]**2) / \
                    dens.d[:,myg.jhi]

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

                # we are assuming that the density is constant in this
                # formulation of HSE, so the pressure comes simply from
                # differencing the HSE equation
                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)

                    ener.d[:, j] = rhoe + ke_base

                    pres_base = pres_above.copy()

            else:
                msg.fail("error: variable not defined")

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

    else:
        msg.fail("error: bc type %s not supported" % (bc_name))