diff --git a/sumpy/expansion/__init__.py b/sumpy/expansion/__init__.py index f1bc491b3a737d3c867917abf2dccaf516ba28b1..6477b9ab4d9b7de6ba5b3a096ee57de42e29b51d 100644 --- a/sumpy/expansion/__init__.py +++ b/sumpy/expansion/__init__.py @@ -58,6 +58,9 @@ class ExpansionBase(object): def get_args(self): return self.kernel.get_args() + def get_source_args(self): + return self.kernel.get_source_args() + # }}} def coefficients_from_source(self, expr, avec, bvec): diff --git a/sumpy/expansion/multipole.py b/sumpy/expansion/multipole.py index 84a19e9a78c51b0d4a99a85992056af6bf188c68..924055dc1d8fc670ff45a55eb4c2884b1e9a47b0 100644 --- a/sumpy/expansion/multipole.py +++ b/sumpy/expansion/multipole.py @@ -49,8 +49,23 @@ class VolumeTaylorMultipoleExpansion( from sumpy.symbolic import make_sym_vector dir_vec = make_sym_vector(kernel.dir_vec_name, kernel.dim) - result = [0] - 1/0 + coeff_identifiers = self.get_coefficient_identifiers() + result = [0] * len(coeff_identifiers) + + for idim in xrange(kernel.dim): + for i, mi in enumerate(coeff_identifiers): + if mi[idim] == 0: + continue + + derivative_mi = tuple(mi_i - 1 if iaxis == idim else mi_i + for iaxis, mi_i in enumerate(mi)) + + result[i] += ( + - 1/mi_factorial(derivative_mi) + * mi_power(avec, derivative_mi) + * dir_vec[idim]) + + return result else: return [ mi_power(avec, mi) / mi_factorial(mi) diff --git a/sumpy/kernel.py b/sumpy/kernel.py index d9133300f8c55cea0b50d4d9777d0c888bad4e36..0f9a9a474251584b04885d76e2ac34e56550656a 100644 --- a/sumpy/kernel.py +++ b/sumpy/kernel.py @@ -127,6 +127,13 @@ class Kernel(object): """ return [] + def get_source_args(self): + """Return list of :cls:`loopy.Argument` instances describing + extra arguments used by kernel in picking up contributions + from point sources. + """ + return [] + def __sub__(self, other): return DifferenceKernel(self, other) @@ -252,6 +259,9 @@ class DifferenceKernel(Kernel): Kernel.__init__(self, self.kernel_plus.dim) + # FIXME + raise NotImplementedError("difference kernel mostly unimplemented") + def __getinitargs__(self): return (self.kernel_plus, self.kernel_minus) @@ -265,8 +275,6 @@ class DifferenceKernel(Kernel): mapper_method = "map_difference_kernel" - # FIXME mostly unimplemented - # }}} @@ -305,6 +313,9 @@ class KernelWrapper(Kernel): def get_args(self): return self.inner_kernel.get_args() + def get_source_args(self): + return self.inner_kernel.get_source_args() + # }}} @@ -376,10 +387,10 @@ class DirectionalDerivative(DerivativeBase): return r"%s . \/_%s %s" % ( self.dir_vec_name, self.directional_kind[0], self.inner_kernel) - def get_args(self): - return self.inner_kernel.get_args() + [ - lp.GlobalArg(self.dir_vec_name, None, shape=lp.auto, - dim_tags="sep,C")] + def get_source_args(self): + return [ + lp.GlobalArg(self.dir_vec_name, None, shape=(self.dim, "nsrc"), + dim_tags="sep,C")] + self.inner_kernel.get_source_args() class DirectionalTargetDerivative(DirectionalDerivative): diff --git a/sumpy/p2e.py b/sumpy/p2e.py index 8114845ab4d78a781fbbe0f0d55a39170ed7da29..cd828d8d5d9a094edf4bfe0b721bc6eca4590785 100644 --- a/sumpy/p2e.py +++ b/sumpy/p2e.py @@ -77,19 +77,20 @@ class P2E(object): complex_dtype=np.complex128 # FIXME ) + from sumpy.tools import gather_source_arguments arguments = ( [ - lp.GlobalArg("sources", None, shape=(self.dim, "nsources")), - lp.GlobalArg("strengths", None, shape="nsources"), + lp.GlobalArg("sources", None, shape=(self.dim, "nsrc")), + lp.GlobalArg("strengths", None, shape="nsrc"), lp.GlobalArg("box_source_starts,box_source_counts_nonchild", None, shape=None), lp.GlobalArg("centers", None, shape="dim, nboxes"), lp.GlobalArg("expansions", None, shape=("nboxes", len(coeff_names))), lp.ValueArg("nboxes", np.int32), - lp.ValueArg("nsources", np.int32), + lp.ValueArg("nsrc", np.int32), "..." - ] + self.expansion.get_args()) + ] + gather_source_arguments([self.expansion])) loopy_knl = lp.make_kernel(self.device, [ diff --git a/sumpy/p2p.py b/sumpy/p2p.py index a581a45ee0559de7d87ca10522373371bc999d13..e7129684e3336fdbe268b4e52fd98acacf082d07 100644 --- a/sumpy/p2p.py +++ b/sumpy/p2p.py @@ -83,7 +83,7 @@ class P2P(KernelComputation): * var("strength_%d" % self.strength_usage[i])[var("isrc")] for i, name in enumerate(result_names)] - from sumpy.tools import gather_arguments + from sumpy.tools import gather_source_arguments arguments = ( [ lp.GlobalArg("src", None, @@ -98,7 +98,7 @@ class P2P(KernelComputation): ]+[ lp.GlobalArg("result_%d" % i, dtype, shape="ntgt", order="C") for i, dtype in enumerate(self.value_dtypes) - ] + gather_arguments(self.kernels)) + ] + gather_source_arguments(self.kernels)) if self.exclude_self: from pymbolic.primitives import If, ComparisonOperator, Variable diff --git a/sumpy/qbx.py b/sumpy/qbx.py index 36a3cb02bc56c58dab943af6d6947820101dce3f..8ed6382711fda7e1db472c27daac86f247c61edd 100644 --- a/sumpy/qbx.py +++ b/sumpy/qbx.py @@ -118,7 +118,7 @@ class LayerPotentialBase(KernelComputation): * self.get_strength_or_not(isrc_sym, i) for i, name in enumerate(result_names)] - from sumpy.tools import gather_arguments + from sumpy.tools import gather_source_arguments arguments = ( [ lp.GlobalArg("src", None, @@ -130,7 +130,7 @@ class LayerPotentialBase(KernelComputation): lp.ValueArg("nsrc", None), lp.ValueArg("ntgt", None), ] + self.get_input_and_output_arguments() - + gather_arguments(self.kernels)) + + gather_source_arguments(self.kernels)) loopy_knl = lp.make_kernel(self.device, "{[isrc,itgt,idim]: 0<=itgt tgt_order - slack assert eoc_rec_grad_x.order_estimate() > tgt_order_grad - grad_slack