Esempio n. 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)
Esempio n. 2
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)
Esempio n. 3
0
    def __init__(self,
                 order,
                 startup_stepper=None,
                 dtype=numpy.float64,
                 rcon=None):
        self.f_history = []

        from pytools import match_precision
        self.dtype = numpy.dtype(dtype)
        self.scalar_dtype = match_precision(numpy.dtype(numpy.float64),
                                            self.dtype)
        self.coefficients = numpy.asarray(make_ab_coefficients(order),
                                          dtype=self.scalar_dtype)

        if startup_stepper is not None:
            self.startup_stepper = startup_stepper
        else:
            from hedge.timestep.runge_kutta import LSRK4TimeStepper
            self.startup_stepper = LSRK4TimeStepper(self.dtype)

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        self.timer = timer_factory(
            "t_ab", "Time spent doing algebra in Adams-Bashforth")
        self.flop_counter = EventCounter(
            "n_flops_ab", "Floating point operations performed in AB")
Esempio n. 4
0
    def __init__(self,
                 dtype=numpy.float64,
                 rcon=None,
                 vector_primitive_factory=None):
        if vector_primitive_factory is None:
            from hedge.vector_primitives import VectorPrimitiveFactory
            self.vector_primitive_factory = VectorPrimitiveFactory()
        else:
            self.vector_primitive_factory = vector_primitive_factory

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        self.timer = timer_factory("t_rk4", "Time spent doing algebra in RK4")
        self.flop_counter = EventCounter(
            "n_flops_rk4", "Floating point operations performed in RK4")

        from pytools import match_precision
        self.dtype = numpy.dtype(dtype)
        self.scalar_dtype = match_precision(numpy.dtype(numpy.float64),
                                            self.dtype)
        self.coeffs = numpy.array([self._RK4A, self._RK4B, self._RK4C],
                                  dtype=self.scalar_dtype).T
Esempio n. 5
0
    def __init__(self, order, startup_stepper=None, dtype=numpy.float64, rcon=None):
        self.f_history = []

        from pytools import match_precision
        self.dtype = numpy.dtype(dtype)
        self.scalar_dtype = match_precision(
                numpy.dtype(numpy.float64), self.dtype)
        self.coefficients = numpy.asarray(make_ab_coefficients(order),
                dtype=self.scalar_dtype)

        if startup_stepper is not None:
            self.startup_stepper = startup_stepper
        else:
            from hedge.timestep.runge_kutta import LSRK4TimeStepper
            self.startup_stepper = LSRK4TimeStepper(self.dtype)

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        self.timer = timer_factory(
                "t_ab", "Time spent doing algebra in Adams-Bashforth")
        self.flop_counter = EventCounter(
                "n_flops_ab", "Floating point operations performed in AB")
Esempio n. 6
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)
Esempio n. 7
0
    def add_instrumentation(self, mgr):
        self.subdiscr.add_instrumentation(mgr)

        from pytools.log import EventCounter
        self.comm_flux_counter = EventCounter(
            "n_comm_flux", "Number of inner flux communication runs")

        mgr.add_quantity(self.comm_flux_counter)
Esempio n. 8
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")
Esempio n. 9
0
    def __init__(self,
                 use_high_order=True,
                 dtype=numpy.float64,
                 rcon=None,
                 vector_primitive_factory=None,
                 atol=0,
                 rtol=0,
                 max_dt_growth=5,
                 min_dt_shrinkage=0.1,
                 limiter=None):
        if vector_primitive_factory is None:
            from hedge.vector_primitives import VectorPrimitiveFactory
            self.vector_primitive_factory = VectorPrimitiveFactory()
        else:
            self.vector_primitive_factory = vector_primitive_factory

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        if limiter is None:
            self.limiter = lambda x: x
        else:
            self.limiter = limiter

        self.timer = timer_factory("t_rk",
                                   "Time spent doing algebra in Runge-Kutta")
        self.flop_counter = EventCounter(
            "n_flops_rk", "Floating point operations performed in Runge-Kutta")

        self.use_high_order = use_high_order

        self.dtype = numpy.dtype(dtype)

        self.adaptive = bool(atol or rtol)
        self.atol = atol
        self.rtol = rtol

        from pytools import match_precision
        self.scalar_dtype = match_precision(numpy.dtype(numpy.float64),
                                            self.dtype)

        self.max_dt_growth = max_dt_growth
        self.min_dt_shrinkage = min_dt_shrinkage

        self.linear_combiner_cache = {}
Esempio n. 10
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")
Esempio n. 11
0
    def __init__(self, dtype=numpy.float64, rcon=None,
            vector_primitive_factory=None):
        if vector_primitive_factory is None:
            from hedge.vector_primitives import VectorPrimitiveFactory
            self.vector_primitive_factory = VectorPrimitiveFactory()
        else:
            self.vector_primitive_factory = vector_primitive_factory

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        self.timer = timer_factory(
                "t_rk4", "Time spent doing algebra in RK4")
        self.flop_counter = EventCounter(
                "n_flops_rk4", "Floating point operations performed in RK4")

        from pytools import match_precision
        self.dtype = numpy.dtype(dtype)
        self.scalar_dtype = match_precision(
                numpy.dtype(numpy.float64), self.dtype)
        self.coeffs = numpy.array([self._RK4A, self._RK4B, self._RK4C], 
                dtype=self.scalar_dtype).T
Esempio n. 12
0
class AdamsBashforthTimeStepper(TimeStepper):
    dt_fudge_factor = 0.95

    def __init__(self, order, startup_stepper=None, dtype=numpy.float64, rcon=None):
        self.f_history = []

        from pytools import match_precision
        self.dtype = numpy.dtype(dtype)
        self.scalar_dtype = match_precision(
                numpy.dtype(numpy.float64), self.dtype)
        self.coefficients = numpy.asarray(make_ab_coefficients(order),
                dtype=self.scalar_dtype)

        if startup_stepper is not None:
            self.startup_stepper = startup_stepper
        else:
            from hedge.timestep.runge_kutta import LSRK4TimeStepper
            self.startup_stepper = LSRK4TimeStepper(self.dtype)

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        self.timer = timer_factory(
                "t_ab", "Time spent doing algebra in Adams-Bashforth")
        self.flop_counter = EventCounter(
                "n_flops_ab", "Floating point operations performed in AB")

    @property
    def order(self):
        return len(self.coefficients)

    def get_stability_relevant_init_args(self):
        return (self.order,)

    def add_instrumentation(self, logmgr):
        logmgr.add_quantity(self.timer)
        logmgr.add_quantity(self.flop_counter)

    def __getinitargs__(self):
        return (self.order, self.startup_stepper)

    def __call__(self, y, t, dt, rhs):
        if len(self.f_history) == 0:
            # insert IC
            self.f_history.append(rhs(t, y))

            from hedge.tools import count_dofs
            self.dof_count = count_dofs(self.f_history[0])

        if len(self.f_history) < len(self.coefficients):
            ynew = self.startup_stepper(y, t, dt, rhs)
            if len(self.f_history) == len(self.coefficients) - 1:
                # here's some memory we won't need any more
                del self.startup_stepper

        else:
            from operator import add

            sub_timer = self.timer.start_sub_timer()
            assert len(self.coefficients) == len(self.f_history)
            ynew = y + dt * reduce(add,
                    (coeff * f 
                        for coeff, f in 
                        zip(self.coefficients, self.f_history)))

            self.f_history.pop()
            sub_timer.stop().submit()

        self.flop_counter.add((2+2*len(self.coefficients)-1)*self.dof_count)

        self.f_history.insert(0, rhs(t+dt, ynew))
        return ynew
Esempio n. 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)),
                    ])
Esempio n. 14
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)),
                            ])
Esempio n. 15
0
class LSRK4TimeStepper(TimeStepper):
    """A low storage fourth-order Runge-Kutta method

    See JSH, TW: Nodal Discontinuous Galerkin Methods p.64
    or 
    Carpenter, M.H., and Kennedy, C.A., Fourth-order-2N-storage 
    Runge-Kutta schemes, NASA Langley Tech Report TM 109112, 1994
    """

    _RK4A = [0.0,
            -567301805773 /1357537059087,
            -2404267990393/2016746695238,
            -3550918686646/2091501179385,
            -1275806237668/ 842570457699,
            ]

    _RK4B = [1432997174477/ 9575080441755,
            5161836677717 /13612068292357,
            1720146321549 / 2090206949498,
            3134564353537 / 4481467310338,
            2277821191437 /14882151754819,
            ]

    _RK4C = [0.0,
            1432997174477/9575080441755,
            2526269341429/6820363962896,
            2006345519317/3224310063776,
            2802321613138/2924317926251,
            #1,
            ]

    dt_fudge_factor = 1

    adaptive = False

    def __init__(self, dtype=numpy.float64, rcon=None,
            vector_primitive_factory=None):
        if vector_primitive_factory is None:
            from hedge.vector_primitives import VectorPrimitiveFactory
            self.vector_primitive_factory = VectorPrimitiveFactory()
        else:
            self.vector_primitive_factory = vector_primitive_factory

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        self.timer = timer_factory(
                "t_rk4", "Time spent doing algebra in RK4")
        self.flop_counter = EventCounter(
                "n_flops_rk4", "Floating point operations performed in RK4")

        from pytools import match_precision
        self.dtype = numpy.dtype(dtype)
        self.scalar_dtype = match_precision(
                numpy.dtype(numpy.float64), self.dtype)
        self.coeffs = numpy.array([self._RK4A, self._RK4B, self._RK4C], 
                dtype=self.scalar_dtype).T

    def get_stability_relevant_init_args(self):
        return ()

    def add_instrumentation(self, logmgr):
        logmgr.add_quantity(self.timer)
        logmgr.add_quantity(self.flop_counter)

    def __call__(self, y, t, dt, rhs):
        try:
            self.residual
        except AttributeError:
            self.residual = 0*rhs(t, y)
            from hedge.tools import count_dofs
            self.dof_count = count_dofs(self.residual)

            self.linear_combiner = self.vector_primitive_factory\
                    .make_linear_combiner(self.dtype, self.scalar_dtype, 
                            y, arg_count=2)

        lc = self.linear_combiner

        for a, b, c in self.coeffs:
            this_rhs = rhs(t + c*dt, y)

            sub_timer = self.timer.start_sub_timer()
            self.residual = lc((a, self.residual), (dt, this_rhs))
            del this_rhs
            y = lc((1, y), (b, self.residual))
            sub_timer.stop().submit()

        # 5 is the number of flops above, *NOT* the number of stages,
        # which is already captured in len(self.coeffs)
        self.flop_counter.add(len(self.coeffs)*self.dof_count*5)

        return y
Esempio n. 16
0
class AdamsBashforthTimeStepper(TimeStepper):
    dt_fudge_factor = 0.95

    def __init__(self,
                 order,
                 startup_stepper=None,
                 dtype=numpy.float64,
                 rcon=None):
        self.f_history = []

        from pytools import match_precision
        self.dtype = numpy.dtype(dtype)
        self.scalar_dtype = match_precision(numpy.dtype(numpy.float64),
                                            self.dtype)
        self.coefficients = numpy.asarray(make_ab_coefficients(order),
                                          dtype=self.scalar_dtype)

        if startup_stepper is not None:
            self.startup_stepper = startup_stepper
        else:
            from hedge.timestep.runge_kutta import LSRK4TimeStepper
            self.startup_stepper = LSRK4TimeStepper(self.dtype)

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        self.timer = timer_factory(
            "t_ab", "Time spent doing algebra in Adams-Bashforth")
        self.flop_counter = EventCounter(
            "n_flops_ab", "Floating point operations performed in AB")

    @property
    def order(self):
        return len(self.coefficients)

    def get_stability_relevant_init_args(self):
        return (self.order, )

    def add_instrumentation(self, logmgr):
        logmgr.add_quantity(self.timer)
        logmgr.add_quantity(self.flop_counter)

    def __getinitargs__(self):
        return (self.order, self.startup_stepper)

    def __call__(self, y, t, dt, rhs):
        if len(self.f_history) == 0:
            # insert IC
            self.f_history.append(rhs(t, y))

            from hedge.tools import count_dofs
            self.dof_count = count_dofs(self.f_history[0])

        if len(self.f_history) < len(self.coefficients):
            ynew = self.startup_stepper(y, t, dt, rhs)
            if len(self.f_history) == len(self.coefficients) - 1:
                # here's some memory we won't need any more
                del self.startup_stepper

        else:
            from operator import add

            sub_timer = self.timer.start_sub_timer()
            assert len(self.coefficients) == len(self.f_history)
            ynew = y + dt * reduce(
                add, (coeff * f
                      for coeff, f in zip(self.coefficients, self.f_history)))

            self.f_history.pop()
            sub_timer.stop().submit()

        self.flop_counter.add(
            (2 + 2 * len(self.coefficients) - 1) * self.dof_count)

        self.f_history.insert(0, rhs(t + dt, ynew))
        return ynew
Esempio n. 17
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()
Esempio n. 18
0
class LSRK4TimeStepper(TimeStepper):
    """A low storage fourth-order Runge-Kutta method

    See JSH, TW: Nodal Discontinuous Galerkin Methods p.64
    or
    Carpenter, M.H., and Kennedy, C.A., Fourth-order-2N-storage
    Runge-Kutta schemes, NASA Langley Tech Report TM 109112, 1994
    """

    _RK4A = [
        0.0,
        -567301805773 / 1357537059087,
        -2404267990393 / 2016746695238,
        -3550918686646 / 2091501179385,
        -1275806237668 / 842570457699,
    ]

    _RK4B = [
        1432997174477 / 9575080441755,
        5161836677717 / 13612068292357,
        1720146321549 / 2090206949498,
        3134564353537 / 4481467310338,
        2277821191437 / 14882151754819,
    ]

    _RK4C = [
        0.0,
        1432997174477 / 9575080441755,
        2526269341429 / 6820363962896,
        2006345519317 / 3224310063776,
        2802321613138 / 2924317926251,
        #1,
    ]

    dt_fudge_factor = 1

    adaptive = False

    def __init__(self,
                 dtype=numpy.float64,
                 rcon=None,
                 vector_primitive_factory=None):
        if vector_primitive_factory is None:
            from hedge.vector_primitives import VectorPrimitiveFactory
            self.vector_primitive_factory = VectorPrimitiveFactory()
        else:
            self.vector_primitive_factory = vector_primitive_factory

        from pytools.log import IntervalTimer, EventCounter
        timer_factory = IntervalTimer
        if rcon is not None:
            timer_factory = rcon.make_timer

        self.timer = timer_factory("t_rk4", "Time spent doing algebra in RK4")
        self.flop_counter = EventCounter(
            "n_flops_rk4", "Floating point operations performed in RK4")

        from pytools import match_precision
        self.dtype = numpy.dtype(dtype)
        self.scalar_dtype = match_precision(numpy.dtype(numpy.float64),
                                            self.dtype)
        self.coeffs = numpy.array([self._RK4A, self._RK4B, self._RK4C],
                                  dtype=self.scalar_dtype).T

    def get_stability_relevant_init_args(self):
        return ()

    def add_instrumentation(self, logmgr):
        logmgr.add_quantity(self.timer)
        logmgr.add_quantity(self.flop_counter)

    def __call__(self, y, t, dt, rhs):
        try:
            self.residual
        except AttributeError:
            self.residual = 0 * rhs(t, y)
            from hedge.tools import count_dofs
            self.dof_count = count_dofs(self.residual)

            self.linear_combiner = self.vector_primitive_factory\
                    .make_linear_combiner(self.dtype, self.scalar_dtype,
                            y, arg_count=2)

        lc = self.linear_combiner

        for a, b, c in self.coeffs:
            this_rhs = rhs(t + c * dt, y)

            sub_timer = self.timer.start_sub_timer()
            self.residual = lc((a, self.residual), (dt, this_rhs))
            del this_rhs
            y = lc((1, y), (b, self.residual))
            sub_timer.stop().submit()

        # 5 is the number of flops above, *NOT* the number of stages,
        # which is already captured in len(self.coeffs)
        self.flop_counter.add(len(self.coeffs) * self.dof_count * 5)

        return y
Esempio n. 19
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)
Esempio n. 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)
Esempio n. 21
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)