Ejemplo n.º 1
0
def build_matrix(actx,
                 places,
                 exprs,
                 input_exprs,
                 domains=None,
                 auto_where=None,
                 context=None):
    """
    :arg actx: a :class:`~meshmode.array_context.ArrayContext`.
    :arg places: a :class:`~pytential.symbolic.execution.GeometryCollection`.
        Alternatively, any list or mapping that is a valid argument for its
        constructor can also be used.
    :arg exprs: an array of expressions corresponding to the output block
        rows of the matrix. May also be a single expression.
    :arg input_exprs: an array of expressions corresponding to the
        input block columns of the matrix. May also be a single expression.
    :arg domains: a list of discretization identifiers (see 'places') or
        *None* values indicating the domains on which each component of the
        solution vector lives.  *None* values indicate that the component
        is a scalar.  If *None*, *auto_where* or, if it is not provided,
        :class:`~pytential.symbolic.primitives.DEFAULT_SOURCE` is required
        to be a key in :attr:`places`.
    :arg auto_where: For simple source-to-self or source-to-target
        evaluations, find 'where' attributes automatically.
    """

    if context is None:
        context = {}

    from pytential import GeometryCollection
    if not isinstance(places, GeometryCollection):
        places = GeometryCollection(places, auto_where=auto_where)
    exprs = _prepare_expr(places, exprs, auto_where=auto_where)

    if not (isinstance(exprs, np.ndarray) and exprs.dtype.char == "O"):
        from pytools.obj_array import make_obj_array
        exprs = make_obj_array([exprs])

    try:
        input_exprs = list(input_exprs)
    except TypeError:
        # not iterable, wrap in a list
        input_exprs = [input_exprs]

    domains = _prepare_domains(len(input_exprs), places, domains,
                               places.auto_source)

    from pytential.symbolic.matrix import MatrixBuilder, is_zero
    nblock_rows = len(exprs)
    nblock_columns = len(input_exprs)
    blocks = np.zeros((nblock_rows, nblock_columns), dtype=np.object)

    dtypes = []
    for ibcol in range(nblock_columns):
        dep_source = places.get_geometry(domains[ibcol].geometry)
        dep_discr = places.get_discretization(domains[ibcol].geometry,
                                              domains[ibcol].discr_stage)

        mbuilder = MatrixBuilder(actx,
                                 dep_expr=input_exprs[ibcol],
                                 other_dep_exprs=(input_exprs[:ibcol] +
                                                  input_exprs[ibcol + 1:]),
                                 dep_source=dep_source,
                                 dep_discr=dep_discr,
                                 places=places,
                                 context=context)

        for ibrow in range(nblock_rows):
            block = mbuilder(exprs[ibrow])
            assert is_zero(block) or isinstance(block, np.ndarray)

            blocks[ibrow, ibcol] = block
            if isinstance(block, np.ndarray):
                dtypes.append(block.dtype)

    return actx.from_numpy(_bmat(blocks, dtypes))
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
                  places=places,
                  context=case.knl_concrete_kwargs)

    if block_builder_type == "qbx":
        from pytential.symbolic.matrix import MatrixBuilder
        from pytential.symbolic.matrix import \
                NearFieldBlockBuilder as BlockMatrixBuilder
    elif block_builder_type == "p2p":
        from pytential.symbolic.matrix import P2PMatrixBuilder as MatrixBuilder
        from pytential.symbolic.matrix import \
                FarFieldBlockBuilder as BlockMatrixBuilder
        kwargs["exclude_self"] = True
    else:
        raise ValueError(f"unknown block builder type: '{block_builder_type}'")

    mat = MatrixBuilder(actx, **kwargs)(sym_prep_op)
    blk = BlockMatrixBuilder(actx, index_set=index_set, **kwargs)(sym_prep_op)

    # }}}

    # {{{ check

    if visualize and ambient_dim == 2:
        try:
            import matplotlib.pyplot as pt
        except ImportError:
            visualize = False

    index_set = index_set.get(actx.queue)
    if visualize and ambient_dim == 2:
        blk_full = np.zeros_like(mat)