コード例 #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()
コード例 #2
0
ファイル: driver.py プロジェクト: gimac/pyrticle
    def __init__(self):
        from pyrticle.units import SIUnitsWithNaturalConstants
        self.units = units = SIUnitsWithNaturalConstants()

        ui = PICCPyUserInterface(units)
        setup = self.setup = ui.gather()

        from pytools.log import LogManager
        import os.path
        self.logmgr = LogManager(os.path.join(
            setup.output_path, "pic.dat"), "w")

        from hedge.backends import guess_run_context
        self.rcon = guess_run_context([])

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

        self.discr = discr = \
                self.rcon.make_discretization(mesh, 
                        order=setup.element_order,
                        debug=setup.dg_debug)

        self.logmgr.set_constant("elements_total", len(setup.mesh.elements))
        self.logmgr.set_constant("elements_local", len(mesh.elements))
        self.logmgr.set_constant("element_order", setup.element_order)

        # em operator ---------------------------------------------------------
        maxwell_kwargs = {
                "epsilon": units.EPSILON0, 
                "mu": units.MU0, 
                "flux_type": setup.maxwell_flux_type,
                "bdry_flux_type": setup.maxwell_bdry_flux_type
                }

        if discr.dimensions == 3:
            from hedge.models.em import MaxwellOperator
            self.maxwell_op = MaxwellOperator(**maxwell_kwargs)
        elif discr.dimensions == 2:
            from hedge.models.em import TEMaxwellOperator
            self.maxwell_op = TEMaxwellOperator(**maxwell_kwargs)
        else:
            raise ValueError, "invalid mesh dimension"

        if setup.chi is not None:
            from pyrticle.hyperbolic import ECleaningMaxwellOperator
            self.maxwell_op = ECleaningMaxwellOperator(self.maxwell_op, 
                    chi=setup.chi, 
                    phi_decay=setup.phi_decay)

            if setup.phi_filter is not None:
                from pyrticle.hyperbolic import PhiFilter
                from hedge.discretization import Filter, ExponentialFilterResponseFunction
                em_filters.append(
                        PhiFilter(maxwell_op, Filter(discr,
                            ExponentialFilterResponseFunction(*setup.phi_filter))))

        # timestepping setup --------------------------------------------------
        goal_dt = self.maxwell_op.estimate_timestep(discr) * setup.dt_scale
        self.nsteps = int(setup.final_time/goal_dt)+1
        self.dt = setup.final_time/self.nsteps

        self.stepper = setup.timestepper_maker(self.dt)

        # particle setup ------------------------------------------------------
        from pyrticle.cloud import PicMethod, PicState, \
                optimize_shape_bandwidth, \
                guess_shape_bandwidth

        method = self.method = PicMethod(discr, units, 
                setup.depositor, setup.pusher,
                dimensions_pos=setup.dimensions_pos, 
                dimensions_velocity=setup.dimensions_velocity, 
                debug=setup.debug)

        self.state = method.make_state()
        method.add_particles( 
                self.state,
                setup.distribution.generate_particles(),
                setup.nparticles)

        self.total_charge = setup.nparticles*setup.distribution.mean()[2][0]
        if isinstance(setup.shape_bandwidth, str):
            if setup.shape_bandwidth == "optimize":
                optimize_shape_bandwidth(method, self.state,
                        setup.distribution.get_rho_interpolant(
                            discr, self.total_charge),
                        setup.shape_exponent)
            elif setup.shape_bandwidth == "guess":
                guess_shape_bandwidth(method, self.state, setup.shape_exponent)
            else:
                raise ValueError, "invalid shape bandwidth setting '%s'" % (
                        setup.shape_bandwidth)
        else:
            from pyrticle._internal import PolynomialShapeFunction
            method.depositor.set_shape_function(
                    self.state,
                    PolynomialShapeFunction(
                        float(setup.shape_bandwidth),
                        method.mesh_data.dimensions,
                        setup.shape_exponent,
                        ))

        # initial condition ---------------------------------------------------
        if "no_ic" in setup.debug:
            self.fields = self.maxwell_op.assemble_eh(discr=discr)
        else:
            from pyrticle.cloud import compute_initial_condition
            self.fields = compute_initial_condition(self.rcon, discr, method, self.state,
                    maxwell_op=self.maxwell_op, 
                    potential_bc=setup.potential_bc, 
                    force_zero=False)

        # rhs calculators -----------------------------------------------------
        from pyrticle.cloud import \
                FieldRhsCalculator, \
                FieldToParticleRhsCalculator, \
                ParticleRhsCalculator, \
                ParticleToFieldRhsCalculator
        self.f_rhs_calculator = FieldRhsCalculator(self.method, self.maxwell_op)
        self.p_rhs_calculator = ParticleRhsCalculator(self.method, self.maxwell_op)
        self.f2p_rhs_calculator = FieldToParticleRhsCalculator(self.method, self.maxwell_op)
        self.p2f_rhs_calculator = ParticleToFieldRhsCalculator(self.method, self.maxwell_op)

        # instrumentation setup -----------------------------------------------
        self.add_instrumentation(self.logmgr)
コード例 #3
0
ファイル: test_pyrticle.py プロジェクト: gimac/pyrticle
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()
コード例 #4
0
    def __init__(self):
        from pyrticle.units import SIUnitsWithNaturalConstants
        self.units = units = SIUnitsWithNaturalConstants()

        ui = PICCPyUserInterface(units)
        setup = self.setup = ui.gather()

        from pytools.log import LogManager
        import os.path
        self.logmgr = LogManager(os.path.join(setup.output_path, "pic.dat"),
                                 "w")

        from hedge.backends import guess_run_context
        self.rcon = guess_run_context([])

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

        self.discr = discr = \
                self.rcon.make_discretization(mesh,
                        order=setup.element_order,
                        debug=setup.dg_debug)

        self.logmgr.set_constant("elements_total", len(setup.mesh.elements))
        self.logmgr.set_constant("elements_local", len(mesh.elements))
        self.logmgr.set_constant("element_order", setup.element_order)

        # em operator ---------------------------------------------------------
        maxwell_kwargs = {
            "epsilon": units.EPSILON0,
            "mu": units.MU0,
            "flux_type": setup.maxwell_flux_type,
            "bdry_flux_type": setup.maxwell_bdry_flux_type
        }

        if discr.dimensions == 3:
            from hedge.models.em import MaxwellOperator
            self.maxwell_op = MaxwellOperator(**maxwell_kwargs)
        elif discr.dimensions == 2:
            from hedge.models.em import TEMaxwellOperator
            self.maxwell_op = TEMaxwellOperator(**maxwell_kwargs)
        else:
            raise ValueError, "invalid mesh dimension"

        if setup.chi is not None:
            from pyrticle.hyperbolic import ECleaningMaxwellOperator
            self.maxwell_op = ECleaningMaxwellOperator(
                self.maxwell_op, chi=setup.chi, phi_decay=setup.phi_decay)

            if setup.phi_filter is not None:
                from pyrticle.hyperbolic import PhiFilter
                from hedge.discretization import Filter, ExponentialFilterResponseFunction
                em_filters.append(
                    PhiFilter(
                        maxwell_op,
                        Filter(
                            discr,
                            ExponentialFilterResponseFunction(
                                *setup.phi_filter))))

        # timestepping setup --------------------------------------------------
        goal_dt = self.maxwell_op.estimate_timestep(discr) * setup.dt_scale
        self.nsteps = int(setup.final_time / goal_dt) + 1
        self.dt = setup.final_time / self.nsteps

        self.stepper = setup.timestepper_maker(self.dt)

        # particle setup ------------------------------------------------------
        from pyrticle.cloud import PicMethod, PicState, \
                optimize_shape_bandwidth, \
                guess_shape_bandwidth

        method = self.method = PicMethod(
            discr,
            units,
            setup.depositor,
            setup.pusher,
            dimensions_pos=setup.dimensions_pos,
            dimensions_velocity=setup.dimensions_velocity,
            debug=setup.debug)

        self.state = method.make_state()
        method.add_particles(self.state,
                             setup.distribution.generate_particles(),
                             setup.nparticles)

        self.total_charge = setup.nparticles * setup.distribution.mean()[2][0]
        if isinstance(setup.shape_bandwidth, str):
            if setup.shape_bandwidth == "optimize":
                optimize_shape_bandwidth(
                    method, self.state,
                    setup.distribution.get_rho_interpolant(
                        discr, self.total_charge), setup.shape_exponent)
            elif setup.shape_bandwidth == "guess":
                guess_shape_bandwidth(method, self.state, setup.shape_exponent)
            else:
                raise ValueError, "invalid shape bandwidth setting '%s'" % (
                    setup.shape_bandwidth)
        else:
            from pyrticle._internal import PolynomialShapeFunction
            method.depositor.set_shape_function(
                self.state,
                PolynomialShapeFunction(
                    float(setup.shape_bandwidth),
                    method.mesh_data.dimensions,
                    setup.shape_exponent,
                ))

        # initial condition ---------------------------------------------------
        if "no_ic" in setup.debug:
            self.fields = self.maxwell_op.assemble_eh(discr=discr)
        else:
            from pyrticle.cloud import compute_initial_condition
            self.fields = compute_initial_condition(
                self.rcon,
                discr,
                method,
                self.state,
                maxwell_op=self.maxwell_op,
                potential_bc=setup.potential_bc,
                force_zero=False)

        # rhs calculators -----------------------------------------------------
        from pyrticle.cloud import \
                FieldRhsCalculator, \
                FieldToParticleRhsCalculator, \
                ParticleRhsCalculator, \
                ParticleToFieldRhsCalculator
        self.f_rhs_calculator = FieldRhsCalculator(self.method,
                                                   self.maxwell_op)
        self.p_rhs_calculator = ParticleRhsCalculator(self.method,
                                                      self.maxwell_op)
        self.f2p_rhs_calculator = FieldToParticleRhsCalculator(
            self.method, self.maxwell_op)
        self.p2f_rhs_calculator = ParticleToFieldRhsCalculator(
            self.method, self.maxwell_op)

        # instrumentation setup -----------------------------------------------
        self.add_instrumentation(self.logmgr)