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)))
def direct_resampler(self): """ .. warning:: This always returns a :class:`~meshmode.discretization.connection.DirectDiscretizationConnection`. In case the geometry has been refined multiple times, a direct connection can have a large number of groups and/or interpolation batches, making it scale significantly worse than the one returned by :attr:`resampler`. """ from meshmode.discretization.connection import \ flatten_chained_connection conn = self.resampler with cl.CommandQueue(self.cl_context) as queue: conn = flatten_chained_connection(queue, conn) return conn
def direct_resampler(self): """ .. warning:: This always returns a :class:`~meshmode.discretization.connection.DirectDiscretizationConnect`. In case the geometry has been refined multiple times, a direct connection can have a large number of groups and/or interpolation batches, making it scale significantly worse than the one returned by :attr:`resampler`. """ from meshmode.discretization.connection import \ flatten_chained_connection conn = self.resampler with cl.CommandQueue(self.cl_context) as queue: conn = flatten_chained_connection(queue, conn) return conn
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) operand = unflatten_from_numpy(actx, discr, operand) return flatten_to_numpy(actx, conn(operand)) elif isinstance(operand, np.ndarray) and operand.ndim == 2: cache = self.places._get_cache("direct_resampler") 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 conn = self.places.get_connection(expr.from_dd, expr.to_dd) conn = flatten_chained_connection(actx, conn) mat = actx.to_numpy(conn.full_resample_matrix(actx)) # 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)))