Beispiel #1
0
def main(ctx_factory, dim=3, order=4, visualize=False):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(
        queue,
        allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue)),
        force_device_scalars=True,
    )

    from meshmode.mesh.generation import generate_regular_rect_mesh
    mesh = generate_regular_rect_mesh(a=(0.0, ) * dim,
                                      b=(1.0, ) * dim,
                                      nelements_per_axis=(4, ) * dim)

    dcoll = DiscretizationCollection(actx, mesh, order=order)

    if 0:
        epsilon0 = 8.8541878176e-12  # C**2 / (N m**2)
        mu0 = 4 * np.pi * 1e-7  # N/A**2.
        epsilon = 1 * epsilon0
        mu = 1 * mu0
    else:
        epsilon = 1
        mu = 1

    from grudge.models.em import MaxwellOperator

    maxwell_operator = MaxwellOperator(dcoll,
                                       epsilon,
                                       mu,
                                       flux_type=0.5,
                                       dimensions=dim)

    def cavity_mode(x, t=0):
        if dim == 3:
            return get_rectangular_cavity_mode(actx, x, t, 1, (1, 2, 2))
        else:
            return get_rectangular_cavity_mode(actx, x, t, 1, (2, 3))

    fields = cavity_mode(thaw(dcoll.nodes(), actx), t=0)

    maxwell_operator.check_bc_coverage(mesh)

    def rhs(t, w):
        return maxwell_operator.operator(t, w)

    dt = maxwell_operator.estimate_rk4_timestep(actx, dcoll, fields=fields)

    dt_stepper = set_up_rk4("w", dt, fields, rhs)

    target_steps = 60
    final_t = dt * target_steps
    nsteps = int(final_t / dt) + 1

    logger.info("dt = %g nsteps = %d", dt, nsteps)

    from grudge.shortcuts import make_visualizer
    vis = make_visualizer(dcoll)

    step = 0

    def norm(u):
        return op.norm(dcoll, u, 2)

    e, h = maxwell_operator.split_eh(fields)

    if visualize:
        vis.write_vtk_file(f"fld-cavities-{step:04d}.vtu", [
            ("e", e),
            ("h", h),
        ])

    for event in dt_stepper.run(t_end=final_t):
        if isinstance(event, dt_stepper.StateComputed):
            assert event.component_id == "w"

            step += 1
            e, h = maxwell_operator.split_eh(event.state_component)

            norm_e0 = actx.to_numpy(norm(u=e[0]))
            norm_e1 = actx.to_numpy(norm(u=e[1]))
            norm_h0 = actx.to_numpy(norm(u=h[0]))
            norm_h1 = actx.to_numpy(norm(u=h[1]))

            logger.info(
                "[%04d] t = %.5f |e0| = %.5e, |e1| = %.5e, |h0| = %.5e, |h1| = %.5e",
                step, event.t, norm_e0, norm_e1, norm_h0, norm_h1)

            if step % 10 == 0:
                if visualize:
                    vis.write_vtk_file(f"fld-cavities-{step:04d}.vtu", [
                        ("e", e),
                        ("h", h),
                    ])

            # NOTE: These are here to ensure the solution is bounded for the
            # time interval specified
            assert norm_e0 < 0.5
            assert norm_e1 < 0.5
            assert norm_h0 < 0.5
            assert norm_h1 < 0.5
Beispiel #2
0
def test_convergence_maxwell(actx_factory, order):
    """Test whether 3D Maxwell's actually converges"""

    actx = actx_factory()

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    dims = 3
    ns = [4, 6, 8]
    for n in ns:
        mesh = mgen.generate_regular_rect_mesh(a=(0.0, ) * dims,
                                               b=(1.0, ) * dims,
                                               nelements_per_axis=(n, ) * dims)

        dcoll = DiscretizationCollection(actx, mesh, order=order)

        epsilon = 1
        mu = 1

        from grudge.models.em import get_rectangular_cavity_mode

        def analytic_sol(x, t=0):
            return get_rectangular_cavity_mode(actx, x, t, 1, (1, 2, 2))

        nodes = thaw(dcoll.nodes(), actx)
        fields = analytic_sol(nodes, t=0)

        from grudge.models.em import MaxwellOperator

        maxwell_operator = MaxwellOperator(dcoll,
                                           epsilon,
                                           mu,
                                           flux_type=0.5,
                                           dimensions=dims)
        maxwell_operator.check_bc_coverage(mesh)

        def rhs(t, w):
            return maxwell_operator.operator(t, w)

        dt = maxwell_operator.estimate_rk4_timestep(actx, dcoll)
        final_t = dt * 5
        nsteps = int(final_t / dt)

        from grudge.shortcuts import set_up_rk4
        dt_stepper = set_up_rk4("w", dt, fields, rhs)

        logger.info("dt %.5e nsteps %5d", dt, nsteps)

        step = 0
        for event in dt_stepper.run(t_end=final_t):
            if isinstance(event, dt_stepper.StateComputed):
                assert event.component_id == "w"
                esc = event.state_component

                step += 1
                logger.debug("[%04d] t = %.5e", step, event.t)

        sol = analytic_sol(nodes, t=step * dt)
        total_error = op.norm(dcoll, esc - sol, 2)
        eoc_rec.add_data_point(1.0 / n, actx.to_numpy(total_error))

    logger.info(
        "\n%s", eoc_rec.pretty_print(abscissa_label="h",
                                     error_label="L2 Error"))

    assert eoc_rec.order_estimate() > order