Ejemplo n.º 1
0
    def get_boundaries(discr, actx, t):
        nodes = thaw(actx, discr.nodes())

        def sym_eval(expr):
            return sym.EvaluationMapper({"x": nodes, "t": t})(expr)

        exact_u = sym_eval(sym_u)
        exact_grad_u = make_obj_array(sym_eval(sym.grad(dim, sym_u)))

        boundaries = {}

        for i in range(dim - 1):
            lower_btag = DTAG_BOUNDARY("-" + str(i))
            upper_btag = DTAG_BOUNDARY("+" + str(i))
            upper_grad_u = discr.project("vol", upper_btag, exact_grad_u)
            normal = thaw(actx, discr.normal(upper_btag))
            upper_grad_u_dot_n = np.dot(upper_grad_u, normal)
            boundaries[lower_btag] = NeumannDiffusionBoundary(0.)
            boundaries[upper_btag] = NeumannDiffusionBoundary(
                upper_grad_u_dot_n)

        lower_btag = DTAG_BOUNDARY("-" + str(dim - 1))
        upper_btag = DTAG_BOUNDARY("+" + str(dim - 1))
        upper_u = discr.project("vol", upper_btag, exact_u)
        boundaries[lower_btag] = DirichletDiffusionBoundary(0.)
        boundaries[upper_btag] = DirichletDiffusionBoundary(upper_u)

        return boundaries
Ejemplo n.º 2
0
    def get_boundaries(self, discr, actx, t):
        nodes = thaw(actx, discr.nodes())

        sym_exact_u = self.get_solution(pmbl.make_sym_vector("x", self.dim),
                                        pmbl.var("t"))

        exact_u = _sym_eval(sym_exact_u, x=nodes, t=t)
        exact_grad_u = _sym_eval(sym.grad(self.dim, sym_exact_u), x=nodes, t=t)

        boundaries = {}

        for i in range(self.dim - 1):
            lower_btag = DTAG_BOUNDARY("-" + str(i))
            upper_btag = DTAG_BOUNDARY("+" + str(i))
            upper_grad_u = discr.project("vol", upper_btag, exact_grad_u)
            normal = thaw(actx, discr.normal(upper_btag))
            upper_grad_u_dot_n = np.dot(upper_grad_u, normal)
            boundaries[lower_btag] = NeumannDiffusionBoundary(0.)
            boundaries[upper_btag] = NeumannDiffusionBoundary(
                upper_grad_u_dot_n)
        lower_btag = DTAG_BOUNDARY("-" + str(self.dim - 1))
        upper_btag = DTAG_BOUNDARY("+" + str(self.dim - 1))
        upper_u = discr.project("vol", upper_btag, exact_u)
        boundaries[lower_btag] = DirichletDiffusionBoundary(0.)
        boundaries[upper_btag] = DirichletDiffusionBoundary(upper_u)

        return boundaries
Ejemplo n.º 3
0
    def get_boundaries(discr, actx, t):
        boundaries = {}

        for i in range(dim-1):
            boundaries[DTAG_BOUNDARY("-"+str(i))] = NeumannDiffusionBoundary(0.)
            boundaries[DTAG_BOUNDARY("+"+str(i))] = NeumannDiffusionBoundary(0.)

        boundaries[DTAG_BOUNDARY("-"+str(dim-1))] = DirichletDiffusionBoundary(0.)
        boundaries[DTAG_BOUNDARY("+"+str(dim-1))] = DirichletDiffusionBoundary(0.)

        return boundaries
Ejemplo n.º 4
0
    def get_boundaries(self, discr, actx, t):
        boundaries = {}

        for i in range(self.dim - 1):
            lower_btag = DTAG_BOUNDARY("-" + str(i))
            upper_btag = DTAG_BOUNDARY("+" + str(i))
            boundaries[lower_btag] = NeumannDiffusionBoundary(0.)
            boundaries[upper_btag] = NeumannDiffusionBoundary(0.)
        lower_btag = DTAG_BOUNDARY("-" + str(self.dim - 1))
        upper_btag = DTAG_BOUNDARY("+" + str(self.dim - 1))
        boundaries[lower_btag] = DirichletDiffusionBoundary(0.)
        boundaries[upper_btag] = DirichletDiffusionBoundary(0.)

        return boundaries
Ejemplo n.º 5
0
    def get_boundaries(discr, actx, t):
        nodes = thaw(actx, discr.nodes())

        def sym_eval(expr):
            return sym.EvaluationMapper({"x": nodes, "t": t})(expr)

        dirichlet_lower_btag = grudge_sym.DTAG_BOUNDARY("dirichlet_lower")
        dirichlet_upper_btag = grudge_sym.DTAG_BOUNDARY("dirichlet_upper")
        neumann_lower_btag = grudge_sym.DTAG_BOUNDARY("neumann_lower")
        neumann_upper_btag = grudge_sym.DTAG_BOUNDARY("neumann_upper")
        exact_u = sym_eval(sym_u)
        exact_grad_u = make_obj_array(sym_eval(sym.grad(dim, sym_u)))
        upper_u = discr.project("vol", dirichlet_upper_btag, exact_u)
        upper_grad_u = discr.project("vol", neumann_upper_btag, exact_grad_u)
        normal = thaw(actx, discr.normal(neumann_upper_btag))
        upper_grad_u_dot_n = np.dot(upper_grad_u, normal)

        return {
            dirichlet_lower_btag: DirichletDiffusionBoundary(0.),
            dirichlet_upper_btag: DirichletDiffusionBoundary(upper_u),
            neumann_lower_btag: NeumannDiffusionBoundary(0.),
            neumann_upper_btag: NeumannDiffusionBoundary(upper_grad_u_dot_n)
        }
Ejemplo n.º 6
0
def test_lazy_op_diffusion(op_test_data, order):
    """Test diffusion operator in lazy context."""
    eager_actx, lazy_actx, get_discr = op_test_data
    discr = get_discr(order)

    from grudge.dof_desc import DTAG_BOUNDARY, DISCR_TAG_BASE
    from mirgecom.diffusion import (
        diffusion_operator,
        DirichletDiffusionBoundary,
        NeumannDiffusionBoundary)

    boundaries = {
        DTAG_BOUNDARY("x"): DirichletDiffusionBoundary(0),
        DTAG_BOUNDARY("y"): NeumannDiffusionBoundary(0)
    }

    def op(alpha, u):
        return diffusion_operator(
            discr, DISCR_TAG_BASE, alpha, boundaries, u)

    lazy_op = lazy_actx.compile(op)

    def get_inputs(actx):
        nodes = thaw(discr.nodes(), actx)
        alpha = discr.zeros(actx) + 1
        u = actx.np.cos(np.pi*nodes[0])
        return alpha, u

    tol = 1e-11
    isclose = partial(
        _isclose, discr, rel_tol=tol, abs_tol=tol, return_operands=True)

    def lazy_to_eager(u):
        return thaw(freeze(u, lazy_actx), eager_actx)

    eager_result = op(*get_inputs(eager_actx))
    lazy_result = lazy_to_eager(lazy_op(*get_inputs(lazy_actx)))
    is_close, lhs, rhs = isclose(lazy_result, eager_result)
    assert is_close, f"{lhs} not <= {rhs}"
Ejemplo n.º 7
0
def main(ctx_factory=cl.create_some_context, use_logmgr=True,
         use_leap=False, use_profiling=False, casename=None,
         rst_filename=None, actx_class=PyOpenCLArrayContext):
    """Run the example."""
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    from mpi4py import MPI
    comm = MPI.COMM_WORLD
    num_parts = comm.Get_size()

    logmgr = initialize_logmgr(use_logmgr,
        filename="heat-source.sqlite", mode="wu", mpi_comm=comm)

    if use_profiling:
        queue = cl.CommandQueue(
            cl_ctx, properties=cl.command_queue_properties.PROFILING_ENABLE)
    else:
        queue = cl.CommandQueue(cl_ctx)

    actx = actx_class(
        queue,
        allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue)))

    from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis
    mesh_dist = MPIMeshDistributor(comm)

    dim = 2
    nel_1d = 16

    t = 0
    t_final = 0.0002
    istep = 0

    if mesh_dist.is_mananger_rank():
        from meshmode.mesh.generation import generate_regular_rect_mesh
        mesh = generate_regular_rect_mesh(
            a=(-0.5,)*dim,
            b=(0.5,)*dim,
            nelements_per_axis=(nel_1d,)*dim,
            boundary_tag_to_face={
                "dirichlet": ["+x", "-x"],
                "neumann": ["+y", "-y"]
                }
            )

        print("%d elements" % mesh.nelements)

        part_per_element = get_partition_by_pymetis(mesh, num_parts)

        local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element, num_parts)

        del mesh

    else:
        local_mesh = mesh_dist.receive_mesh_part()

    order = 3

    discr = EagerDGDiscretization(actx, local_mesh, order=order,
                    mpi_communicator=comm)

    if dim == 2:
        # no deep meaning here, just a fudge factor
        dt = 0.0025/(nel_1d*order**2)
    else:
        raise ValueError("don't have a stable time step guesstimate")

    source_width = 0.2

    from arraycontext import thaw
    nodes = thaw(discr.nodes(), actx)

    boundaries = {
        DTAG_BOUNDARY("dirichlet"): DirichletDiffusionBoundary(0.),
        DTAG_BOUNDARY("neumann"): NeumannDiffusionBoundary(0.)
    }

    u = discr.zeros(actx)

    if logmgr:
        logmgr_add_device_name(logmgr, queue)
        logmgr_add_device_memory_usage(logmgr, queue)

        logmgr.add_watches(["step.max", "t_step.max", "t_log.max"])

        try:
            logmgr.add_watches(["memory_usage_python.max", "memory_usage_gpu.max"])
        except KeyError:
            pass

        if use_profiling:
            logmgr.add_watches(["multiply_time.max"])

        vis_timer = IntervalTimer("t_vis", "Time spent visualizing")
        logmgr.add_quantity(vis_timer)

    vis = make_visualizer(discr)

    def rhs(t, u):
        return (
            diffusion_operator(
                discr, quad_tag=DISCR_TAG_BASE,
                alpha=1, boundaries=boundaries, u=u)
            + actx.np.exp(-np.dot(nodes, nodes)/source_width**2))

    compiled_rhs = actx.compile(rhs)

    rank = comm.Get_rank()

    while t < t_final:
        if logmgr:
            logmgr.tick_before()

        if istep % 10 == 0:
            print(istep, t, actx.to_numpy(actx.np.linalg.norm(u[0])))
            vis.write_vtk_file("fld-heat-source-mpi-%03d-%04d.vtu" % (rank, istep),
                    [
                        ("u", u)
                        ], overwrite=True)

        u = rk4_step(u, t, dt, compiled_rhs)
        t += dt
        istep += 1

        if logmgr:
            set_dt(logmgr, dt)
            logmgr.tick_after()
    final_answer = discr.norm(u, np.inf)
    resid = abs(final_answer - 0.00020620711665201585)
    if resid > 1e-15:
        raise ValueError(f"Run did not produce the expected result {resid=}")
Ejemplo n.º 8
0
def main():
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue,
                                allocator=cl_tools.MemoryPool(
                                    cl_tools.ImmediateAllocator(queue)))

    from mpi4py import MPI
    comm = MPI.COMM_WORLD
    num_parts = comm.Get_size()

    from meshmode.distributed import MPIMeshDistributor, get_partition_by_pymetis
    mesh_dist = MPIMeshDistributor(comm)

    dim = 2
    nel_1d = 16

    if mesh_dist.is_mananger_rank():
        from meshmode.mesh.generation import generate_regular_rect_mesh
        mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim,
                                          b=(0.5, ) * dim,
                                          n=(nel_1d, ) * dim,
                                          boundary_tag_to_face={
                                              "dirichlet": ["+x", "-x"],
                                              "neumann": ["+y", "-y"]
                                          })

        print("%d elements" % mesh.nelements)

        part_per_element = get_partition_by_pymetis(mesh, num_parts)

        local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element,
                                               num_parts)

        del mesh

    else:
        local_mesh = mesh_dist.receive_mesh_part()

    order = 3

    discr = EagerDGDiscretization(actx,
                                  local_mesh,
                                  order=order,
                                  mpi_communicator=comm)

    if dim == 2:
        # no deep meaning here, just a fudge factor
        dt = 0.0025 / (nel_1d * order**2)
    else:
        raise ValueError("don't have a stable time step guesstimate")

    source_width = 0.2

    nodes = thaw(actx, discr.nodes())

    u = discr.zeros(actx)

    vis = make_visualizer(discr, order + 3 if dim == 2 else order)

    boundaries = {
        grudge_sym.DTAG_BOUNDARY("dirichlet"): DirichletDiffusionBoundary(0.),
        grudge_sym.DTAG_BOUNDARY("neumann"): NeumannDiffusionBoundary(0.)
    }

    def rhs(t, u):
        return (
            diffusion_operator(discr, alpha=1, boundaries=boundaries, u=u) +
            actx.np.exp(-np.dot(nodes, nodes) / source_width**2))

    rank = comm.Get_rank()

    t = 0
    t_final = 0.01
    istep = 0

    while True:
        if istep % 10 == 0:
            print(istep, t, discr.norm(u))
            vis.write_vtk_file(
                "fld-heat-source-mpi-%03d-%04d.vtu" % (rank, istep),
                [("u", u)])

        if t >= t_final:
            break

        u = rk4_step(u, t, dt, rhs)
        t += dt
        istep += 1
Ejemplo n.º 9
0
def test_diffusion_discontinuous_alpha(actx_factory, order, visualize=False):
    """
    Checks the accuracy of the diffusion operator for an alpha field that has a
    jump across an element face.
    """
    actx = actx_factory()

    n = 8

    mesh = get_box_mesh(1, -1, 1, n)

    from grudge.eager import EagerDGDiscretization
    discr = EagerDGDiscretization(actx, mesh, order=order)

    nodes = thaw(actx, discr.nodes())

    # Set up a 1D heat equation interface problem, apply the diffusion operator to
    # the exact steady state solution, and check that it's zero

    lower_mask_np = np.empty((n, order + 1), dtype=int)
    lower_mask_np[:, :] = 0
    lower_mask_np[:int(n / 2), :] = 1
    lower_mask = DOFArray(actx, (actx.from_numpy(lower_mask_np), ))

    upper_mask_np = np.empty((n, order + 1), dtype=int)
    upper_mask_np[:, :] = 0
    upper_mask_np[int(n / 2):, :] = 1
    upper_mask = DOFArray(actx, (actx.from_numpy(upper_mask_np), ))

    alpha_lower = 0.5
    alpha_upper = 1

    alpha = alpha_lower * lower_mask + alpha_upper * upper_mask

    boundaries = {
        DTAG_BOUNDARY("-0"): DirichletDiffusionBoundary(0.),
        DTAG_BOUNDARY("+0"): DirichletDiffusionBoundary(1.),
    }

    flux = -alpha_lower * alpha_upper / (alpha_lower + alpha_upper)

    u_steady = (
        -flux / alpha_lower * (nodes[0] + 1) * lower_mask  # noqa: E126, E221
        + (1 - flux / alpha_upper * (nodes[0] - 1)) * upper_mask)  # noqa: E131

    def get_rhs(t, u):
        return diffusion_operator(discr,
                                  quad_tag=DISCR_TAG_BASE,
                                  alpha=alpha,
                                  boundaries=boundaries,
                                  u=u)

    rhs = get_rhs(0, u_steady)

    if visualize:
        from grudge.shortcuts import make_visualizer
        vis = make_visualizer(discr, discr.order + 3)
        vis.write_vtk_file(
            "diffusion_discontinuous_alpha_rhs_{order}.vtu".format(
                order=order), [
                    ("alpha", alpha),
                    ("u_steady", u_steady),
                    ("rhs", rhs),
                ])

    linf_err = discr.norm(rhs, np.inf)
    assert (linf_err < 1e-11)

    # Now check stability

    from numpy.random import rand
    perturb_np = np.empty((n, order + 1), dtype=float)
    for i in range(n):
        perturb_np[i, :] = 0.1 * (rand() - 0.5)
    perturb = DOFArray(actx, (actx.from_numpy(perturb_np), ))

    u = u_steady + perturb

    dt = 1e-3 / order**2
    t = 0

    from mirgecom.integrators import rk4_step

    for _ in range(50):
        u = rk4_step(u, t, dt, get_rhs)
        t += dt

    if visualize:
        vis.write_vtk_file(
            "diffusion_disc_alpha_stability_{order}.vtu".format(order=order), [
                ("alpha", alpha),
                ("u", u),
                ("u_steady", u_steady),
            ])

    linf_diff = discr.norm(u - u_steady, np.inf)
    assert linf_diff < 0.1
Ejemplo n.º 10
0
 def get_boundaries(discr, actx, t):
     return {
         grudge_sym.DTAG_BOUNDARY("dirichlet"):
         DirichletDiffusionBoundary(0.),
         grudge_sym.DTAG_BOUNDARY("neumann"): NeumannDiffusionBoundary(0.),
     }