Esempio n. 1
0
    def muller_solve_func(beta):
        from pytential.symbolic.execution import build_matrix
        mat = build_matrix(
                queue, qbx, op, u_sym,
                context={"beta": beta}).get()

        return 1/x_vec.dot(la.solve(mat, y_vec))
Esempio n. 2
0
def test_matrix_build(ctx_factory, k, curve_f, lpot_id, visualize=False):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)

    # prevent cache 'splosion
    from sympy.core.cache import clear_cache
    clear_cache()

    target_order = 7
    qbx_order = 4
    nelements = 30
    mesh = make_curve_mesh(curve_f,
            np.linspace(0, 1, nelements + 1),
            target_order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    pre_density_discr = Discretization(
            cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    from pytential.qbx import QBXLayerPotentialSource
    qbx, _ = QBXLayerPotentialSource(pre_density_discr, 4 * target_order,
            qbx_order,
            # Don't use FMM for now
            fmm_order=False).with_refinement()
    density_discr = qbx.density_discr

    op, u_sym, knl_kwargs = _build_op(lpot_id, k=k)
    bound_op = bind(qbx, op)

    from pytential.symbolic.execution import build_matrix
    mat = build_matrix(queue, qbx, op, u_sym).get()

    if visualize:
        from sumpy.tools import build_matrix as build_matrix_via_matvec
        mat2 = bound_op.scipy_op(queue, "u", dtype=mat.dtype, **knl_kwargs)
        mat2 = build_matrix_via_matvec(mat2)
        print(la.norm((mat - mat2).real, "fro") / la.norm(mat2.real, "fro"),
              la.norm((mat - mat2).imag, "fro") / la.norm(mat2.imag, "fro"))

        import matplotlib.pyplot as pt
        pt.subplot(121)
        pt.imshow(np.log10(np.abs(1.0e-20 + (mat - mat2).real)))
        pt.colorbar()
        pt.subplot(122)
        pt.imshow(np.log10(np.abs(1.0e-20 + (mat - mat2).imag)))
        pt.colorbar()
        pt.show()

    if visualize:
        import matplotlib.pyplot as pt
        pt.subplot(121)
        pt.imshow(mat.real)
        pt.colorbar()
        pt.subplot(122)
        pt.imshow(mat.imag)
        pt.colorbar()
        pt.show()

    from sumpy.tools import vector_to_device, vector_from_device
    np.random.seed(12)
    for i in range(5):
        if is_obj_array(u_sym):
            u = make_obj_array([
                np.random.randn(density_discr.nnodes)
                for _ in range(len(u_sym))
                ])
        else:
            u = np.random.randn(density_discr.nnodes)

        u_dev = vector_to_device(queue, u)
        res_matvec = np.hstack(
                list(vector_from_device(
                    queue, bound_op(queue, u=u_dev))))

        res_mat = mat.dot(np.hstack(list(u)))

        abs_err = la.norm(res_mat - res_matvec, np.inf)
        rel_err = abs_err / la.norm(res_matvec, np.inf)

        print("AbsErr {:.5e} RelErr {:.5e}".format(abs_err, rel_err))
        assert rel_err < 1e-13
Esempio n. 3
0
def test_build_matrix(ctx_factory, k, curve_fn, op_type, visualize=False):
    """Checks that the matrix built with `symbolic.execution.build_matrix`
    gives the same (to tolerance) answer as a direct evaluation.
    """

    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    # prevent cache 'splosion
    from sympy.core.cache import clear_cache
    clear_cache()

    case = extra.CurveTestCase(name="curve",
                               knl_class_or_helmholtz_k=k,
                               curve_fn=curve_fn,
                               op_type=op_type,
                               target_order=7,
                               qbx_order=4,
                               resolutions=[30])

    logger.info("\n%s", case)

    # {{{ geometry

    qbx = case.get_layer_potential(actx, case.resolutions[-1],
                                   case.target_order)

    from pytential.qbx.refinement import refine_geometry_collection
    places = GeometryCollection(qbx, auto_where=case.name)
    places = refine_geometry_collection(places,
                                        kernel_length_scale=(5 /
                                                             k if k else None))

    dd = places.auto_source.to_stage1()
    density_discr = places.get_discretization(dd.geometry)

    logger.info("nelements:     %d", density_discr.mesh.nelements)
    logger.info("ndofs:         %d", density_discr.ndofs)

    # }}}

    # {{{ symbolic

    sym_u, sym_op = case.get_operator(places.ambient_dim)
    bound_op = bind(places, sym_op)

    # }}}

    # {{{ dense matrix

    from pytential.symbolic.execution import build_matrix
    mat = actx.to_numpy(
        build_matrix(actx,
                     places,
                     sym_op,
                     sym_u,
                     context=case.knl_concrete_kwargs))

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

    if visualize:
        from sumpy.tools import build_matrix as build_matrix_via_matvec
        mat2 = bound_op.scipy_op(actx,
                                 "u",
                                 dtype=mat.dtype,
                                 **case.knl_concrete_kwargs)
        mat2 = build_matrix_via_matvec(mat2)

        logger.info(
            "real %.5e imag %.5e",
            la.norm((mat - mat2).real, "fro") / la.norm(mat2.real, "fro"),
            la.norm((mat - mat2).imag, "fro") / la.norm(mat2.imag, "fro"))

        pt.subplot(121)
        pt.imshow(np.log10(np.abs(1.0e-20 + (mat - mat2).real)))
        pt.colorbar()
        pt.subplot(122)
        pt.imshow(np.log10(np.abs(1.0e-20 + (mat - mat2).imag)))
        pt.colorbar()
        pt.show()
        pt.clf()

    if visualize:
        pt.subplot(121)
        pt.imshow(mat.real)
        pt.colorbar()
        pt.subplot(122)
        pt.imshow(mat.imag)
        pt.colorbar()
        pt.show()
        pt.clf()

    # }}}

    # {{{ check

    from pytential.utils import unflatten_from_numpy, flatten_to_numpy

    np.random.seed(12)
    for i in range(5):
        if isinstance(sym_u, np.ndarray):
            u = make_obj_array([
                np.random.randn(density_discr.ndofs) for _ in range(len(sym_u))
            ])
        else:
            u = np.random.randn(density_discr.ndofs)
        u_dev = unflatten_from_numpy(actx, density_discr, u)

        res_matvec = np.hstack(
            flatten_to_numpy(
                actx, bound_op(actx, u=u_dev, **case.knl_concrete_kwargs)))
        res_mat = mat.dot(np.hstack(u))

        abs_err = la.norm(res_mat - res_matvec, np.inf)
        rel_err = abs_err / la.norm(res_matvec, np.inf)

        logger.info("AbsErr {:.5e} RelErr {:.5e}".format(abs_err, rel_err))
        assert rel_err < 1.0e-13, 'iteration: {}'.format(i)
Esempio n. 4
0
    def muller_solve_func(beta):
        from pytential.symbolic.execution import build_matrix
        mat = build_matrix(queue, qbx, op, u_sym, context={"beta": beta}).get()

        return 1 / x_vec.dot(la.solve(mat, y_vec))
Esempio n. 5
0
def test_build_matrix_conditioning(actx_factory,
                                   side,
                                   op_type,
                                   visualize=False):
    """Checks that :math:`I + K`, where :math:`K` is compact gives a
    well-conditioned operator when it should. For example, the exterior Laplace
    problem has a nullspace, so we check that and remove it.
    """

    actx = actx_factory()

    # prevent cache explosion
    from sympy.core.cache import clear_cache
    clear_cache()

    case = extra.CurveTestCase(
        name="ellipse",
        curve_fn=lambda t: ellipse(3.0, t),
        target_order=16,
        source_ovsmp=1,
        qbx_order=4,
        resolutions=[64],
        op_type=op_type,
        side=side,
    )
    logger.info("\n%s", case)

    # {{{ geometry

    qbx = case.get_layer_potential(actx, case.resolutions[-1],
                                   case.target_order)

    from pytential.qbx.refinement import refine_geometry_collection
    places = GeometryCollection(qbx, auto_where=case.name)
    places = refine_geometry_collection(
        places, refine_discr_stage=sym.QBX_SOURCE_QUAD_STAGE2)

    dd = places.auto_source.to_stage1()
    density_discr = places.get_discretization(dd.geometry)

    logger.info("nelements:     %d", density_discr.mesh.nelements)
    logger.info("ndofs:         %d", density_discr.ndofs)

    # }}}

    # {{{ check matrix

    from pytential.symbolic.execution import build_matrix
    sym_u, sym_op = case.get_operator(places.ambient_dim,
                                      qbx_forced_limit="avg")

    mat = actx.to_numpy(
        build_matrix(actx,
                     places,
                     sym_op,
                     sym_u,
                     context=case.knl_concrete_kwargs))

    kappa = la.cond(mat)
    _, sigma, _ = la.svd(mat)

    logger.info("cond: %.5e sigma_max %.5e", kappa, sigma[0])

    # NOTE: exterior Laplace has a nullspace
    if side == +1 and op_type == "double":
        assert kappa > 1.0e+9
        assert sigma[-1] < 1.0e-9
    else:
        assert kappa < 1.0e+1
        assert sigma[-1] > 1.0e-2

    # remove the nullspace and check that it worked
    if side == +1 and op_type == "double":
        # NOTE: this adds the "mean" to remove the nullspace for the operator
        # See `pytential.symbolic.pde.scalar` for the equivalent formulation
        w = actx.to_numpy(
            flatten(
                bind(places,
                     sym.sqrt_jac_q_weight(places.ambient_dim)**2)(actx),
                actx))

        w = np.tile(w.reshape(-1, 1), w.size).T
        kappa = la.cond(mat + w)

        assert kappa < 1.0e+2

    # }}}

    # {{{ plot

    if not visualize:
        return

    side = "int" if side == -1 else "ext"

    import matplotlib.pyplot as plt
    plt.imshow(mat)
    plt.colorbar()
    plt.title(fr"$\kappa(A) = {kappa:.5e}$")
    plt.savefig(f"test_cond_{op_type}_{side}_mat")
    plt.clf()

    plt.plot(sigma)
    plt.ylabel(r"$\sigma$")
    plt.grid()
    plt.savefig(f"test_cond_{op_type}_{side}_svd")
    plt.clf()