Example #1
0
    def targets_from_sources(sign, dist, dim=2):
        nodes = actx.to_numpy(
            flatten(
                bind(places, sym.nodes(dim, dofdesc=dd))(actx).as_vector(),
                actx)).reshape(dim, -1)
        normals = actx.to_numpy(
            flatten(
                bind(places, sym.normal(dim, dofdesc=dd))(actx).as_vector(),
                actx)).reshape(dim, -1)

        return actx.from_numpy(nodes + normals * sign * dist)
Example #2
0
    def exec_compute_potential_insn_direct(self, actx: PyOpenCLArrayContext,
                                           insn, bound_expr, evaluate):
        kernel_args = {}

        for arg_name, arg_expr in insn.kernel_arguments.items():
            kernel_args[arg_name] = flatten(evaluate(arg_expr),
                                            actx,
                                            leaf_class=DOFArray)

        from pytential import bind, sym
        waa = bind(
            bound_expr.places,
            sym.weights_and_area_elements(self.ambient_dim,
                                          dofdesc=insn.source))(actx)
        strengths = [waa * evaluate(density) for density in insn.densities]
        flat_strengths = [flatten(strength, actx) for strength in strengths]

        results = []
        p2p = None

        for o in insn.outputs:
            target_discr = bound_expr.places.get_discretization(
                o.target_name.geometry, o.target_name.discr_stage)

            if p2p is None:
                p2p = self.get_p2p(actx,
                                   source_kernels=insn.source_kernels,
                                   target_kernels=insn.target_kernels)

            evt, output_for_each_kernel = p2p(
                actx.queue,
                targets=flatten(target_discr.nodes(),
                                actx,
                                leaf_class=DOFArray),
                sources=flatten(self.density_discr.nodes(),
                                actx,
                                leaf_class=DOFArray),
                strength=flat_strengths,
                **kernel_args)

            from meshmode.discretization import Discretization
            result = output_for_each_kernel[o.target_kernel_index]
            if isinstance(target_discr, Discretization):
                template_ary = thaw(target_discr.nodes()[0], actx)
                result = unflatten(template_ary, result, actx, strict=False)

            results.append((o.name, result))

        timing_data = {}
        return results, timing_data
Example #3
0
    def map_num_reference_derivative(self, expr):
        from pytential import bind, sym
        rec_operand = self.rec(expr.operand)

        assert isinstance(rec_operand, np.ndarray)
        if self.is_kind_matrix(rec_operand):
            raise NotImplementedError("derivatives")

        actx = self.array_context
        dofdesc = expr.dofdesc
        op = sym.NumReferenceDerivative(ref_axes=expr.ref_axes,
                                        operand=sym.var("u"),
                                        dofdesc=dofdesc)

        discr = self.places.get_discretization(dofdesc.geometry,
                                               dofdesc.discr_stage)

        template_ary = thaw(discr.nodes()[0], actx)
        rec_operand = unflatten(template_ary, actx.from_numpy(rec_operand),
                                actx)

        return actx.to_numpy(
            flatten(
                bind(self.places, op)(self.array_context, u=rec_operand),
                actx))
Example #4
0
    def check_element_prop_threshold(self,
                                     element_property,
                                     threshold,
                                     refine_flags,
                                     debug,
                                     wait_for=None):
        actx = self.array_context
        knl = self.code_container.element_prop_threshold_checker()

        if debug:
            nelements_to_refine_prev = actx.to_numpy(
                actx.np.sum(refine_flags)).item()

        element_property = flatten(element_property, self.array_context)

        evt, out = knl(actx.queue,
                       element_property=element_property,
                       refine_flags=refine_flags,
                       refine_flags_updated=np.array(0),
                       threshold=np.array(threshold),
                       wait_for=wait_for)

        import pyopencl as cl
        cl.wait_for_events([evt])

        if debug:
            nelements_to_refine = actx.to_numpy(
                actx.np.sum(refine_flags)).item()
            if nelements_to_refine > nelements_to_refine_prev:
                logger.debug("refiner: found %d element(s) to refine",
                             nelements_to_refine - nelements_to_refine_prev)

        return out["refine_flags_updated"] == 1
Example #5
0
    def target_info(self):
        """Return a :class:`TargetInfo`. |cached|"""

        actx = self._setup_actx
        code_getter = self.code_getter
        ntargets = self.ncenters
        target_discr_starts = []

        for target_discr, _qbx_side in self.target_discrs_and_qbx_sides:
            target_discr_starts.append(ntargets)
            ntargets += target_discr.ndofs

        target_discr_starts.append(ntargets)

        targets = actx.empty((self.ambient_dim, ntargets), self.coord_dtype)
        code_getter.copy_targets_kernel()(actx.queue,
                                          targets=targets[:, :self.ncenters],
                                          points=self.flat_centers())

        for start, (target_discr, _) in zip(target_discr_starts,
                                            self.target_discrs_and_qbx_sides):
            code_getter.copy_targets_kernel()(
                actx.queue,
                targets=targets[:, start:start + target_discr.ndofs],
                points=flatten(target_discr.nodes(), actx,
                               leaf_class=DOFArray),
            )

        return TargetInfo(targets=actx.freeze(targets),
                          target_discr_starts=target_discr_starts,
                          ntargets=ntargets)
Example #6
0
    def target_info(self):
        code_getter = self.code_getter
        lpot_src = self.lpot_source
        target_discrs = self.target_discrs

        ntargets = 0
        target_discr_starts = []

        for target_discr in target_discrs:
            target_discr_starts.append(ntargets)
            ntargets += target_discr.ndofs

        actx = self.array_context
        target_discr_starts.append(ntargets)

        targets = actx.empty((lpot_src.ambient_dim, ntargets),
                             self.coord_dtype)

        for start, target_discr in zip(target_discr_starts, target_discrs):
            code_getter.copy_targets_kernel()(
                actx.queue,
                targets=targets[:, start:start + target_discr.ndofs],
                points=flatten(target_discr.nodes(), actx,
                               leaf_class=DOFArray),
            )

        return _TargetInfo(targets=targets,
                           target_discr_starts=target_discr_starts,
                           ntargets=ntargets).with_queue(None)
Example #7
0
    def map_node_coordinate_component(self, expr):
        from pytential import bind, sym
        op = sym.NodeCoordinateComponent(expr.ambient_axis,
                                         dofdesc=expr.dofdesc)

        actx = self.array_context
        return actx.to_numpy(flatten(bind(self.places, op)(actx), actx))
Example #8
0
def test_interpolation(actx_factory, name, source_discr_stage, target_granularity):
    actx = actx_factory()

    nelements = 32
    target_order = 7
    qbx_order = 4

    where = sym.as_dofdesc("test_interpolation")
    from_dd = sym.DOFDescriptor(
            geometry=where.geometry,
            discr_stage=source_discr_stage,
            granularity=sym.GRANULARITY_NODE)
    to_dd = sym.DOFDescriptor(
            geometry=where.geometry,
            discr_stage=sym.QBX_SOURCE_QUAD_STAGE2,
            granularity=target_granularity)

    mesh = mgen.make_curve_mesh(mgen.starfish,
            np.linspace(0.0, 1.0, nelements + 1),
            target_order)
    discr = Discretization(actx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    from pytential.qbx import QBXLayerPotentialSource
    qbx = QBXLayerPotentialSource(discr,
            fine_order=4 * target_order,
            qbx_order=qbx_order,
            fmm_order=False)

    from pytential import GeometryCollection
    places = GeometryCollection(qbx, auto_where=where)

    sigma_sym = sym.var("sigma")
    op_sym = sym.sin(sym.interp(from_dd, to_dd, sigma_sym))
    bound_op = bind(places, op_sym, auto_where=where)

    def discr_and_nodes(stage):
        density_discr = places.get_discretization(where.geometry, stage)
        return density_discr, actx.to_numpy(
                flatten(density_discr.nodes(), actx)
                ).reshape(density_discr.ambient_dim, -1)

    _, target_nodes = discr_and_nodes(sym.QBX_SOURCE_QUAD_STAGE2)
    source_discr, source_nodes = discr_and_nodes(source_discr_stage)

    sigma_target = np.sin(la.norm(target_nodes, axis=0))
    sigma_dev = unflatten(
            thaw(source_discr.nodes()[0], actx),
            actx.from_numpy(la.norm(source_nodes, axis=0)), actx)
    sigma_target_interp = actx.to_numpy(
            flatten(bound_op(actx, sigma=sigma_dev), actx)
            )

    if name in ("default", "default_explicit", "stage2", "quad"):
        error = la.norm(sigma_target_interp - sigma_target) / la.norm(sigma_target)
        assert error < 1.0e-10
    elif name in ("stage2_center",):
        assert len(sigma_target_interp) == 2 * len(sigma_target)
    else:
        raise ValueError(f"unknown test case name: {name}")
Example #9
0
    def tree(self):
        """Build and return a :class:`boxtree.tree.Tree`
        for this source with these targets.

        |cached|
        """

        code_getter = self.code_getter
        lpot_src = self.lpot_source
        target_info = self.target_info()

        actx = self.array_context

        nsources = lpot_src.density_discr.ndofs
        nparticles = nsources + target_info.ntargets

        refine_weights = actx.zeros(nparticles, dtype=np.int32)
        refine_weights[:nsources] = 1
        refine_weights.finish()

        MAX_LEAF_REFINE_WEIGHT = 32  # noqa

        tree, _ = code_getter.build_tree(
            actx.queue,
            particles=flatten(lpot_src.density_discr.nodes(),
                              actx,
                              leaf_class=DOFArray),
            targets=target_info.targets,
            max_leaf_refine_weight=MAX_LEAF_REFINE_WEIGHT,
            refine_weights=refine_weights,
            debug=self.debug,
            kind="adaptive")

        return tree
Example #10
0
    def tree(self):
        """Build and return a :class:`boxtree.Tree`
        for this source with these targets.

        |cached|
        """

        actx = self._setup_actx
        code_getter = self.code_getter
        lpot_source = self.lpot_source
        target_info = self.target_info()

        from pytential import sym
        quad_stage2_discr = self.places.get_discretization(
            self.source_dd.geometry, sym.QBX_SOURCE_QUAD_STAGE2)

        nsources = sum(grp.ndofs for grp in quad_stage2_discr.groups)
        nparticles = nsources + target_info.ntargets

        target_radii = None
        if lpot_source._expansions_in_tree_have_extent:
            target_radii = actx.zeros(target_info.ntargets, self.coord_dtype)
            target_radii[:self.ncenters] = self.flat_expansion_radii()

        refine_weights = actx.empty(nparticles, dtype=np.int32)

        # Assign a weight of 1 to all sources, QBX centers, and conventional
        # (non-QBX) targets. Assign a weight of 0 to all targets that need
        # QBX centers. The potential at the latter targets is mediated
        # entirely by the QBX center, so as a matter of evaluation cost,
        # their location in the tree is irrelevant.
        refine_weights[:-target_info.ntargets] = 1
        user_ttc = actx.thaw(self.user_target_to_center())
        refine_weights[-target_info.ntargets:] = (
            user_ttc == target_state.NO_QBX_NEEDED).astype(np.int32)

        refine_weights.finish()

        tree, _ = code_getter.build_tree()(
            actx.queue,
            particles=flatten(quad_stage2_discr.nodes(),
                              actx,
                              leaf_class=DOFArray),
            targets=target_info.targets,
            target_radii=target_radii,
            max_leaf_refine_weight=lpot_source._max_leaf_refine_weight,
            refine_weights=refine_weights,
            debug=self.debug,
            stick_out_factor=lpot_source._expansion_stick_out_factor,
            extent_norm=lpot_source._box_extent_norm,
            kind=self.tree_kind)

        if self.debug:
            tgt_count_2 = actx.to_numpy(
                actx.np.sum(tree.box_target_counts_nonchild))
            assert (tree.ntargets == tgt_count_2), (tree.ntargets, tgt_count_2)

        return tree.with_queue(None)
Example #11
0
        def flatten_and_reorder_sources(source_array):
            if isinstance(source_array, DOFArray):
                source_array = flatten(source_array, actx)

            if isinstance(source_array, actx.array_types):
                return actx.freeze(
                    actx.thaw(source_array)[tree_user_source_ids])
            else:
                return source_array
Example #12
0
    def check_sufficient_source_quadrature_resolution(self,
                                                      stage2_density_discr,
                                                      tree,
                                                      peer_lists,
                                                      refine_flags,
                                                      debug,
                                                      wait_for=None):
        actx = self.array_context

        # Avoid generating too many kernels.
        from pytools import div_ceil
        max_levels = MAX_LEVELS_INCREMENT * div_ceil(tree.nlevels,
                                                     MAX_LEVELS_INCREMENT)

        knl = self.code_container.sufficient_source_quadrature_resolution_checker(
            tree.dimensions, tree.coord_dtype, tree.box_id_dtype,
            peer_lists.peer_list_starts.dtype, tree.particle_id_dtype,
            max_levels)
        if debug:
            nelements_to_refine_prev = actx.to_numpy(
                actx.np.sum(refine_flags)).item()

        found_element_to_refine = actx.zeros(1, dtype=np.int32)
        found_element_to_refine.finish()

        from pytential import bind, sym
        dd = sym.as_dofdesc(sym.GRANULARITY_ELEMENT).to_stage2()
        source_danger_zone_radii_by_element = flatten(
            bind(
                stage2_density_discr,
                sym._source_danger_zone_radii(stage2_density_discr.ambient_dim,
                                              dofdesc=dd))(self.array_context),
            self.array_context)
        unwrap_args = AreaQueryElementwiseTemplate.unwrap_args

        evt = knl(*unwrap_args(
            tree, peer_lists, tree.box_to_qbx_center_starts,
            tree.box_to_qbx_center_lists, tree.qbx_element_to_source_starts,
            tree.qbx_user_source_slice.start, tree.qbx_user_center_slice.start,
            tree.sorted_target_ids, source_danger_zone_radii_by_element,
            tree.nqbxelements, refine_flags, found_element_to_refine,
            *tree.sources),
                  range=slice(tree.nqbxsources),
                  queue=actx.queue,
                  wait_for=wait_for)

        import pyopencl as cl
        cl.wait_for_events([evt])

        if debug:
            nelements_to_refine = actx.to_numpy(
                actx.np.sum(refine_flags)).item()
            if nelements_to_refine > nelements_to_refine_prev:
                logger.debug("refiner: found %d element(s) to refine",
                             nelements_to_refine - nelements_to_refine_prev)

        return actx.to_numpy(found_element_to_refine)[0] == 1
Example #13
0
def evaluate_kernel_arguments(actx, evaluate, kernel_arguments, flat=True):
    kernel_args = {}
    for arg_name, arg_expr in kernel_arguments.items():
        value = evaluate(arg_expr)

        if flat:
            value = flatten(value, actx, leaf_class=DOFArray)
        kernel_args[arg_name] = value

    return kernel_args
Example #14
0
def get_flat_strengths_from_densities(
        actx, places, evaluate, densities, dofdesc=None):
    from pytential import bind, sym
    waa = bind(
            places,
            sym.weights_and_area_elements(places.ambient_dim, dofdesc=dofdesc),
            )(actx)
    strength_vecs = [waa * evaluate(density) for density in densities]

    return [flatten(strength, actx) for strength in strength_vecs]
Example #15
0
def _isclose(discr, x, y, rel_tol=1e-9, abs_tol=0, return_operands=False):

    from mirgecom.simutil import componentwise_norms
    from arraycontext import flatten
    actx = x.array_context
    lhs = actx.to_numpy(flatten(componentwise_norms(discr, x - y, np.inf), actx))

    rhs = np.maximum(
        rel_tol * np.maximum(
            actx.to_numpy(flatten(componentwise_norms(discr, x, np.inf), actx)),
            actx.to_numpy(flatten(componentwise_norms(discr, y, np.inf), actx))),
        abs_tol)

    is_close = np.all(lhs <= rhs)

    if return_operands:
        return is_close, lhs, rhs
    else:
        return is_close
Example #16
0
def max_component_norm(discr, fields, order=np.inf):
    """Return the max *order*-norm over the components of *fields*.

    .. note::
        This is a collective routine and must be called by all MPI ranks.
    """
    actx = fields.array_context
    return max(
        actx.to_numpy(flatten(componentwise_norms(discr, fields, order),
                              actx)))
Example #17
0
def partition_by_nodes(
        actx: PyOpenCLArrayContext,
        discr: Discretization,
        *,
        tree_kind: Optional[str] = "adaptive-level-restricted",
        max_particles_in_box: Optional[int] = None) -> BlockIndexRanges:
    """Generate equally sized ranges of nodes. The partition is created at the
    lowest level of granularity, i.e. nodes. This results in balanced ranges
    of points, but will split elements across different ranges.

    :arg tree_kind: if not *None*, it is passed to :class:`boxtree.TreeBuilder`.
    :arg max_particles_in_box: passed to :class:`boxtree.TreeBuilder`.
    """

    if max_particles_in_box is None:
        # FIXME: this is just an arbitrary value
        max_particles_in_box = 32

    if tree_kind is not None:
        from boxtree import box_flags_enum
        from boxtree import TreeBuilder

        builder = TreeBuilder(actx.context)

        from arraycontext import thaw
        tree, _ = builder(actx.queue,
                          particles=flatten(thaw(discr.nodes(), actx),
                                            actx,
                                            leaf_class=DOFArray),
                          max_particles_in_box=max_particles_in_box,
                          kind=tree_kind)

        tree = tree.get(actx.queue)
        leaf_boxes, = (tree.box_flags
                       & box_flags_enum.HAS_CHILDREN == 0).nonzero()

        indices = np.empty(len(leaf_boxes), dtype=object)
        ranges = None

        for i, ibox in enumerate(leaf_boxes):
            box_start = tree.box_source_starts[ibox]
            box_end = box_start + tree.box_source_counts_cumul[ibox]
            indices[i] = tree.user_source_ids[box_start:box_end]
    else:
        if discr.ambient_dim != 2 and discr.dim == 1:
            raise ValueError("only curves are supported for 'tree_kind=None'")

        nblocks = max(discr.ndofs // max_particles_in_box, 2)
        indices = np.arange(0, discr.ndofs, dtype=np.int64)
        ranges = np.linspace(0, discr.ndofs, nblocks + 1, dtype=np.int64)
        assert ranges[-1] == discr.ndofs

    from pytential.linalg import make_block_index_from_array
    return make_block_index_from_array(indices, ranges=ranges)
Example #18
0
def compare_fluid_solutions(discr, red_state, blue_state):
    """Return inf norm of (*red_state* - *blue_state*) for each component.

    .. note::
        This is a collective routine and must be called by all MPI ranks.
    """
    actx = red_state.array_context
    resid = red_state - blue_state
    resid_errs = actx.to_numpy(
        flatten(componentwise_norms(discr, resid, order=np.inf), actx))

    return resid_errs.tolist()
Example #19
0
    def map_interpolation(self, expr):
        from pytential import sym

        if expr.to_dd.discr_stage != sym.QBX_SOURCE_QUAD_STAGE2:
            raise RuntimeError(
                "can only interpolate to QBX_SOURCE_QUAD_STAGE2")
        operand = self.rec(expr.operand)
        actx = self.array_context

        if isinstance(operand, (int, float, complex, np.number)):
            return operand
        elif isinstance(operand, np.ndarray) and operand.ndim == 1:
            conn = self.places.get_connection(expr.from_dd, expr.to_dd)
            discr = self.places.get_discretization(expr.from_dd.geometry,
                                                   expr.from_dd.discr_stage)
            template_ary = thaw(discr.nodes()[0], actx)

            from pytools.obj_array import make_obj_array
            return make_obj_array([
                actx.to_numpy(
                    flatten(
                        conn(unflatten(template_ary, actx.from_numpy(o),
                                       actx)), actx)) for o in operand
            ])
        elif isinstance(operand, np.ndarray) and operand.ndim == 2:
            cache = self.places._get_cache(
                MatrixBuilderDirectResamplerCacheKey)
            key = (expr.from_dd.geometry, expr.from_dd.discr_stage,
                   expr.to_dd.discr_stage)

            try:
                mat = cache[key]
            except KeyError:
                from meshmode.discretization.connection import \
                    flatten_chained_connection
                from meshmode.discretization.connection.direct import \
                    make_direct_full_resample_matrix

                conn = self.places.get_connection(expr.from_dd, expr.to_dd)
                conn = flatten_chained_connection(actx, conn)
                mat = actx.to_numpy(
                    make_direct_full_resample_matrix(actx, conn))

                # FIXME: the resample matrix is slow to compute and very big
                # to store, so caching it may not be the best idea
                cache[key] = mat

            return mat.dot(operand)
        else:
            raise RuntimeError("unknown operand type: {}".format(
                type(operand)))
Example #20
0
    def flat_centers(self):
        """Return an object array of (interleaved) center coordinates.

        ``coord_t [ambient_dim][ncenters]``
        """
        from pytential import bind, sym

        actx = self._setup_actx
        centers = bind(
            self.places,
            sym.interleaved_expansion_centers(
                self.ambient_dim, dofdesc=self.source_dd.to_stage1()))(actx)

        return freeze(flatten(centers, actx, leaf_class=DOFArray), actx)
Example #21
0
    def __init__(self,
                 dcoll: DiscretizationCollection,
                 array_container: ArrayOrContainerT,
                 remote_rank, tag=None):
        actx = get_container_context_recursively(array_container)
        btag = BTAG_PARTITION(remote_rank)

        local_bdry_data = project(dcoll, "vol", btag, array_container)
        comm = dcoll.mpi_communicator

        self.dcoll = dcoll
        self.array_context = actx
        self.remote_btag = btag
        self.bdry_discr = dcoll.discr_from_dd(btag)
        self.local_bdry_data = local_bdry_data
        self.local_bdry_data_np = \
            to_numpy(flatten(self.local_bdry_data, actx), actx)

        self.tag = self.base_tag
        if tag is not None:
            self.tag += tag

        # Here, we initialize both send and recieve operations through
        # mpi4py `Request` (MPI_Request) instances for comm.Isend (MPI_Isend)
        # and comm.Irecv (MPI_Irecv) respectively. These initiate non-blocking
        # point-to-point communication requests and require explicit management
        # via the use of wait (MPI_Wait, MPI_Waitall, MPI_Waitany, MPI_Waitsome),
        # test (MPI_Test, MPI_Testall, MPI_Testany, MPI_Testsome), and cancel
        # (MPI_Cancel). The rank-local data `self.local_bdry_data_np` will have its
        # associated memory buffer sent across connected ranks and must not be
        # modified at the Python level during this process. Completion of the
        # requests is handled in :meth:`finish`.
        #
        # For more details on the mpi4py semantics, see:
        # https://mpi4py.readthedocs.io/en/stable/overview.html#nonblocking-communications
        #
        # NOTE: mpi4py currently (2021-11-03) holds a reference to the send
        # memory buffer for (i.e. `self.local_bdry_data_np`) until the send
        # requests is complete, however it is not clear that this is documented
        # behavior. We hold on to the buffer (via the instance attribute)
        # as well, just in case.
        self.send_req = comm.Isend(self.local_bdry_data_np,
                                   remote_rank,
                                   tag=self.tag)
        self.remote_data_host_numpy = np.empty_like(self.local_bdry_data_np)
        self.recv_req = comm.Irecv(self.remote_data_host_numpy,
                                   remote_rank,
                                   tag=self.tag)
Example #22
0
    def map_call(self, expr):
        arg, = expr.parameters
        rec_arg = self.rec(arg)

        if isinstance(rec_arg, np.ndarray) and self.is_kind_matrix(rec_arg):
            raise RuntimeError("expression is nonlinear in variable")

        from numbers import Number
        if isinstance(rec_arg, Number):
            return getattr(np, expr.function.name)(rec_arg)
        else:
            actx = self.array_context

            rec_arg = actx.from_numpy(rec_arg)
            result = getattr(actx.np, expr.function.name)(rec_arg)
            return actx.to_numpy(flatten(result, actx))
Example #23
0
    def flat_expansion_radii(self):
        """Return an array of radii associated with the (interleaved)
        expansion centers.

        ``coord_t [ncenters]``
        """
        from pytential import bind, sym

        actx = self._setup_actx
        radii = bind(
            self.places,
            sym.expansion_radii(self.ambient_dim,
                                granularity=sym.GRANULARITY_CENTER,
                                dofdesc=self.source_dd.to_stage1()))(actx)

        return freeze(flatten(radii, actx), actx)
Example #24
0
    def exec_compute_potential_insn(self, actx, insn, bound_expr, evaluate,
                                    return_timing_data):
        if return_timing_data:
            from warnings import warn
            warn("Timing data collection not supported.",
                 category=UnableToCollectTimingData)

        p2p = None

        kernel_args = evaluate_kernel_arguments(actx,
                                                evaluate,
                                                insn.kernel_arguments,
                                                flat=False)
        strengths = [evaluate(density) for density in insn.densities]

        # FIXME: Do this all at once
        results = []
        for o in insn.outputs:
            target_discr = bound_expr.places.get_discretization(
                o.target_name.geometry, o.target_name.discr_stage)

            # no on-disk kernel caching
            if p2p is None:
                p2p = self.get_p2p(actx,
                                   source_kernels=insn.source_kernels,
                                   target_kernels=insn.target_kernels)

            evt, output_for_each_kernel = p2p(actx.queue,
                                              targets=flatten(
                                                  target_discr.nodes(),
                                                  actx,
                                                  leaf_class=DOFArray),
                                              sources=self._nodes,
                                              strength=strengths,
                                              **kernel_args)

            from meshmode.discretization import Discretization
            result = output_for_each_kernel[o.target_kernel_index]
            if isinstance(target_discr, Discretization):
                template_ary = thaw(target_discr.nodes()[0], actx)
                result = unflatten(template_ary, result, actx, strict=False)

            results.append((o.name, result))

        timing_data = {}
        return results, timing_data
Example #25
0
def test_unregularized_with_ones_kernel(actx_factory):
    actx = actx_factory()

    nelements = 10
    order = 8

    mesh = mgen.make_curve_mesh(partial(mgen.ellipse, 1),
                                np.linspace(0, 1, nelements + 1), order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    discr = Discretization(actx, mesh,
                           InterpolatoryQuadratureSimplexGroupFactory(order))

    from pytential.unregularized import UnregularizedLayerPotentialSource
    lpot_source = UnregularizedLayerPotentialSource(discr)
    from pytential.target import PointsTarget
    targets = PointsTarget(actx.from_numpy(np.zeros((2, 1), dtype=np.float64)))

    places = GeometryCollection({
        sym.DEFAULT_SOURCE: lpot_source,
        sym.DEFAULT_TARGET: lpot_source,
        "target_non_self": targets
    })

    from sumpy.kernel import one_kernel_2d
    sigma_sym = sym.var("sigma")
    op = sym.int_g_vec(one_kernel_2d, sigma_sym, qbx_forced_limit=None)

    sigma = discr.zeros(actx) + 1

    result_self = bind(places, op, auto_where=places.auto_where)(actx,
                                                                 sigma=sigma)
    result_nonself = bind(places,
                          op,
                          auto_where=(places.auto_source,
                                      "target_non_self"))(actx, sigma=sigma)

    assert np.allclose(actx.to_numpy(flatten(result_self, actx)), 2 * np.pi)
    assert np.allclose(actx.to_numpy(result_nonself), 2 * np.pi)
Example #26
0
def test_analytic_comparison(actx_factory):
    """Quick test of state comparison routine."""
    from mirgecom.initializers import Vortex2D
    from mirgecom.simutil import compare_fluid_solutions, componentwise_norms

    actx = actx_factory()
    nel_1d = 4
    dim = 2

    from meshmode.mesh.generation import generate_regular_rect_mesh

    mesh = generate_regular_rect_mesh(a=(1.0, ) * dim,
                                      b=(2.0, ) * dim,
                                      nelements_per_axis=(nel_1d, ) * dim)

    order = 2
    discr = EagerDGDiscretization(actx, mesh, order=order)
    nodes = thaw(discr.nodes(), actx)
    zeros = discr.zeros(actx)
    ones = zeros + 1.0
    mass = ones
    energy = ones
    velocity = 2 * nodes
    mom = mass * velocity
    vortex_init = Vortex2D()
    vortex_soln = vortex_init(x_vec=nodes, eos=IdealSingleGas())

    cv = make_conserved(dim, mass=mass, energy=energy, momentum=mom)
    resid = vortex_soln - cv

    expected_errors = actx.to_numpy(
        flatten(componentwise_norms(discr, resid, order=np.inf),
                actx)).tolist()

    errors = compare_fluid_solutions(discr, cv, cv)
    assert max(errors) == 0

    errors = compare_fluid_solutions(discr, cv, vortex_soln)
    assert errors == expected_errors
Example #27
0
 def _flat_centers(dofdesc, qbx_forced_limit):
     centers = bind(bound_expr.places,
             sym.expansion_centers(
                 self.ambient_dim, qbx_forced_limit, dofdesc=dofdesc),
             )(actx)
     return freeze(flatten(centers, actx, leaf_class=DOFArray), actx)
Example #28
0
 def _flat_expansion_radii(dofdesc):
     radii = bind(
             bound_expr.places,
             sym.expansion_radii(self.ambient_dim, dofdesc=dofdesc),
             )(actx)
     return freeze(flatten(radii, actx), actx)
Example #29
0
 def _flat_nodes(dofdesc):
     discr = bound_expr.places.get_discretization(
             dofdesc.geometry, dofdesc.discr_stage)
     return freeze(flatten(discr.nodes(), actx, leaf_class=DOFArray), actx)
Example #30
0
def main(curve_fn=starfish, visualize=True):
    import logging
    logging.basicConfig(level=logging.WARNING)  # INFO for more progress info

    import pyopencl as cl
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue, force_device_scalars=True)

    from meshmode.mesh.generation import make_curve_mesh
    mesh = make_curve_mesh(
            curve_fn,
            np.linspace(0, 1, nelements+1),
            target_order)

    from pytential.qbx import QBXLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    pre_density_discr = Discretization(
            actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))

    qbx = QBXLayerPotentialSource(
            pre_density_discr, 4*target_order, qbx_order,
            fmm_order=qbx_order+3,
            target_association_tolerance=0.005,
            #fmm_backend="fmmlib",
            )

    from pytential.target import PointsTarget
    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=1000)
    targets_dev = actx.from_numpy(fplot.points)

    from pytential import GeometryCollection
    places = GeometryCollection({
        "qbx": qbx,
        "targets": PointsTarget(targets_dev),
        }, auto_where="qbx")

    density_discr = places.get_discretization("qbx")

    nodes = thaw(density_discr.nodes(), actx)
    angle = actx.np.arctan2(nodes[1], nodes[0])

    if k:
        kernel = HelmholtzKernel(2)
        kernel_kwargs = {"k": sym.var("k")}
    else:
        kernel = LaplaceKernel(2)
        kernel_kwargs = {}

    def op(**kwargs):
        kwargs.update(kernel_kwargs)

        #op = sym.d_dx(sym.S(kernel, sym.var("sigma"), **kwargs))
        return sym.D(kernel, sym.var("sigma"), **kwargs)
        #op = sym.S(kernel, sym.var("sigma"), qbx_forced_limit=None, **kwargs)

    if 0:
        from random import randrange
        sigma = actx.zeros(density_discr.ndofs, angle.entry_dtype)
        for _ in range(5):
            sigma[randrange(len(sigma))] = 1

        from arraycontext import unflatten
        sigma = unflatten(angle, sigma, actx)
    else:
        sigma = actx.np.cos(mode_nr*angle)

    if isinstance(kernel, HelmholtzKernel):
        for i, elem in np.ndenumerate(sigma):
            sigma[i] = elem.astype(np.complex128)

    bound_bdry_op = bind(places, op())
    if visualize:
        fld_in_vol = actx.to_numpy(
                bind(places, op(
                    source="qbx",
                    target="targets",
                    qbx_forced_limit=None))(actx, sigma=sigma, k=k))

        if enable_mayavi:
            fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
        else:
            fplot.write_vtk_file("layerpot-potential.vts", [
                ("potential", fld_in_vol)
                ])

    if 0:
        apply_op = bound_bdry_op.scipy_op(actx, "sigma", np.float64, k=k)
        from sumpy.tools import build_matrix
        mat = build_matrix(apply_op)

        import matplotlib.pyplot as pt
        pt.imshow(mat)
        pt.colorbar()
        pt.show()

    if enable_mayavi:
        # {{{ plot boundary field

        from arraycontext import flatten
        fld_on_bdry = actx.to_numpy(
                flatten(bound_bdry_op(actx, sigma=sigma, k=k), actx))
        nodes_host = actx.to_numpy(
                flatten(density_discr.nodes(), actx)
                ).reshape(density_discr.ambient_dim, -1)

        mlab.points3d(nodes_host[0], nodes_host[1],
                fld_on_bdry.real, scale_factor=0.03)

        mlab.colorbar()
        mlab.show()