def test_prim(self):

        # U -> q
        gamma = self.sim.cc_data.get_aux("gamma")
        q = flx.cons_to_prim_wrapper(self.sim.cc_data.data, gamma, self.sim.ivars, self.sim.cc_data.grid)

        assert q[:, :, self.sim.ivars.ip].min() == pytest.approx(1.0) and \
               q[:, :, self.sim.ivars.ip].max() == pytest.approx(1.0)

        # q -> U
        U = sn.prim_to_cons(q, gamma, self.sim.ivars, self.sim.cc_data.grid)
        assert_array_almost_equal(U, self.sim.cc_data.data)
Пример #2
0
def derive_primitives(myd, varnames, ivars, myg):
    """
    derive desired primitive variables from conserved state
    """

    # get the variables we need
    gamma = myd.get_aux("gamma")

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

    derived_vars = []

    dens = q[:, :, ivars.irho]
    u = q[:, :, ivars.iu]
    v = q[:, :, ivars.iv]
    p = q[:, :, ivars.ip]
    try:
        e = eos.rhoe(gamma, p) / dens
    except FloatingPointError:
        p[:, :] = myd.data[:, :, ivars.iener] * (gamma - 1)
        e = myd.data[:, :, ivars.iener]  # p / (gamma - 1)

    gamma = myd.get_aux("gamma")
    if isinstance(varnames, str):
        wanted = [varnames]
    else:
        wanted = list(varnames)

    for var in wanted:

        if var == "velocity":
            derived_vars.append(u)
            derived_vars.append(v)

        elif var in ["e", "eint"]:
            derived_vars.append(e)

        elif var in ["p", "pressure"]:
            derived_vars.append(p)

        elif var == "primitive":
            derived_vars.append(dens)
            derived_vars.append(u)
            derived_vars.append(v)
            derived_vars.append(p)

        elif var == "soundspeed":
            derived_vars.append(np.sqrt(gamma * p / dens))
    if len(derived_vars) > 1:
        return derived_vars
    else:
        return derived_vars[0]
Пример #3
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")

        myg = self.cc_data.grid

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

        rho = q[:, :, ivars.irho]
        u = q[:, :, ivars.iu]
        v = q[:, :, ivars.iv]
        p = q[:, :, ivars.ip]
        try:
            e = eos.rhoe(gamma, p)/rho
        except FloatingPointError:
            p[:, :] = self.cc_data.data[:, :, ivars.iener] * (gamma-1)
            e = self.cc_data.data[:, :, ivars.iener]  # p / (gamma - 1)

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

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

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

        plt.pause(0.001)
        plt.draw()
Пример #4
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))