Пример #1
0
def _get_centers_and_expansion_radii(queue, source, target_discr,
                                     qbx_forced_limit):
    """
    :arg queue: a :class:`pyopencl.CommandQueue`.
    :arg source: a :class:`pytential.source.LayerPotentialSourceBase`.
    :arg target_discr: a :class:`meshmode.discretization.Discretization`.
    :arg qbx_forced_limit: an integer (*+1* or *-1*).

    :return: a tuple of `(centers, radii)` for each node in *target_discr*.
    """

    if source.density_discr is target_discr:
        # NOTE: skip expensive target association
        centers = bind(
            source, sym.expansion_centers(source.ambient_dim,
                                          qbx_forced_limit))(queue)
        radii = bind(source, sym.expansion_radii(source.ambient_dim))(queue)
    else:
        from pytential.qbx.utils import get_interleaved_centers
        centers = get_interleaved_centers(queue, source)
        radii = bind(
            source,
            sym.expansion_radii(source.ambient_dim,
                                granularity=sym.GRANULARITY_CENTER))(queue)

        # NOTE: using a very small tolerance to make sure all the stage2
        # targets are associated to a center. We can't use the user provided
        # source.target_association_tolerance here because it will likely be
        # way too small.
        target_association_tolerance = 1.0e-1

        from pytential.qbx.target_assoc import associate_targets_to_qbx_centers
        code_container = source.target_association_code_container
        assoc = associate_targets_to_qbx_centers(
            source,
            code_container.get_wrangler(queue),
            [(target_discr, qbx_forced_limit)],
            target_association_tolerance=target_association_tolerance)

        centers = [
            cl.array.take(c, assoc.target_to_center, queue=queue)
            for c in centers
        ]
        radii = cl.array.take(radii, assoc.target_to_center, queue=queue)

    return centers, radii
Пример #2
0
    def weights_and_area_elements(self):
        import pytential.symbolic.primitives as p
        from pytential.symbolic.execution import bind
        with cl.CommandQueue(self.cl_context) as queue:
            # quad_stage2_density_discr is not guaranteed to be usable for
            # interpolation/differentiation. Use density_discr to find
            # area element instead, then upsample that.

            area_element = self.resampler(
                    queue,
                    bind(
                        self.density_discr,
                        p.area_element(self.ambient_dim, self.dim)
                        )(queue))

            qweight = bind(self.quad_stage2_density_discr, p.QWeight())(queue)

            return (area_element.with_queue(queue)*qweight).with_queue(None)
Пример #3
0
def _norm_inf_op(discr, num_components):
    from pytential import sym, bind
    if num_components is not None:
        from pymbolic.primitives import make_sym_vector
        v = make_sym_vector("arg", num_components)
        max_arg = sym.abs(v)
    else:
        max_arg = sym.abs(sym.var("arg"))

    return bind(discr, sym.NodeMax(max_arg))
Пример #4
0
def _norm_op(discr, num_components):
    from pytential import sym, bind
    if num_components is not None:
        from pymbolic.primitives import make_sym_vector
        v = make_sym_vector("integrand", num_components)
        integrand = sym.real(np.dot(sym.conj(v), v))
    else:
        integrand = sym.abs(sym.var("integrand"))**2

    return bind(discr, sym.integral(integrand))
Пример #5
0
def _norm_2_op(discr, num_components):
    from pytential import sym, bind
    if num_components is not None:
        from pymbolic.primitives import make_sym_vector
        v = make_sym_vector("integrand", num_components)
        integrand = sym.real(np.dot(sym.conj(v), v))
    else:
        integrand = sym.abs(sym.var("integrand"))**2

    return bind(discr, sym.integral(discr.ambient_dim, discr.dim, integrand))
Пример #6
0
def _norm_inf_op(discr, num_components):
    from pytential import sym, bind
    if num_components is not None:
        from pymbolic.primitives import make_sym_vector
        v = make_sym_vector("arg", num_components)
        max_arg = sym.abs(v)
    else:
        max_arg = sym.abs(sym.var("arg"))

    return bind(discr, sym.NodeMax(max_arg))
Пример #7
0
def _get_weights_and_area_elements(queue, source, source_discr):
    """
    :arg queue: a :class:`pyopencl.CommandQueue`.
    :arg source: a :class:`pytential.source.LayerPotentialSourceBase`.
    :arg source_discr: a :class:`meshmode.discretization.Discretization`.

    :return: quadrature weights for each node in *source_discr*.
    """

    if source.quad_stage2_density_discr is source_discr:
        waa = source.weights_and_area_elements().with_queue(queue)
    else:
        # NOTE: copied from `weights_and_area_elements`, but using the
        # discretization given by `where` and no interpolation
        area = bind(source_discr,
                sym.area_element(source.ambient_dim, source.dim))(queue)
        qweight = bind(source_discr, sym.QWeight())(queue)
        waa = area * qweight

    return waa
Пример #8
0
    def map_num_reference_derivative(self, expr):
        rec_operand = self.rec(expr.operand)

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

        where_discr = self.places[expr.where]
        op = sym.NumReferenceDerivative(expr.ref_axes, sym.var("u"))
        return bind(where_discr, op)(
                self.queue, u=cl.array.to_device(self.queue, rec_operand)).get()
Пример #9
0
def _get_weights_and_area_elements(queue, source, source_discr):
    """
    :arg queue: a :class:`pyopencl.CommandQueue`.
    :arg source: a :class:`pytential.source.LayerPotentialSourceBase`.
    :arg source_discr: a :class:`meshmode.discretization.Discretization`.

    :return: quadrature weights for each node in *source_discr*.
    """

    if source.quad_stage2_density_discr is source_discr:
        waa = source.weights_and_area_elements().with_queue(queue)
    else:
        # NOTE: copied from `weights_and_area_elements`, but using the
        # discretization given by `where` and no interpolation
        area = bind(source_discr,
                    sym.area_element(source.ambient_dim, source.dim))(queue)
        qweight = bind(source_discr, sym.QWeight())(queue)
        waa = area * qweight

    return waa
Пример #10
0
    def map_num_reference_derivative(self, expr):
        rec_operand = self.rec(expr.operand)

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

        rec_operand = cl.array.to_device(self.queue, rec_operand)
        op = sym.NumReferenceDerivative(ref_axes=expr.ref_axes,
                                        operand=sym.var("u"),
                                        dofdesc=expr.dofdesc)
        return bind(self.places, op)(self.queue, u=rec_operand).get()
Пример #11
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")

        if isinstance(rec_arg, np.ndarray):
            rec_arg = cl.array.to_device(self.queue, rec_arg)

        op = expr.function(sym.var("u"))
        result = bind(self.dep_source, op)(self.queue, u=rec_arg)

        if isinstance(result, cl.array.Array):
            result = result.get()

        return result
Пример #12
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")

        if isinstance(rec_arg, np.ndarray):
            rec_arg = cl.array.to_device(self.queue, rec_arg)

        op = expr.function(sym.var("u"))
        result = bind(self.dep_source, op)(self.queue, u=rec_arg)

        if isinstance(result, cl.array.Array):
            result = result.get()

        return result
Пример #13
0
    def _coarsest_quad_resolution(self, last_dim_length="npanels"):
        """This measures the quadrature resolution across the
        mesh. In a 1D uniform mesh of uniform 'parametrization speed', it
        should be the same as the panel length.
        """
        import pytential.qbx.utils as utils
        from pytential import sym, bind
        with cl.CommandQueue(self.cl_context) as queue:
            maxstretch = bind(
                    self,
                    sym._simplex_mapping_max_stretch_factor(
                        self.ambient_dim)
                    )(queue)

            maxstretch = utils.to_last_dim_length(
                    self.density_discr, maxstretch, last_dim_length)
            maxstretch = maxstretch.with_queue(None)

        return maxstretch
Пример #14
0
    def _stage2_coarsest_quad_resolution(self, last_dim_length="npanels"):
        """This measures the quadrature resolution across the
        mesh. In a 1D uniform mesh of uniform 'parametrization speed', it
        should be the same as the panel length.
        """
        if last_dim_length != "npanels":
            # Not technically required below, but no need to loosen for now.
            raise NotImplementedError()

        import pytential.qbx.utils as utils
        from pytential import sym, bind
        with cl.CommandQueue(self.cl_context) as queue:
            maxstretch = bind(
                    self, sym._simplex_mapping_max_stretch_factor(
                        self.ambient_dim,
                        where=sym.QBXSourceStage2(sym.DEFAULT_SOURCE))
                    )(queue)
            maxstretch = utils.to_last_dim_length(
                    self.stage2_density_discr, maxstretch, last_dim_length)
            maxstretch = maxstretch.with_queue(None)

        return maxstretch
Пример #15
0
def _integral_op(discr):
    from pytential import sym, bind
    return bind(discr,
            sym.integral(
                discr.ambient_dim, discr.dim, sym.var("integrand")))
Пример #16
0
def _integral_op(discr):
    from pytential import sym, bind
    return bind(
        discr, sym.integral(discr.ambient_dim, discr.dim,
                            sym.var("integrand")))
Пример #17
0
 def map_node_coordinate_component(self, expr):
     where_discr = self.places[expr.where]
     op = sym.NodeCoordinateComponent(expr.ambient_axis)
     return bind(where_discr, op)(self.queue).get()
Пример #18
0
def _integral_op(discr):
    from pytential import sym, bind
    return bind(discr, sym.integral(sym.var("integrand")))
Пример #19
0
 def map_node_coordinate_component(self, expr):
     op = sym.NodeCoordinateComponent(expr.ambient_axis,
                                      dofdesc=expr.dofdesc)
     return bind(self.places, op)(self.queue).get()