コード例 #1
0
ファイル: test_viscous.py プロジェクト: dreamer2368/mirgecom
def test_diffusive_heat_flux(actx_factory):
    """Test diffusive heat flux and values against exact."""
    actx = actx_factory()
    dim = 3
    nel_1d = 4

    from meshmode.mesh.generation import generate_regular_rect_mesh

    mesh = generate_regular_rect_mesh(a=(1.0, ) * dim,
                                      b=(2.0, ) * dim,
                                      nelements_per_axis=(nel_1d, ) * dim)

    order = 1

    discr = EagerDGDiscretization(actx, mesh, order=order)
    nodes = thaw(actx, discr.nodes())
    zeros = discr.zeros(actx)
    ones = zeros + 1.0

    # assemble velocities for simple, unique grad components
    velocity_x = nodes[0] + 2 * nodes[1] + 3 * nodes[2]
    velocity_y = 4 * nodes[0] + 5 * nodes[1] + 6 * nodes[2]
    velocity_z = 7 * nodes[0] + 8 * nodes[1] + 9 * nodes[2]
    velocity = make_obj_array([velocity_x, velocity_y, velocity_z])

    # assemble y so that each one has simple, but unique grad components
    nspecies = 2 * dim
    y = make_obj_array([ones for _ in range(nspecies)])
    for idim in range(dim):
        ispec = 2 * idim
        y[ispec] = (ispec + 1) * (idim * dim + 1) * sum(
            [(iidim + 1) * nodes[iidim] for iidim in range(dim)])
        y[ispec + 1] = -y[ispec]

    massval = 2
    mass = massval * ones
    energy = zeros + 2.5
    mom = mass * velocity
    species_mass = mass * y

    cv = make_conserved(dim,
                        mass=mass,
                        energy=energy,
                        momentum=mom,
                        species_mass=species_mass)
    grad_cv = op.local_grad(discr, cv)

    mu_b = 1.0
    mu = 0.5
    kappa = 5.0
    # assemble d_alpha so that every species has a unique j
    d_alpha = np.array([(ispec + 1) for ispec in range(nspecies)])

    tv_model = SimpleTransport(bulk_viscosity=mu_b,
                               viscosity=mu,
                               thermal_conductivity=kappa,
                               species_diffusivity=d_alpha)

    eos = IdealSingleGas()
    gas_model = GasModel(eos=eos, transport=tv_model)
    fluid_state = make_fluid_state(cv, gas_model)

    from mirgecom.viscous import diffusive_flux
    j = diffusive_flux(fluid_state, grad_cv)

    def inf_norm(x):
        return actx.to_numpy(discr.norm(x, np.inf))

    tol = 1e-10
    for idim in range(dim):
        ispec = 2 * idim
        exact_dy = np.array([((ispec + 1) * (idim * dim + 1)) * (iidim + 1)
                             for iidim in range(dim)])
        exact_j = -massval * d_alpha[ispec] * exact_dy
        assert inf_norm(j[ispec] - exact_j) < tol
        exact_j = massval * d_alpha[ispec + 1] * exact_dy
        assert inf_norm(j[ispec + 1] - exact_j) < tol
コード例 #2
0
ファイル: test_viscous.py プロジェクト: thomasgibson/mirgecom
def test_poiseuille_fluxes(actx_factory, order, kappa):
    """Test the viscous fluxes using a Poiseuille input state."""
    actx = actx_factory()
    dim = 2

    from pytools.convergence import EOCRecorder
    e_eoc_rec = EOCRecorder()
    p_eoc_rec = EOCRecorder()

    base_pressure = 100000.0
    pressure_ratio = 1.001
    mu = 42  # arbitrary
    left_boundary_location = 0
    right_boundary_location = 0.1
    ybottom = 0.
    ytop = .02
    nspecies = 0
    spec_diffusivity = 0 * np.ones(nspecies)
    transport_model = SimpleTransport(viscosity=mu,
                                      thermal_conductivity=kappa,
                                      species_diffusivity=spec_diffusivity)

    xlen = right_boundary_location - left_boundary_location
    p_low = base_pressure
    p_hi = pressure_ratio * base_pressure
    dpdx = (p_low - p_hi) / xlen
    rho = 1.0

    eos = IdealSingleGas(transport_model=transport_model)

    from mirgecom.initializers import PlanarPoiseuille
    initializer = PlanarPoiseuille(density=rho, mu=mu)

    def _elbnd_flux(discr, compute_interior_flux, compute_boundary_flux,
                    int_tpair, boundaries):
        return (compute_interior_flux(int_tpair) +
                sum(compute_boundary_flux(btag) for btag in boundaries))

    from mirgecom.flux import gradient_flux_central

    def cv_flux_interior(int_tpair):
        normal = thaw(actx, discr.normal(int_tpair.dd))
        flux_weak = gradient_flux_central(int_tpair, normal)
        return discr.project(int_tpair.dd, "all_faces", flux_weak)

    def cv_flux_boundary(btag):
        boundary_discr = discr.discr_from_dd(btag)
        bnd_nodes = thaw(actx, boundary_discr.nodes())
        cv_bnd = initializer(x_vec=bnd_nodes, eos=eos)
        bnd_nhat = thaw(actx, discr.normal(btag))
        from grudge.trace_pair import TracePair
        bnd_tpair = TracePair(btag, interior=cv_bnd, exterior=cv_bnd)
        flux_weak = gradient_flux_central(bnd_tpair, bnd_nhat)
        return discr.project(bnd_tpair.dd, "all_faces", flux_weak)

    for nfac in [1, 2, 4]:

        npts_axis = nfac * (11, 21)
        box_ll = (left_boundary_location, ybottom)
        box_ur = (right_boundary_location, ytop)
        mesh = _get_box_mesh(2, a=box_ll, b=box_ur, n=npts_axis)

        logger.info(f"Number of {dim}d elements: {mesh.nelements}")

        discr = EagerDGDiscretization(actx, mesh, order=order)
        nodes = thaw(actx, discr.nodes())

        # compute max element size
        from grudge.dt_utils import h_max_from_volume
        h_max = h_max_from_volume(discr)

        # form exact cv
        cv = initializer(x_vec=nodes, eos=eos)
        cv_int_tpair = interior_trace_pair(discr, cv)
        boundaries = [BTAG_ALL]
        cv_flux_bnd = _elbnd_flux(discr, cv_flux_interior, cv_flux_boundary,
                                  cv_int_tpair, boundaries)
        from mirgecom.operators import grad_operator
        grad_cv = make_conserved(dim,
                                 q=grad_operator(discr, cv.join(),
                                                 cv_flux_bnd.join()))

        xp_grad_cv = initializer.exact_grad(x_vec=nodes, eos=eos, cv_exact=cv)
        xp_grad_v = 1 / cv.mass * xp_grad_cv.momentum
        xp_tau = mu * (xp_grad_v + xp_grad_v.transpose())

        # sanity check the gradient:
        relerr_scale_e = 1.0 / discr.norm(xp_grad_cv.energy, np.inf)
        relerr_scale_p = 1.0 / discr.norm(xp_grad_cv.momentum, np.inf)
        graderr_e = discr.norm((grad_cv.energy - xp_grad_cv.energy), np.inf)
        graderr_p = discr.norm((grad_cv.momentum - xp_grad_cv.momentum),
                               np.inf)
        graderr_e *= relerr_scale_e
        graderr_p *= relerr_scale_p
        assert graderr_e < 5e-7
        assert graderr_p < 5e-11

        zeros = discr.zeros(actx)
        ones = zeros + 1
        pressure = eos.pressure(cv)
        # grad of p should be dp/dx
        xp_grad_p = make_obj_array([dpdx * ones, zeros])
        grad_p = op.local_grad(discr, pressure)
        dpscal = 1.0 / np.abs(dpdx)

        temperature = eos.temperature(cv)
        tscal = rho * eos.gas_const() * dpscal
        xp_grad_t = xp_grad_p / (cv.mass * eos.gas_const())
        grad_t = op.local_grad(discr, temperature)

        # sanity check
        assert discr.norm(grad_p - xp_grad_p, np.inf) * dpscal < 5e-9
        assert discr.norm(grad_t - xp_grad_t, np.inf) * tscal < 5e-9

        # verify heat flux
        from mirgecom.viscous import conductive_heat_flux
        heat_flux = conductive_heat_flux(discr, eos, cv, grad_t)
        xp_heat_flux = -kappa * xp_grad_t
        assert discr.norm(heat_flux - xp_heat_flux, np.inf) < 2e-8

        # verify diffusive mass flux is zilch (no scalar components)
        from mirgecom.viscous import diffusive_flux
        j = diffusive_flux(discr, eos, cv, grad_cv)
        assert len(j) == 0

        xp_e_flux = np.dot(xp_tau, cv.velocity) - xp_heat_flux
        xp_mom_flux = xp_tau
        from mirgecom.viscous import viscous_flux
        vflux = viscous_flux(discr, eos, cv, grad_cv, grad_t)

        efluxerr = (discr.norm(vflux.energy - xp_e_flux, np.inf) /
                    discr.norm(xp_e_flux, np.inf))
        momfluxerr = (discr.norm(vflux.momentum - xp_mom_flux, np.inf) /
                      discr.norm(xp_mom_flux, np.inf))

        assert discr.norm(vflux.mass, np.inf) == 0
        e_eoc_rec.add_data_point(h_max, efluxerr)
        p_eoc_rec.add_data_point(h_max, momfluxerr)

    assert (e_eoc_rec.order_estimate() >= order - 0.5
            or e_eoc_rec.max_error() < 3e-9)
    assert (p_eoc_rec.order_estimate() >= order - 0.5
            or p_eoc_rec.max_error() < 2e-12)