示例#1
0
    def add_instrumentation(self, mgr, observer):
        Depositor.add_instrumentation(self, mgr, observer)

        # instrumentation
        from pytools.log import IntervalTimer, EventCounter
        self.element_activation_counter = EventCounter(
            "n_el_activations",
            "#Advective rec. elements activated this timestep")
        self.element_kill_counter = EventCounter(
            "n_el_kills", "#Advective rec. elements retired this timestep")
        self.advective_rhs_timer = IntervalTimer(
            "t_advective_rhs", "Time spent evaluating advective RHS")
        self.active_elements_log = ActiveAdvectiveElements(observer)

        mgr.add_quantity(self.element_activation_counter)
        mgr.add_quantity(self.element_kill_counter)
        mgr.add_quantity(self.advective_rhs_timer)
        mgr.add_quantity(self.active_elements_log)

        mgr.set_constant("el_activation_threshold", self.activation_threshold)
        mgr.set_constant("el_kill_threshold", self.kill_threshold)
        mgr.set_constant("adv_upwind_alpha", self.upwind_alpha)

        mgr.set_constant("filter_amp", self.filter_amp)
        mgr.set_constant("filter_amp", self.filter_order)
示例#2
0
def main():
    logmgr = LogManager("mylog.dat", "w")  # , comm=...

    # set a run property
    logmgr.set_constant("myconst", uniform(0, 1))

    add_run_info(logmgr)
    add_general_quantities(logmgr)
    add_simulation_quantities(logmgr)

    vis_timer = IntervalTimer("t_vis", "Time spent visualizing")
    logmgr.add_quantity(vis_timer)
    logmgr.add_quantity(Fifteen("fifteen"))
    logmgr.add_watches(["step.max", "t_sim.max", "t_step.max"])

    for istep in range(200):
        logmgr.tick_before()

        dt = uniform(0.01, 0.1)
        set_dt(logmgr, dt)
        sleep(dt)

        # Illustrate custom timers
        if istep % 10 == 0:
            with vis_timer.start_sub_timer():
                sleep(0.05)

        # Illustrate warnings capture
        if uniform(0, 1) < 0.05:
            warn("Oof. Something went awry.")

        logmgr.tick_after()

    logmgr.close()
示例#3
0
    def __init__(self, method, maxwell_op):
        self.method = method
        self.maxwell_op = maxwell_op

        self.bound_maxwell_op = maxwell_op.bind(self.method.discretization)

        from pytools.log import IntervalTimer
        self.field_solve_timer = IntervalTimer("t_field",
                                               "Time spent in field solver")
示例#4
0
文件: cloud.py 项目: gimac/pyrticle
class FieldRhsCalculator(object):
    def __init__(self, method, maxwell_op):
        self.method = method
        self.maxwell_op = maxwell_op

        self.bound_maxwell_op = maxwell_op.bind(self.method.discretization)

        from pytools.log import IntervalTimer
        self.field_solve_timer = IntervalTimer(
                "t_field",
                "Time spent in field solver")

    def add_instrumentation(self, mgr):
        mgr.add_quantity(self.field_solve_timer)

    def __call__(self, t, fields_f, state_f):
        # calculate EM right-hand side
        sub_timer = self.field_solve_timer.start_sub_timer()

        from pyrticle.hyperbolic import CleaningMaxwellOperator
        if isinstance(self.maxwell_op, CleaningMaxwellOperator):
            rhs_fields = self.bound_maxwell_op(t, fields_f(),
                    self.method.deposit_rho(state_f()))
        else:
            rhs_fields = self.bound_maxwell_op(t, fields_f())

        sub_timer.stop().submit()

        return rhs_fields
示例#5
0
    def add_instrumentation(self, mgr, observer):
        mgr.set_constant("depositor", self.__class__.__name__)

        for key, value in self.log_constants.iteritems():
            mgr.set_constant(key, value)

        from pytools.log import IntervalTimer, EventCounter,\
                time_and_count_function

        self.deposit_timer = IntervalTimer("t_deposit",
                                           "Time spent depositing")
        self.deposit_counter = EventCounter("n_deposit",
                                            "Number of depositions")

        self.deposit_densities = time_and_count_function(
            self.deposit_densites, self.deposit_timer, self.deposit_counter,
            1 + self.method.dimensions_velocity)

        self.deposit_j = time_and_count_function(
            self.deposit_j, self.deposit_timer, self.deposit_counter,
            self.method.dimensions_velocity)

        self.deposit_rho = time_and_count_function(self.deposit_rho,
                                                   self.deposit_timer,
                                                   self.deposit_counter)

        mgr.add_quantity(self.deposit_timer)
        mgr.add_quantity(self.deposit_counter)
示例#6
0
class FieldRhsCalculator(object):
    def __init__(self, method, maxwell_op):
        self.method = method
        self.maxwell_op = maxwell_op

        self.bound_maxwell_op = maxwell_op.bind(self.method.discretization)

        from pytools.log import IntervalTimer
        self.field_solve_timer = IntervalTimer("t_field",
                                               "Time spent in field solver")

    def add_instrumentation(self, mgr):
        mgr.add_quantity(self.field_solve_timer)

    def __call__(self, t, fields_f, state_f):
        # calculate EM right-hand side
        sub_timer = self.field_solve_timer.start_sub_timer()

        from pyrticle.hyperbolic import CleaningMaxwellOperator
        if isinstance(self.maxwell_op, CleaningMaxwellOperator):
            rhs_fields = self.bound_maxwell_op(
                t, fields_f(), self.method.deposit_rho(state_f()))
        else:
            rhs_fields = self.bound_maxwell_op(t, fields_f())

        sub_timer.stop().submit()

        return rhs_fields
示例#7
0
    def add_instrumentation(self, mgr, observer):
        Depositor.add_instrumentation(self, mgr, observer)

        # instrumentation
        from pytools.log import IntervalTimer, EventCounter
        self.element_activation_counter = EventCounter(
                "n_el_activations",
                "#Advective rec. elements activated this timestep")
        self.element_kill_counter = EventCounter(
                "n_el_kills",
                "#Advective rec. elements retired this timestep")
        self.advective_rhs_timer = IntervalTimer(
                "t_advective_rhs",
                "Time spent evaluating advective RHS")
        self.active_elements_log = ActiveAdvectiveElements(observer)

        mgr.add_quantity(self.element_activation_counter)
        mgr.add_quantity(self.element_kill_counter)
        mgr.add_quantity(self.advective_rhs_timer)
        mgr.add_quantity(self.active_elements_log)

        mgr.set_constant("el_activation_threshold", self.activation_threshold)
        mgr.set_constant("el_kill_threshold", self.kill_threshold)
        mgr.set_constant("adv_upwind_alpha", self.upwind_alpha)

        mgr.set_constant("filter_amp", self.filter_amp)
        mgr.set_constant("filter_amp", self.filter_order)
示例#8
0
文件: cloud.py 项目: gimac/pyrticle
    def __init__(self, method, maxwell_op):
        self.method = method
        self.maxwell_op = maxwell_op

        self.bound_maxwell_op = maxwell_op.bind(self.method.discretization)

        from pytools.log import IntervalTimer
        self.field_solve_timer = IntervalTimer(
                "t_field",
                "Time spent in field solver")
示例#9
0
    def __init__(self,
                 discr,
                 units,
                 depositor,
                 pusher,
                 dimensions_pos,
                 dimensions_velocity,
                 debug=set()):

        self.units = units
        self.discretization = discr
        self.debug = debug

        self.depositor = depositor
        self.pusher = pusher

        self.dimensions_mesh = discr.dimensions
        self.dimensions_pos = dimensions_pos
        self.dimensions_velocity = dimensions_velocity

        dims = (dimensions_pos, dimensions_velocity)

        self.mesh_data = _internal.MeshData(discr.dimensions)
        self.mesh_data.fill_from_hedge(discr)

        # subsystem init
        self.depositor.initialize(self)
        self.pusher.initialize(self)

        # instrumentation
        from pytools.log import IntervalTimer, EventCounter

        self.find_el_timer = IntervalTimer("t_find",
                                           "Time spent finding new elements")
        self.find_same_counter = EventCounter(
            "n_find_same", "#Particles found in same element")
        self.find_by_neighbor_counter = EventCounter(
            "n_find_neighbor", "#Particles found through neighbor")
        self.find_by_vertex_counter = EventCounter(
            "n_find_by_vertex", "#Particles found by vertex")
        self.find_global_counter = EventCounter(
            "n_find_global", "#Particles found by global search")
示例#10
0
class Pusher(object):
    def __init__(self):
        from pytools.log import IntervalTimer, EventCounter

        self.force_timer = IntervalTimer(
                "t_force",
                "Time spent calculating forces")

    def initialize(self, method):
        self.method = method

    def make_state(self, state):
        return EmptyPusherState()

    def advance_state(self, state):
        return state.pusher_state

    def add_instrumentation(self, mgr, observer):
        mgr.set_constant("pusher", self.__class__.__name__)

        mgr.add_quantity(self.force_timer)

    def upkeep(self, state):
        pass

    def _forces(self, state, velocities, *field_args):
        return self.backend.forces(
                ps=state.particle_state,
                velocities=velocities,
                vis_listener=state.vis_listener,
                *field_args
                )

    def forces(self, state, velocities, *field_args):
        sub_timer = self.force_timer.start_sub_timer()
        forces = self._forces(state, velocities, *field_args)
        sub_timer.stop().submit()
        return forces

    def note_move(self, state, orig, dest, size):
        pass

    def note_change_size(self, state, count):
        pass
示例#11
0
文件: cloud.py 项目: gimac/pyrticle
    def __init__(self, discr, units,
            depositor, pusher,
            dimensions_pos, dimensions_velocity,
            debug=set()):

        self.units = units
        self.discretization = discr
        self.debug = debug

        self.depositor = depositor
        self.pusher = pusher

        self.dimensions_mesh = discr.dimensions
        self.dimensions_pos = dimensions_pos
        self.dimensions_velocity = dimensions_velocity

        dims = (dimensions_pos, dimensions_velocity)

        self.mesh_data = _internal.MeshData(discr.dimensions)
        self.mesh_data.fill_from_hedge(discr)

        # subsystem init
        self.depositor.initialize(self)
        self.pusher.initialize(self)

        # instrumentation
        from pytools.log import IntervalTimer, EventCounter

        self.find_el_timer = IntervalTimer(
                "t_find",
                "Time spent finding new elements")
        self.find_same_counter = EventCounter(
                "n_find_same",
                "#Particles found in same element")
        self.find_by_neighbor_counter = EventCounter(
                "n_find_neighbor",
                "#Particles found through neighbor")
        self.find_by_vertex_counter = EventCounter(
                "n_find_by_vertex",
                "#Particles found by vertex")
        self.find_global_counter = EventCounter(
                "n_find_global",
                "#Particles found by global search")
示例#12
0
    def __init__(self):
        from pytools.log import IntervalTimer, EventCounter

        self.force_timer = IntervalTimer(
                "t_force",
                "Time spent calculating forces")
示例#13
0
class PicMethod(object):
    """
    @arg debug: A set of strings telling what to debug. So far, the
      following debug flags are in use:

      - depositor: Debug the depositor.
      - verbose_vis: Generate E and B fields and force
        visualizations at particle locations.
      - ic: Check the initial condition when it's generated.
      - no_ic: Start with zero fields.
      - discretization: (See driver.py.) Turn on debug mode for the
        discretization.
      - shape_bw: Debug the finding of the optimal shape bandwidth.

      - interactive: Allow debug measures that require user interaction.
      - vis_files: Allow debug measures that write extra visualization
        files.
    """
    def __init__(self,
                 discr,
                 units,
                 depositor,
                 pusher,
                 dimensions_pos,
                 dimensions_velocity,
                 debug=set()):

        self.units = units
        self.discretization = discr
        self.debug = debug

        self.depositor = depositor
        self.pusher = pusher

        self.dimensions_mesh = discr.dimensions
        self.dimensions_pos = dimensions_pos
        self.dimensions_velocity = dimensions_velocity

        dims = (dimensions_pos, dimensions_velocity)

        self.mesh_data = _internal.MeshData(discr.dimensions)
        self.mesh_data.fill_from_hedge(discr)

        # subsystem init
        self.depositor.initialize(self)
        self.pusher.initialize(self)

        # instrumentation
        from pytools.log import IntervalTimer, EventCounter

        self.find_el_timer = IntervalTimer("t_find",
                                           "Time spent finding new elements")
        self.find_same_counter = EventCounter(
            "n_find_same", "#Particles found in same element")
        self.find_by_neighbor_counter = EventCounter(
            "n_find_neighbor", "#Particles found through neighbor")
        self.find_by_vertex_counter = EventCounter(
            "n_find_by_vertex", "#Particles found by vertex")
        self.find_global_counter = EventCounter(
            "n_find_global", "#Particles found by global search")

    def make_state(self):
        state = PicState(self)

        state.particle_number_shift_signaller.subscribe_with_state(
            self.depositor)
        state.particle_number_shift_signaller.subscribe_with_state(self.pusher)

        return state

    def get_dimensionality_suffix(self):
        return "%dd%dv" % (self.dimensions_pos, self.dimensions_velocity)

    def get_shape_function_class(self):
        from pyrticle.tools import \
                PolynomialShapeFunction, \
                CInfinityShapeFunction

        from pyrticle._internal import get_shape_function_name
        name = get_shape_function_name()

        if name == "c_infinity":
            return CInfinityShapeFunction
        elif name == "polynomial":
            return PolynomialShapeFunction
        else:
            raise ValueError, "unknown shape function class"

    def set_ignore_core_warnings(self, ignore):
        from pyrticle.tools import WarningForwarder, WarningIgnorer
        import pyrticle.tools
        del pyrticle.tools.warning_forwarder
        if ignore:
            pyrticle.tools.warning_forwarder = WarningIgnorer()
        else:
            pyrticle.tools.warning_forwarder = WarningForwarder()

    def add_instrumentation(self, mgr, observer):
        mgr.add_quantity(self.find_el_timer)
        mgr.add_quantity(self.find_same_counter)
        mgr.add_quantity(self.find_by_neighbor_counter)
        mgr.add_quantity(self.find_by_vertex_counter)
        mgr.add_quantity(self.find_global_counter)

        self.depositor.add_instrumentation(mgr, observer)
        self.pusher.add_instrumentation(mgr, observer)

    def velocities(self, state):
        try:
            return state.derived_quantity_cache["velocities"]
        except KeyError:
            result = _internal.get_velocities(state.particle_state,
                                              self.units.VACUUM_LIGHT_SPEED())
            state.derived_quantity_cache["velocities"] = result
            return result

    def mean_beta(self, state):
        if len(state):
            return numpy.average(self.velocities(state), axis=0) \
                    / self.units.VACUUM_LIGHT_SPEED()
        else:
            return numpy.zeros((self.dimensions_velocity, ))

    def add_particles(self, state, iterable, maxcount=None):
        """Add the  particles from C{iterable} to the cloud.

        C{iterable} is expected to yield tuples
        C{(position, velocity, charge, mass)}.

        If C{maxcount} is specified, maximally C{maxcount}
        particles are obtained from the iterable.
        """

        pstate = state.particle_state

        if maxcount is not None:
            if pstate.particle_count + maxcount >= len(
                    pstate.containing_elements):
                state.resize(pstate.particle_count + maxcount)

        for pos, vel, charge, mass in iterable:
            if maxcount is not None:
                if maxcount == 0:
                    break
                maxcount -= 1

            assert len(pos) == self.dimensions_pos
            assert len(vel) == self.dimensions_velocity

            pos = numpy.asarray(pos)
            vel = numpy.asarray(vel)
            mom = mass * self.units.gamma_from_v(vel) * vel

            cont_el = self.mesh_data.find_containing_element(pos)
            if cont_el == MeshData.INVALID_ELEMENT:
                print "not in valid element"

                continue

            if pstate.particle_count >= len(pstate.containing_elements):
                state.resize(max(128, 2 * pstate.particle_count))

            pstate.containing_elements[pstate.particle_count] = cont_el
            pstate.positions[pstate.particle_count] = pos
            pstate.momenta[pstate.particle_count] = mom
            pstate.charges[pstate.particle_count] = charge
            pstate.masses[pstate.particle_count] = mass

            pstate.particle_count += 1

        self.check_containment(state)
        state.particle_number_shift_signaller.note_change_size(
            pstate.particle_count)
        state.derived_quantity_cache.clear()

    def check_containment(self, state):
        """Check that a containing element is known for each particle.

        This is a new invariant as of 1/17/08, and violations of this end up
        segfaulting, which we should avoid.
        """
        assert (state.particle_state.containing_elements[:len(state)] !=
                MeshData.INVALID_ELEMENT).all()

    def upkeep(self, state):
        """Perform any operations must fall in between timesteps,
        such as resampling or deleting particles.
        """
        self.depositor.upkeep(state)
        self.pusher.upkeep(state)

        state.vis_listener.clear()

    # deposition ----------------------------------------------------------
    def deposit_densities(self, state):
        """Return a tuple (charge_density, current_densities), where
        current_densities is an d-by-n array, where d is the number
        of velocity dimensions, and n is the discretization nodes.
        """
        def all_getter():
            rho, j = self.depositor.deposit_densities(state, self.velocities())
            j = numpy.asarray(j.T, order="C")
            return rho, j

        return state.get_derived_quantities_from_cache(
            ["rho", "j"], [self.deposit_rho, self.deposit_j], all_getter)

    def deposit_j(self, state):
        """Return a the current densities as an d-by-n array, where d
        is the number of velocity dimensions, and n is the number of
        discretization nodes.
        """
        def j_getter():
            return numpy.asarray(self.depositor.deposit_j(
                state, self.velocities(state)).T,
                                 order="C")

        return state.get_derived_quantity_from_cache("j", j_getter)

    def deposit_rho(self, state):
        """Return a the charge_density as a volume vector."""
        def rho_getter():
            return self.depositor.deposit_rho(state)

        return state.get_derived_quantity_from_cache("rho", rho_getter)

    # time advance ------------------------------------------------------------
    def advance_state(self, state, dx, dp, ddep):
        pstate = state.particle_state
        cnt = pstate.particle_count

        positions = pstate.positions.copy()
        momenta = pstate.momenta.copy()
        positions[:cnt] += dx
        momenta[:cnt] += dp

        new_state = PicState(
            self,
            particle_count=cnt,
            containing_elements=pstate.containing_elements,
            positions=positions,
            momenta=momenta,
            charges=pstate.charges,
            masses=pstate.masses,
            depositor_state=self.depositor.advance_state(state, ddep),
            pusher_state=self.pusher.advance_state(state),
            pnss=state.particle_number_shift_signaller,
            vis_listener=state.vis_listener,
        )

        from pyrticle._internal import FindEventCounters
        find_counters = FindEventCounters()

        class BHitListener(_internal.BoundaryHitListener):
            def note_boundary_hit(subself, pn):
                _internal.kill_particle(
                    new_state.particle_state, pn,
                    new_state.particle_number_shift_signaller)

        from pyrticle._internal import update_containing_elements
        sub_timer = self.find_el_timer.start_sub_timer()
        update_containing_elements(self.mesh_data, new_state.particle_state,
                                   BHitListener(), find_counters)
        sub_timer.stop().submit()

        self.find_same_counter.transfer(find_counters.find_same)
        self.find_by_neighbor_counter.transfer(find_counters.find_by_neighbor)
        self.find_by_vertex_counter.transfer(find_counters.find_by_vertex)
        self.find_global_counter.transfer(find_counters.find_global)

        return new_state

    # visualization -----------------------------------------------------------
    def get_mesh_vis_vars(self):
        return self.vis_listener.mesh_vis_map.items()

    def add_to_vis(self,
                   visualizer,
                   vis_file,
                   state,
                   time=None,
                   step=None,
                   beamaxis=None,
                   vis_listener=None):
        from hedge.visualization import VtkVisualizer, SiloVisualizer
        if isinstance(visualizer, VtkVisualizer):
            return self._add_to_vtk(visualizer, vis_file, state, time, step)
        elif isinstance(visualizer, SiloVisualizer):
            return self._add_to_silo(visualizer, vis_file, state, time, step,
                                     beamaxis, vis_listener)
        else:
            raise ValueError, "unknown visualizer type `%s'" % type(visualizer)

    def _add_to_silo(self,
                     visualizer,
                     db,
                     state,
                     time,
                     step,
                     beamaxis,
                     vis_listener=None):
        from pylo import DBOPT_DTIME, DBOPT_CYCLE
        optlist = {}
        if time is not None:
            optlist[DBOPT_DTIME] = time
        if step is not None:
            optlist[DBOPT_CYCLE] = step

        pcount = len(state)

        if pcount:
            # real-space ------------------------------------------------------
            db.put_pointmesh("particles",
                             numpy.asarray(state.positions.T, order="C"),
                             optlist)
            db.put_pointvar1("charge", "particles", state.charges)
            db.put_pointvar1("mass", "particles", state.masses)
            db.put_pointvar("momentum", "particles",
                            numpy.asarray(state.momenta.T, order="C"))
            db.put_pointvar("velocity", "particles",
                            numpy.asarray(self.velocities(state).T, order="C"))

            if vis_listener is not None:
                for name, value in self.vis_listener.particle_vis_map.iteritems(
                ):
                    from pyrticle.tools import NumberShiftableVector
                    value = NumberShiftableVector.unwrap(value)
                    dim, remainder = divmod(len(value), pcount)
                    assert remainder == 0, (
                        "particle vis value '%s' had invalid number of entries: "
                        "%d (#particles=%d)" % (name, len(value), pcount))
                    if dim == 1:
                        db.put_pointvar1(name, "particles", value)
                    else:
                        db.put_pointvar(name, "particles",
                                        [value[i::dim] for i in range(dim)])

            # phase-space -----------------------------------------------------
            axes_names = ["x", "y", "z"]

            if beamaxis is not None:
                for axis in range(
                        min(self.dimensions_pos, self.dimensions_velocity)):
                    if axis == beamaxis:
                        continue

                    axname = axes_names[axis]

                    db.put_defvars("phasespace_%s" % axname, [
                        ("part_%s" % axname, "coord(particles)[%d]" % axis),
                        ("part_%s_prime" % axname,
                         "momentum[%d]/momentum[%d]" % (axis, beamaxis)),
                        ("part_%s_momentum" % axname, "momentum[%d]" % (axis)),
                    ])
示例#14
0
def main(write_output=True,
         dir_tag=TAG_NONE,
         neu_tag=TAG_NONE,
         rad_tag=TAG_ALL,
         flux_type_arg="upwind"):
    from math import sin, cos, pi, exp, sqrt  # noqa

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 2

    if dim == 1:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_uniform_1d_mesh
            mesh = make_uniform_1d_mesh(-10, 10, 500)
    elif dim == 2:
        from hedge.mesh.generator import make_rect_mesh
        if rcon.is_head_rank:
            mesh = make_rect_mesh(a=(-1, -1), b=(1, 1), max_area=0.003)
    elif dim == 3:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_ball_mesh
            mesh = make_ball_mesh(max_volume=0.0005)
    else:
        raise RuntimeError("bad number of dimensions")

    if rcon.is_head_rank:
        print "%d elements" % len(mesh.elements)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    discr = rcon.make_discretization(mesh_data, order=4)

    from hedge.timestep.runge_kutta import LSRK4TimeStepper
    stepper = LSRK4TimeStepper()

    from hedge.visualization import VtkVisualizer
    if write_output:
        vis = VtkVisualizer(discr, rcon, "fld")

    source_center = np.array([0.7, 0.4])
    source_width = 1 / 16
    source_omega = 3

    import hedge.optemplate as sym
    sym_x = sym.nodes(2)
    sym_source_center_dist = sym_x - source_center

    from hedge.models.wave import VariableVelocityStrongWaveOperator
    op = VariableVelocityStrongWaveOperator(
        c=sym.If(sym.Comparison(np.dot(sym_x, sym_x), "<", 0.4**2), 1, 0.5),
        dimensions=discr.dimensions,
        source=sym.CFunction("sin")(source_omega * sym.ScalarParameter("t")) *
        sym.CFunction("exp")(
            -np.dot(sym_source_center_dist, sym_source_center_dist) /
            source_width**2),
        dirichlet_tag=dir_tag,
        neumann_tag=neu_tag,
        radiation_tag=rad_tag,
        flux_type=flux_type_arg)

    from hedge.tools import join_fields
    fields = join_fields(
        discr.volume_zeros(),
        [discr.volume_zeros() for i in range(discr.dimensions)])

    # {{{ diagnostics setup

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

    if write_output:
        log_file_name = "wave.dat"
    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)

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

    from hedge.log import LpNorm
    u_getter = lambda: fields[0]
    logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u"))
    logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u"))

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

    # }}}

    # {{{ timestep loop

    rhs = op.bind(discr)
    try:
        from hedge.timestep.stability import \
                approximate_rk4_relative_imag_stability_region
        max_dt = (1 / discr.compile(op.max_eigenvalue_expr())() *
                  discr.dt_non_geometric_factor() *
                  discr.dt_geometric_factor() *
                  approximate_rk4_relative_imag_stability_region(stepper))
        if flux_type_arg == "central":
            max_dt *= 0.25

        from hedge.timestep import times_and_steps
        step_it = times_and_steps(final_time=3,
                                  logmgr=logmgr,
                                  max_dt_getter=lambda t: max_dt)

        for step, t, dt in step_it:
            if step % 10 == 0 and write_output:
                visf = vis.make_file("fld-%04d" % step)

                vis.add_data(visf, [
                    ("u", fields[0]),
                    ("v", fields[1:]),
                ],
                             time=t,
                             step=step)
                visf.close()

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

        assert discr.norm(fields) < 1
    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()
示例#15
0
class AdvectiveDepositor(Depositor):
    name = "Advective"

    def __init__(self, activation_threshold=1e-5, kill_threshold=1e-3,
            filter_amp=None, filter_order=None,
            upwind_alpha=1,
            ):
        Depositor.__init__(self)

        self.activation_threshold = activation_threshold
        self.kill_threshold = kill_threshold
        self.upwind_alpha = upwind_alpha

        self.shape_function = None

        self.filter_amp = filter_amp
        self.filter_order = filter_order

        if filter_amp is not None:
            from hedge.discretization import ExponentialFilterResponseFunction
            self.filter_response = ExponentialFilterResponseFunction(
                    filter_amp, filter_order)
        else:
            self.filter_response = None

    def initialize(self, method):
        Depositor.initialize(self, method)

        discr = method.discretization

        eg, = discr.element_groups
        fg, = discr.face_groups
        ldis = eg.local_discretization

        from hedge.mesh import TAG_ALL
        bdry = discr.get_boundary(TAG_ALL)

        bdry_fg, = bdry.face_groups

        if self.filter_response:
            from hedge.discretization import Filter
            filter = Filter(discr, self.filter_response)
            filter_mat, = filter.filter_matrices
        else:
            filter_mat = numpy.zeros((0,0))

        backend_class = getattr(_internal, "AdvectiveDepositor"
                + method.get_dimensionality_suffix())
        self.backend = backend_class(method.mesh_data,
                len(ldis.face_indices()),
                ldis.node_count(),
                ldis.mass_matrix(),
                ldis.inverse_mass_matrix(),
                filter_mat,
                ldis.face_mass_matrix(),
                fg,
                bdry_fg,
                self.activation_threshold,
                self.kill_threshold,
                self.upwind_alpha)

        for i, diffmat in enumerate(ldis.differentiation_matrices()):
            self.backend.add_local_diff_matrix(i, diffmat)

    def make_state(self, state):
        state = self.backend.DepositorState()

        from pyrticle.tools import NumberShiftMultiplexer
        state.rho_dof_shift_listener = NumberShiftMultiplexer(
                name="advective_rho_dofs")

        eg, = self.method.discretization.element_groups
        ldis = eg.local_discretization
        #state.resize_rho(eg.local_discretization.node_count() * 1024)

        return state

    def add_instrumentation(self, mgr, observer):
        Depositor.add_instrumentation(self, mgr, observer)

        # instrumentation
        from pytools.log import IntervalTimer, EventCounter
        self.element_activation_counter = EventCounter(
                "n_el_activations",
                "#Advective rec. elements activated this timestep")
        self.element_kill_counter = EventCounter(
                "n_el_kills",
                "#Advective rec. elements retired this timestep")
        self.advective_rhs_timer = IntervalTimer(
                "t_advective_rhs",
                "Time spent evaluating advective RHS")
        self.active_elements_log = ActiveAdvectiveElements(observer)

        mgr.add_quantity(self.element_activation_counter)
        mgr.add_quantity(self.element_kill_counter)
        mgr.add_quantity(self.advective_rhs_timer)
        mgr.add_quantity(self.active_elements_log)

        mgr.set_constant("el_activation_threshold", self.activation_threshold)
        mgr.set_constant("el_kill_threshold", self.kill_threshold)
        mgr.set_constant("adv_upwind_alpha", self.upwind_alpha)

        mgr.set_constant("filter_amp", self.filter_amp)
        mgr.set_constant("filter_amp", self.filter_order)

    def set_shape_function(self, state, sf):
        Depositor.set_shape_function(self, state, sf)

        state.depositor_state.clear()
        for pn in xrange(len(state)):
            self.backend.add_advective_particle(
                    state.depositor_state,
                    state.particle_state,
                    sf, pn)

    def note_move(self, state, orig, dest, size):
        self.backend.note_move(state.depositor_state, orig, dest, size)

    def note_change_size(self, state, new_size):
        self.backend.note_change_size(state.depositor_state, new_size)

        if (self.shape_function is not None
                and new_size > state.depositor_state.count_advective_particles()):
            for pn in range(
                    state.depositor_state.count_advective_particles(),
                    new_size):
                self.backend.add_advective_particle(
                        state.depositor_state,
                        state.particle_state,
                        self.shape_function, pn)

    def clear_particles(self):
        Depositor.clear_particles(self)
        self.cloud.pic_algorithm.clear_advective_particles()

    def upkeep(self, state):
        self.backend.perform_depositor_upkeep(
                state.depositor_state,
                state.particle_state)

    def rhs(self, state):
        from pyrticle.tools import NumberShiftableVector
        sub_timer = self.advective_rhs_timer.start_sub_timer()
        result =  NumberShiftableVector(
                self.backend.get_advective_particle_rhs(
                    state.depositor_state,
                    state.particle_state,
                    self.method.velocities(state)),
                signaller=state.depositor_state.rho_dof_shift_listener
                )
        sub_timer.stop()
        self.element_activation_counter.transfer(
                state.depositor_state.element_activation_counter)
        self.element_kill_counter.transfer(
                state.depositor_state.element_kill_counter)

        return result

    def advance_state(self, state, rhs):
        # depositor states tend to linger on for a bit--ours here are
        # big, so they need to go.
        from gc import collect
        collect()

        from pyrticle.tools import NumberShiftableVector
        return self.backend.apply_advective_particle_rhs(
                state.depositor_state,
                state.particle_state,
                NumberShiftableVector.unwrap(rhs),
                state.depositor_state.rho_dof_shift_listener)
示例#16
0
def main(write_output=True, allow_features=None):
    from hedge.timestep import RK4TimeStepper
    from hedge.mesh import make_ball_mesh, make_cylinder_mesh, make_box_mesh
    from hedge.visualization import \
            VtkVisualizer, \
            SiloVisualizer, \
            get_rank_partition
    from math import sqrt, pi

    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

    dims = 3

    if rcon.is_head_rank:
        if dims == 2:
            from hedge.mesh import make_rect_mesh
            mesh = make_rect_mesh(
                    a=(-10.5,-1.5),
                    b=(10.5,1.5),
                    max_area=0.1
                    )
        elif dims == 3:
            from hedge.mesh import make_box_mesh
            mesh = make_box_mesh(
                    a=(-10.5,-1.5,-1.5),
                    b=(10.5,1.5,1.5),
                    max_volume=0.1)

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

    #for order in [1,2,3,4,5,6]:
    discr = rcon.make_discretization(mesh_data, order=3)

    if write_output:
        vis = VtkVisualizer(discr, rcon, "dipole")

    from analytic_solutions import DipoleFarField, SphericalFieldAdapter
    from hedge.data import ITimeDependentGivenFunction

    sph_dipole = DipoleFarField(
            q=1, #C
            d=1/39,
            omega=2*pi*1e8,
            epsilon=epsilon0,
            mu=mu0,
            )
    cart_dipole = SphericalFieldAdapter(sph_dipole)

    class PointDipoleSource(ITimeDependentGivenFunction):
        def __init__(self):
            from pyrticle.tools import CInfinityShapeFunction
            sf = CInfinityShapeFunction(
                        0.1*sph_dipole.wavelength,
                        discr.dimensions)
            self.num_sf = discr.interpolate_volume_function(
                    lambda x, el: sf(x))
            self.vol_0 = discr.volume_zeros()

        def volume_interpolant(self, t, discr):
            from hedge.tools import make_obj_array
            return make_obj_array([
                self.vol_0,
                self.vol_0,
                sph_dipole.source_modulation(t)*self.num_sf
                ])

    from hedge.mesh import TAG_ALL, TAG_NONE
    if dims == 2:
        from hedge.models.em import TMMaxwellOperator as MaxwellOperator
    else:
        from hedge.models.em import MaxwellOperator

    op = MaxwellOperator(
            epsilon, mu,
            flux_type=1,
            pec_tag=TAG_NONE,
            absorb_tag=TAG_ALL,
            current=PointDipoleSource(),
            )

    fields = op.assemble_eh(discr=discr)

    if rcon.is_head_rank:
        print "#elements=", len(mesh.elements)

    stepper = RK4TimeStepper()

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

    if write_output:
        log_file_name = "dipole.dat"
    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)

    from pytools.log import PushLogQuantity
    relerr_e_q = PushLogQuantity("relerr_e", "1", "Relative error in masked E-field")
    relerr_h_q = PushLogQuantity("relerr_h", "1", "Relative error in masked H-field")
    logmgr.add_quantity(relerr_e_q)
    logmgr.add_quantity(relerr_h_q)

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

    if write_output:
        point_timeseries = [
                (open("b-x%d-vs-time.dat" % i, "w"), 
                    open("b-x%d-vs-time-true.dat" % i, "w"), 
                    discr.get_point_evaluator(numpy.array([i,0,0][:dims],
                        dtype=discr.default_scalar_type)))
                    for i in range(1,5)
                    ]

    # timestep loop -------------------------------------------------------
    mask = discr.interpolate_volume_function(sph_dipole.far_field_mask)

    def apply_mask(field):
        from hedge.tools import log_shape
        ls = log_shape(field)
        result = discr.volume_empty(ls)
        from pytools import indices_in_shape
        for i in indices_in_shape(ls):
            result[i] = mask * field[i]

        return result

    rhs = op.bind(discr)

    t = 0
    try:
        from hedge.timestep import times_and_steps
        step_it = times_and_steps(
                final_time=1e-8, 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 write_output and step % 10 == 0:
                sub_timer = vis_timer.start_sub_timer()
                e, h = op.split_eh(fields)
                sph_dipole.set_time(t)
                true_e, true_h = op.split_eh(
                        discr.interpolate_volume_function(cart_dipole))
                visf = vis.make_file("dipole-%04d" % step)

                mask_e = apply_mask(e)
                mask_h = apply_mask(h)
                mask_true_e = apply_mask(true_e)
                mask_true_h = apply_mask(true_h)

                from pyvisfile.silo import DB_VARTYPE_VECTOR
                vis.add_data(visf,
                        [ 
                            ("e", e), 
                            ("h", h), 
                            ("true_e", true_e), 
                            ("true_h", true_h), 
                            ("mask_e", mask_e), 
                            ("mask_h", mask_h), 
                            ("mask_true_e", mask_true_e), 
                            ("mask_true_h", mask_true_h)],
                        time=t, step=step)
                visf.close()
                sub_timer.stop().submit()

                from hedge.tools import relative_error
                relerr_e_q.push_value(
                        relative_error(
                            discr.norm(mask_e-mask_true_e),
                            discr.norm(mask_true_e)))
                relerr_h_q.push_value(
                        relative_error(
                            discr.norm(mask_h-mask_true_h),
                            discr.norm(mask_true_h)))

                if write_output:
                    for outf_num, outf_true, evaluator in point_timeseries:
                        for outf, ev_h in zip([outf_num, outf_true],
                                [h, true_h]):
                            outf.write("%g\t%g\n" % (t, op.mu*evaluator(ev_h[1])))
                            outf.flush()

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

    finally:
        if write_output:
            vis.close()

        logmgr.save()
        discr.close()
示例#17
0
class AdvectiveDepositor(Depositor):
    name = "Advective"

    def __init__(
        self,
        activation_threshold=1e-5,
        kill_threshold=1e-3,
        filter_amp=None,
        filter_order=None,
        upwind_alpha=1,
    ):
        Depositor.__init__(self)

        self.activation_threshold = activation_threshold
        self.kill_threshold = kill_threshold
        self.upwind_alpha = upwind_alpha

        self.shape_function = None

        self.filter_amp = filter_amp
        self.filter_order = filter_order

        if filter_amp is not None:
            from hedge.discretization import ExponentialFilterResponseFunction
            self.filter_response = ExponentialFilterResponseFunction(
                filter_amp, filter_order)
        else:
            self.filter_response = None

    def initialize(self, method):
        Depositor.initialize(self, method)

        discr = method.discretization

        eg, = discr.element_groups
        fg, = discr.face_groups
        ldis = eg.local_discretization

        from hedge.mesh import TAG_ALL
        bdry = discr.get_boundary(TAG_ALL)

        bdry_fg, = bdry.face_groups

        if self.filter_response:
            from hedge.discretization import Filter
            filter = Filter(discr, self.filter_response)
            filter_mat, = filter.filter_matrices
        else:
            filter_mat = numpy.zeros((0, 0))

        backend_class = getattr(
            _internal,
            "AdvectiveDepositor" + method.get_dimensionality_suffix())
        self.backend = backend_class(method.mesh_data,
                                     len(ldis.face_indices()),
                                     ldis.node_count(), ldis.mass_matrix(),
                                     ldis.inverse_mass_matrix(), filter_mat,
                                     ldis.face_mass_matrix(), fg, bdry_fg,
                                     self.activation_threshold,
                                     self.kill_threshold, self.upwind_alpha)

        for i, diffmat in enumerate(ldis.differentiation_matrices()):
            self.backend.add_local_diff_matrix(i, diffmat)

    def make_state(self, state):
        state = self.backend.DepositorState()

        from pyrticle.tools import NumberShiftMultiplexer
        state.rho_dof_shift_listener = NumberShiftMultiplexer(
            name="advective_rho_dofs")

        eg, = self.method.discretization.element_groups
        ldis = eg.local_discretization
        #state.resize_rho(eg.local_discretization.node_count() * 1024)

        return state

    def add_instrumentation(self, mgr, observer):
        Depositor.add_instrumentation(self, mgr, observer)

        # instrumentation
        from pytools.log import IntervalTimer, EventCounter
        self.element_activation_counter = EventCounter(
            "n_el_activations",
            "#Advective rec. elements activated this timestep")
        self.element_kill_counter = EventCounter(
            "n_el_kills", "#Advective rec. elements retired this timestep")
        self.advective_rhs_timer = IntervalTimer(
            "t_advective_rhs", "Time spent evaluating advective RHS")
        self.active_elements_log = ActiveAdvectiveElements(observer)

        mgr.add_quantity(self.element_activation_counter)
        mgr.add_quantity(self.element_kill_counter)
        mgr.add_quantity(self.advective_rhs_timer)
        mgr.add_quantity(self.active_elements_log)

        mgr.set_constant("el_activation_threshold", self.activation_threshold)
        mgr.set_constant("el_kill_threshold", self.kill_threshold)
        mgr.set_constant("adv_upwind_alpha", self.upwind_alpha)

        mgr.set_constant("filter_amp", self.filter_amp)
        mgr.set_constant("filter_amp", self.filter_order)

    def set_shape_function(self, state, sf):
        Depositor.set_shape_function(self, state, sf)

        state.depositor_state.clear()
        for pn in xrange(len(state)):
            self.backend.add_advective_particle(state.depositor_state,
                                                state.particle_state, sf, pn)

    def note_move(self, state, orig, dest, size):
        self.backend.note_move(state.depositor_state, orig, dest, size)

    def note_change_size(self, state, new_size):
        self.backend.note_change_size(state.depositor_state, new_size)

        if (self.shape_function is not None and
                new_size > state.depositor_state.count_advective_particles()):
            for pn in range(state.depositor_state.count_advective_particles(),
                            new_size):
                self.backend.add_advective_particle(state.depositor_state,
                                                    state.particle_state,
                                                    self.shape_function, pn)

    def clear_particles(self):
        Depositor.clear_particles(self)
        self.cloud.pic_algorithm.clear_advective_particles()

    def upkeep(self, state):
        self.backend.perform_depositor_upkeep(state.depositor_state,
                                              state.particle_state)

    def rhs(self, state):
        from pyrticle.tools import NumberShiftableVector
        sub_timer = self.advective_rhs_timer.start_sub_timer()
        result = NumberShiftableVector(
            self.backend.get_advective_particle_rhs(
                state.depositor_state, state.particle_state,
                self.method.velocities(state)),
            signaller=state.depositor_state.rho_dof_shift_listener)
        sub_timer.stop()
        self.element_activation_counter.transfer(
            state.depositor_state.element_activation_counter)
        self.element_kill_counter.transfer(
            state.depositor_state.element_kill_counter)

        return result

    def advance_state(self, state, rhs):
        # depositor states tend to linger on for a bit--ours here are
        # big, so they need to go.
        from gc import collect
        collect()

        from pyrticle.tools import NumberShiftableVector
        return self.backend.apply_advective_particle_rhs(
            state.depositor_state, state.particle_state,
            NumberShiftableVector.unwrap(rhs),
            state.depositor_state.rho_dof_shift_listener)
示例#18
0
class PICRunner(object):
    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)

    def add_instrumentation(self, logmgr):
        from pytools.log import \
                add_simulation_quantities, \
                add_general_quantities, \
                add_run_info, ETA
        from pyrticle.log import add_particle_quantities, add_field_quantities, \
                add_beam_quantities, add_currents

        setup = self.setup

        from pyrticle.log import StateObserver
        self.observer = StateObserver(self.method, self.maxwell_op)
        self.observer.set_fields_and_state(self.fields, self.state)

        add_run_info(logmgr)
        add_general_quantities(logmgr)
        add_simulation_quantities(logmgr)
        add_particle_quantities(logmgr, self.observer)
        add_field_quantities(logmgr, self.observer)

        if setup.beam_axis is not None and setup.beam_diag_axis is not None:
            add_beam_quantities(logmgr,
                                self.observer,
                                axis=setup.beam_diag_axis,
                                beam_axis=setup.beam_axis)

        if setup.tube_length is not None:
            from hedge.tools import unit_vector
            add_currents(
                logmgr, self.observer,
                unit_vector(self.method.dimensions_velocity, setup.beam_axis),
                setup.tube_length)

        self.method.add_instrumentation(logmgr, self.observer)

        self.f_rhs_calculator.add_instrumentation(logmgr)

        if hasattr(self.stepper, "add_instrumentation"):
            self.stepper.add_instrumentation(logmgr)

        mean_beta = self.method.mean_beta(self.state)
        gamma = self.method.units.gamma_from_beta(mean_beta)

        logmgr.set_constant("dt", self.dt)
        logmgr.set_constant("beta", mean_beta)
        logmgr.set_constant("gamma", gamma)
        logmgr.set_constant("v", mean_beta * self.units.VACUUM_LIGHT_SPEED())
        logmgr.set_constant("Q0", self.total_charge)
        logmgr.set_constant("n_part_0", setup.nparticles)
        logmgr.set_constant("pmass", setup.distribution.mean()[3][0])
        logmgr.set_constant("chi", setup.chi)
        logmgr.set_constant("phi_decay", setup.phi_decay)
        logmgr.set_constant("shape_radius_setup", setup.shape_bandwidth)
        logmgr.set_constant("shape_radius",
                            self.method.depositor.shape_function.radius)
        logmgr.set_constant("shape_exponent",
                            self.method.depositor.shape_function.exponent)

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

        logmgr.add_quantity(ETA(self.nsteps))

        logmgr.add_watches(setup.watch_vars)

    def inner_run(self):
        t = 0

        setup = self.setup
        setup.hook_startup(self)

        vis_order = setup.vis_order
        if vis_order is None:
            vis_order = setup.element_order

        if vis_order != setup.element_order:
            vis_discr = self.rcon.make_discretization(self.discr.mesh,
                                                      order=vis_order,
                                                      debug=setup.dg_debug)

            from hedge.discretization import Projector
            vis_proj = Projector(self.discr, vis_discr)
        else:
            vis_discr = self.discr

            def vis_proj(f):
                return f

        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(vis_discr)

        fields = self.fields
        self.observer.set_fields_and_state(fields, self.state)

        from hedge.tools import make_obj_array
        from pyrticle.cloud import TimesteppablePicState

        def visualize(observer):
            sub_timer = self.vis_timer.start_sub_timer()
            import os.path
            visf = vis.make_file(
                os.path.join(setup.output_path, setup.vis_pattern % step))

            self.method.add_to_vis(vis,
                                   visf,
                                   observer.state,
                                   time=t,
                                   step=step)
            vis.add_data(
                visf, [(name, vis_proj(fld))
                       for name, fld in setup.hook_vis_quantities(observer)],
                time=t,
                step=step)
            setup.hook_visualize(self, vis, visf, observer)

            visf.close()
            sub_timer.stop().submit()

        from hedge.timestep.multirate_ab import TwoRateAdamsBashforthTimeStepper
        if not isinstance(self.stepper, TwoRateAdamsBashforthTimeStepper):

            def rhs(t, fields_and_state):
                fields, ts_state = fields_and_state
                state_f = lambda: ts_state.state
                fields_f = lambda: fields

                fields_rhs = (self.f_rhs_calculator(t, fields_f, state_f) +
                              self.p2f_rhs_calculator(t, fields_f, state_f))
                state_rhs = (self.p_rhs_calculator(t, fields_f, state_f) +
                             self.f2p_rhs_calculator(t, fields_f, state_f))

                return make_obj_array([fields_rhs, state_rhs])

            step_args = (self.dt, rhs)
        else:

            def add_unwrap(rhs):
                def unwrapping_rhs(t, fields, ts_state):
                    return rhs(t, fields, lambda: ts_state().state)

                return unwrapping_rhs

            step_args = ((
                add_unwrap(self.f_rhs_calculator),
                add_unwrap(self.p2f_rhs_calculator),
                add_unwrap(self.f2p_rhs_calculator),
                add_unwrap(self.p_rhs_calculator),
            ), )

        y = make_obj_array(
            [fields, TimesteppablePicState(self.method, self.state)])
        del self.state

        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(max_steps=self.nsteps,
                                      logmgr=self.logmgr,
                                      max_dt_getter=lambda t: self.dt)

            for step, t, dt in step_it:
                self.method.upkeep(y[1].state)

                if step % setup.vis_interval == 0:
                    visualize(self.observer)

                y = self.stepper(y, t, *step_args)

                fields, ts_state = y
                self.observer.set_fields_and_state(fields, ts_state.state)

                setup.hook_after_step(self, self.observer)
        finally:
            vis.close()
            self.discr.close()
            self.logmgr.save()

        setup.hook_when_done(self)

    def run(self):
        if self.setup.profile_output_filename is not None:
            from cProfile import Profile
            prof = Profile()
            try:
                prof.runcall(self.inner_run)
            finally:
                from lsprofcalltree import KCacheGrind
                kg = KCacheGrind(prof)
                kg.output(open(self.setup.profile_output_filename, "w"))
        else:
            self.inner_run()
示例#19
0
def main(write_output=True,
         dir_tag=TAG_NONE,
         neu_tag=TAG_NONE,
         rad_tag=TAG_ALL,
         flux_type_arg="upwind",
         dtype=np.float64,
         debug=[]):
    from math import sin, cos, pi, exp, sqrt  # noqa

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

    dim = 2

    if dim == 1:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_uniform_1d_mesh
            mesh = make_uniform_1d_mesh(-10, 10, 500)
    elif dim == 2:
        from hedge.mesh.generator import make_rect_mesh
        if rcon.is_head_rank:
            mesh = make_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5), max_area=0.008)
    elif dim == 3:
        if rcon.is_head_rank:
            from hedge.mesh.generator import make_ball_mesh
            mesh = make_ball_mesh(max_volume=0.0005)
    else:
        raise RuntimeError("bad number of dimensions")

    if rcon.is_head_rank:
        print "%d elements" % len(mesh.elements)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    from hedge.timestep.runge_kutta import LSRK4TimeStepper
    stepper = LSRK4TimeStepper(dtype=dtype)

    from hedge.models.wave import StrongWaveOperator
    from hedge.mesh import TAG_ALL, TAG_NONE  # noqa

    source_center = np.array([0.1, 0.22])
    source_width = 0.05
    source_omega = 3

    import hedge.optemplate as sym
    sym_x = sym.nodes(2)
    sym_source_center_dist = sym_x - source_center

    op = StrongWaveOperator(
        -1,
        dim,
        source_f=sym.CFunction("sin")(
            source_omega * sym.ScalarParameter("t")) * sym.CFunction("exp")(
                -np.dot(sym_source_center_dist, sym_source_center_dist) /
                source_width**2),
        dirichlet_tag=dir_tag,
        neumann_tag=neu_tag,
        radiation_tag=rad_tag,
        flux_type=flux_type_arg)

    discr = rcon.make_discretization(mesh_data,
                                     order=4,
                                     debug=debug,
                                     default_scalar_type=dtype,
                                     tune_for=op.op_template())

    from hedge.visualization import VtkVisualizer
    if write_output:
        vis = VtkVisualizer(discr, rcon, "fld")

    from hedge.tools import join_fields
    fields = join_fields(
        discr.volume_zeros(dtype=dtype),
        [discr.volume_zeros(dtype=dtype) for i in range(discr.dimensions)])

    # {{{ diagnostics setup

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

    if write_output:
        log_file_name = "wave.dat"
    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)

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

    from hedge.log import LpNorm
    u_getter = lambda: fields[0]
    logmgr.add_quantity(LpNorm(u_getter, discr, 1, name="l1_u"))
    logmgr.add_quantity(LpNorm(u_getter, discr, name="l2_u"))

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

    # }}}

    # {{{ timestep loop

    rhs = op.bind(discr)
    try:
        from hedge.timestep import times_and_steps
        step_it = times_and_steps(
            final_time=4,
            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 % 10 == 0 and write_output:
                visf = vis.make_file("fld-%04d" % step)

                vis.add_data(visf, [
                    ("u", discr.convert_volume(fields[0], kind="numpy")),
                    ("v", discr.convert_volume(fields[1:], kind="numpy")),
                ],
                             time=t,
                             step=step)
                visf.close()

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

        assert discr.norm(fields) < 1
        assert fields[0].dtype == dtype

    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()
示例#20
0
def mpi_communication_entrypoint():
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

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

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

    dim = 2
    dt = 0.04
    order = 4

    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=(16, ) * dim)

        part_per_element = get_partition_by_pymetis(mesh, num_parts)

        local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element,
                                               num_parts)
    else:
        local_mesh = mesh_dist.receive_mesh_part()

    vol_discr = DGDiscretizationWithBoundaries(cl_ctx,
                                               local_mesh,
                                               order=order,
                                               mpi_communicator=comm)

    source_center = np.array([0.1, 0.22, 0.33])[:local_mesh.dim]
    source_width = 0.05
    source_omega = 3

    sym_x = sym.nodes(local_mesh.dim)
    sym_source_center_dist = sym_x - source_center
    sym_t = sym.ScalarVariable("t")

    from grudge.models.wave import StrongWaveOperator
    from meshmode.mesh import BTAG_ALL, BTAG_NONE
    op = StrongWaveOperator(
        -0.1,
        vol_discr.dim,
        source_f=(
            sym.sin(source_omega * sym_t) *
            sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) /
                    source_width**2)),
        dirichlet_tag=BTAG_NONE,
        neumann_tag=BTAG_NONE,
        radiation_tag=BTAG_ALL,
        flux_type="upwind")

    from pytools.obj_array import join_fields
    fields = join_fields(
        vol_discr.zeros(queue),
        [vol_discr.zeros(queue) for i in range(vol_discr.dim)])

    # FIXME
    # dt = op.estimate_rk4_timestep(vol_discr, fields=fields)

    # FIXME: Should meshmode consider BTAG_PARTITION to be a boundary?
    #           Fails because: "found faces without boundary conditions"
    # op.check_bc_coverage(local_mesh)

    from pytools.log import LogManager, \
            add_general_quantities, \
            add_run_info, \
            IntervalTimer, EventCounter
    log_filename = None
    # NOTE: LogManager hangs when using a file on a shared directory.
    # log_filename = 'grudge_log.dat'
    logmgr = LogManager(log_filename, "w", comm)
    add_run_info(logmgr)
    add_general_quantities(logmgr)
    log_quantities =\
        {"rank_data_swap_timer": IntervalTimer("rank_data_swap_timer",
        "Time spent evaluating RankDataSwapAssign"),
        "rank_data_swap_counter": EventCounter("rank_data_swap_counter",
        "Number of RankDataSwapAssign instructions evaluated"),
        "exec_timer": IntervalTimer("exec_timer",
        "Total time spent executing instructions"),
        "insn_eval_timer": IntervalTimer("insn_eval_timer",
        "Time spend evaluating instructions"),
        "future_eval_timer": IntervalTimer("future_eval_timer",
        "Time spent evaluating futures"),
        "busy_wait_timer": IntervalTimer("busy_wait_timer",
        "Time wasted doing busy wait")}
    for quantity in log_quantities.values():
        logmgr.add_quantity(quantity)

    # print(sym.pretty(op.sym_operator()))
    bound_op = bind(vol_discr, op.sym_operator())

    # print(bound_op)
    # 1/0

    def rhs(t, w):
        val, rhs.profile_data = bound_op(queue,
                                         profile_data=rhs.profile_data,
                                         log_quantities=log_quantities,
                                         t=t,
                                         w=w)
        return val

    rhs.profile_data = {}

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

    final_t = 4
    nsteps = int(final_t / dt)
    print("rank=%d dt=%g nsteps=%d" % (i_local_rank, dt, nsteps))

    # from grudge.shortcuts import make_visualizer
    # vis = make_visualizer(vol_discr, vis_order=order)

    step = 0

    norm = bind(vol_discr, sym.norm(2, sym.var("u")))

    from time import time
    t_last_step = time()

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

            step += 1
            print(step, event.t, norm(queue, u=event.state_component[0]),
                  time() - t_last_step)

            # if step % 10 == 0:
            #     vis.write_vtk_file("rank%d-fld-%04d.vtu" % (i_local_rank, step),
            #                        [("u", event.state_component[0]),
            #                         ("v", event.state_component[1:])])
            t_last_step = time()
            logmgr.tick_after()
            logmgr.tick_before()
    logmgr.tick_after()

    def print_profile_data(data):
        print("""execute() for rank %d:
            \tInstruction Evaluation: %f%%
            \tFuture Evaluation: %f%%
            \tBusy Wait: %f%%
            \tTotal: %f seconds""" %
              (i_local_rank, data['insn_eval_time'] / data['total_time'] * 100,
               data['future_eval_time'] / data['total_time'] * 100,
               data['busy_wait_time'] / data['total_time'] * 100,
               data['total_time']))

    print_profile_data(rhs.profile_data)
    logmgr.close()
    logger.debug("Rank %d exiting", i_local_rank)
示例#21
0
def main(write_output=True):
    from math import sqrt, pi, exp
    from os.path import join

    from grudge.backends import guess_run_context
    rcon = guess_run_context()

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

    output_dir = "maxwell-2d"
    import os
    if not os.access(output_dir, os.F_OK):
        os.makedirs(output_dir)

    from grudge.mesh.generator import make_disk_mesh
    mesh = make_disk_mesh(r=0.5, max_area=1e-3)

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

    class CurrentSource:
        shape = (3, )

        def __call__(self, x, el):
            return [0, 0, exp(-80 * la.norm(x))]

    order = 3
    final_time = 1e-8
    discr = rcon.make_discretization(mesh_data,
                                     order=order,
                                     debug=["cuda_no_plan"])

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

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

    from grudge.mesh import BTAG_ALL, BTAG_NONE
    from grudge.models.em import TMMaxwellOperator
    from grudge.data import make_tdep_given, TimeIntervalGivenFunction
    op = TMMaxwellOperator(epsilon,
                           mu,
                           flux_type=1,
                           current=TimeIntervalGivenFunction(
                               make_tdep_given(CurrentSource()),
                               off_time=final_time / 10),
                           absorb_tag=BTAG_ALL,
                           pec_tag=BTAG_NONE)
    fields = op.assemble_eh(discr=discr)

    from grudge.timestep import LSRK4TimeStepper
    stepper = LSRK4TimeStepper()
    from time import time
    last_tstep = time()
    t = 0

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

    if write_output:
        log_file_name = join(output_dir, "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 grudge.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)

    try:
        from grudge.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 % 10 == 0 and write_output:
                e, h = op.split_eh(fields)
                visf = vis.make_file(
                    join(output_dir, "em-%d-%04d" % (order, step)))
                vis.add_data(visf, [
                    ("e", discr.convert_volume(e, "numpy")),
                    ("h", discr.convert_volume(h, "numpy")),
                ],
                             time=t,
                             step=step)
                visf.close()

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

        assert discr.norm(fields) < 0.03
    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()
示例#22
0
 def make_timer(self, name, description=None):
     from pytools.log import IntervalTimer
     return IntervalTimer(name, description)
示例#23
0
    def add_instrumentation(self, logmgr):
        from pytools.log import \
                add_simulation_quantities, \
                add_general_quantities, \
                add_run_info, ETA
        from pyrticle.log import add_particle_quantities, add_field_quantities, \
                add_beam_quantities, add_currents

        setup = self.setup

        from pyrticle.log import StateObserver
        self.observer = StateObserver(self.method, self.maxwell_op)
        self.observer.set_fields_and_state(self.fields, self.state)

        add_run_info(logmgr)
        add_general_quantities(logmgr)
        add_simulation_quantities(logmgr)
        add_particle_quantities(logmgr, self.observer)
        add_field_quantities(logmgr, self.observer)

        if setup.beam_axis is not None and setup.beam_diag_axis is not None:
            add_beam_quantities(logmgr,
                                self.observer,
                                axis=setup.beam_diag_axis,
                                beam_axis=setup.beam_axis)

        if setup.tube_length is not None:
            from hedge.tools import unit_vector
            add_currents(
                logmgr, self.observer,
                unit_vector(self.method.dimensions_velocity, setup.beam_axis),
                setup.tube_length)

        self.method.add_instrumentation(logmgr, self.observer)

        self.f_rhs_calculator.add_instrumentation(logmgr)

        if hasattr(self.stepper, "add_instrumentation"):
            self.stepper.add_instrumentation(logmgr)

        mean_beta = self.method.mean_beta(self.state)
        gamma = self.method.units.gamma_from_beta(mean_beta)

        logmgr.set_constant("dt", self.dt)
        logmgr.set_constant("beta", mean_beta)
        logmgr.set_constant("gamma", gamma)
        logmgr.set_constant("v", mean_beta * self.units.VACUUM_LIGHT_SPEED())
        logmgr.set_constant("Q0", self.total_charge)
        logmgr.set_constant("n_part_0", setup.nparticles)
        logmgr.set_constant("pmass", setup.distribution.mean()[3][0])
        logmgr.set_constant("chi", setup.chi)
        logmgr.set_constant("phi_decay", setup.phi_decay)
        logmgr.set_constant("shape_radius_setup", setup.shape_bandwidth)
        logmgr.set_constant("shape_radius",
                            self.method.depositor.shape_function.radius)
        logmgr.set_constant("shape_exponent",
                            self.method.depositor.shape_function.exponent)

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

        logmgr.add_quantity(ETA(self.nsteps))

        logmgr.add_watches(setup.watch_vars)
示例#24
0
文件: cloud.py 项目: gimac/pyrticle
class PicMethod(object):
    """
    @arg debug: A set of strings telling what to debug. So far, the
      following debug flags are in use:

      - depositor: Debug the depositor.
      - verbose_vis: Generate E and B fields and force
        visualizations at particle locations.
      - ic: Check the initial condition when it's generated.
      - no_ic: Start with zero fields.
      - discretization: (See driver.py.) Turn on debug mode for the
        discretization.
      - shape_bw: Debug the finding of the optimal shape bandwidth.

      - interactive: Allow debug measures that require user interaction.
      - vis_files: Allow debug measures that write extra visualization
        files.
    """

    def __init__(self, discr, units,
            depositor, pusher,
            dimensions_pos, dimensions_velocity,
            debug=set()):

        self.units = units
        self.discretization = discr
        self.debug = debug

        self.depositor = depositor
        self.pusher = pusher

        self.dimensions_mesh = discr.dimensions
        self.dimensions_pos = dimensions_pos
        self.dimensions_velocity = dimensions_velocity

        dims = (dimensions_pos, dimensions_velocity)

        self.mesh_data = _internal.MeshData(discr.dimensions)
        self.mesh_data.fill_from_hedge(discr)

        # subsystem init
        self.depositor.initialize(self)
        self.pusher.initialize(self)

        # instrumentation
        from pytools.log import IntervalTimer, EventCounter

        self.find_el_timer = IntervalTimer(
                "t_find",
                "Time spent finding new elements")
        self.find_same_counter = EventCounter(
                "n_find_same",
                "#Particles found in same element")
        self.find_by_neighbor_counter = EventCounter(
                "n_find_neighbor",
                "#Particles found through neighbor")
        self.find_by_vertex_counter = EventCounter(
                "n_find_by_vertex",
                "#Particles found by vertex")
        self.find_global_counter = EventCounter(
                "n_find_global",
                "#Particles found by global search")


    def make_state(self):
        state = PicState(self)

        state.particle_number_shift_signaller.subscribe_with_state(self.depositor)
        state.particle_number_shift_signaller.subscribe_with_state(self.pusher)

        return state

    def get_dimensionality_suffix(self):
        return "%dd%dv" % (self.dimensions_pos, self.dimensions_velocity)

    def get_shape_function_class(self):
        from pyrticle.tools import \
                PolynomialShapeFunction, \
                CInfinityShapeFunction

        from pyrticle._internal import get_shape_function_name
        name = get_shape_function_name()

        if name == "c_infinity":
            return CInfinityShapeFunction
        elif name == "polynomial":
            return PolynomialShapeFunction
        else:
            raise ValueError, "unknown shape function class"

    def set_ignore_core_warnings(self, ignore):
        from pyrticle.tools import WarningForwarder, WarningIgnorer
        import pyrticle.tools
        del pyrticle.tools.warning_forwarder
        if ignore:
            pyrticle.tools.warning_forwarder = WarningIgnorer()
        else:
            pyrticle.tools.warning_forwarder = WarningForwarder()

    def add_instrumentation(self, mgr, observer):
        mgr.add_quantity(self.find_el_timer)
        mgr.add_quantity(self.find_same_counter)
        mgr.add_quantity(self.find_by_neighbor_counter)
        mgr.add_quantity(self.find_by_vertex_counter)
        mgr.add_quantity(self.find_global_counter)

        self.depositor.add_instrumentation(mgr, observer)
        self.pusher.add_instrumentation(mgr, observer)

    def velocities(self, state):
        try:
            return state.derived_quantity_cache["velocities"]
        except KeyError:
            result = _internal.get_velocities(
                    state.particle_state, self.units.VACUUM_LIGHT_SPEED())
            state.derived_quantity_cache["velocities"] = result
            return result

    def mean_beta(self, state):
        if len(state):
            return numpy.average(self.velocities(state), axis=0) \
                    / self.units.VACUUM_LIGHT_SPEED()
        else:
            return numpy.zeros((self.dimensions_velocity,))

    def add_particles(self, state, iterable, maxcount=None):
        """Add the  particles from C{iterable} to the cloud.

        C{iterable} is expected to yield tuples
        C{(position, velocity, charge, mass)}.

        If C{maxcount} is specified, maximally C{maxcount}
        particles are obtained from the iterable.
        """

        pstate = state.particle_state

        if maxcount is not None:
            if pstate.particle_count+maxcount >= len(pstate.containing_elements):
                state.resize(pstate.particle_count+maxcount)

        for pos, vel, charge, mass in iterable:
            if maxcount is not None:
                if maxcount == 0:
                    break
                maxcount -= 1

            assert len(pos) == self.dimensions_pos
            assert len(vel) == self.dimensions_velocity

            pos = numpy.asarray(pos)
            vel = numpy.asarray(vel)
            mom = mass*self.units.gamma_from_v(vel)*vel

            cont_el = self.mesh_data.find_containing_element(pos)
            if cont_el == MeshData.INVALID_ELEMENT:
                print "not in valid element"

                continue

            if pstate.particle_count >= len(pstate.containing_elements):
                state.resize(max(128, 2*pstate.particle_count))

            pstate.containing_elements[pstate.particle_count] = cont_el
            pstate.positions[pstate.particle_count] = pos
            pstate.momenta[pstate.particle_count] = mom
            pstate.charges[pstate.particle_count] = charge
            pstate.masses[pstate.particle_count] = mass

            pstate.particle_count += 1

        self.check_containment(state)
        state.particle_number_shift_signaller.note_change_size(
                pstate.particle_count)
        state.derived_quantity_cache.clear()

    def check_containment(self, state):
        """Check that a containing element is known for each particle.

        This is a new invariant as of 1/17/08, and violations of this end up
        segfaulting, which we should avoid.
        """
        assert (state.particle_state.containing_elements[:len(state)]
                != MeshData.INVALID_ELEMENT).all()

    def upkeep(self, state):
        """Perform any operations must fall in between timesteps,
        such as resampling or deleting particles.
        """
        self.depositor.upkeep(state)
        self.pusher.upkeep(state)

        state.vis_listener.clear()



    # deposition ----------------------------------------------------------
    def deposit_densities(self, state):
        """Return a tuple (charge_density, current_densities), where
        current_densities is an d-by-n array, where d is the number
        of velocity dimensions, and n is the discretization nodes.
        """
        def all_getter():
            rho, j = self.depositor.deposit_densities(state, self.velocities())
            j = numpy.asarray(j.T, order="C")
            return rho, j

        return state.get_derived_quantities_from_cache(
                ["rho", "j"],
                [self.deposit_rho, self.deposit_j],
                all_getter)

    def deposit_j(self, state):
        """Return a the current densities as an d-by-n array, where d
        is the number of velocity dimensions, and n is the number of
        discretization nodes.
        """

        def j_getter():
            return numpy.asarray(
                    self.depositor.deposit_j(
                        state, self.velocities(state))
                    .T, order="C")

        return state.get_derived_quantity_from_cache("j", j_getter)

    def deposit_rho(self, state):
        """Return a the charge_density as a volume vector."""

        def rho_getter():
            return self.depositor.deposit_rho(state)

        return state.get_derived_quantity_from_cache("rho", rho_getter)




    # time advance ------------------------------------------------------------
    def advance_state(self, state, dx, dp, ddep):
        pstate = state.particle_state
        cnt = pstate.particle_count

        positions = pstate.positions.copy()
        momenta = pstate.momenta.copy()
        positions[:cnt] += dx
        momenta[:cnt] += dp

        new_state = PicState(
                self,
                particle_count=cnt,
                containing_elements=pstate.containing_elements,
                positions=positions,
                momenta=momenta,
                charges=pstate.charges,
                masses=pstate.masses,
                depositor_state=self.depositor.advance_state(
                    state, ddep),
                pusher_state=self.pusher.advance_state(state),
                pnss=state.particle_number_shift_signaller,
                vis_listener=state.vis_listener,
                )

        from pyrticle._internal import FindEventCounters
        find_counters = FindEventCounters()

        class BHitListener(_internal.BoundaryHitListener):
            def note_boundary_hit(subself, pn):
                _internal.kill_particle(
                        new_state.particle_state,
                        pn, new_state.particle_number_shift_signaller)

        from pyrticle._internal import update_containing_elements
        sub_timer = self.find_el_timer.start_sub_timer()
        update_containing_elements(
                self.mesh_data, new_state.particle_state,
                BHitListener(), find_counters)
        sub_timer.stop().submit()

        self.find_same_counter.transfer(
                find_counters.find_same)
        self.find_by_neighbor_counter.transfer(
                find_counters.find_by_neighbor)
        self.find_by_vertex_counter.transfer(
                find_counters.find_by_vertex)
        self.find_global_counter.transfer(
                find_counters.find_global)

        return new_state

    # visualization -----------------------------------------------------------
    def get_mesh_vis_vars(self):
        return self.vis_listener.mesh_vis_map.items()

    def add_to_vis(self, visualizer, vis_file, state, time=None, step=None, beamaxis=None,
            vis_listener=None):
        from hedge.visualization import VtkVisualizer, SiloVisualizer
        if isinstance(visualizer, VtkVisualizer):
            return self._add_to_vtk(visualizer, vis_file, state, time, step)
        elif isinstance(visualizer, SiloVisualizer):
            return self._add_to_silo(visualizer, vis_file, state, time, step, beamaxis, vis_listener)
        else:
            raise ValueError, "unknown visualizer type `%s'" % type(visualizer)

    def _add_to_silo(self, visualizer, db, state, time, step, beamaxis, vis_listener=None):
        from pylo import DBOPT_DTIME, DBOPT_CYCLE
        optlist = {}
        if time is not None:
            optlist[DBOPT_DTIME] = time
        if step is not None:
            optlist[DBOPT_CYCLE] = step

        pcount = len(state)

        if pcount:
            # real-space ------------------------------------------------------
            db.put_pointmesh("particles",
                    numpy.asarray(state.positions.T, order="C"), optlist)
            db.put_pointvar1("charge", "particles", state.charges)
            db.put_pointvar1("mass", "particles", state.masses)
            db.put_pointvar("momentum", "particles",
                    numpy.asarray(state.momenta.T, order="C"))
            db.put_pointvar("velocity", "particles",
                    numpy.asarray(self.velocities(state).T, order="C"))

            if vis_listener is not None:
                for name, value in self.vis_listener.particle_vis_map.iteritems():
                    from pyrticle.tools import NumberShiftableVector
                    value = NumberShiftableVector.unwrap(value)
                    dim, remainder = divmod(len(value), pcount)
                    assert remainder == 0, (
                            "particle vis value '%s' had invalid number of entries: "
                            "%d (#particles=%d)" % (name, len(value), pcount))
                    if dim == 1:
                        db.put_pointvar1(name, "particles", value)
                    else:
                        db.put_pointvar(name, "particles", [value[i::dim] for i in range(dim)])

            # phase-space -----------------------------------------------------
            axes_names = ["x", "y", "z"]

            if beamaxis is not None:
                for axis in range(min(self.dimensions_pos, self.dimensions_velocity)):
                    if axis == beamaxis:
                        continue

                    axname = axes_names[axis]

                    db.put_defvars("phasespace_%s" % axname,
                            [
                            ("part_%s" % axname, "coord(particles)[%d]" % axis),
                            ("part_%s_prime" % axname,
                                "momentum[%d]/momentum[%d]" % (axis, beamaxis)),
                            ("part_%s_momentum" % axname,
                                "momentum[%d]" % (axis)),
                            ])
示例#25
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
示例#26
0
def simple_wave_entrypoint(dim=2,
                           num_elems=256,
                           order=4,
                           num_steps=30,
                           log_filename="grudge.dat"):
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    from mpi4py import MPI
    comm = MPI.COMM_WORLD
    num_parts = comm.Get_size()
    n = int(num_elems**(1. / dim))

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

    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=(n, ) * dim)

        from pymetis import part_graph
        _, p = part_graph(num_parts,
                          xadj=mesh.nodal_adjacency.neighbors_starts.tolist(),
                          adjncy=mesh.nodal_adjacency.neighbors.tolist())
        part_per_element = np.array(p)

        local_mesh = mesh_dist.send_mesh_parts(mesh, part_per_element,
                                               num_parts)
    else:
        local_mesh = mesh_dist.receive_mesh_part()

    vol_discr = DGDiscretizationWithBoundaries(cl_ctx,
                                               local_mesh,
                                               order=order,
                                               mpi_communicator=comm)

    source_center = np.array([0.1, 0.22, 0.33])[:local_mesh.dim]
    source_width = 0.05
    source_omega = 3

    sym_x = sym.nodes(local_mesh.dim)
    sym_source_center_dist = sym_x - source_center
    sym_t = sym.ScalarVariable("t")

    from grudge.models.wave import StrongWaveOperator
    from meshmode.mesh import BTAG_ALL, BTAG_NONE
    op = StrongWaveOperator(
        -0.1,
        vol_discr.dim,
        source_f=(
            sym.sin(source_omega * sym_t) *
            sym.exp(-np.dot(sym_source_center_dist, sym_source_center_dist) /
                    source_width**2)),
        dirichlet_tag=BTAG_NONE,
        neumann_tag=BTAG_NONE,
        radiation_tag=BTAG_ALL,
        flux_type="upwind")

    from pytools.obj_array import join_fields
    fields = join_fields(
        vol_discr.zeros(queue),
        [vol_discr.zeros(queue) for i in range(vol_discr.dim)])

    from pytools.log import LogManager, \
            add_general_quantities, \
            add_run_info, \
            IntervalTimer, EventCounter
    # NOTE: LogManager hangs when using a file on a shared directory.
    logmgr = LogManager(log_filename, "w", comm)
    add_run_info(logmgr)
    add_general_quantities(logmgr)
    log_quantities =\
        {"rank_data_swap_timer": IntervalTimer("rank_data_swap_timer",
                        "Time spent evaluating RankDataSwapAssign"),
        "rank_data_swap_counter": EventCounter("rank_data_swap_counter",
                        "Number of RankDataSwapAssign instructions evaluated"),
        "exec_timer": IntervalTimer("exec_timer",
                        "Total time spent executing instructions"),
        "insn_eval_timer": IntervalTimer("insn_eval_timer",
                        "Time spend evaluating instructions"),
        "future_eval_timer": IntervalTimer("future_eval_timer",
                        "Time spent evaluating futures"),
        "busy_wait_timer": IntervalTimer("busy_wait_timer",
                        "Time wasted doing busy wait")}
    for quantity in log_quantities.values():
        logmgr.add_quantity(quantity)

    bound_op = bind(vol_discr, op.sym_operator())

    def rhs(t, w):
        val, rhs.profile_data = bound_op(queue,
                                         profile_data=rhs.profile_data,
                                         log_quantities=log_quantities,
                                         t=t,
                                         w=w)
        return val

    rhs.profile_data = {}

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

    logmgr.tick_before()
    for event in dt_stepper.run(t_end=dt * num_steps):
        if isinstance(event, dt_stepper.StateComputed):
            logmgr.tick_after()
            logmgr.tick_before()
    logmgr.tick_after()

    def print_profile_data(data):
        print("""execute() for rank %d:
            \tInstruction Evaluation: %f%%
            \tFuture Evaluation: %f%%
            \tBusy Wait: %f%%
            \tTotal: %f seconds""" %
              (comm.Get_rank(), data['insn_eval_time'] / data['total_time'] *
               100, data['future_eval_time'] / data['total_time'] * 100,
               data['busy_wait_time'] / data['total_time'] * 100,
               data['total_time']))

    print_profile_data(rhs.profile_data)
    logmgr.close()
示例#27
0
文件: driver.py 项目: gimac/pyrticle
class PICRunner(object):
    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)

    def add_instrumentation(self, logmgr):
        from pytools.log import \
                add_simulation_quantities, \
                add_general_quantities, \
                add_run_info, ETA
        from pyrticle.log import add_particle_quantities, add_field_quantities, \
                add_beam_quantities, add_currents

        setup = self.setup

        from pyrticle.log import StateObserver
        self.observer = StateObserver(self.method, self.maxwell_op)
        self.observer.set_fields_and_state(self.fields, self.state)

        add_run_info(logmgr)
        add_general_quantities(logmgr)
        add_simulation_quantities(logmgr)
        add_particle_quantities(logmgr, self.observer)
        add_field_quantities(logmgr, self.observer)

        if setup.beam_axis is not None and setup.beam_diag_axis is not None:
            add_beam_quantities(logmgr, self.observer, 
                    axis=setup.beam_diag_axis, 
                    beam_axis=setup.beam_axis)

        if setup.tube_length is not None:
            from hedge.tools import unit_vector
            add_currents(logmgr, self.observer, 
                    unit_vector(self.method.dimensions_velocity, setup.beam_axis), 
                    setup.tube_length)

        self.method.add_instrumentation(logmgr, self.observer)

        self.f_rhs_calculator.add_instrumentation(logmgr)

        if hasattr(self.stepper, "add_instrumentation"):
            self.stepper.add_instrumentation(logmgr)

        mean_beta = self.method.mean_beta(self.state)
        gamma = self.method.units.gamma_from_beta(mean_beta)

        logmgr.set_constant("dt", self.dt)
        logmgr.set_constant("beta", mean_beta)
        logmgr.set_constant("gamma", gamma)
        logmgr.set_constant("v", mean_beta*self.units.VACUUM_LIGHT_SPEED())
        logmgr.set_constant("Q0", self.total_charge)
        logmgr.set_constant("n_part_0", setup.nparticles)
        logmgr.set_constant("pmass", setup.distribution.mean()[3][0])
        logmgr.set_constant("chi", setup.chi)
        logmgr.set_constant("phi_decay", setup.phi_decay)
        logmgr.set_constant("shape_radius_setup", setup.shape_bandwidth)
        logmgr.set_constant("shape_radius", self.method.depositor.shape_function.radius)
        logmgr.set_constant("shape_exponent", self.method.depositor.shape_function.exponent)

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

        logmgr.add_quantity(ETA(self.nsteps))

        logmgr.add_watches(setup.watch_vars)

    def inner_run(self): 
        t = 0
        
        setup = self.setup
        setup.hook_startup(self)

        vis_order = setup.vis_order
        if vis_order is None:
            vis_order = setup.element_order

        if vis_order != setup.element_order:
            vis_discr = self.rcon.make_discretization(self.discr.mesh, 
                            order=vis_order, debug=setup.dg_debug)

            from hedge.discretization import Projector
            vis_proj = Projector(self.discr, vis_discr)
        else:
            vis_discr = self.discr

            def vis_proj(f):
                return f

        from hedge.visualization import SiloVisualizer
        vis = SiloVisualizer(vis_discr)

        fields = self.fields
        self.observer.set_fields_and_state(fields, self.state)

        from hedge.tools import make_obj_array
        from pyrticle.cloud import TimesteppablePicState

        def visualize(observer):
            sub_timer = self.vis_timer.start_sub_timer()
            import os.path
            visf = vis.make_file(os.path.join(
                setup.output_path, setup.vis_pattern % step))

            self.method.add_to_vis(vis, visf, observer.state, time=t, step=step)
            vis.add_data(visf, 
                    [(name, vis_proj(fld))
                        for name, fld in setup.hook_vis_quantities(observer)],
                    time=t, step=step)
            setup.hook_visualize(self, vis, visf, observer)

            visf.close()
            sub_timer.stop().submit()

        from hedge.timestep.multirate_ab import TwoRateAdamsBashforthTimeStepper 
        if not isinstance(self.stepper, TwoRateAdamsBashforthTimeStepper): 
            def rhs(t, fields_and_state):
                fields, ts_state = fields_and_state
                state_f = lambda: ts_state.state
                fields_f = lambda: fields

                fields_rhs = (
                        self.f_rhs_calculator(t, fields_f, state_f)
                        + self.p2f_rhs_calculator(t, fields_f, state_f))
                state_rhs = (
                        self.p_rhs_calculator(t, fields_f, state_f)
                        + self.f2p_rhs_calculator(t, fields_f, state_f))

                return make_obj_array([fields_rhs, state_rhs])
            step_args = (self.dt, rhs)
        else:
            def add_unwrap(rhs):
                def unwrapping_rhs(t, fields, ts_state):
                    return rhs(t, fields, lambda: ts_state().state)
                return unwrapping_rhs

            step_args = ((
                    add_unwrap(self.f_rhs_calculator),
                    add_unwrap(self.p2f_rhs_calculator),
                    add_unwrap(self.f2p_rhs_calculator),
                    add_unwrap(self.p_rhs_calculator),
                    ),)

        y = make_obj_array([
            fields, 
            TimesteppablePicState(self.method, self.state)
            ])
        del self.state

        try:
            from hedge.timestep import times_and_steps
            step_it = times_and_steps(
                    max_steps=self.nsteps,
                    logmgr=self.logmgr,
                    max_dt_getter=lambda t: self.dt)

            for step, t, dt in step_it:
                self.method.upkeep(y[1].state)

                if step % setup.vis_interval == 0:
                    visualize(self.observer)

                y = self.stepper(y, t, *step_args)

                fields, ts_state = y
                self.observer.set_fields_and_state(fields, ts_state.state)

                setup.hook_after_step(self, self.observer)
        finally:
            vis.close()
            self.discr.close()
            self.logmgr.save()

        setup.hook_when_done(self)

    def run(self):
        if self.setup.profile_output_filename is not None:
            from cProfile import Profile
            prof = Profile()
            try:
                prof.runcall(self.inner_run)
            finally:
                from lsprofcalltree import KCacheGrind
                kg = KCacheGrind(prof)
                kg.output(open(self.setup.profile_output_filename, "w"))
        else:
            self.inner_run()
示例#28
0
文件: driver.py 项目: gimac/pyrticle
    def add_instrumentation(self, logmgr):
        from pytools.log import \
                add_simulation_quantities, \
                add_general_quantities, \
                add_run_info, ETA
        from pyrticle.log import add_particle_quantities, add_field_quantities, \
                add_beam_quantities, add_currents

        setup = self.setup

        from pyrticle.log import StateObserver
        self.observer = StateObserver(self.method, self.maxwell_op)
        self.observer.set_fields_and_state(self.fields, self.state)

        add_run_info(logmgr)
        add_general_quantities(logmgr)
        add_simulation_quantities(logmgr)
        add_particle_quantities(logmgr, self.observer)
        add_field_quantities(logmgr, self.observer)

        if setup.beam_axis is not None and setup.beam_diag_axis is not None:
            add_beam_quantities(logmgr, self.observer, 
                    axis=setup.beam_diag_axis, 
                    beam_axis=setup.beam_axis)

        if setup.tube_length is not None:
            from hedge.tools import unit_vector
            add_currents(logmgr, self.observer, 
                    unit_vector(self.method.dimensions_velocity, setup.beam_axis), 
                    setup.tube_length)

        self.method.add_instrumentation(logmgr, self.observer)

        self.f_rhs_calculator.add_instrumentation(logmgr)

        if hasattr(self.stepper, "add_instrumentation"):
            self.stepper.add_instrumentation(logmgr)

        mean_beta = self.method.mean_beta(self.state)
        gamma = self.method.units.gamma_from_beta(mean_beta)

        logmgr.set_constant("dt", self.dt)
        logmgr.set_constant("beta", mean_beta)
        logmgr.set_constant("gamma", gamma)
        logmgr.set_constant("v", mean_beta*self.units.VACUUM_LIGHT_SPEED())
        logmgr.set_constant("Q0", self.total_charge)
        logmgr.set_constant("n_part_0", setup.nparticles)
        logmgr.set_constant("pmass", setup.distribution.mean()[3][0])
        logmgr.set_constant("chi", setup.chi)
        logmgr.set_constant("phi_decay", setup.phi_decay)
        logmgr.set_constant("shape_radius_setup", setup.shape_bandwidth)
        logmgr.set_constant("shape_radius", self.method.depositor.shape_function.radius)
        logmgr.set_constant("shape_exponent", self.method.depositor.shape_function.exponent)

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

        logmgr.add_quantity(ETA(self.nsteps))

        logmgr.add_watches(setup.watch_vars)
示例#29
0
def main(write_output=True, allow_features=None):
    from grudge.timestep import RK4TimeStepper
    from grudge.mesh import make_ball_mesh, make_cylinder_mesh, make_box_mesh
    from grudge.visualization import \
            VtkVisualizer, \
            SiloVisualizer, \
            get_rank_partition
    from math import sqrt, pi

    from grudge.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

    dims = 3

    if rcon.is_head_rank:
        if dims == 2:
            from grudge.mesh import make_rect_mesh
            mesh = make_rect_mesh(a=(-10.5, -1.5), b=(10.5, 1.5), max_area=0.1)
        elif dims == 3:
            from grudge.mesh import make_box_mesh
            mesh = make_box_mesh(a=(-10.5, -1.5, -1.5),
                                 b=(10.5, 1.5, 1.5),
                                 max_volume=0.1)

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

    #for order in [1,2,3,4,5,6]:
    discr = rcon.make_discretization(mesh_data, order=3)

    if write_output:
        vis = VtkVisualizer(discr, rcon, "dipole")

    from analytic_solutions import DipoleFarField, SphericalFieldAdapter
    from grudge.data import ITimeDependentGivenFunction

    sph_dipole = DipoleFarField(
        q=1,  #C
        d=1 / 39,
        omega=2 * pi * 1e8,
        epsilon=epsilon0,
        mu=mu0,
    )
    cart_dipole = SphericalFieldAdapter(sph_dipole)

    class PointDipoleSource(ITimeDependentGivenFunction):
        def __init__(self):
            from pyrticle.tools import CInfinityShapeFunction
            sf = CInfinityShapeFunction(0.1 * sph_dipole.wavelength,
                                        discr.dimensions)
            self.num_sf = discr.interpolate_volume_function(
                lambda x, el: sf(x))
            self.vol_0 = discr.volume_zeros()

        def volume_interpolant(self, t, discr):
            from grudge.tools import make_obj_array
            return make_obj_array([
                self.vol_0, self.vol_0,
                sph_dipole.source_modulation(t) * self.num_sf
            ])

    from grudge.mesh import BTAG_ALL, BTAG_NONE
    if dims == 2:
        from grudge.models.em import TMMaxwellOperator as MaxwellOperator
    else:
        from grudge.models.em import MaxwellOperator

    op = MaxwellOperator(
        epsilon,
        mu,
        flux_type=1,
        pec_tag=BTAG_NONE,
        absorb_tag=BTAG_ALL,
        current=PointDipoleSource(),
    )

    fields = op.assemble_eh(discr=discr)

    if rcon.is_head_rank:
        print("#elements=", len(mesh.elements))

    stepper = RK4TimeStepper()

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

    if write_output:
        log_file_name = "dipole.dat"
    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 grudge.log import EMFieldGetter, add_em_quantities
    field_getter = EMFieldGetter(discr, op, lambda: fields)
    add_em_quantities(logmgr, op, field_getter)

    from pytools.log import PushLogQuantity
    relerr_e_q = PushLogQuantity("relerr_e", "1",
                                 "Relative error in masked E-field")
    relerr_h_q = PushLogQuantity("relerr_h", "1",
                                 "Relative error in masked H-field")
    logmgr.add_quantity(relerr_e_q)
    logmgr.add_quantity(relerr_h_q)

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

    if write_output:
        point_timeseries = [(open("b-x%d-vs-time.dat" % i,
                                  "w"), open("b-x%d-vs-time-true.dat" % i,
                                             "w"),
                             discr.get_point_evaluator(
                                 numpy.array([i, 0, 0][:dims],
                                             dtype=discr.default_scalar_type)))
                            for i in range(1, 5)]

    # timestep loop -------------------------------------------------------
    mask = discr.interpolate_volume_function(sph_dipole.far_field_mask)

    def apply_mask(field):
        from grudge.tools import log_shape
        ls = log_shape(field)
        result = discr.volume_empty(ls)
        from pytools import indices_in_shape
        for i in indices_in_shape(ls):
            result[i] = mask * field[i]

        return result

    rhs = op.bind(discr)

    t = 0
    try:
        from grudge.timestep import times_and_steps
        step_it = times_and_steps(
            final_time=1e-8,
            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 write_output and step % 10 == 0:
                sub_timer = vis_timer.start_sub_timer()
                e, h = op.split_eh(fields)
                sph_dipole.set_time(t)
                true_e, true_h = op.split_eh(
                    discr.interpolate_volume_function(cart_dipole))
                visf = vis.make_file("dipole-%04d" % step)

                mask_e = apply_mask(e)
                mask_h = apply_mask(h)
                mask_true_e = apply_mask(true_e)
                mask_true_h = apply_mask(true_h)

                from pyvisfile.silo import DB_VARTYPE_VECTOR
                vis.add_data(visf, [("e", e), ("h", h), ("true_e", true_e),
                                    ("true_h", true_h), ("mask_e", mask_e),
                                    ("mask_h", mask_h),
                                    ("mask_true_e", mask_true_e),
                                    ("mask_true_h", mask_true_h)],
                             time=t,
                             step=step)
                visf.close()
                sub_timer.stop().submit()

                from grudge.tools import relative_error
                relerr_e_q.push_value(
                    relative_error(discr.norm(mask_e - mask_true_e),
                                   discr.norm(mask_true_e)))
                relerr_h_q.push_value(
                    relative_error(discr.norm(mask_h - mask_true_h),
                                   discr.norm(mask_true_h)))

                if write_output:
                    for outf_num, outf_true, evaluator in point_timeseries:
                        for outf, ev_h in zip([outf_num, outf_true],
                                              [h, true_h]):
                            outf.write("%g\t%g\n" %
                                       (t, op.mu * evaluator(ev_h[1])))
                            outf.flush()

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

    finally:
        if write_output:
            vis.close()

        logmgr.save()
        discr.close()
示例#30
0
def main(write_output=True, allow_features=None, flux_type_arg=1,
        bdry_flux_type_arg=None, extra_discr_args={}):
    from math import sqrt, pi
    from hedge.models.em import TEMaxwellOperator

    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.
    c = 1/sqrt(mu0*epsilon0)

    materials = {"vacuum" : (epsilon0, mu0),
                 "dielectric" : (2*epsilon0, mu0)}

    output_dir = "2d_cavity"

    import os
    if not os.access(output_dir, os.F_OK):
        os.makedirs(output_dir)

    # should no tag raise an error or default to free space?
    def eps_val(x, el):
        for key in materials.keys():
            if el in material_elements[key]:
                return materials[key][0]
        raise ValueError, "Element does not belong to any material"

    def mu_val(x, el):
        for key in materials.keys():
            if el in material_elements[key]:
                return materials[key][1]
        raise ValueError, "Element does not belong to any material"

    # geometry of cavity
    d = 100e-3
    a = 150e-3

    # analytical frequency and transverse wavenumbers of resonance
    f0 = 9.0335649907522321e8
    h = 2*pi*f0/c
    l = -h*sqrt(2)

    # substitute the following and change materials for a homogeneous cavity
    #h = pi/a
    #l =-h

    def initial_val(discr):
        # the initial solution for the TE_10-like mode
        def initial_Hz(x, el):
            from math import cos, sin
            if el in material_elements["vacuum"]:
                return h*cos(h*x[0])
            else:
                return -l*sin(h*d)/sin(l*(a-d))*cos(l*(a-x[0]))

        from hedge.tools import make_obj_array
        result_zero = discr.volume_zeros(kind="numpy", dtype=numpy.float64)
        H_z = make_tdep_given(initial_Hz).volume_interpolant(0, discr)
        return make_obj_array([result_zero, result_zero, H_z])

    if rcon.is_head_rank:
        from hedge.mesh.reader.gmsh import generate_gmsh
        mesh = generate_gmsh(CAVITY_GEOMETRY, 2, force_dimension=2)
        mesh_data = rcon.distribute_mesh(mesh)
    else:
        mesh_data = rcon.receive_mesh()

    # Work out which elements belong to each material
    material_elements = {}
    for key in materials.keys():
        material_elements[key] = set(mesh_data.tag_to_elements[key])

    order = 3
    #extra_discr_args.setdefault("debug", []).append("cuda_no_plan")
    #extra_discr_args.setdefault("debug", []).append("dump_optemplate_stages")

    from hedge.data import make_tdep_given
    from hedge.mesh import TAG_ALL

    op = TEMaxwellOperator(epsilon=make_tdep_given(eps_val), mu=make_tdep_given(mu_val), \
            flux_type=flux_type_arg, \
            bdry_flux_type=bdry_flux_type_arg, dimensions=2, pec_tag=TAG_ALL)
    # op = TEMaxwellOperator(epsilon=epsilon0, mu=mu0,
            # flux_type=flux_type_arg, \
            # bdry_flux_type=bdry_flux_type_arg, dimensions=2, pec_tag=TAG_ALL)

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

    # create the initial solution
    fields = initial_val(discr)

    from hedge.visualization import VtkVisualizer
    if write_output:
        from os.path import join
        vis = VtkVisualizer(discr, rcon, join(output_dir, "cav-%d" % order))

    # monitor the solution at a point to find the resonant frequency
    try:
        point_getter = discr.get_point_evaluator(numpy.array([75e-3, 25e-3, 0])) #[0.25, 0.25, 0.25]))
    except RuntimeError:
        point_getter = None

    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:
        from os.path import join
        log_file_name = join(output_dir, "cavity-%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 = 10e-9

    if point_getter is not None:
        from os.path import join
        pointfile = open(join(output_dir, "point.txt"), "wt")
        done_dt = False
    try:
        from hedge.timestep import times_and_steps
        from os.path import join
        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 % 10 == 0 and write_output:
                sub_timer = vis_timer.start_sub_timer()
                e, h = op.split_eh(fields)
                visf = vis.make_file(join(output_dir, "cav-%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)
            if point_getter is not None:
                val = point_getter(fields)
                #print val
                if not done_dt:
                    pointfile.write("#%g\n" % dt)
                    done_dt = True
                pointfile.write("%g\n" %val[0])

    finally:
        if write_output:
            vis.close()

        logmgr.close()
        discr.close()

        if point_getter is not None:
            pointfile.close()
示例#31
0
def main(write_output=True):
    from hedge.timestep.runge_kutta import LSRK4TimeStepper
    from math import sqrt, pi, exp

    from hedge.backends import guess_run_context
    rcon = guess_run_context()

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

    c = 1 / sqrt(mu * epsilon)

    pml_width = 0.5
    #mesh = make_mesh(a=np.array((-1,-1,-1)), b=np.array((1,1,1)),
    #mesh = make_mesh(a=np.array((-3,-3)), b=np.array((3,3)),
    mesh = make_mesh(
        a=np.array((-1, -1)),
        b=np.array((1, 1)),
        #mesh = make_mesh(a=np.array((-2,-2)), b=np.array((2,2)),
        pml_width=pml_width,
        max_volume=0.01)

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

    class Current:
        def volume_interpolant(self, t, discr):
            from hedge.tools import make_obj_array

            result = discr.volume_zeros(kind="numpy", dtype=np.float64)

            omega = 6 * c
            if omega * t > 2 * pi:
                return make_obj_array([result, result, result])

            x = make_obj_array(discr.nodes.T)
            r = np.sqrt(np.dot(x, x))

            idx = r < 0.3
            result[idx] = (1+np.cos(pi*r/0.3))[idx] \
                    *np.sin(omega*t)**3

            result = discr.convert_volume(result,
                                          kind=discr.compute_kind,
                                          dtype=discr.default_scalar_type)
            return make_obj_array([-result, result, result])

    order = 3
    discr = rcon.make_discretization(mesh_data,
                                     order=order,
                                     debug=["cuda_no_plan"])

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

    from hedge.mesh import TAG_ALL, TAG_NONE
    from hedge.data import GivenFunction, TimeHarmonicGivenFunction, TimeIntervalGivenFunction
    from hedge.models.em import MaxwellOperator
    from hedge.models.pml import \
            AbarbanelGottliebPMLMaxwellOperator, \
            AbarbanelGottliebPMLTMMaxwellOperator, \
            AbarbanelGottliebPMLTEMaxwellOperator

    op = AbarbanelGottliebPMLTEMaxwellOperator(epsilon,
                                               mu,
                                               flux_type=1,
                                               current=Current(),
                                               pec_tag=TAG_ALL,
                                               absorb_tag=TAG_NONE,
                                               add_decay=True)

    fields = op.assemble_ehpq(discr=discr)

    stepper = LSRK4TimeStepper()

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

    # 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"])

    from hedge.log import LpNorm

    class FieldIdxGetter:
        def __init__(self, whole_getter, idx):
            self.whole_getter = whole_getter
            self.idx = idx

        def __call__(self):
            return self.whole_getter()[self.idx]

    # timestep loop -------------------------------------------------------

    t = 0
    pml_coeff = op.coefficients_from_width(discr, width=pml_width)
    rhs = op.bind(discr, pml_coeff)

    try:
        from hedge.timestep import times_and_steps
        step_it = times_and_steps(
            final_time=4 / c,
            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 % 10 == 0 and write_output:
                e, h, p, q = op.split_ehpq(fields)
                visf = vis.make_file("em-%d-%04d" % (order, step))
                #pml_rhs_e, pml_rhs_h, pml_rhs_p, pml_rhs_q = \
                #op.split_ehpq(rhs(t, fields))
                j = Current().volume_interpolant(t, discr)
                vis.add_data(
                    visf,
                    [
                        ("e", discr.convert_volume(e, "numpy")),
                        ("h", discr.convert_volume(h, "numpy")),
                        ("p", discr.convert_volume(p, "numpy")),
                        ("q", discr.convert_volume(q, "numpy")),
                        ("j", discr.convert_volume(j, "numpy")),
                        #("pml_rhs_e", pml_rhs_e),
                        #("pml_rhs_h", pml_rhs_h),
                        #("pml_rhs_p", pml_rhs_p),
                        #("pml_rhs_q", pml_rhs_q),
                        #("max_rhs_e", max_rhs_e),
                        #("max_rhs_h", max_rhs_h),
                        #("max_rhs_p", max_rhs_p),
                        #("max_rhs_q", max_rhs_q),
                    ],
                    time=t,
                    step=step)
                visf.close()

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

        _, _, energies_data = logmgr.get_expr_dataset("W_el+W_mag")
        energies = [value for tick_nbr, value in energies_data]

        assert energies[-1] < max(energies) * 1e-2

    finally:
        logmgr.close()

        if write_output:
            vis.close()
示例#32
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