def test_build_matrix_places(ctx_factory, source_discr_stage, target_discr_stage, visualize=False): ctx = ctx_factory() queue = cl.CommandQueue(ctx) # prevent cache explosion from sympy.core.cache import clear_cache clear_cache() qbx_forced_limit = -1 place_ids = ( sym.DOFDescriptor( geometry=sym.DEFAULT_SOURCE, discr_stage=source_discr_stage), sym.DOFDescriptor( geometry=sym.DEFAULT_TARGET, discr_stage=target_discr_stage), ) # build test operators qbx = _build_qbx_discr(queue, nelements=8, target_order=2, ndim=2, curve_f=partial(ellipse, 1.0)) op, u_sym, _ = _build_op(lpot_id=1, ndim=2, source=place_ids[0], target=place_ids[1], qbx_forced_limit=qbx_forced_limit) from pytential.symbolic.execution import GeometryCollection places = GeometryCollection(qbx, auto_where=place_ids) source_discr = places.get_discretization(place_ids[0]) target_discr = places.get_discretization(place_ids[1]) index_set = _build_block_index(source_discr, factor=0.6) from pytential.symbolic.execution import _prepare_expr op = _prepare_expr(places, op) # build full QBX matrix from pytential.symbolic.matrix import MatrixBuilder mbuilder = MatrixBuilder(queue, dep_expr=u_sym, other_dep_exprs=[], dep_source=places.get_geometry(place_ids[0]), dep_discr=places.get_discretization(place_ids[0]), places=places, context={}) qbx_mat = mbuilder(op) # build full p2p matrix from pytential.symbolic.matrix import P2PMatrixBuilder mbuilder = P2PMatrixBuilder(queue, dep_expr=u_sym, other_dep_exprs=[], dep_source=places.get_geometry(place_ids[0]), dep_discr=places.get_discretization(place_ids[0]), places=places, context={}) p2p_mat = mbuilder(op) assert p2p_mat.shape == (target_discr.nnodes, source_discr.nnodes) # build block qbx and p2p matrices from pytential.symbolic.matrix import NearFieldBlockBuilder mbuilder = NearFieldBlockBuilder(queue, dep_expr=u_sym, other_dep_exprs=[], dep_source=places.get_geometry(place_ids[0]), dep_discr=places.get_discretization(place_ids[0]), places=places, index_set=index_set, context={}) mat = mbuilder(op) if place_ids[0].discr_stage is not None: assert _max_block_error(qbx_mat, mat, index_set.get(queue)) < 1.0e-14 from pytential.symbolic.matrix import FarFieldBlockBuilder mbuilder = FarFieldBlockBuilder(queue, dep_expr=u_sym, other_dep_exprs=[], dep_source=places.get_geometry(place_ids[0]), dep_discr=places.get_discretization(place_ids[0]), places=places, index_set=index_set, context={}, exclude_self=True) mat = mbuilder(op) assert _max_block_error(p2p_mat, mat, index_set.get(queue)) < 1.0e-14
def test_build_matrix_fixed_stage(ctx_factory, source_discr_stage, target_discr_stage, visualize=False): """Checks that the block builders match for difference stages.""" ctx = ctx_factory() queue = cl.CommandQueue(ctx) actx = PyOpenCLArrayContext(queue) # prevent cache explosion from sympy.core.cache import clear_cache clear_cache() case = extra.CurveTestCase( name="starfish", curve_fn=NArmedStarfish(5, 0.25), target_order=4, resolutions=[32], index_sparsity_factor=0.6, op_type="scalar", tree_kind=None, ) logger.info("\n%s", case) # {{{ geometry dd = sym.DOFDescriptor(case.name) qbx = case.get_layer_potential(actx, case.resolutions[-1], case.target_order) places = GeometryCollection( {case.name: qbx}, auto_where=(dd.copy(discr_stage=source_discr_stage), dd.copy(discr_stage=target_discr_stage))) dd = places.auto_source density_discr = places.get_discretization(dd.geometry, dd.discr_stage) # }}} # {{{ symbolic if source_discr_stage is target_discr_stage: qbx_forced_limit = -1 else: qbx_forced_limit = None sym_u, sym_op = case.get_operator(places.ambient_dim, qbx_forced_limit) from pytential.symbolic.execution import _prepare_expr sym_prep_op = _prepare_expr(places, sym_op) # }}} # {{{ check source_discr = places.get_discretization(case.name, source_discr_stage) target_discr = places.get_discretization(case.name, target_discr_stage) logger.info("nelements: %d", density_discr.mesh.nelements) logger.info("ndofs: %d", source_discr.ndofs) logger.info("ndofs: %d", target_discr.ndofs) icols = case.get_block_indices(actx, source_discr, matrix_indices=False) irows = case.get_block_indices(actx, target_discr, matrix_indices=False) index_set = MatrixBlockIndexRanges(actx.context, icols, irows) kwargs = dict( dep_expr=sym_u, other_dep_exprs=[], dep_source=places.get_geometry(case.name), dep_discr=density_discr, places=places, context=case.knl_concrete_kwargs, ) # qbx from pytential.symbolic import matrix mat = matrix.MatrixBuilder(actx, **kwargs)(sym_prep_op) blk = matrix.NearFieldBlockBuilder(actx, index_set=index_set, **kwargs)(sym_prep_op) assert mat.shape == (target_discr.ndofs, source_discr.ndofs) assert extra.max_block_error(mat, blk, index_set.get(queue)) < 1.0e-14 # p2p mat = matrix.P2PMatrixBuilder(actx, exclude_self=True, **kwargs)(sym_prep_op) blk = matrix.FarFieldBlockBuilder(actx, index_set=index_set, exclude_self=True, **kwargs)(sym_prep_op) assert mat.shape == (target_discr.ndofs, source_discr.ndofs) assert extra.max_block_error(mat, blk, index_set.get(queue)) < 1.0e-14
def test_qbx_block_builder(ctx_factory, factor, ndim, lpot_id, visualize=False): ctx = ctx_factory() queue = cl.CommandQueue(ctx) # prevent cache explosion from sympy.core.cache import clear_cache clear_cache() place_ids = ( sym.DOFDescriptor( geometry=sym.DEFAULT_SOURCE, discr_stage=sym.QBX_SOURCE_STAGE2), sym.DOFDescriptor( geometry=sym.DEFAULT_TARGET, discr_stage=sym.QBX_SOURCE_STAGE2), ) target_order = 2 if ndim == 3 else 7 qbx = _build_qbx_discr(queue, target_order=target_order, ndim=ndim) op, u_sym, _ = _build_op(lpot_id, ndim=ndim, source=place_ids[0], target=place_ids[1], qbx_forced_limit="avg") from pytential.symbolic.execution import GeometryCollection, _prepare_expr places = GeometryCollection(qbx, auto_where=place_ids) expr = _prepare_expr(places, op) density_discr = places.get_discretization(place_ids[0]) index_set = _build_block_index(density_discr, factor=factor) from pytential.symbolic.matrix import NearFieldBlockBuilder mbuilder = NearFieldBlockBuilder(queue, dep_expr=u_sym, other_dep_exprs=[], dep_source=places.get_geometry(place_ids[0]), dep_discr=places.get_discretization(place_ids[0]), places=places, index_set=index_set, context={}) blk = mbuilder(expr) from pytential.symbolic.matrix import MatrixBuilder mbuilder = MatrixBuilder(queue, dep_expr=u_sym, other_dep_exprs=[], dep_source=places.get_geometry(place_ids[0]), dep_discr=places.get_discretization(place_ids[0]), places=places, context={}) mat = mbuilder(expr) index_set = index_set.get(queue) if visualize: blk_full = np.zeros_like(mat) mat_full = np.zeros_like(mat) for i in range(index_set.nblocks): itgt, isrc = index_set.block_indices(i) blk_full[np.ix_(itgt, isrc)] = index_set.block_take(blk, i) mat_full[np.ix_(itgt, isrc)] = index_set.take(mat, i) import matplotlib.pyplot as mp _, (ax1, ax2) = mp.subplots(1, 2, figsize=(10, 8), constrained_layout=True) ax1.imshow(mat_full) ax1.set_title('MatrixBuilder') ax2.imshow(blk_full) ax2.set_title('NearFieldBlockBuilder') mp.savefig("test_qbx_block_builder.png", dpi=300) assert _max_block_error(mat, blk, index_set) < 1.0e-14
case.target_order) places = GeometryCollection(qbx, auto_where=(dd, dd.to_stage1())) density_discr = places.get_discretization(dd.geometry, dd.discr_stage) logger.info("nelements: %d", density_discr.mesh.nelements) logger.info("ndofs: %d", density_discr.ndofs) # }}} # {{{ symbolic sym_u, sym_op = case.get_operator(ambient_dim) from pytential.symbolic.execution import _prepare_expr sym_prep_op = _prepare_expr(places, sym_op) # }}} # {{{ matrix index_set = case.get_block_indices(actx, density_discr) kwargs = dict(dep_expr=sym_u, other_dep_exprs=[], dep_source=places.get_geometry(dd.geometry), dep_discr=density_discr, places=places, context=case.knl_concrete_kwargs) if block_builder_type == "qbx": from pytential.symbolic.matrix import MatrixBuilder