Beispiel #1
0
def test_efield_vs_gauss_law():
    from hedge.mesh.generator import \
            make_box_mesh, \
            make_cylinder_mesh
    from math import sqrt, pi
    from pytools.arithmetic_container import \
            ArithmeticList, join_fields
    from random import seed
    from pytools.stopwatch import Job

    from pyrticle.units import SIUnitsWithNaturalConstants
    units = SIUnitsWithNaturalConstants()

    seed(0)

    nparticles = 10000
    beam_radius = 2.5 * units.MM
    emittance = 5 * units.MM * units.MRAD
    final_time = 0.1 * units.M / units.VACUUM_LIGHT_SPEED()
    field_dump_interval = 1
    tube_length = 20 * units.MM

    # discretization setup ----------------------------------------------------
    from pyrticle.geometry import make_cylinder_with_fine_core
    mesh = make_cylinder_with_fine_core(
        r=10 * beam_radius,
        inner_r=1 * beam_radius,
        min_z=0,
        max_z=tube_length,
        max_volume_inner=10 * units.MM**3,
        max_volume_outer=100 * units.MM**3,
        radial_subdiv=10,
    )

    from hedge.backends import guess_run_context
    rcon = guess_run_context([])
    discr = rcon.make_discretization(mesh, order=3)

    from hedge.models.em import MaxwellOperator
    max_op = MaxwellOperator(epsilon=units.EPSILON0, mu=units.MU0, flux_type=1)

    from hedge.models.nd_calculus import DivergenceOperator
    div_op = DivergenceOperator(discr.dimensions)

    # particles setup ---------------------------------------------------------
    from pyrticle.cloud import PicMethod
    from pyrticle.deposition.shape import ShapeFunctionDepositor
    from pyrticle.pusher import MonomialParticlePusher

    method = PicMethod(discr, units, ShapeFunctionDepositor(),
                       MonomialParticlePusher(), 3, 3)

    # particle ic ---------------------------------------------------------
    cloud_charge = -1e-9 * units.C
    electrons_per_particle = abs(cloud_charge / nparticles / units.EL_CHARGE)

    el_energy = 10 * units.EL_REST_ENERGY()
    el_lorentz_gamma = el_energy / units.EL_REST_ENERGY()
    beta = (1 - 1 / el_lorentz_gamma**2)**0.5
    gamma = 1 / sqrt(1 - beta**2)

    from pyrticle.distribution import KVZIntervalBeam
    beam = KVZIntervalBeam(units,
                           total_charge=cloud_charge,
                           p_charge=cloud_charge / nparticles,
                           p_mass=electrons_per_particle * units.EL_MASS,
                           radii=2 * [beam_radius],
                           emittances=2 * [5 * units.MM * units.MRAD],
                           z_length=tube_length,
                           z_pos=tube_length / 2,
                           beta=beta)

    state = method.make_state()

    method.add_particles(state, beam.generate_particles(), nparticles)

    # field ic ----------------------------------------------------------------
    from pyrticle.cloud import guess_shape_bandwidth
    guess_shape_bandwidth(method, state, 2)

    from pyrticle.cloud import compute_initial_condition

    from hedge.data import ConstantGivenFunction
    fields = compute_initial_condition(rcon,
                                       discr,
                                       method,
                                       state,
                                       maxwell_op=max_op,
                                       potential_bc=ConstantGivenFunction())

    # check against theory ----------------------------------------------------
    q_per_unit_z = cloud_charge / beam.z_length

    class TheoreticalEField:
        shape = (3, )

        def __call__(self, x, el):
            r = la.norm(x[:2])
            if r >= max(beam.radii):
                xy_unit = x / r
                xy_unit[2] = 0
                return xy_unit * ((q_per_unit_z) /
                                  (2 * pi * r * max_op.epsilon))
            else:
                return numpy.zeros((3, ))

    def theory_indicator(x, el):
        r = la.norm(x[:2])
        if r >= max(beam.radii):
            return 1
        else:
            return 0

    from hedge.tools import join_fields, to_obj_array
    e_theory = to_obj_array(
        discr.interpolate_volume_function(TheoreticalEField()))
    theory_ind = discr.interpolate_volume_function(theory_indicator)

    e_field, h_field = max_op.split_eh(fields)
    restricted_e = join_fields(*[e_i * theory_ind for e_i in e_field])

    def l2_error(field, true):
        return discr.norm(field - true) / discr.norm(true)

    outer_l2 = l2_error(restricted_e, e_theory)
    assert outer_l2 < 0.08

    if False:
        visf = vis.make_file("e_comparison")
        mesh_scalars, mesh_vectors = \
                method.add_to_vis(vis, visf)
        vis.add_data(visf, [
            ("e", restricted_e),
            ("e_theory", e_theory),
        ] + mesh_vectors + mesh_scalars)
        visf.close()
Beispiel #2
0
def main(write_output=True, allow_features=None, flux_type_arg=1, bdry_flux_type_arg=None, extra_discr_args={}):
    from hedge.mesh.generator import make_cylinder_mesh, make_box_mesh
    from hedge.tools import EOCRecorder, to_obj_array
    from math import sqrt, pi
    from analytic_solutions import (
        check_time_harmonic_solution,
        RealPartAdapter,
        SplitComplexAdapter,
        CylindricalFieldAdapter,
        CylindricalCavityMode,
        RectangularWaveguideMode,
        RectangularCavityMode,
    )
    from hedge.models.em import MaxwellOperator

    from hedge.backends import guess_run_context

    rcon = guess_run_context(allow_features)

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

    eoc_rec = EOCRecorder()

    cylindrical = False
    periodic = False

    if cylindrical:
        R = 1
        d = 2
        mode = CylindricalCavityMode(m=1, n=1, p=1, radius=R, height=d, epsilon=epsilon, mu=mu)
        r_sol = CylindricalFieldAdapter(RealPartAdapter(mode))
        c_sol = SplitComplexAdapter(CylindricalFieldAdapter(mode))

        if rcon.is_head_rank:
            mesh = make_cylinder_mesh(radius=R, height=d, max_volume=0.01)
    else:
        if periodic:
            mode = RectangularWaveguideMode(epsilon, mu, (3, 2, 1))
            periodicity = (False, False, True)
        else:
            periodicity = None
        mode = RectangularCavityMode(epsilon, mu, (1, 2, 2))

        if rcon.is_head_rank:
            mesh = make_box_mesh(max_volume=0.001, periodicity=periodicity)

    if rcon.is_head_rank:
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [4, 5, 6]:
        # for order in [1,2,3,4,5,6]:
        extra_discr_args.setdefault("debug", []).extend(["cuda_no_plan", "cuda_dump_kernels"])

        op = MaxwellOperator(epsilon, mu, flux_type=flux_type_arg, bdry_flux_type=bdry_flux_type_arg)

        discr = rcon.make_discretization(mesh_data, order=order, tune_for=op.op_template(), **extra_discr_args)

        from hedge.visualization import VtkVisualizer

        if write_output:
            vis = VtkVisualizer(discr, rcon, "em-%d" % order)

        mode.set_time(0)

        def get_true_field():
            return discr.convert_volume(
                to_obj_array(mode(discr).real.astype(discr.default_scalar_type).copy()), kind=discr.compute_kind
            )

        fields = get_true_field()

        if rcon.is_head_rank:
            print "---------------------------------------------"
            print "order %d" % order
            print "---------------------------------------------"
            print "#elements=", len(mesh.elements)

        from hedge.timestep.runge_kutta import LSRK4TimeStepper

        stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type, rcon=rcon)
        # from hedge.timestep.dumka3 import Dumka3TimeStepper
        # stepper = Dumka3TimeStepper(3, dtype=discr.default_scalar_type, rcon=rcon)

        # diagnostics setup ---------------------------------------------------
        from pytools.log import LogManager, add_general_quantities, add_simulation_quantities, add_run_info

        if write_output:
            log_file_name = "maxwell-%d.dat" % order
        else:
            log_file_name = None

        logmgr = LogManager(log_file_name, "w", rcon.communicator)

        add_run_info(logmgr)
        add_general_quantities(logmgr)
        add_simulation_quantities(logmgr)
        discr.add_instrumentation(logmgr)
        stepper.add_instrumentation(logmgr)

        from pytools.log import IntervalTimer

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

        from hedge.log import EMFieldGetter, add_em_quantities

        field_getter = EMFieldGetter(discr, op, lambda: fields)
        add_em_quantities(logmgr, op, field_getter)

        logmgr.add_watches(["step.max", "t_sim.max", ("W_field", "W_el+W_mag"), "t_step.max"])

        # timestep loop -------------------------------------------------------
        rhs = op.bind(discr)
        final_time = 0.5e-9

        try:
            from hedge.timestep import times_and_steps

            step_it = times_and_steps(
                final_time=final_time,
                logmgr=logmgr,
                max_dt_getter=lambda t: op.estimate_timestep(discr, stepper=stepper, t=t, fields=fields),
            )

            for step, t, dt in step_it:
                if step % 50 == 0 and write_output:
                    sub_timer = vis_timer.start_sub_timer()
                    e, h = op.split_eh(fields)
                    visf = vis.make_file("em-%d-%04d" % (order, step))
                    vis.add_data(
                        visf,
                        [("e", discr.convert_volume(e, kind="numpy")), ("h", discr.convert_volume(h, kind="numpy"))],
                        time=t,
                        step=step,
                    )
                    visf.close()
                    sub_timer.stop().submit()

                fields = stepper(fields, t, dt, rhs)

            mode.set_time(final_time)

            eoc_rec.add_data_point(order, discr.norm(fields - get_true_field()))

        finally:
            if write_output:
                vis.close()

            logmgr.close()
            discr.close()

        if rcon.is_head_rank:
            print
            print eoc_rec.pretty_print("P.Deg.", "L2 Error")

    assert eoc_rec.estimate_order_of_convergence()[0, 1] > 6
Beispiel #3
0
def test_efield_vs_gauss_law():
    from hedge.mesh.generator import \
            make_box_mesh, \
            make_cylinder_mesh
    from math import sqrt, pi
    from pytools.arithmetic_container import \
            ArithmeticList, join_fields
    from random import seed
    from pytools.stopwatch import Job

    from pyrticle.units import SIUnitsWithNaturalConstants
    units = SIUnitsWithNaturalConstants()

    seed(0)

    nparticles = 10000
    beam_radius = 2.5 * units.MM
    emittance = 5 * units.MM * units.MRAD
    final_time = 0.1*units.M/units.VACUUM_LIGHT_SPEED()
    field_dump_interval = 1
    tube_length = 20*units.MM

    # discretization setup ----------------------------------------------------
    from pyrticle.geometry import make_cylinder_with_fine_core
    mesh = make_cylinder_with_fine_core(
            r=10*beam_radius, inner_r=1*beam_radius,
            min_z=0, max_z=tube_length,
            max_volume_inner=10*units.MM**3,
            max_volume_outer=100*units.MM**3,
            radial_subdiv=10,
            )

    from hedge.backends import guess_run_context
    rcon = guess_run_context([])
    discr = rcon.make_discretization(mesh, order=3)

    from hedge.models.em import MaxwellOperator
    max_op = MaxwellOperator(
            epsilon=units.EPSILON0,
            mu=units.MU0,
            flux_type=1)

    from hedge.models.nd_calculus import DivergenceOperator
    div_op = DivergenceOperator(discr.dimensions)

    # particles setup ---------------------------------------------------------
    from pyrticle.cloud import PicMethod
    from pyrticle.deposition.shape import ShapeFunctionDepositor
    from pyrticle.pusher import MonomialParticlePusher

    method = PicMethod(discr, units,
            ShapeFunctionDepositor(),
            MonomialParticlePusher(),
            3, 3)

    # particle ic ---------------------------------------------------------
    cloud_charge = -1e-9 * units.C
    electrons_per_particle = abs(cloud_charge/nparticles/units.EL_CHARGE)

    el_energy = 10*units.EL_REST_ENERGY()
    el_lorentz_gamma = el_energy/units.EL_REST_ENERGY()
    beta = (1-1/el_lorentz_gamma**2)**0.5
    gamma = 1/sqrt(1-beta**2)

    from pyrticle.distribution import KVZIntervalBeam
    beam = KVZIntervalBeam(units, total_charge=cloud_charge,
            p_charge=cloud_charge/nparticles,
            p_mass=electrons_per_particle*units.EL_MASS,
            radii=2*[beam_radius],
            emittances=2*[5 * units.MM * units.MRAD],
            z_length=tube_length,
            z_pos=tube_length/2,
            beta=beta)

    state = method.make_state()

    method.add_particles(state, beam.generate_particles(), nparticles)

    # field ic ----------------------------------------------------------------
    from pyrticle.cloud import guess_shape_bandwidth
    guess_shape_bandwidth(method, state, 2)

    from pyrticle.cloud import compute_initial_condition

    from hedge.data import ConstantGivenFunction
    fields = compute_initial_condition(
            rcon,
            discr, method, state, maxwell_op=max_op,
            potential_bc=ConstantGivenFunction())

    # check against theory ----------------------------------------------------
    q_per_unit_z = cloud_charge/beam.z_length
    class TheoreticalEField:
        shape = (3,)

        def __call__(self, x, el):
            r = la.norm(x[:2])
            if r >= max(beam.radii):
                xy_unit = x/r
                xy_unit[2] = 0
                return xy_unit*((q_per_unit_z)
                        /
                        (2*pi*r*max_op.epsilon))
            else:
                return numpy.zeros((3,))

    def theory_indicator(x, el):
        r = la.norm(x[:2])
        if r >= max(beam.radii):
            return 1
        else:
            return 0

    from hedge.tools import join_fields, to_obj_array
    e_theory = to_obj_array(discr.interpolate_volume_function(TheoreticalEField()))
    theory_ind = discr.interpolate_volume_function(theory_indicator)

    e_field, h_field = max_op.split_eh(fields)
    restricted_e = join_fields(*[e_i * theory_ind for e_i in e_field])

    def l2_error(field, true):
        return discr.norm(field-true)/discr.norm(true)

    outer_l2 = l2_error(restricted_e, e_theory)
    assert outer_l2 < 0.08

    if False:
        visf = vis.make_file("e_comparison")
        mesh_scalars, mesh_vectors = \
                method.add_to_vis(vis, visf)
        vis.add_data(visf, [
            ("e", restricted_e),
            ("e_theory", e_theory),
            ]
            + mesh_vectors
            + mesh_scalars
            )
        visf.close()
Beispiel #4
0
def main(write_output=True,
         allow_features=None,
         flux_type_arg=1,
         bdry_flux_type_arg=None,
         extra_discr_args={}):
    from hedge.mesh.generator import make_cylinder_mesh, make_box_mesh
    from hedge.tools import EOCRecorder, to_obj_array
    from math import sqrt, pi  # noqa
    from analytic_solutions import (  # noqa
        RealPartAdapter, SplitComplexAdapter, CylindricalFieldAdapter,
        CylindricalCavityMode, RectangularWaveguideMode, RectangularCavityMode)
    from hedge.models.em import MaxwellOperator

    logging.basicConfig(level=logging.DEBUG)

    from hedge.backends import guess_run_context
    rcon = guess_run_context(allow_features)

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

    eoc_rec = EOCRecorder()

    cylindrical = False
    periodic = False

    if cylindrical:
        R = 1
        d = 2
        mode = CylindricalCavityMode(m=1,
                                     n=1,
                                     p=1,
                                     radius=R,
                                     height=d,
                                     epsilon=epsilon,
                                     mu=mu)
        # r_sol = CylindricalFieldAdapter(RealPartAdapter(mode))
        # c_sol = SplitComplexAdapter(CylindricalFieldAdapter(mode))

        if rcon.is_head_rank:
            mesh = make_cylinder_mesh(radius=R, height=d, max_volume=0.01)
    else:
        if periodic:
            mode = RectangularWaveguideMode(epsilon, mu, (3, 2, 1))
            periodicity = (False, False, True)
        else:
            periodicity = None
        mode = RectangularCavityMode(epsilon, mu, (1, 2, 2))

        if rcon.is_head_rank:
            mesh = make_box_mesh(max_volume=0.001, periodicity=periodicity)

    if rcon.is_head_rank:
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    for order in [4, 5, 6]:
        #for order in [1,2,3,4,5,6]:
        extra_discr_args.setdefault("debug", []).extend(
            ["cuda_no_plan", "cuda_dump_kernels"])

        op = MaxwellOperator(epsilon,
                             mu,
                             flux_type=flux_type_arg,
                             bdry_flux_type=bdry_flux_type_arg)

        discr = rcon.make_discretization(mesh_data,
                                         order=order,
                                         tune_for=op.op_template(),
                                         **extra_discr_args)

        from hedge.visualization import VtkVisualizer
        if write_output:
            vis = VtkVisualizer(discr, rcon, "em-%d" % order)

        mode.set_time(0)

        def get_true_field():
            return discr.convert_volume(to_obj_array(
                mode(discr).real.astype(discr.default_scalar_type).copy()),
                                        kind=discr.compute_kind)

        fields = get_true_field()

        if rcon.is_head_rank:
            print "---------------------------------------------"
            print "order %d" % order
            print "---------------------------------------------"
            print "#elements=", len(mesh.elements)

        from hedge.timestep.runge_kutta import LSRK4TimeStepper
        stepper = LSRK4TimeStepper(dtype=discr.default_scalar_type, rcon=rcon)
        #from hedge.timestep.dumka3 import Dumka3TimeStepper
        #stepper = Dumka3TimeStepper(3, dtype=discr.default_scalar_type, rcon=rcon)

        # {{{ diagnostics setup

        from pytools.log import LogManager, add_general_quantities, \
                add_simulation_quantities, add_run_info

        if write_output:
            log_file_name = "maxwell-%d.dat" % order
        else:
            log_file_name = None

        logmgr = LogManager(log_file_name, "w", rcon.communicator)

        add_run_info(logmgr)
        add_general_quantities(logmgr)
        add_simulation_quantities(logmgr)
        discr.add_instrumentation(logmgr)
        stepper.add_instrumentation(logmgr)

        from pytools.log import IntervalTimer
        vis_timer = IntervalTimer("t_vis", "Time spent visualizing")
        logmgr.add_quantity(vis_timer)

        from hedge.log import EMFieldGetter, add_em_quantities
        field_getter = EMFieldGetter(discr, op, lambda: fields)
        add_em_quantities(logmgr, op, field_getter)

        logmgr.add_watches(
            ["step.max", "t_sim.max", ("W_field", "W_el+W_mag"), "t_step.max"])

        # }}}

        # {{{ timestep loop

        rhs = op.bind(discr)
        final_time = 0.5e-9

        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                final_time=final_time,
                logmgr=logmgr,
                max_dt_getter=lambda t: op.estimate_timestep(
                    discr, stepper=stepper, t=t, fields=fields))

            for step, t, dt in step_it:
                if step % 50 == 0 and write_output:
                    sub_timer = vis_timer.start_sub_timer()
                    e, h = op.split_eh(fields)
                    visf = vis.make_file("em-%d-%04d" % (order, step))
                    vis.add_data(visf, [
                        ("e", discr.convert_volume(e, kind="numpy")),
                        ("h", discr.convert_volume(h, kind="numpy")),
                    ],
                                 time=t,
                                 step=step)
                    visf.close()
                    sub_timer.stop().submit()

                fields = stepper(fields, t, dt, rhs)

            mode.set_time(final_time)

            eoc_rec.add_data_point(order,
                                   discr.norm(fields - get_true_field()))

        finally:
            if write_output:
                vis.close()

            logmgr.close()
            discr.close()

        if rcon.is_head_rank:
            print
            print eoc_rec.pretty_print("P.Deg.", "L2 Error")

        # }}}

    assert eoc_rec.estimate_order_of_convergence()[0, 1] > 6