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 ))
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))
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) )
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))
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)))
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
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)))
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 ))
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)))
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)))
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)))
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)))
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))
def map_common_subexpression(self, expr): return prim.cse( self.rec(expr.child), expr.prefix, expr.scope)
def map_common_subexpression(self, expr): return prim.cse(self.rec(expr.child), expr.prefix, expr.scope)
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)
def get_weight(self, where=None): if self.use_l2_weighting: return cse(area_element(where)*QWeight(where)) else: return 1