Пример #1
0
    def operator(self, u):
        from sumpy.kernel import HelmholtzKernel, LaplaceKernel

        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u/sqrt_w)

        knl = self.kernel
        lknl = self.laplace_kernel

        knl_kwargs = {}
        knl_kwargs["kernel_arguments"] = self.kernel_arguments

        DpS0u = sym.Dp(knl,  # noqa
                cse(sym.S(lknl, inv_sqrt_w_u)),
                **knl_kwargs)

        if self.use_improved_operator:
            Dp0S0u = -0.25*u + sym.Sp(  # noqa
                    lknl,  # noqa
                    sym.Sp(lknl, inv_sqrt_w_u, qbx_forced_limit="avg"),
                    qbx_forced_limit="avg")

            if isinstance(self.kernel, HelmholtzKernel):
                DpS0u = (  # noqa
                        sym.Dp(knl - lknl,  # noqa
                            cse(sym.S(lknl, inv_sqrt_w_u, qbx_forced_limit=+1)),
                            qbx_forced_limit=+1, **knl_kwargs)
                        + Dp0S0u)
            elif isinstance(knl, LaplaceKernel):
                DpS0u = Dp0S0u  # noqa
            else:
                raise ValueError("no improved operator for %s known"
                        % self.kernel)

        if self.is_unique_only_up_to_constant():
            # The interior Neumann operator in this representation
            # has a nullspace. The mean of the density must be matched
            # to the desired solution separately. As is, this operator
            # returns a mean that is not well-specified.

            amb_dim = self.kernel.dim
            ones_contribution = (
                    sym.Ones() * sym.mean(amb_dim, amb_dim-1, inv_sqrt_w_u))
        else:
            ones_contribution = 0

        return (-self.loc_sign*0.5*u
                + sqrt_w*(
                    sym.Sp(knl, inv_sqrt_w_u, qbx_forced_limit="avg", **knl_kwargs)
                    - self.alpha*DpS0u
                    + ones_contribution
                    ))
Пример #2
0
    def operator(self, u):
        from sumpy.kernel import HelmholtzKernel, LaplaceKernel

        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u / sqrt_w)

        knl = self.kernel
        lknl = self.laplace_kernel

        knl_kwargs = {}
        knl_kwargs["kernel_arguments"] = self.kernel_arguments

        DpS0u = sym.Dp(
            knl,  # noqa
            cse(sym.S(lknl, inv_sqrt_w_u)),
            **knl_kwargs)

        if self.use_improved_operator:
            Dp0S0u = -0.25 * u + sym.Sp(  # noqa
                lknl,  # noqa
                sym.Sp(lknl, inv_sqrt_w_u, qbx_forced_limit="avg"),
                qbx_forced_limit="avg")

            if isinstance(self.kernel, HelmholtzKernel):
                DpS0u = (  # noqa
                    sym.Dp(
                        knl - lknl,  # noqa
                        cse(sym.S(lknl, inv_sqrt_w_u, qbx_forced_limit=+1)),
                        qbx_forced_limit=+1,
                        **knl_kwargs) + Dp0S0u)
            elif isinstance(knl, LaplaceKernel):
                DpS0u = Dp0S0u  # noqa
            else:
                raise ValueError(
                    f"no improved operator for '{self.kernel}' known")

        if self.is_unique_only_up_to_constant():
            # The interior Neumann operator in this representation
            # has a nullspace. The mean of the density must be matched
            # to the desired solution separately. As is, this operator
            # returns a mean that is not well-specified.

            amb_dim = self.kernel.dim
            ones_contribution = (sym.Ones() *
                                 sym.mean(amb_dim, amb_dim - 1, inv_sqrt_w_u))
        else:
            ones_contribution = 0

        return (
            -self.loc_sign * 0.5 * u + sqrt_w *
            (sym.Sp(knl, inv_sqrt_w_u, qbx_forced_limit="avg", **knl_kwargs) -
             self.alpha * DpS0u + ones_contribution))
Пример #3
0
    def operator(self, u):
        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u / sqrt_w)

        if self.is_unique_only_up_to_constant():
            # The exterior Dirichlet operator in this representation
            # has a nullspace. The mean of the density must be matched
            # to the desired solution separately. As is, this operator
            # returns a mean that is not well-specified.
            #
            # See Hackbusch, https://books.google.com/books?id=Ssnf7SZB0ZMC
            # Theorem 8.2.18b

            amb_dim = self.kernel.dim
            ones_contribution = (sym.Ones() *
                                 sym.mean(amb_dim, amb_dim - 1, inv_sqrt_w_u))
        else:
            ones_contribution = 0

        return (
            -self.loc_sign * 0.5 * u + sqrt_w *
            (self.alpha * sym.S(self.kernel,
                                inv_sqrt_w_u,
                                qbx_forced_limit=+1,
                                kernel_arguments=self.kernel_arguments) -
             sym.D(self.kernel,
                   inv_sqrt_w_u,
                   qbx_forced_limit="avg",
                   kernel_arguments=self.kernel_arguments) + ones_contribution)
        )
Пример #4
0
    def operator(self, u):
        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u/sqrt_w)

        if self.is_unique_only_up_to_constant():
            # The exterior Dirichlet operator in this representation
            # has a nullspace. The mean of the density must be matched
            # to the desired solution separately. As is, this operator
            # returns a mean that is not well-specified.
            #
            # See Hackbusch, http://books.google.com/books?id=Ssnf7SZB0ZMC
            # Theorem 8.2.18b

            amb_dim = self.kernel.dim
            ones_contribution = (
                    sym.Ones() * sym.mean(amb_dim, amb_dim-1, inv_sqrt_w_u))
        else:
            ones_contribution = 0

        return (-self.loc_sign*0.5*u
                + sqrt_w*(
                    self.alpha*sym.S(self.kernel, inv_sqrt_w_u,
                        qbx_forced_limit=+1, kernel_arguments=self.kernel_arguments)
                    - sym.D(self.kernel, inv_sqrt_w_u,
                        qbx_forced_limit="avg",
                        kernel_arguments=self.kernel_arguments)
                    + ones_contribution))
Пример #5
0
    def map_int_g_ds(self, expr):
        dsource = self.rec(expr.dsource)

        ambient_dim = self.ambient_dim

        from sumpy.kernel import KernelDimensionSetter
        kernel = _insert_source_derivative_into_kernel(
                KernelDimensionSetter(ambient_dim)(expr.kernel))

        from pytools.obj_array import make_obj_array
        nabla = MultiVector(make_obj_array(
            [prim.NablaComponent(axis, None)
                for axis in range(ambient_dim)]))

        kernel_arguments = dict(
                (name, self.rec(arg_expr))
                for name, arg_expr in expr.kernel_arguments.items()
                )

        def add_dir_vec_to_kernel_args(coeff):
            result = kernel_arguments.copy()
            result[_DIR_VEC_NAME] = _get_dir_vec(coeff, ambient_dim)
            return result

        rec_operand = prim.cse(self.rec(expr.density))
        return (dsource*nabla).map(
                lambda coeff: prim.IntG(
                    kernel,
                    rec_operand, expr.qbx_forced_limit, expr.source, expr.target,
                    kernel_arguments=add_dir_vec_to_kernel_args(coeff)))
Пример #6
0
 def get_weight(self, dofdesc=None):
     if self.use_l2_weighting:
         return cse(
             area_element(self.kernel.dim, dofdesc=dofdesc) *
             QWeight(dofdesc=dofdesc))
     else:
         return 1
Пример #7
0
    def representation(self, u, map_potentials=None, **kwargs):
        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u/sqrt_w)

        if map_potentials is None:
            map_potentials = lambda x: x

        return (
                self.alpha*map_potentials(
                    S(self.kernel_and_args, inv_sqrt_w_u, **kwargs))
                - map_potentials(D(self.kernel_and_args, inv_sqrt_w_u, **kwargs)))
Пример #8
0
    def operator(self, u):
        from sumpy.kernel import HelmholtzKernel, LaplaceKernel

        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u/sqrt_w)

        DpS0u = Dp(self.kernel_and_args,  # noqa
                cse(S(self.laplace_kernel_and_args, inv_sqrt_w_u)))

        if self.use_improved_operator:
            Dp0S0u = -0.25*u + Sp(self.laplace_kernel_and_args,  # noqa
                    Sp(self.laplace_kernel_and_args, inv_sqrt_w_u))

            if isinstance(self.kernel, HelmholtzKernel):
                DpS0u = (Dp(self.kernel_and_args - self.laplace_kernel_and_args,  # noqa
                    cse(S(self.laplace_kernel_and_args, inv_sqrt_w_u))) + Dp0S0u)
            elif isinstance(self.kernel_and_args, LaplaceKernel):
                DpS0u = Dp0S0u  # noqa
            else:
                raise ValueError("no improved operator for %s known"
                        % self.kernel)

        if self.is_unique_only_up_to_constant():
            # The interior Neumann operator in this representation
            # has a nullspace. The mean of the density must be matched
            # to the desired solution separately. As is, this operator
            # returns a mean that is not well-specified.

            ones_contribution = Ones() * mean(inv_sqrt_w_u)
        else:
            ones_contribution = 0

        return (-self.loc_sign*0.5*u
                + sqrt_w*(
                    Sp(self.kernel_and_args, inv_sqrt_w_u)
                    - self.alpha*DpS0u
                    + ones_contribution
                    ))
Пример #9
0
    def representation(self, u, map_potentials=None, qbx_forced_limit=None,
            **kwargs):
        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u/sqrt_w)

        if map_potentials is None:
            def map_potentials(x):  # pylint:disable=function-redefined
                return x

        kwargs["qbx_forced_limit"] = qbx_forced_limit
        kwargs["kernel_arguments"] = self.kernel_arguments

        return (
                map_potentials(
                    sym.S(self.kernel, inv_sqrt_w_u, **kwargs))
                - self.alpha
                * map_potentials(
                    sym.D(self.kernel,
                        sym.S(self.laplace_kernel, inv_sqrt_w_u),
                        **kwargs)))
Пример #10
0
    def representation(self,
                       u,
                       map_potentials=None,
                       qbx_forced_limit=None,
                       **kwargs):
        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u / sqrt_w)

        if map_potentials is None:

            def map_potentials(x):  # pylint:disable=function-redefined
                return x

        kwargs["qbx_forced_limit"] = qbx_forced_limit
        kwargs["kernel_arguments"] = self.kernel_arguments

        return (map_potentials(sym.S(self.kernel, inv_sqrt_w_u, **kwargs)) -
                self.alpha * map_potentials(
                    sym.D(self.kernel, sym.S(self.laplace_kernel,
                                             inv_sqrt_w_u), **kwargs)))
Пример #11
0
    def representation(self,
            u, map_potentials=None, qbx_forced_limit=None):
        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u/sqrt_w)

        if map_potentials is None:
            def map_potentials(x):  # pylint:disable=function-redefined
                return x

        def S(density):  # noqa
            return sym.S(self.kernel, density,
                    kernel_arguments=self.kernel_arguments,
                    qbx_forced_limit=qbx_forced_limit)

        def D(density):  # noqa
            return sym.D(self.kernel, density,
                    kernel_arguments=self.kernel_arguments,
                    qbx_forced_limit=qbx_forced_limit)

        return (
                self.alpha*map_potentials(S(inv_sqrt_w_u))
                - map_potentials(D(inv_sqrt_w_u)))
Пример #12
0
    def representation(self,
            u, map_potentials=None, qbx_forced_limit=None):
        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u/sqrt_w)

        if map_potentials is None:
            def map_potentials(x):  # pylint:disable=function-redefined
                return x

        def S(density):  # noqa
            return sym.S(self.kernel, density,
                    kernel_arguments=self.kernel_arguments,
                    qbx_forced_limit=qbx_forced_limit)

        def D(density):  # noqa
            return sym.D(self.kernel, density,
                    kernel_arguments=self.kernel_arguments,
                    qbx_forced_limit=qbx_forced_limit)

        return (
                self.alpha*map_potentials(S(inv_sqrt_w_u))
                - map_potentials(D(inv_sqrt_w_u)))
Пример #13
0
    def operator(self, u):
        sqrt_w = self.get_sqrt_weight()
        inv_sqrt_w_u = cse(u/sqrt_w)

        if self.is_unique_only_up_to_constant():
            # The exterior Dirichlet operator in this representation
            # has a nullspace. The mean of the density must be matched
            # to the desired solution separately. As is, this operator
            # returns a mean that is not well-specified.
            #
            # See Hackbusch, http://books.google.com/books?id=Ssnf7SZB0ZMC
            # Theorem 8.2.18b

            ones_contribution = Ones() * mean(inv_sqrt_w_u)
        else:
            ones_contribution = 0

        return (-self.loc_sign*0.5*u
                + sqrt_w*(
                    self.alpha*S(self.kernel_and_args, inv_sqrt_w_u)
                    - D(self.kernel_and_args, inv_sqrt_w_u)
                    + ones_contribution))
Пример #14
0
 def map_common_subexpression(self, expr):
     return prim.cse(
             self.rec(expr.child),
             expr.prefix,
             expr.scope)
Пример #15
0
 def map_common_subexpression(self, expr):
     return prim.cse(self.rec(expr.child), expr.prefix, expr.scope)
Пример #16
0
    def map_common_subexpression(self, expr):
        child = self.rec(expr.child)
        if child is expr.child:
            return expr

        return prim.cse(child, expr.prefix, expr.scope)
Пример #17
0
 def get_weight(self, where=None):
     if self.use_l2_weighting:
         return cse(area_element(where)*QWeight(where))
     else:
         return 1