Пример #1
0
def test_open_curved_mesh(curve_name):
    def arc_curve(t, start=0, end=np.pi):
        return np.vstack([
            np.cos((end - start) * t + start),
            np.sin((end - start) * t + start)
        ])

    if curve_name == "ellipse":
        from functools import partial
        from meshmode.mesh.generation import ellipse
        curve_f = partial(ellipse, 2.0)
        closed = True
    elif curve_name == "arc":
        curve_f = arc_curve
        closed = False
    else:
        raise ValueError("unknown curve")

    from meshmode.mesh.generation import make_curve_mesh
    nelements = 32
    order = 4
    make_curve_mesh(curve_f,
                    np.linspace(0.0, 1.0, nelements + 1),
                    order=order,
                    closed=closed)
Пример #2
0
def starfish_lpot_source(queue, n_arms):
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import (
        InterpolatoryQuadratureSimplexGroupFactory)

    from meshmode.mesh.generation import make_curve_mesh, NArmedStarfish

    mesh = make_curve_mesh(NArmedStarfish(n_arms, 0.8),
                           np.linspace(0, 1, 1 + PANELS_PER_ARM * n_arms),
                           TARGET_ORDER)

    pre_density_discr = Discretization(
        queue.context, mesh,
        InterpolatoryQuadratureSimplexGroupFactory(TARGET_ORDER))

    lpot_kwargs = DEFAULT_LPOT_KWARGS.copy()
    lpot_kwargs.update(target_association_tolerance=0.025,
                       _expansion_stick_out_factor=TCF,
                       fmm_order=FMM_ORDER,
                       qbx_order=QBX_ORDER,
                       fmm_backend="fmmlib")

    from pytential.qbx import QBXLayerPotentialSource
    lpot_source = QBXLayerPotentialSource(pre_density_discr,
                                          OVSMP_FACTOR * TARGET_ORDER,
                                          **lpot_kwargs)

    lpot_source, _ = lpot_source.with_refinement()

    return lpot_source
Пример #3
0
def get_lpot_source(actx: PyOpenCLArrayContext, dim):
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import (
            InterpolatoryQuadratureSimplexGroupFactory)

    target_order = TARGET_ORDER

    if dim == 2:
        from meshmode.mesh.generation import starfish, make_curve_mesh
        mesh = make_curve_mesh(starfish, np.linspace(0, 1, 50), order=target_order)
    elif dim == 3:
        from meshmode.mesh.generation import generate_torus
        mesh = generate_torus(2, 1, order=target_order)
    else:
        raise ValueError("unsupported dimension: %d" % dim)

    pre_density_discr = Discretization(
            actx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    lpot_kwargs = DEFAULT_LPOT_KWARGS.copy()
    lpot_kwargs.update(
            _expansion_stick_out_factor=TCF,
            fmm_order=FMM_ORDER,
            qbx_order=QBX_ORDER,
            fmm_backend="fmmlib",
            )

    from pytential.qbx import QBXLayerPotentialSource
    lpot_source = QBXLayerPotentialSource(
            pre_density_discr, OVSMP_FACTOR*target_order,
            **lpot_kwargs)

    return lpot_source
Пример #4
0
def make_mesh(nx, ny):
    from meshmode.mesh.generation import ellipse, make_curve_mesh
    from functools import partial

    base_mesh = make_curve_mesh(
            partial(ellipse, 1),
            np.linspace(0, 1, nelements+1),
            mesh_order)

    from meshmode.mesh.processing import affine_map, merge_disjoint_meshes
    dx = 2 / nx
    meshes = [
            affine_map(
                base_mesh,
                A=np.diag([dx*0.25, dx*0.25]),
                b=np.array([dx*(ix-nx/2), dx*(iy-ny/2)]))
            for ix in range(nx)
            for iy in range(ny)]

    mesh = merge_disjoint_meshes(meshes, single_group=True)

    if 0:
        from meshmode.mesh.visualization import draw_curve
        draw_curve(mesh)
        import matplotlib.pyplot as plt
        plt.show()

    return mesh
Пример #5
0
def test_mesh_rotation(ambient_dim, visualize=False):
    order = 3

    if ambient_dim == 2:
        nelements = 32
        mesh = mgen.make_curve_mesh(partial(mgen.ellipse, 2.0),
                                    np.linspace(0.0, 1.0, nelements + 1),
                                    order=order)
    elif ambient_dim == 3:
        mesh = mgen.generate_torus(4.0, 2.0, order=order)
    else:
        raise ValueError("unsupported dimension")

    from meshmode.mesh.processing import _get_rotation_matrix_from_angle_and_axis
    mat = _get_rotation_matrix_from_angle_and_axis(np.pi / 3.0,
                                                   np.array([1.0, 2.0, 1.4]))

    # check that the matrix is in the rotation group
    assert abs(abs(la.det(mat)) - 1) < 10e-14
    assert la.norm(mat @ mat.T - np.eye(3)) < 1.0e-14

    from meshmode.mesh.processing import rotate_mesh_around_axis
    rotated_mesh = rotate_mesh_around_axis(mesh,
                                           theta=np.pi / 2.0,
                                           axis=np.array([1, 0, 0]))

    if visualize:
        from meshmode.mesh.visualization import write_vertex_vtk_file
        write_vertex_vtk_file(mesh, "mesh_rotation_original.vtu")
        write_vertex_vtk_file(rotated_mesh, "mesh_rotation_rotated.vtu")
Пример #6
0
def test_interpolation(actx_factory, name, source_discr_stage, target_granularity):
    actx = actx_factory()

    nelements = 32
    target_order = 7
    qbx_order = 4

    where = sym.as_dofdesc("test_interpolation")
    from_dd = sym.DOFDescriptor(
            geometry=where.geometry,
            discr_stage=source_discr_stage,
            granularity=sym.GRANULARITY_NODE)
    to_dd = sym.DOFDescriptor(
            geometry=where.geometry,
            discr_stage=sym.QBX_SOURCE_QUAD_STAGE2,
            granularity=target_granularity)

    mesh = mgen.make_curve_mesh(mgen.starfish,
            np.linspace(0.0, 1.0, nelements + 1),
            target_order)
    discr = Discretization(actx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    from pytential.qbx import QBXLayerPotentialSource
    qbx = QBXLayerPotentialSource(discr,
            fine_order=4 * target_order,
            qbx_order=qbx_order,
            fmm_order=False)

    from pytential import GeometryCollection
    places = GeometryCollection(qbx, auto_where=where)

    sigma_sym = sym.var("sigma")
    op_sym = sym.sin(sym.interp(from_dd, to_dd, sigma_sym))
    bound_op = bind(places, op_sym, auto_where=where)

    def discr_and_nodes(stage):
        density_discr = places.get_discretization(where.geometry, stage)
        return density_discr, actx.to_numpy(
                flatten(density_discr.nodes(), actx)
                ).reshape(density_discr.ambient_dim, -1)

    _, target_nodes = discr_and_nodes(sym.QBX_SOURCE_QUAD_STAGE2)
    source_discr, source_nodes = discr_and_nodes(source_discr_stage)

    sigma_target = np.sin(la.norm(target_nodes, axis=0))
    sigma_dev = unflatten(
            thaw(source_discr.nodes()[0], actx),
            actx.from_numpy(la.norm(source_nodes, axis=0)), actx)
    sigma_target_interp = actx.to_numpy(
            flatten(bound_op(actx, sigma=sigma_dev), actx)
            )

    if name in ("default", "default_explicit", "stage2", "quad"):
        error = la.norm(sigma_target_interp - sigma_target) / la.norm(sigma_target)
        assert error < 1.0e-10
    elif name in ("stage2_center",):
        assert len(sigma_target_interp) == 2 * len(sigma_target)
    else:
        raise ValueError(f"unknown test case name: {name}")
Пример #7
0
def make_mesh(nx, ny, visualize=False):
    from meshmode.mesh.generation import ellipse, make_curve_mesh
    from functools import partial

    base_mesh = make_curve_mesh(partial(ellipse, 1),
                                np.linspace(0, 1, nelements + 1), mesh_order)

    from meshmode.mesh.processing import affine_map, merge_disjoint_meshes
    dx = 2 / nx
    meshes = [
        affine_map(base_mesh,
                   A=np.diag([dx * 0.25, dx * 0.25]),
                   b=np.array([dx * (ix - nx / 2), dx * (iy - ny / 2)]))
        for ix in range(nx) for iy in range(ny)
    ]

    mesh = merge_disjoint_meshes(meshes, single_group=True)

    if visualize:
        from meshmode.mesh.visualization import draw_curve
        draw_curve(mesh)
        import matplotlib.pyplot as plt
        plt.show()

    return mesh
Пример #8
0
def create_discretization(queue, ndim,
                          nelements=42,
                          mesh_order=5,
                          discr_order=5):
    ctx = queue.context

    # construct mesh
    if ndim == 2:
        from functools import partial
        from meshmode.mesh.generation import make_curve_mesh, ellipse
        mesh = make_curve_mesh(partial(ellipse, 2),
                               np.linspace(0.0, 1.0, nelements + 1),
                               order=mesh_order)
    elif ndim == 3:
        from meshmode.mesh.generation import generate_torus
        mesh = generate_torus(10.0, 5.0, order=mesh_order)
    else:
        raise ValueError("Unsupported dimension: {}".format(ndim))

    # create discretization
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    discr = Discretization(ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(discr_order))

    return discr
Пример #9
0
def _build_qbx_discr(queue,
        ndim=2,
        nelements=30,
        target_order=7,
        qbx_order=4,
        curve_f=None):

    if curve_f is None:
        curve_f = NArmedStarfish(5, 0.25)

    if ndim == 2:
        mesh = make_curve_mesh(curve_f,
                np.linspace(0, 1, nelements + 1),
                target_order)
    elif ndim == 3:
        mesh = generate_torus(10.0, 2.0, order=target_order)
    else:
        raise ValueError("unsupported ambient dimension")

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    from pytential.qbx import QBXLayerPotentialSource
    density_discr = Discretization(
            queue.context, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    qbx, _ = QBXLayerPotentialSource(density_discr,
            fine_order=4 * target_order,
            qbx_order=qbx_order,
            fmm_order=False).with_refinement()

    return qbx
Пример #10
0
def _build_qbx_discr(queue,
        ndim=2,
        nelements=30,
        target_order=7,
        qbx_order=4,
        curve_f=None):

    if curve_f is None:
        curve_f = NArmedStarfish(5, 0.25)

    if ndim == 2:
        mesh = make_curve_mesh(curve_f,
                np.linspace(0, 1, nelements + 1),
                target_order)
    elif ndim == 3:
        mesh = generate_torus(10.0, 2.0, order=target_order)
    else:
        raise ValueError("unsupported ambient dimension")

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    from pytential.qbx import QBXLayerPotentialSource
    density_discr = Discretization(
            queue.context, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    qbx, _ = QBXLayerPotentialSource(density_discr,
            fine_order=4 * target_order,
            qbx_order=qbx_order,
            fmm_order=False).with_refinement()

    return qbx
Пример #11
0
def test_geometry(ctx_factory):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    nelements = 30
    order = 5

    mesh = make_curve_mesh(partial(ellipse, 1),
            np.linspace(0, 1, nelements+1),
            order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    discr = Discretization(actx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(order))

    import pytential.symbolic.primitives as prim
    area_sym = prim.integral(2, 1, 1)

    area = bind(discr, area_sym)(actx)

    err = abs(area-2*np.pi)
    print(err)
    assert err < 1e-3
Пример #12
0
def test_geometry(ctx_getter):
    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

    nelements = 30
    order = 5

    mesh = make_curve_mesh(partial(ellipse, 1),
            np.linspace(0, 1, nelements+1),
            order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    discr = Discretization(cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(order))

    import pytential.symbolic.primitives as prim
    area_sym = prim.integral(2, 1, 1)

    area = bind(discr, area_sym)(queue)

    err = abs(area-2*np.pi)
    print(err)
    assert err < 1e-3
Пример #13
0
def test_off_surface_eval(actx_factory, use_fmm, visualize=False):
    logging.basicConfig(level=logging.INFO)

    actx = actx_factory()

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

    nelements = 30
    target_order = 8
    qbx_order = 3
    if use_fmm:
        fmm_order = qbx_order
    else:
        fmm_order = False

    mesh = mgen.make_curve_mesh(partial(mgen.ellipse, 3),
                                np.linspace(0, 1, nelements + 1), target_order)

    from pytential.qbx import QBXLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    pre_density_discr = Discretization(
        actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))
    qbx = QBXLayerPotentialSource(
        pre_density_discr,
        4 * target_order,
        qbx_order,
        fmm_order=fmm_order,
    )

    from pytential.target import PointsTarget
    fplot = FieldPlotter(np.zeros(2), extent=0.54, npoints=30)
    targets = PointsTarget(actx.freeze(actx.from_numpy(fplot.points)))

    places = GeometryCollection((qbx, targets))
    density_discr = places.get_discretization(places.auto_source.geometry)

    from sumpy.kernel import LaplaceKernel
    op = sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=-2)

    sigma = density_discr.zeros(actx) + 1
    fld_in_vol = bind(places, op)(actx, sigma=sigma)
    fld_in_vol_exact = -1

    linf_err = actx.to_numpy(
        actx.np.linalg.norm(fld_in_vol - fld_in_vol_exact, ord=np.inf))
    logger.info("l_inf error: %.12e", linf_err)

    if visualize:
        fplot.show_scalar_in_matplotlib(actx.to_numpy(fld_in_vol))
        import matplotlib.pyplot as pt
        pt.colorbar()
        pt.show()

    assert linf_err < 1e-3
Пример #14
0
def test_unregularized_off_surface_fmm_vs_direct(ctx_factory):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    nelements = 300
    target_order = 8
    fmm_order = 4

    # {{{ geometry

    mesh = make_curve_mesh(WobblyCircle.random(8, seed=30),
                np.linspace(0, 1, nelements+1),
                target_order)

    from pytential.unregularized import UnregularizedLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    density_discr = Discretization(
            actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))
    direct = UnregularizedLayerPotentialSource(
            density_discr,
            fmm_order=False,
            )
    fmm = direct.copy(
            fmm_level_to_order=lambda kernel, kernel_args, tree, level: fmm_order)

    sigma = density_discr.zeros(actx) + 1

    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=100)
    from pytential.target import PointsTarget
    ptarget = PointsTarget(fplot.points)

    from pytential import GeometryCollection
    places = GeometryCollection({
        "unregularized_direct": direct,
        "unregularized_fmm": fmm,
        "targets": ptarget})

    # }}}

    # {{{ check

    from sumpy.kernel import LaplaceKernel
    op = sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=None)

    direct_fld_in_vol = bind(places, op,
            auto_where=("unregularized_direct", "targets"))(
                    actx, sigma=sigma)
    fmm_fld_in_vol = bind(places, op,
            auto_where=("unregularized_fmm", "targets"))(actx, sigma=sigma)

    err = actx.np.fabs(fmm_fld_in_vol - direct_fld_in_vol)
    linf_err = actx.to_numpy(err).max()
    print("l_inf error:", linf_err)

    assert linf_err < 5e-3
Пример #15
0
def test_off_surface_eval(ctx_factory, use_fmm, do_plot=False):
    logging.basicConfig(level=logging.INFO)

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

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

    nelements = 30
    target_order = 8
    qbx_order = 3
    if use_fmm:
        fmm_order = qbx_order
    else:
        fmm_order = False

    mesh = make_curve_mesh(partial(ellipse, 3),
                           np.linspace(0, 1, nelements + 1), target_order)

    from pytential.qbx import QBXLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    pre_density_discr = Discretization(
        cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))
    qbx, _ = QBXLayerPotentialSource(
        pre_density_discr,
        4 * target_order,
        qbx_order,
        fmm_order=fmm_order,
    ).with_refinement()

    density_discr = qbx.density_discr

    from sumpy.kernel import LaplaceKernel
    op = sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=-2)

    sigma = density_discr.zeros(queue) + 1

    fplot = FieldPlotter(np.zeros(2), extent=0.54, npoints=30)
    from pytential.target import PointsTarget
    fld_in_vol = bind((qbx, PointsTarget(fplot.points)), op)(queue,
                                                             sigma=sigma)

    err = cl.clmath.fabs(fld_in_vol - (-1))

    linf_err = cl.array.max(err).get()
    print("l_inf error:", linf_err)

    if do_plot:
        fplot.show_scalar_in_matplotlib(fld_in_vol.get())
        import matplotlib.pyplot as pt
        pt.colorbar()
        pt.show()

    assert linf_err < 1e-3
Пример #16
0
def create_discretization(queue, ndim,
                          nelements=42,
                          mesh_name=None,
                          order=4):
    ctx = queue.context

    # construct mesh
    if ndim == 2:
        from functools import partial
        from meshmode.mesh.generation import make_curve_mesh, ellipse, starfish

        if mesh_name is None:
            mesh_name = "ellipse"

        t = np.linspace(0.0, 1.0, nelements + 1)
        if mesh_name == "ellipse":
            mesh = make_curve_mesh(partial(ellipse, 2), t, order=order)
        elif mesh_name == "starfish":
            mesh = make_curve_mesh(starfish, t, order=order)
        else:
            raise ValueError('unknown mesh name: {}'.format(mesh_name))
    elif ndim == 3:
        from meshmode.mesh.generation import generate_torus
        from meshmode.mesh.generation import generate_warped_rect_mesh

        if mesh_name is None:
            mesh_name = "torus"

        if mesh_name == "torus":
            mesh = generate_torus(10.0, 5.0, order=order,
                    n_inner=nelements, n_outer=nelements)
        elif mesh_name == "warp":
            mesh = generate_warped_rect_mesh(ndim, order=order, n=nelements)
        else:
            raise ValueError("unknown mesh name: {}".format(mesh_name))
    else:
        raise ValueError("unsupported dimension: {}".format(ndim))

    # create discretization
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    discr = Discretization(ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(order))

    return discr
Пример #17
0
def create_discretization(queue, ndim,
                          nelements=42,
                          mesh_name=None,
                          order=4):
    ctx = queue.context

    # construct mesh
    if ndim == 2:
        from functools import partial
        from meshmode.mesh.generation import make_curve_mesh, ellipse, starfish

        if mesh_name is None:
            mesh_name = "ellipse"

        t = np.linspace(0.0, 1.0, nelements + 1)
        if mesh_name == "ellipse":
            mesh = make_curve_mesh(partial(ellipse, 2), t, order=order)
        elif mesh_name == "starfish":
            mesh = make_curve_mesh(starfish, t, order=order)
        else:
            raise ValueError('unknown mesh name: {}'.format(mesh_name))
    elif ndim == 3:
        from meshmode.mesh.generation import generate_torus
        from meshmode.mesh.generation import generate_warped_rect_mesh

        if mesh_name is None:
            mesh_name = "torus"

        if mesh_name == "torus":
            mesh = generate_torus(10.0, 5.0, order=order,
                    n_minor=nelements, n_major=nelements)
        elif mesh_name == "warp":
            mesh = generate_warped_rect_mesh(ndim, order=order, n=nelements)
        else:
            raise ValueError("unknown mesh name: {}".format(mesh_name))
    else:
        raise ValueError("unsupported dimension: {}".format(ndim))

    # create discretization
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    discr = Discretization(ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(order))

    return discr
def main():
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    target_order = 10

    from functools import partial
    nelements = 30
    qbx_order = 4

    from sumpy.kernel import LaplaceKernel
    from meshmode.mesh.generation import (  # noqa
            ellipse, cloverleaf, starfish, drop, n_gon, qbx_peanut,
            make_curve_mesh)
    mesh = make_curve_mesh(partial(ellipse, 1),
            np.linspace(0, 1, nelements+1),
            target_order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    density_discr = Discretization(cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    from pytential.qbx import QBXLayerPotentialSource
    qbx = QBXLayerPotentialSource(density_discr, 4*target_order,
            qbx_order, fmm_order=False)

    from pytools.obj_array import join_fields
    sig_sym = sym.var("sig")
    knl = LaplaceKernel(2)
    op = join_fields(
            sym.tangential_derivative(mesh.ambient_dim,
                sym.D(knl, sig_sym, qbx_forced_limit=+1)).as_scalar(),
            sym.tangential_derivative(mesh.ambient_dim,
                sym.D(knl, sig_sym, qbx_forced_limit=-1)).as_scalar(),
            )

    nodes = density_discr.nodes().with_queue(queue)
    angle = cl.clmath.atan2(nodes[1], nodes[0])
    n = 10
    sig = cl.clmath.sin(n*angle)
    dt_sig = n*cl.clmath.cos(n*angle)

    res = bind(qbx, op)(queue, sig=sig)

    extval = res[0].get()
    intval = res[1].get()
    pv = 0.5*(extval + intval)

    dt_sig_h = dt_sig.get()

    import matplotlib.pyplot as pt
    pt.plot(extval, label="+num")
    pt.plot(pv + dt_sig_h*0.5, label="+ex")
    pt.legend(loc="best")
    pt.show()
Пример #19
0
def test_parallel_vtk_file(actx_factory, dim):
    r"""
    Simple test just generates a sample parallel PVTU file
    and checks it against the expected result.  The expected
    result is just a file in the tests directory.
    """
    logging.basicConfig(level=logging.INFO)

    actx = actx_factory()

    nelements = 64
    target_order = 4

    if dim == 1:
        mesh = mgen.make_curve_mesh(mgen.NArmedStarfish(5, 0.25),
                                    np.linspace(0.0, 1.0, nelements + 1),
                                    target_order)
    elif dim == 2:
        mesh = mgen.generate_torus(5.0, 1.0, order=target_order)
    elif dim == 3:
        mesh = mgen.generate_warped_rect_mesh(dim,
                                              target_order,
                                              nelements_side=4)
    else:
        raise ValueError("unknown dimensionality")

    from meshmode.discretization import Discretization
    discr = Discretization(
        actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))

    from meshmode.discretization.visualization import make_visualizer
    vis = make_visualizer(actx, discr, target_order)

    class FakeComm:
        def Get_rank(self):  # noqa: N802
            return 0

        def Get_size(self):  # noqa: N802
            return 2

    file_name_pattern = f"visualizer_vtk_linear_{dim}_{{rank}}.vtu"
    pvtu_filename = file_name_pattern.format(rank=0).replace("vtu", "pvtu")

    vis.write_parallel_vtk_file(
        FakeComm(),
        file_name_pattern,
        [("scalar", discr.zeros(actx)),
         ("vector", make_obj_array([discr.zeros(actx) for i in range(dim)]))],
        overwrite=True)

    import os
    assert os.path.exists(pvtu_filename)

    import filecmp
    assert filecmp.cmp(f"ref-{pvtu_filename}", pvtu_filename)
Пример #20
0
def test_is_affine_group_check(mesh_name):
    order = 4
    nelements = 16

    if mesh_name.startswith("box"):
        dim = int(mesh_name[-2])
        is_affine = True
        mesh = mgen.generate_regular_rect_mesh(
            a=(-0.5, ) * dim,
            b=(0.5, ) * dim,
            nelements_per_axis=(nelements, ) * dim,
            order=order)
    elif mesh_name.startswith("warped_box"):
        dim = int(mesh_name[-2])
        is_affine = False
        mesh = mgen.generate_warped_rect_mesh(dim,
                                              order,
                                              nelements_side=nelements)
    elif mesh_name == "cross_warped_box":
        dim = 2
        is_affine = False
        mesh = _generate_cross_warped_rect_mesh(dim, order, nelements)
    elif mesh_name == "circle":
        is_affine = False
        mesh = mgen.make_curve_mesh(lambda t: mgen.ellipse(1.0, t),
                                    np.linspace(0.0, 1.0, nelements + 1),
                                    order=order)
    elif mesh_name == "ellipse":
        is_affine = False
        mesh = mgen.make_curve_mesh(lambda t: mgen.ellipse(2.0, t),
                                    np.linspace(0.0, 1.0, nelements + 1),
                                    order=order)
    elif mesh_name == "sphere":
        is_affine = False
        mesh = mgen.generate_icosphere(r=1.0, order=order)
    elif mesh_name == "torus":
        is_affine = False
        mesh = mgen.generate_torus(10.0, 2.0, order=order)
    else:
        raise ValueError(f"unknown mesh name: {mesh_name}")

    assert all(grp.is_affine for grp in mesh.groups) == is_affine
Пример #21
0
def test_mesh_with_interior_unit_nodes(actx_factory, ambient_dim):
    actx = actx_factory()

    # NOTE: smaller orders or coarser meshes make the cases fail the
    # node_vertex_consistency test; the default warp_and_blend_nodes have
    # nodes at the vertices, so they pass for much smaller tolerances

    order = 8
    nelements = 32
    n_minor = 2 * nelements
    uniform_refinement_rounds = 4

    import modepy as mp
    if ambient_dim == 2:
        unit_nodes = mp.LegendreGaussQuadrature(order,
                                                force_dim_axis=True).nodes

        mesh = mgen.make_curve_mesh(partial(mgen.ellipse, 2.0),
                                    np.linspace(0.0, 1.0, nelements + 1),
                                    order=order,
                                    unit_nodes=unit_nodes)
    elif ambient_dim == 3:
        unit_nodes = mp.VioreanuRokhlinSimplexQuadrature(order, 2).nodes

        mesh = mgen.generate_torus(4.0,
                                   2.0,
                                   n_major=2 * n_minor,
                                   n_minor=n_minor,
                                   order=order,
                                   unit_nodes=unit_nodes)

        mesh = mgen.generate_icosphere(
            1.0,
            uniform_refinement_rounds=uniform_refinement_rounds,
            order=order,
            unit_nodes=unit_nodes)
    else:
        raise ValueError(f"unsupported dimension: '{ambient_dim}'")

    assert mesh.facial_adjacency_groups
    assert mesh.nodal_adjacency

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import QuadratureSimplexGroupFactory
    discr = Discretization(actx, mesh, QuadratureSimplexGroupFactory(order))

    from meshmode.discretization.connection import make_face_restriction
    conn = make_face_restriction(
        actx,
        discr,
        group_factory=QuadratureSimplexGroupFactory(order),
        boundary_tag=FACE_RESTR_ALL)
    assert conn
Пример #22
0
def test_target_association_failure(ctx_factory):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    # {{{ generate circle

    order = 5
    nelements = 40

    # Make the curve mesh.
    curve_f = partial(ellipse, 1)
    mesh = make_curve_mesh(curve_f, np.linspace(0, 1, nelements + 1), order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    factory = InterpolatoryQuadratureSimplexGroupFactory(order)
    discr = Discretization(actx, mesh, factory)
    lpot_source = QBXLayerPotentialSource(
        discr,
        qbx_order=order,  # not used in target association
        fine_order=order)
    places = GeometryCollection(lpot_source)

    # }}}

    # {{{ generate targets and check

    close_circle = 0.999 * np.exp(
        2j * np.pi * np.linspace(0, 1, 500, endpoint=False))
    from pytential.target import PointsTarget
    close_circle_target = (PointsTarget(
        actx.from_numpy(np.array([close_circle.real, close_circle.imag]))))

    targets = ((close_circle_target, 0), )

    from pytential.qbx.target_assoc import (TargetAssociationCodeContainer,
                                            associate_targets_to_qbx_centers,
                                            QBXTargetAssociationFailedException
                                            )

    from pytential.qbx.utils import TreeCodeContainer

    code_container = TargetAssociationCodeContainer(actx,
                                                    TreeCodeContainer(actx))

    with pytest.raises(QBXTargetAssociationFailedException):
        associate_targets_to_qbx_centers(places,
                                         places.auto_source,
                                         code_container.get_wrangler(actx),
                                         targets,
                                         target_association_tolerance=1e-10)
Пример #23
0
def test_target_association_failure(ctx_getter):
    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

    # {{{ generate circle

    order = 5
    nelements = 40

    # Make the curve mesh.
    curve_f = partial(ellipse, 1)
    mesh = make_curve_mesh(curve_f, np.linspace(0, 1, nelements+1), order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    factory = InterpolatoryQuadratureSimplexGroupFactory(order)
    discr = Discretization(cl_ctx, mesh, factory)
    lpot_source = QBXLayerPotentialSource(discr,
            qbx_order=order,  # not used in target association
            fine_order=order)

    # }}}

    # {{{ generate targets and check

    close_circle = 0.999 * np.exp(
        2j * np.pi * np.linspace(0, 1, 500, endpoint=False))
    from pytential.target import PointsTarget
    close_circle_target = (
        PointsTarget(cl.array.to_device(
            queue, np.array([close_circle.real, close_circle.imag]))))

    targets = (
        (close_circle_target, 0),
        )

    from pytential.qbx.target_assoc import (
            TargetAssociationCodeContainer, associate_targets_to_qbx_centers,
            QBXTargetAssociationFailedException)

    from pytential.qbx.utils import TreeCodeContainer

    code_container = TargetAssociationCodeContainer(
            cl_ctx, TreeCodeContainer(cl_ctx))

    with pytest.raises(QBXTargetAssociationFailedException):
        associate_targets_to_qbx_centers(
            lpot_source,
            code_container.get_wrangler(queue),
            targets,
            target_association_tolerance=1e-10)
Пример #24
0
def test_interpolation(ctx_factory, name, source_discr_stage,
                       target_granularity):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    nelements = 32
    target_order = 7
    qbx_order = 4

    mesh = make_curve_mesh(starfish, np.linspace(0.0, 1.0, nelements + 1),
                           target_order)
    discr = Discretization(
        ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))

    from pytential.qbx import QBXLayerPotentialSource
    qbx, _ = QBXLayerPotentialSource(discr,
                                     fine_order=4 * target_order,
                                     qbx_order=qbx_order,
                                     fmm_order=False).with_refinement()

    where = 'test-interpolation'
    from_dd = sym.DOFDescriptor(geometry=where,
                                discr_stage=source_discr_stage,
                                granularity=sym.GRANULARITY_NODE)
    to_dd = sym.DOFDescriptor(geometry=where,
                              discr_stage=sym.QBX_SOURCE_QUAD_STAGE2,
                              granularity=target_granularity)

    sigma_sym = sym.var("sigma")
    op_sym = sym.sin(sym.interp(from_dd, to_dd, sigma_sym))
    bound_op = bind(qbx, op_sym, auto_where=where)

    target_nodes = qbx.quad_stage2_density_discr.nodes().get(queue)
    if source_discr_stage == sym.QBX_SOURCE_STAGE2:
        source_nodes = qbx.stage2_density_discr.nodes().get(queue)
    elif source_discr_stage == sym.QBX_SOURCE_QUAD_STAGE2:
        source_nodes = target_nodes
    else:
        source_nodes = qbx.density_discr.nodes().get(queue)

    sigma_dev = cl.array.to_device(queue, la.norm(source_nodes, axis=0))
    sigma_target = np.sin(la.norm(target_nodes, axis=0))
    sigma_target_interp = bound_op(queue, sigma=sigma_dev).get(queue)

    if name in ('default', 'default-explicit', 'stage2', 'quad'):
        error = la.norm(sigma_target_interp -
                        sigma_target) / la.norm(sigma_target)
        assert error < 1.0e-10
    elif name in ('stage2-center', ):
        assert len(sigma_target_interp) == 2 * len(sigma_target)
    else:
        raise ValueError('unknown test case name: {}'.format(name))
Пример #25
0
def test_open_curved_mesh(curve_name):
    def arc_curve(t, start=0, end=np.pi):
        return np.vstack([
            np.cos((end - start) * t + start),
            np.sin((end - start) * t + start)
        ])

    if curve_name == "ellipse":
        curve_f = partial(mgen.ellipse, 2.0)
        closed = True
    elif curve_name == "arc":
        curve_f = arc_curve
        closed = False
    else:
        raise ValueError("unknown curve")

    nelements = 32
    order = 4
    mgen.make_curve_mesh(curve_f,
                         np.linspace(0.0, 1.0, nelements + 1),
                         order=order,
                         closed=closed)
Пример #26
0
def test_discr_nodes_caching(actx_factory):
    actx = actx_factory()
    nelements = 30
    target_order = 5
    mesh = mgen.make_curve_mesh(
            mgen.NArmedStarfish(5, 0.25),
            np.linspace(0.0, 1.0, nelements + 1),
            target_order)
    discr = Discretization(actx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    discr.nodes(cached=False)
    assert discr._cached_nodes is None
    discr.nodes()
    assert discr._cached_nodes is not None
Пример #27
0
def main():
    from meshmode.mesh.generation import (  # noqa
            make_curve_mesh, starfish)
    mesh1 = make_curve_mesh(starfish, np.linspace(0, 1, 20), 4)

    from meshmode.mesh.processing import affine_map, merge_disjoint_meshes
    mesh2 = affine_map(mesh1, b=np.array([2, 3]))

    mesh = merge_disjoint_meshes((mesh1, mesh2))

    from meshmode.mesh.visualization import draw_2d_mesh
    draw_2d_mesh(mesh, set_bounding_box=True)

    import matplotlib.pyplot as pt
    pt.show()
Пример #28
0
def main():
    from meshmode.mesh.generation import (  # noqa
        make_curve_mesh, starfish)
    mesh1 = make_curve_mesh(starfish, np.linspace(0, 1, 20), 4)

    from meshmode.mesh.processing import affine_map, merge_disjoint_meshes
    mesh2 = affine_map(mesh1, b=np.array([2, 3]))

    mesh = merge_disjoint_meshes((mesh1, mesh2))

    from meshmode.mesh.visualization import draw_2d_mesh
    draw_2d_mesh(mesh, set_bounding_box=True)

    import matplotlib.pyplot as pt
    pt.show()
Пример #29
0
def get_square_with_ref_mean_curvature(cl_ctx):
    nelements = 8
    order = 8

    from extra_curve_data import unit_square

    mesh = make_curve_mesh(
            unit_square,
            np.linspace(0, 1, nelements+1),
            order)

    discr = Discretization(cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(order))

    return discr, 0
Пример #30
0
def test_copy_visualizer(actx_factory, ambient_dim, visualize=True):
    actx = actx_factory()
    target_order = 4

    if ambient_dim == 2:
        nelements = 128
        mesh = mgen.make_curve_mesh(partial(mgen.ellipse, 1.0),
                                    np.linspace(0.0, 1.0, nelements + 1),
                                    target_order)
    elif ambient_dim == 3:
        mesh = mgen.generate_icosphere(1.0,
                                       target_order,
                                       uniform_refinement_rounds=2)
    else:
        raise ValueError(f"unsupported dimension: {ambient_dim}")

    from meshmode.mesh.processing import affine_map
    translated_mesh = affine_map(mesh,
                                 b=np.array([2.5, 0.0, 0.0][:ambient_dim]))

    from meshmode.discretization import Discretization
    discr = Discretization(actx, mesh,
                           PolynomialWarpAndBlendGroupFactory(target_order))
    translated_discr = Discretization(
        actx, translated_mesh,
        PolynomialWarpAndBlendGroupFactory(target_order))

    from meshmode.discretization.visualization import make_visualizer
    vis = make_visualizer(actx, discr, target_order, force_equidistant=True)
    assert vis._vtk_connectivity
    assert vis._vtk_lagrange_connectivity

    translated_vis = vis.copy_with_same_connectivity(actx, translated_discr)
    assert translated_vis._cached_vtk_connectivity is not None
    assert translated_vis._cached_vtk_lagrange_connectivity is not None

    assert translated_vis._vtk_connectivity \
            is vis._vtk_connectivity
    assert translated_vis._vtk_lagrange_connectivity \
            is vis._vtk_lagrange_connectivity

    if not visualize:
        return

    vis.write_vtk_file(f"visualizer_copy_{ambient_dim}d_orig.vtu", [],
                       overwrite=True)
    translated_vis.write_vtk_file(
        f"visualizer_copy_{ambient_dim}d_translated.vtu", [], overwrite=True)
Пример #31
0
def get_ellipse_with_ref_mean_curvature(cl_ctx, nelements, aspect=1):
    order = 4
    mesh = make_curve_mesh(partial(ellipse, aspect),
                           np.linspace(0, 1, nelements + 1), order)

    discr = Discretization(cl_ctx, mesh,
                           InterpolatoryQuadratureSimplexGroupFactory(order))

    with cl.CommandQueue(cl_ctx) as queue:
        nodes = discr.nodes().get(queue=queue)

    a = 1
    b = 1 / aspect
    t = np.arctan2(nodes[1] * aspect, nodes[0])

    return discr, a * b / ((a * np.sin(t))**2 + (b * np.cos(t))**2)**(3 / 2)
Пример #32
0
def test_source_refinement_2d(actx_factory,
                              curve_name,
                              curve_f,
                              nelements,
                              visualize=False):
    helmholtz_k = 10
    order = 8

    mesh = mgen.make_curve_mesh(curve_f, np.linspace(0, 1, nelements + 1),
                                order)
    run_source_refinement_test(actx_factory,
                               mesh,
                               order,
                               helmholtz_k=helmholtz_k,
                               surface_name=curve_name,
                               visualize=visualize)
Пример #33
0
def test_as_python():
    from meshmode.mesh.generation import make_curve_mesh, cloverleaf
    mesh = make_curve_mesh(cloverleaf, np.linspace(0, 1, 100), order=3)

    mesh.element_connectivity

    from meshmode.mesh import as_python
    code = as_python(mesh)

    print(code)
    exec_dict = {}
    exec(compile(code, "gen_code.py", "exec"), exec_dict)

    mesh_2 = exec_dict["make_mesh"]()

    assert mesh == mesh_2
Пример #34
0
def get_ellipse_with_ref_mean_curvature(actx, nelements, aspect=1):
    order = 4
    mesh = make_curve_mesh(partial(ellipse, aspect),
                           np.linspace(0, 1, nelements + 1), order)

    discr = Discretization(actx, mesh,
                           InterpolatoryQuadratureSimplexGroupFactory(order))

    from meshmode.dof_array import thaw
    nodes = thaw(actx, discr.nodes())

    a = 1
    b = 1 / aspect
    t = actx.np.arctan2(nodes[1] * aspect, nodes[0])

    return discr, a * b / ((a * actx.np.sin(t))**2 +
                           (b * actx.np.cos(t))**2)**(3 / 2)
Пример #35
0
def test_unregularized_with_ones_kernel(ctx_factory):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    nelements = 10
    order = 8

    mesh = make_curve_mesh(partial(ellipse, 1),
            np.linspace(0, 1, nelements+1),
            order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    discr = Discretization(actx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(order))

    from pytential.unregularized import UnregularizedLayerPotentialSource
    lpot_source = UnregularizedLayerPotentialSource(discr)
    from pytential.target import PointsTarget
    targets = PointsTarget(np.zeros((2, 1), dtype=float))

    places = GeometryCollection({
        sym.DEFAULT_SOURCE: lpot_source,
        sym.DEFAULT_TARGET: lpot_source,
        "target_non_self": targets})

    from sumpy.kernel import one_kernel_2d
    sigma_sym = sym.var("sigma")
    op = sym.IntG(one_kernel_2d, sigma_sym, qbx_forced_limit=None)

    sigma = discr.zeros(actx) + 1

    result_self = bind(places, op,
            auto_where=places.auto_where)(
                    actx, sigma=sigma)
    result_nonself = bind(places, op,
            auto_where=(places.auto_source, "target_non_self"))(
                    actx, sigma=sigma)

    from meshmode.dof_array import flatten
    assert np.allclose(actx.to_numpy(flatten(result_self)), 2 * np.pi)
    assert np.allclose(actx.to_numpy(result_nonself), 2 * np.pi)
Пример #36
0
def test_unregularized_off_surface_fmm_vs_direct(ctx_getter):
    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

    nelements = 300
    target_order = 8
    fmm_order = 4

    mesh = make_curve_mesh(WobblyCircle.random(8, seed=30),
                np.linspace(0, 1, nelements+1),
                target_order)

    from pytential.unregularized import UnregularizedLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    density_discr = Discretization(
            cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))
    direct = UnregularizedLayerPotentialSource(
            density_discr,
            fmm_order=False,
            )
    fmm = direct.copy(
            fmm_level_to_order=lambda kernel, kernel_args, tree, level: fmm_order)

    sigma = density_discr.zeros(queue) + 1

    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=100)
    from pytential.target import PointsTarget
    ptarget = PointsTarget(fplot.points)
    from sumpy.kernel import LaplaceKernel

    op = sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=None)

    direct_fld_in_vol = bind((direct, ptarget), op)(queue, sigma=sigma)
    fmm_fld_in_vol = bind((fmm, ptarget), op)(queue, sigma=sigma)

    err = cl.clmath.fabs(fmm_fld_in_vol - direct_fld_in_vol)

    linf_err = cl.array.max(err).get()
    print("l_inf error:", linf_err)
    assert linf_err < 5e-3
Пример #37
0
def test_unregularized_off_surface_fmm_vs_direct(ctx_factory):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)

    nelements = 300
    target_order = 8
    fmm_order = 4

    mesh = make_curve_mesh(WobblyCircle.random(8, seed=30),
                           np.linspace(0, 1, nelements + 1), target_order)

    from pytential.unregularized import UnregularizedLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    density_discr = Discretization(
        cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))
    direct = UnregularizedLayerPotentialSource(
        density_discr,
        fmm_order=False,
    )
    fmm = direct.copy(
        fmm_level_to_order=lambda kernel, kernel_args, tree, level: fmm_order)

    sigma = density_discr.zeros(queue) + 1

    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=100)
    from pytential.target import PointsTarget
    ptarget = PointsTarget(fplot.points)
    from sumpy.kernel import LaplaceKernel

    op = sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=None)

    direct_fld_in_vol = bind((direct, ptarget), op)(queue, sigma=sigma)
    fmm_fld_in_vol = bind((fmm, ptarget), op)(queue, sigma=sigma)

    err = cl.clmath.fabs(fmm_fld_in_vol - direct_fld_in_vol)

    linf_err = cl.array.max(err).get()
    print("l_inf error:", linf_err)
    assert linf_err < 5e-3
Пример #38
0
def get_ellipse_with_ref_mean_curvature(cl_ctx, aspect=1):
    nelements = 20
    order = 16

    mesh = make_curve_mesh(
            partial(ellipse, aspect),
            np.linspace(0, 1, nelements+1),
            order)

    a = 1
    b = 1/aspect

    discr = Discretization(cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(order))

    with cl.CommandQueue(cl_ctx) as queue:
        nodes = discr.nodes().get(queue=queue)

    t = np.arctan2(nodes[1] * aspect, nodes[0])

    return discr, a*b / ((a*np.sin(t))**2 + (b*np.cos(t))**2)**(3/2)
Пример #39
0
def test_lookup_tree(do_plot=False):
    from meshmode.mesh.generation import make_curve_mesh, cloverleaf
    mesh = make_curve_mesh(cloverleaf, np.linspace(0, 1, 1000), order=3)

    from meshmode.mesh.tools import make_element_lookup_tree
    tree = make_element_lookup_tree(mesh)

    from meshmode.mesh.processing import find_bounding_box
    bbox_min, bbox_max = find_bounding_box(mesh)

    extent = bbox_max-bbox_min

    for i in range(20):
        pt = bbox_min + np.random.rand(2) * extent
        print(pt)
        for igrp, iel in tree.generate_matches(pt):
            print(igrp, iel)

    if do_plot:
        with open("tree.dat", "w") as outf:
            tree.visualize(outf)
Пример #40
0
def test_lookup_tree(do_plot=False):
    from meshmode.mesh.generation import make_curve_mesh, cloverleaf
    mesh = make_curve_mesh(cloverleaf, np.linspace(0, 1, 1000), order=3)

    from meshmode.mesh.tools import make_element_lookup_tree
    tree = make_element_lookup_tree(mesh)

    from meshmode.mesh.processing import find_bounding_box
    bbox_min, bbox_max = find_bounding_box(mesh)

    extent = bbox_max - bbox_min

    for i in range(20):
        pt = bbox_min + np.random.rand(2) * extent
        print(pt)
        for igrp, iel in tree.generate_matches(pt):
            print(igrp, iel)

    if do_plot:
        with open("tree.dat", "w") as outf:
            tree.visualize(outf)
Пример #41
0
def test_node_reduction(ctx_factory):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)
    actx = PyOpenCLArrayContext(queue)

    # {{{ build discretization

    target_order = 4
    nelements = 32

    mesh = make_curve_mesh(starfish,
            np.linspace(0.0, 1.0, nelements + 1),
            target_order)
    discr = Discretization(actx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    # }}}

    # {{{ test

    # create a shuffled [1, nelements + 1] array
    ary = []
    el_nr_base = 0
    for grp in discr.groups:
        x = 1 + np.arange(el_nr_base, grp.nelements)
        np.random.shuffle(x)

        ary.append(actx.freeze(actx.from_numpy(x.reshape(-1, 1))))
        el_nr_base += grp.nelements

    from meshmode.dof_array import DOFArray
    ary = DOFArray(actx, tuple(ary))

    for func, expected in [
            (sym.NodeSum, nelements * (nelements + 1) // 2),
            (sym.NodeMax, nelements),
            (sym.NodeMin, 1),
            ]:
        r = bind(discr, func(sym.var("x")))(actx, x=ary)
        assert abs(r - expected) < 1.0e-15, r
Пример #42
0
def test_unregularized_with_ones_kernel(ctx_getter):
    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

    nelements = 10
    order = 8

    mesh = make_curve_mesh(partial(ellipse, 1),
            np.linspace(0, 1, nelements+1),
            order)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    discr = Discretization(cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(order))

    from pytential.unregularized import UnregularizedLayerPotentialSource
    lpot_src = UnregularizedLayerPotentialSource(discr)

    from sumpy.kernel import one_kernel_2d

    expr = sym.IntG(one_kernel_2d, sym.var("sigma"), qbx_forced_limit=None)

    from pytential.target import PointsTarget
    op_self = bind(lpot_src, expr)
    op_nonself = bind((lpot_src, PointsTarget(np.zeros((2, 1), dtype=float))), expr)

    with cl.CommandQueue(cl_ctx) as queue:
        sigma = cl.array.zeros(queue, discr.nnodes, dtype=float)
        sigma.fill(1)
        sigma.finish()

        result_self = op_self(queue, sigma=sigma)
        result_nonself = op_nonself(queue, sigma=sigma)

    assert np.allclose(result_self.get(), 2 * np.pi)
    assert np.allclose(result_nonself.get(), 2 * np.pi)
Пример #43
0
def test_refinement_connection(
        ctx_getter, refiner_cls, group_factory,
        mesh_name, dim, mesh_pars, mesh_order, refine_flags, visualize=False):
    from random import seed
    seed(13)

    # Discretization order
    order = 5

    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.discretization import Discretization
    from meshmode.discretization.connection import (
            make_refinement_connection, check_connection)

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    for mesh_par in mesh_pars:
        # {{{ get mesh

        if mesh_name == "circle":
            assert dim == 1
            h = 1 / mesh_par
            mesh = make_curve_mesh(
                partial(ellipse, 1), np.linspace(0, 1, mesh_par + 1),
                order=mesh_order)
        elif mesh_name == "blob":
            if mesh_order == 5:
                pytest.xfail("https://gitlab.tiker.net/inducer/meshmode/issues/2")
            assert dim == 2
            mesh = get_blob_mesh(mesh_par, mesh_order)
            h = float(mesh_par)
        elif mesh_name == "warp":
            from meshmode.mesh.generation import generate_warped_rect_mesh
            mesh = generate_warped_rect_mesh(dim, order=mesh_order, n=mesh_par)
            h = 1/mesh_par
        else:
            raise ValueError("mesh_name not recognized")

        # }}}

        from meshmode.mesh.processing import find_bounding_box
        mesh_bbox_low, mesh_bbox_high = find_bounding_box(mesh)
        mesh_ext = mesh_bbox_high-mesh_bbox_low

        def f(x):
            result = 1
            if mesh_name == "blob":
                factor = 15
            else:
                factor = 9

            for iaxis in range(len(x)):
                result = result * cl.clmath.sin(factor * (x[iaxis]/mesh_ext[iaxis]))

            return result

        discr = Discretization(cl_ctx, mesh, group_factory(order))

        refiner = refiner_cls(mesh)
        flags = refine_flags(mesh)
        refiner.refine(flags)

        connection = make_refinement_connection(
            refiner, discr, group_factory(order))
        check_connection(connection)

        fine_discr = connection.to_discr

        x = discr.nodes().with_queue(queue)
        x_fine = fine_discr.nodes().with_queue(queue)
        f_coarse = f(x)
        f_interp = connection(queue, f_coarse).with_queue(queue)
        f_true = f(x_fine).with_queue(queue)

        if visualize == "dots":
            import matplotlib.pyplot as plt
            x = x.get(queue)
            err = np.array(np.log10(
                1e-16 + np.abs((f_interp - f_true).get(queue))), dtype=float)
            import matplotlib.cm as cm
            cmap = cm.ScalarMappable(cmap=cm.jet)
            cmap.set_array(err)
            plt.scatter(x[0], x[1], c=cmap.to_rgba(err), s=20, cmap=cmap)
            plt.colorbar(cmap)
            plt.show()

        elif visualize == "vtk":
            from meshmode.discretization.visualization import make_visualizer
            fine_vis = make_visualizer(queue, fine_discr, mesh_order)

            fine_vis.write_vtk_file(
                    "refine-fine-%s-%dd-%s.vtu" % (mesh_name, dim, mesh_par), [
                        ("f_interp", f_interp),
                        ("f_true", f_true),
                        ])

        import numpy.linalg as la
        err = la.norm((f_interp - f_true).get(queue), np.inf)
        eoc_rec.add_data_point(h, err)

    order_slack = 0.5
    if mesh_name == "blob" and order > 1:
        order_slack = 1

    print(eoc_rec)
    assert (
            eoc_rec.order_estimate() >= order-order_slack
            or eoc_rec.max_error() < 1e-14)
Пример #44
0
def test_off_surface_eval(ctx_getter, use_fmm, do_plot=False):
    logging.basicConfig(level=logging.INFO)

    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

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

    nelements = 30
    target_order = 8
    qbx_order = 3
    if use_fmm:
        fmm_order = qbx_order
    else:
        fmm_order = False

    mesh = make_curve_mesh(partial(ellipse, 3),
            np.linspace(0, 1, nelements+1),
            target_order)

    from pytential.qbx import QBXLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    pre_density_discr = Discretization(
            cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))
    qbx, _ = QBXLayerPotentialSource(
            pre_density_discr,
            4*target_order,
            qbx_order,
            fmm_order=fmm_order,
            ).with_refinement()

    density_discr = qbx.density_discr

    from sumpy.kernel import LaplaceKernel
    op = sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=-2)

    sigma = density_discr.zeros(queue) + 1

    fplot = FieldPlotter(np.zeros(2), extent=0.54, npoints=30)
    from pytential.target import PointsTarget
    fld_in_vol = bind(
            (qbx, PointsTarget(fplot.points)),
            op)(queue, sigma=sigma)

    err = cl.clmath.fabs(fld_in_vol - (-1))

    linf_err = cl.array.max(err).get()
    print("l_inf error:", linf_err)

    if do_plot:
        fplot.show_scalar_in_matplotlib(fld_in_vol.get())
        import matplotlib.pyplot as pt
        pt.colorbar()
        pt.show()

    assert linf_err < 1e-3
Пример #45
0
def run_int_eq_test(
        cl_ctx, queue, curve_f, nelements, qbx_order, bc_type, loc_sign, k,
        target_order, source_order):

    mesh = make_curve_mesh(curve_f,
            np.linspace(0, 1, nelements+1),
            target_order)

    if 0:
        from pytential.visualization import show_mesh
        show_mesh(mesh)

        pt.gca().set_aspect("equal")
        pt.show()

    from pytential.qbx import QBXLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    density_discr = Discretization(
            cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))

    if source_order is None:
        source_order = 4*target_order

    qbx = QBXLayerPotentialSource(
            density_discr, fine_order=source_order, qbx_order=qbx_order,
            # Don't use FMM for now
            fmm_order=False)

    # {{{ set up operator

    from pytential.symbolic.pde.scalar import (
            DirichletOperator,
            NeumannOperator)

    from sumpy.kernel import LaplaceKernel, HelmholtzKernel, AxisTargetDerivative
    if k:
        knl = HelmholtzKernel(2)
        knl_kwargs = {"k": k}
    else:
        knl = LaplaceKernel(2)
        knl_kwargs = {}

    if knl.is_complex_valued:
        dtype = np.complex128
    else:
        dtype = np.float64

    if bc_type == "dirichlet":
        op = DirichletOperator((knl, knl_kwargs), loc_sign, use_l2_weighting=True)
    elif bc_type == "neumann":
        op = NeumannOperator((knl, knl_kwargs), loc_sign, use_l2_weighting=True,
                 use_improved_operator=False)
    else:
        assert False

    op_u = op.operator(sym.var("u"))

    # }}}

    # {{{ set up test data

    inner_radius = 0.1
    outer_radius = 2

    if loc_sign < 0:
        test_src_geo_radius = outer_radius
        test_tgt_geo_radius = inner_radius
    else:
        test_src_geo_radius = inner_radius
        test_tgt_geo_radius = outer_radius

    point_sources = make_circular_point_group(10, test_src_geo_radius,
            func=lambda x: x**1.5)
    test_targets = make_circular_point_group(20, test_tgt_geo_radius)

    np.random.seed(22)
    source_charges = np.random.randn(point_sources.shape[1])
    source_charges[-1] = -np.sum(source_charges[:-1])
    source_charges = source_charges.astype(dtype)
    assert np.sum(source_charges) < 1e-15

    # }}}

    if 0:
        # show geometry, centers, normals
        nodes_h = density_discr.nodes().get(queue=queue)
        pt.plot(nodes_h[0], nodes_h[1], "x-")
        normal = bind(density_discr, sym.normal())(queue).as_vector(np.object)
        pt.quiver(nodes_h[0], nodes_h[1], normal[0].get(queue), normal[1].get(queue))
        pt.gca().set_aspect("equal")
        pt.show()

    # {{{ establish BCs

    from sumpy.p2p import P2P
    pot_p2p = P2P(cl_ctx,
            [knl], exclude_self=False, value_dtypes=dtype)

    evt, (test_direct,) = pot_p2p(
            queue, test_targets, point_sources, [source_charges],
            out_host=False, **knl_kwargs)

    nodes = density_discr.nodes()

    evt, (src_pot,) = pot_p2p(
            queue, nodes, point_sources, [source_charges],
            **knl_kwargs)

    grad_p2p = P2P(cl_ctx,
            [AxisTargetDerivative(0, knl), AxisTargetDerivative(1, knl)],
            exclude_self=False, value_dtypes=dtype)
    evt, (src_grad0, src_grad1) = grad_p2p(
            queue, nodes, point_sources, [source_charges],
            **knl_kwargs)

    if bc_type == "dirichlet":
        bc = src_pot
    elif bc_type == "neumann":
        normal = bind(density_discr, sym.normal())(queue).as_vector(np.object)
        bc = (src_grad0*normal[0] + src_grad1*normal[1])

    # }}}

    # {{{ solve

    bound_op = bind(qbx, op_u)

    rhs = bind(density_discr, op.prepare_rhs(sym.var("bc")))(queue, bc=bc)

    from pytential.solve import gmres
    gmres_result = gmres(
            bound_op.scipy_op(queue, "u", k=k),
            rhs, tol=1e-14, progress=True,
            hard_failure=False)

    u = gmres_result.solution
    print("gmres state:", gmres_result.state)

    if 0:
        # {{{ build matrix for spectrum check

        from sumpy.tools import build_matrix
        mat = build_matrix(bound_op.scipy_op("u"))
        w, v = la.eig(mat)
        if 0:
            pt.imshow(np.log10(1e-20+np.abs(mat)))
            pt.colorbar()
            pt.show()

        #assert abs(s[-1]) < 1e-13, "h
        #assert abs(s[-2]) > 1e-7
        #from pudb import set_trace; set_trace()

        # }}}

    # }}}

    # {{{ error check

    from pytential.target import PointsTarget

    bound_tgt_op = bind((qbx, PointsTarget(test_targets)),
            op.representation(sym.var("u")))

    test_via_bdry = bound_tgt_op(queue, u=u, k=k)

    err = test_direct-test_via_bdry

    err = err.get()
    test_direct = test_direct.get()
    test_via_bdry = test_via_bdry.get()

    # {{{ remove effect of net source charge

    if k == 0 and bc_type == "neumann" and loc_sign == -1:
        # remove constant offset in interior Laplace Neumann error
        tgt_ones = np.ones_like(test_direct)
        tgt_ones = tgt_ones/la.norm(tgt_ones)
        err = err - np.vdot(tgt_ones, err)*tgt_ones

    # }}}

    rel_err_2 = la.norm(err)/la.norm(test_direct)
    rel_err_inf = la.norm(err, np.inf)/la.norm(test_direct, np.inf)

    # }}}

    print("rel_err_2: %g rel_err_inf: %g" % (rel_err_2, rel_err_inf))

    # {{{ test tangential derivative

    bound_t_deriv_op = bind(qbx,
            op.representation(
                sym.var("u"), map_potentials=sym.tangential_derivative,
                qbx_forced_limit=loc_sign))

    #print(bound_t_deriv_op.code)

    tang_deriv_from_src = bound_t_deriv_op(queue, u=u).as_scalar().get()

    tangent = bind(
            density_discr,
            sym.pseudoscalar()/sym.area_element())(queue).as_vector(np.object)

    tang_deriv_ref = (src_grad0 * tangent[0] + src_grad1 * tangent[1]).get()

    if 0:
        pt.plot(tang_deriv_ref.real)
        pt.plot(tang_deriv_from_src.real)
        pt.show()

    td_err = tang_deriv_from_src - tang_deriv_ref

    rel_td_err_inf = la.norm(td_err, np.inf)/la.norm(tang_deriv_ref, np.inf)

    print("rel_td_err_inf: %g" % rel_td_err_inf)

    # }}}

    # {{{ plotting

    if 0:
        fplot = FieldPlotter(np.zeros(2),
                extent=1.25*2*max(test_src_geo_radius, test_tgt_geo_radius),
                npoints=200)

        #pt.plot(u)
        #pt.show()

        evt, (fld_from_src,) = pot_p2p(
                queue, fplot.points, point_sources, [source_charges],
                **knl_kwargs)
        fld_from_bdry = bind(
                (qbx, PointsTarget(fplot.points)),
                op.representation(sym.var("u"))
                )(queue, u=u, k=k)
        fld_from_src = fld_from_src.get()
        fld_from_bdry = fld_from_bdry.get()

        nodes = density_discr.nodes().get(queue=queue)

        def prep():
            pt.plot(point_sources[0], point_sources[1], "o",
                    label="Monopole 'Point Charges'")
            pt.plot(test_targets[0], test_targets[1], "v",
                    label="Observation Points")
            pt.plot(nodes[0], nodes[1], "k-",
                    label=r"$\Gamma$")

        from matplotlib.cm import get_cmap
        cmap = get_cmap()
        cmap._init()
        if 0:
            cmap._lut[(cmap.N*99)//100:, -1] = 0  # make last percent transparent?

        prep()
        if 1:
            pt.subplot(131)
            pt.title("Field error (loc_sign=%s)" % loc_sign)
            log_err = np.log10(1e-20+np.abs(fld_from_src-fld_from_bdry))
            log_err = np.minimum(-3, log_err)
            fplot.show_scalar_in_matplotlib(log_err, cmap=cmap)

            #from matplotlib.colors import Normalize
            #im.set_norm(Normalize(vmin=-6, vmax=1))

            cb = pt.colorbar(shrink=0.9)
            cb.set_label(r"$\log_{10}(\mathdefault{Error})$")

        if 1:
            pt.subplot(132)
            prep()
            pt.title("Source Field")
            fplot.show_scalar_in_matplotlib(
                    fld_from_src.real, max_val=3)

            pt.colorbar(shrink=0.9)
        if 1:
            pt.subplot(133)
            prep()
            pt.title("Solved Field")
            fplot.show_scalar_in_matplotlib(
                    fld_from_bdry.real, max_val=3)

            pt.colorbar(shrink=0.9)

        # total field
        #fplot.show_scalar_in_matplotlib(
        #fld_from_src.real+fld_from_bdry.real, max_val=0.1)

        #pt.colorbar()

        pt.legend(loc="best", prop=dict(size=15))
        from matplotlib.ticker import NullFormatter
        pt.gca().xaxis.set_major_formatter(NullFormatter())
        pt.gca().yaxis.set_major_formatter(NullFormatter())

        pt.gca().set_aspect("equal")

        if 0:
            border_factor_top = 0.9
            border_factor = 0.3

            xl, xh = pt.xlim()
            xhsize = 0.5*(xh-xl)
            pt.xlim(xl-border_factor*xhsize, xh+border_factor*xhsize)

            yl, yh = pt.ylim()
            yhsize = 0.5*(yh-yl)
            pt.ylim(yl-border_factor_top*yhsize, yh+border_factor*yhsize)

        #pt.savefig("helmholtz.pdf", dpi=600)
        pt.show()

        # }}}

    class Result(Record):
        pass

    return Result(
            rel_err_2=rel_err_2,
            rel_err_inf=rel_err_inf,
            rel_td_err_inf=rel_td_err_inf,
            gmres_result=gmres_result)
Пример #46
0
def test_perf_data_gathering(ctx_getter, n_arms=5):
    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

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

    target_order = 8

    starfish_func = NArmedStarfish(n_arms, 0.8)
    mesh = make_curve_mesh(
            starfish_func,
            np.linspace(0, 1, n_arms * 30),
            target_order)

    sigma_sym = sym.var("sigma")

    # The kernel doesn't really matter here
    from sumpy.kernel import LaplaceKernel
    k_sym = LaplaceKernel(mesh.ambient_dim)

    sym_op = sym.S(k_sym, sigma_sym, qbx_forced_limit=+1)

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import (
            InterpolatoryQuadratureSimplexGroupFactory)
    pre_density_discr = Discretization(
            queue.context, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    results = []

    def inspect_geo_data(insn, bound_expr, geo_data):
        from pytential.qbx.fmm import assemble_performance_data
        perf_data = assemble_performance_data(geo_data, uses_pde_expansions=True)
        results.append(perf_data)

        return False  # no need to do the actual FMM

    from pytential.qbx import QBXLayerPotentialSource
    lpot_source = QBXLayerPotentialSource(
            pre_density_discr, 4*target_order,
            # qbx order and fmm order don't really matter
            10, fmm_order=10,
            _expansions_in_tree_have_extent=True,
            _expansion_stick_out_factor=0.5,
            geometry_data_inspector=inspect_geo_data,
            target_association_tolerance=1e-10,
            )

    lpot_source, _ = lpot_source.with_refinement()

    density_discr = lpot_source.density_discr

    if 0:
        from meshmode.discretization.visualization import draw_curve
        draw_curve(density_discr)
        import matplotlib.pyplot as plt
        plt.show()

    nodes = density_discr.nodes().with_queue(queue)
    sigma = cl.clmath.sin(10 * nodes[0])

    bind(lpot_source, sym_op)(queue, sigma=sigma)
Пример #47
0
def main():
    logging.basicConfig(level=logging.INFO)

    nelements = 60
    qbx_order = 3
    k_fac = 4
    k0 = 3*k_fac
    k1 = 2.9*k_fac
    mesh_order = 10
    bdry_quad_order = mesh_order
    bdry_ovsmp_quad_order = bdry_quad_order * 4
    fmm_order = qbx_order * 2

    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.mesh.generation import ellipse, make_curve_mesh
    from functools import partial
    mesh = make_curve_mesh(
            partial(ellipse, 3),
            np.linspace(0, 1, nelements+1),
            mesh_order)

    density_discr = Discretization(
            cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(bdry_quad_order))

    logger.info("%d elements" % mesh.nelements)

    # from meshmode.discretization.visualization import make_visualizer
    # bdry_vis = make_visualizer(queue, density_discr, 20)

    # {{{ solve bvp

    from sumpy.kernel import HelmholtzKernel
    kernel = HelmholtzKernel(2)

    beta = 2.5*k_fac
    K0 = np.sqrt(k0**2-beta**2)
    K1 = np.sqrt(k1**2-beta**2)

    from pytential.symbolic.pde.scalar import DielectricSDRep2DBoundaryOperator
    pde_op = DielectricSDRep2DBoundaryOperator(
            mode='tm',
            k_vacuum=1,
            interfaces=((0, 1, sym.DEFAULT_SOURCE),),
            domain_k_exprs=(k0, k1),
            beta=beta)

    op_unknown_sym = pde_op.make_unknown("unknown")

    representation0_sym = pde_op.representation(op_unknown_sym, 0)
    representation1_sym = pde_op.representation(op_unknown_sym, 1)

    from pytential.qbx import QBXLayerPotentialSource
    qbx = QBXLayerPotentialSource(
            density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order,
            fmm_order=fmm_order
            )

    bound_pde_op = bind(qbx, pde_op.operator(op_unknown_sym))

    # in inner domain
    sources_1 = make_obj_array(list(np.array([
        [-1.5, 0.5]
        ]).T.copy()))
    strengths_1 = np.array([1])

    from sumpy.p2p import P2P
    pot_p2p = P2P(cl_ctx, [kernel], exclude_self=False)

    _, (Einc,) = pot_p2p(queue, density_discr.nodes(), sources_1, [strengths_1],
                    out_host=False, k=K0)

    sqrt_w = bind(density_discr, sym.sqrt_jac_q_weight())(queue)

    bvp_rhs = np.zeros(len(pde_op.bcs), dtype=np.object)
    for i_bc, terms in enumerate(pde_op.bcs):
        for term in terms:
            assert term.i_interface == 0
            assert term.field_kind == pde_op.field_kind_e

            if term.direction == pde_op.dir_none:
                bvp_rhs[i_bc] += (
                        term.coeff_outer * (-Einc)
                        )
            elif term.direction == pde_op.dir_normal:
                # no jump in normal derivative
                bvp_rhs[i_bc] += 0*Einc
            else:
                raise NotImplementedError("direction spec in RHS")

        bvp_rhs[i_bc] *= sqrt_w

    from pytential.solve import gmres
    gmres_result = gmres(
            bound_pde_op.scipy_op(queue, "unknown", dtype=np.complex128,
                domains=[sym.DEFAULT_TARGET]*2, K0=K0, K1=K1),
            bvp_rhs, tol=1e-6, progress=True,
            hard_failure=True, stall_iterations=0)

    # }}}

    unknown = gmres_result.solution

    # {{{ visualize

    from pytential.qbx import QBXLayerPotentialSource
    lap_qbx = QBXLayerPotentialSource(
            density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order,
            fmm_order=qbx_order
            )

    from sumpy.visualization import FieldPlotter
    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=300)
    from pytential.target import PointsTarget
    fld0 = bind(
            (qbx, PointsTarget(fplot.points)),
            representation0_sym)(queue, unknown=unknown, K0=K0).get()
    fld1 = bind(
            (qbx, PointsTarget(fplot.points)),
            representation1_sym)(queue, unknown=unknown, K1=K1).get()
    ones = cl.array.empty(queue, density_discr.nnodes, np.float64)
    dom1_indicator = -bind(
            (lap_qbx, PointsTarget(fplot.points)),
            sym.D(0, sym.var("sigma")))(
                    queue, sigma=ones.fill(1)).get()
    _, (fld_inc_vol,) = pot_p2p(queue, fplot.points, sources_1, [strengths_1],
                    out_host=True, k=K0)

    #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
    fplot.write_vtk_file(
            "potential.vts",
            [
                ("fld0", fld0),
                ("fld1", fld1),
                ("fld_inc_vol", fld_inc_vol),
                ("fld_total", (
                    (fld_inc_vol + fld0)*(1-dom1_indicator)
                    +
                    fld1*dom1_indicator
                    )),
                ("dom1_indicator", dom1_indicator),
                ]
            )
Пример #48
0
qbx_order = 3
nelements = 60
mode_nr = 3

k = 2
if k:
    kernel = HelmholtzKernel(helmholtz_k_name="k")
else:
    kernel = LaplaceKernel()
#kernel = OneKernel()

from meshmode.mesh.generation import (  # noqa
        make_curve_mesh, starfish, ellipse, drop)
mesh = make_curve_mesh(
        #lambda t: ellipse(1, t),
        starfish,
        np.linspace(0, 1, nelements+1),
        target_order)

from pytential.qbx import QBXLayerPotentialSource
from meshmode.discretization import Discretization
from meshmode.discretization.poly_element import \
        InterpolatoryQuadratureSimplexGroupFactory

density_discr = Discretization(
        cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))

qbx = QBXLayerPotentialSource(density_discr, 4*target_order, qbx_order,
        fmm_order=qbx_order)

nodes = density_discr.nodes().with_queue(queue)
Пример #49
0
def test_off_surface_eval_vs_direct(ctx_getter,  do_plot=False):
    logging.basicConfig(level=logging.INFO)

    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

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

    nelements = 300
    target_order = 8
    qbx_order = 3

    mesh = make_curve_mesh(WobblyCircle.random(8, seed=30),
                np.linspace(0, 1, nelements+1),
                target_order)

    from pytential.qbx import QBXLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    pre_density_discr = Discretization(
            cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))
    direct_qbx, _ = QBXLayerPotentialSource(
            pre_density_discr, 4*target_order, qbx_order,
            fmm_order=False,
            target_association_tolerance=0.05,
            ).with_refinement()
    fmm_qbx, _ = QBXLayerPotentialSource(
            pre_density_discr, 4*target_order, qbx_order,
            fmm_order=qbx_order + 3,
            _expansions_in_tree_have_extent=True,
            target_association_tolerance=0.05,
            ).with_refinement()

    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=1000)
    from pytential.target import PointsTarget
    ptarget = PointsTarget(fplot.points)
    from sumpy.kernel import LaplaceKernel

    op = sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=None)

    from pytential.qbx import QBXTargetAssociationFailedException
    try:
        direct_density_discr = direct_qbx.density_discr
        direct_sigma = direct_density_discr.zeros(queue) + 1
        direct_fld_in_vol = bind((direct_qbx, ptarget), op)(
                queue, sigma=direct_sigma)

    except QBXTargetAssociationFailedException as e:
        fplot.show_scalar_in_matplotlib(e.failed_target_flags.get(queue))
        import matplotlib.pyplot as pt
        pt.show()
        raise

    fmm_density_discr = fmm_qbx.density_discr
    fmm_sigma = fmm_density_discr.zeros(queue) + 1
    fmm_fld_in_vol = bind((fmm_qbx, ptarget), op)(queue, sigma=fmm_sigma)

    err = cl.clmath.fabs(fmm_fld_in_vol - direct_fld_in_vol)

    linf_err = cl.array.max(err).get()
    print("l_inf error:", linf_err)

    if do_plot:
        #fplot.show_scalar_in_mayavi(0.1*.get(queue))
        fplot.write_vtk_file("potential.vts", [
            ("fmm_fld_in_vol", fmm_fld_in_vol.get(queue)),
            ("direct_fld_in_vol", direct_fld_in_vol.get(queue))
            ])

    assert linf_err < 1e-3
Пример #50
0
def main():
    import logging
    logging.basicConfig(level=logging.INFO)

    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.mesh.generation import ellipse, make_curve_mesh
    from functools import partial

    mesh = make_curve_mesh(
            partial(ellipse, 3),
            np.linspace(0, 1, nelements+1),
            mesh_order)

    density_discr = Discretization(
            cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(bdry_quad_order))

    from pytential.qbx import QBXLayerPotentialSource
    qbx = QBXLayerPotentialSource(
            density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order,
            fmm_order=fmm_order
            )

    # {{{ describe bvp

    from sumpy.kernel import HelmholtzKernel
    kernel = HelmholtzKernel(2)

    cse = sym.cse

    sigma_sym = sym.var("sigma")
    sqrt_w = sym.sqrt_jac_q_weight()
    inv_sqrt_w_sigma = cse(sigma_sym/sqrt_w)

    # Brakhage-Werner parameter
    alpha = 1j

    # -1 for interior Dirichlet
    # +1 for exterior Dirichlet
    loc_sign = -1

    bdry_op_sym = (-loc_sign*0.5*sigma_sym
            + sqrt_w*(
                alpha*sym.S(kernel, inv_sqrt_w_sigma, k=sym.var("k"))
                - sym.D(kernel, inv_sqrt_w_sigma, k=sym.var("k"))
                ))

    # }}}

    bound_op = bind(qbx, bdry_op_sym)

    # {{{ fix rhs and solve

    mode_nr = 3
    nodes = density_discr.nodes().with_queue(queue)
    angle = cl.clmath.atan2(nodes[1], nodes[0])

    bc = cl.clmath.cos(mode_nr*angle)

    bvp_rhs = bind(qbx, sqrt_w*sym.var("bc"))(queue, bc=bc)

    from pytential.solve import gmres
    gmres_result = gmres(
            bound_op.scipy_op(queue, "sigma", k=k),
            bvp_rhs, tol=1e-14, progress=True,
            stall_iterations=0,
            hard_failure=True)

    # }}}

    # {{{ postprocess/visualize

    sigma = gmres_result.solution

    representation_sym = (
            alpha*sym.S(kernel, inv_sqrt_w_sigma, k=sym.var("k"))
            - sym.D(kernel, inv_sqrt_w_sigma, k=sym.var("k")))

    from sumpy.visualization import FieldPlotter
    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=1500)
    from pytential.target import PointsTarget
    fld_in_vol = bind(
            (qbx, PointsTarget(fplot.points)),
            representation_sym)(queue, sigma=sigma, k=k).get()

    #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
    fplot.write_vtk_file(
            "potential.vts",
            [
                ("potential", fld_in_vol)
                ]
            )
Пример #51
0
def main():
    import logging
    logging.basicConfig(level=logging.INFO)

    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.mesh.generation import ellipse, make_curve_mesh
    from functools import partial

    mesh = make_curve_mesh(
                partial(ellipse, 2),
                np.linspace(0, 1, nelements+1),
                mesh_order)

    pre_density_discr = Discretization(
            cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(bdry_quad_order))

    from pytential.qbx import (
            QBXLayerPotentialSource, QBXTargetAssociationFailedException)
    qbx, _ = QBXLayerPotentialSource(
            pre_density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order,
            fmm_order=fmm_order,
            expansion_disks_in_tree_have_extent=True,
            ).with_refinement()
    density_discr = qbx.density_discr

    from pytential.symbolic.pde.cahn_hilliard import CahnHilliardOperator
    chop = CahnHilliardOperator(
            # FIXME: Constants?
            lambda1=1.5,
            lambda2=1.25,
            c=1)

    unk = chop.make_unknown("sigma")
    bound_op = bind(qbx, chop.operator(unk))

    # {{{ fix rhs and solve

    nodes = density_discr.nodes().with_queue(queue)

    def g(xvec):
        x, y = xvec
        return cl.clmath.atan2(y, x)

    bc = sym.make_obj_array([
        # FIXME: Realistic BC
        g(nodes),
        -g(nodes),
        ])

    from pytential.solve import gmres
    gmres_result = gmres(
            bound_op.scipy_op(queue, "sigma", dtype=np.complex128),
            bc, tol=1e-8, progress=True,
            stall_iterations=0,
            hard_failure=True)

    # }}}

    # {{{ postprocess/visualize

    sigma = gmres_result.solution

    from sumpy.visualization import FieldPlotter
    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=500)

    targets = cl.array.to_device(queue, fplot.points)

    qbx_stick_out = qbx.copy(target_association_tolerance=0.05)

    indicator_qbx = qbx_stick_out.copy(qbx_order=2)

    from sumpy.kernel import LaplaceKernel
    ones_density = density_discr.zeros(queue)
    ones_density.fill(1)
    indicator = bind(
            (indicator_qbx, PointsTarget(targets)),
            sym.D(LaplaceKernel(2), sym.var("sigma")))(
            queue, sigma=ones_density).get()

    try:
        fld_in_vol = bind(
                (qbx_stick_out, PointsTarget(targets)),
                chop.representation(unk))(queue, sigma=sigma).get()
    except QBXTargetAssociationFailedException as e:
        fplot.write_vtk_file(
                "failed-targets.vts",
                [
                    ("failed", e.failed_target_flags.get(queue))
                    ]
                )
        raise

    #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
    fplot.write_vtk_file(
            "potential.vts",
            [
                ("potential", fld_in_vol),
                ("indicator", indicator),
                ]
            )
Пример #52
0
def main():
    import logging
    logging.basicConfig(level=logging.WARNING)  # INFO for more progress info

    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.mesh.generation import ellipse, make_curve_mesh
    from functools import partial

    if 0:
        mesh = make_curve_mesh(
                partial(ellipse, 1),
                np.linspace(0, 1, nelements+1),
                mesh_order)
    else:
        base_mesh = make_curve_mesh(
                partial(ellipse, 1),
                np.linspace(0, 1, nelements+1),
                mesh_order)

        from meshmode.mesh.processing import affine_map, merge_disjoint_meshes
        nx = 2
        ny = 2
        dx = 2 / nx
        meshes = [
                affine_map(
                    base_mesh,
                    A=np.diag([dx*0.25, dx*0.25]),
                    b=np.array([dx*(ix-nx/2), dx*(iy-ny/2)]))
                for ix in range(nx)
                for iy in range(ny)]

        mesh = merge_disjoint_meshes(meshes, single_group=True)

        if 0:
            from meshmode.mesh.visualization import draw_curve
            draw_curve(mesh)
            import matplotlib.pyplot as plt
            plt.show()

    pre_density_discr = Discretization(
            cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(bdry_quad_order))

    from pytential.qbx import (
            QBXLayerPotentialSource, QBXTargetAssociationFailedException)
    qbx, _ = QBXLayerPotentialSource(
            pre_density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order,
            fmm_order=fmm_order
            ).with_refinement()
    density_discr = qbx.density_discr

    # {{{ describe bvp

    from sumpy.kernel import LaplaceKernel, HelmholtzKernel
    kernel = HelmholtzKernel(2)

    cse = sym.cse

    sigma_sym = sym.var("sigma")
    sqrt_w = sym.sqrt_jac_q_weight(2)
    inv_sqrt_w_sigma = cse(sigma_sym/sqrt_w)

    # Brakhage-Werner parameter
    alpha = 1j

    # -1 for interior Dirichlet
    # +1 for exterior Dirichlet
    loc_sign = +1

    bdry_op_sym = (-loc_sign*0.5*sigma_sym
            + sqrt_w*(
                alpha*sym.S(kernel, inv_sqrt_w_sigma, k=sym.var("k"),
                    qbx_forced_limit=+1)
                - sym.D(kernel, inv_sqrt_w_sigma, k=sym.var("k"),
                    qbx_forced_limit="avg")
                ))

    # }}}

    bound_op = bind(qbx, bdry_op_sym)

    # {{{ fix rhs and solve

    nodes = density_discr.nodes().with_queue(queue)
    k_vec = np.array([2, 1])
    k_vec = k * k_vec / la.norm(k_vec, 2)

    def u_incoming_func(x):
        return cl.clmath.exp(
                1j * (x[0] * k_vec[0] + x[1] * k_vec[1]))

    bc = -u_incoming_func(nodes)

    bvp_rhs = bind(qbx, sqrt_w*sym.var("bc"))(queue, bc=bc)

    from pytential.solve import gmres
    gmres_result = gmres(
            bound_op.scipy_op(queue, "sigma", dtype=np.complex128, k=k),
            bvp_rhs, tol=1e-8, progress=True,
            stall_iterations=0,
            hard_failure=True)

    # }}}

    # {{{ postprocess/visualize

    sigma = gmres_result.solution

    repr_kwargs = dict(k=sym.var("k"), qbx_forced_limit=None)
    representation_sym = (
            alpha*sym.S(kernel, inv_sqrt_w_sigma, **repr_kwargs)
            - sym.D(kernel, inv_sqrt_w_sigma, **repr_kwargs))

    from sumpy.visualization import FieldPlotter
    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=500)

    targets = cl.array.to_device(queue, fplot.points)

    u_incoming = u_incoming_func(targets)

    qbx_stick_out = qbx.copy(target_association_tolerance=0.05)

    ones_density = density_discr.zeros(queue)
    ones_density.fill(1)
    indicator = bind(
            (qbx_stick_out, PointsTarget(targets)),
            sym.D(LaplaceKernel(2), sym.var("sigma"), qbx_forced_limit=None))(
            queue, sigma=ones_density).get()

    try:
        fld_in_vol = bind(
                (qbx_stick_out, PointsTarget(targets)),
                representation_sym)(queue, sigma=sigma, k=k).get()
    except QBXTargetAssociationFailedException as e:
        fplot.write_vtk_file(
                "failed-targets.vts",
                [
                    ("failed", e.failed_target_flags.get(queue))
                    ]
                )
        raise

    #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
    fplot.write_vtk_file(
            "potential-helm.vts",
            [
                ("potential", fld_in_vol),
                ("indicator", indicator),
                ("u_incoming", u_incoming.get()),
                ]
            )
Пример #53
0
def main():
    import logging
    logging.basicConfig(level=logging.WARNING)  # INFO for more progress info

    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    target_order = 16
    qbx_order = 3
    nelements = 60
    mode_nr = 0

    k = 0
    if k:
        kernel = HelmholtzKernel(2)
    else:
        kernel = LaplaceKernel(2)
    #kernel = OneKernel()

    mesh = make_curve_mesh(
            #lambda t: ellipse(1, t),
            starfish,
            np.linspace(0, 1, nelements+1),
            target_order)

    from pytential.qbx import QBXLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    pre_density_discr = Discretization(
            cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    slow_qbx, _ = QBXLayerPotentialSource(
            pre_density_discr, fine_order=2*target_order,
            qbx_order=qbx_order, fmm_order=False,
            target_association_tolerance=.05
            ).with_refinement()
    qbx = slow_qbx.copy(fmm_order=10)
    density_discr = slow_qbx.density_discr

    nodes = density_discr.nodes().with_queue(queue)

    angle = cl.clmath.atan2(nodes[1], nodes[0])

    from pytential import bind, sym
    #op = sym.d_dx(sym.S(kernel, sym.var("sigma")), qbx_forced_limit=None)
    #op = sym.D(kernel, sym.var("sigma"), qbx_forced_limit=None)
    op = sym.S(kernel, sym.var("sigma"), qbx_forced_limit=None)

    sigma = cl.clmath.cos(mode_nr*angle)

    if isinstance(kernel, HelmholtzKernel):
        sigma = sigma.astype(np.complex128)

    fplot = FieldPlotter(np.zeros(2), extent=5, npoints=600)
    from pytential.target import PointsTarget

    fld_in_vol = bind(
            (slow_qbx, PointsTarget(fplot.points)),
            op)(queue, sigma=sigma, k=k).get()

    fmm_fld_in_vol = bind(
            (qbx, PointsTarget(fplot.points)),
            op)(queue, sigma=sigma, k=k).get()

    err = fmm_fld_in_vol-fld_in_vol

    import matplotlib
    matplotlib.use('Agg')
    im = fplot.show_scalar_in_matplotlib(np.log10(np.abs(err) + 1e-17))

    from matplotlib.colors import Normalize
    im.set_norm(Normalize(vmin=-12, vmax=0))

    import matplotlib.pyplot as pt
    from matplotlib.ticker import NullFormatter
    pt.gca().xaxis.set_major_formatter(NullFormatter())
    pt.gca().yaxis.set_major_formatter(NullFormatter())

    cb = pt.colorbar(shrink=0.9)
    cb.set_label(r"$\log_{10}(\mathdefault{Error})$")

    pt.savefig("fmm-error-order-%d.pdf" % qbx_order)
Пример #54
0
def find_mode():
    import warnings
    warnings.simplefilter("error", np.ComplexWarning)

    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    k0 = 1.4447
    k1 = k0*1.02
    beta_sym = sym.var("beta")

    from pytential.symbolic.pde.scalar import (  # noqa
            DielectricSRep2DBoundaryOperator as SRep,
            DielectricSDRep2DBoundaryOperator as SDRep)
    pde_op = SDRep(
            mode="te",
            k_vacuum=1,
            interfaces=((0, 1, sym.DEFAULT_SOURCE),),
            domain_k_exprs=(k0, k1),
            beta=beta_sym,
            use_l2_weighting=False)

    u_sym = pde_op.make_unknown("u")
    op = pde_op.operator(u_sym)

    # {{{ discretization setup

    from meshmode.mesh.generation import ellipse, make_curve_mesh
    curve_f = partial(ellipse, 1)

    target_order = 7
    qbx_order = 4
    nelements = 30

    from meshmode.mesh.processing import affine_map
    mesh = make_curve_mesh(curve_f,
            np.linspace(0, 1, nelements+1),
            target_order)
    lambda_ = 1.55
    circle_radius = 3.4*2*np.pi/lambda_
    mesh = affine_map(mesh, A=circle_radius*np.eye(2))

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    from pytential.qbx import QBXLayerPotentialSource
    density_discr = Discretization(
            cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(target_order))

    qbx = QBXLayerPotentialSource(density_discr, 4*target_order,
            qbx_order,
            # Don't use FMM for now
            fmm_order=False)

    # }}}

    x_vec = np.random.randn(len(u_sym)*density_discr.nnodes)
    y_vec = np.random.randn(len(u_sym)*density_discr.nnodes)

    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))

    starting_guesses = (1+0j)*(
            k0
            + (k1-k0) * np.random.rand(3))

    from pytential.muller import muller
    beta, niter = muller(muller_solve_func, z_start=starting_guesses)
    print("beta")
Пример #55
0
def test_identities(ctx_getter, zero_op_name, curve_name, curve_f, qbx_order, k):
    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

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

    target_order = 7

    u_sym = sym.var("u")
    grad_u_sym = sym.VectorVariable("grad_u")
    dn_u_sym = sym.var("dn_u")

    if k == 0:
        k_sym = 0
    else:
        k_sym = "k"

    zero_op_table = {
            "green":
            sym.S(k_sym, dn_u_sym) - sym.D(k_sym, u_sym) - 0.5*u_sym,

            "green_grad":
            d1.nabla * d1(sym.S(k_sym, dn_u_sym))
            - d2.nabla * d2(sym.D(k_sym, u_sym))
            - 0.5*grad_u_sym,

            # only for k==0:
            "zero_calderon":
            -sym.Dp(0, sym.S(0, u_sym))
            - 0.25*u_sym + sym.Sp(0, sym.Sp(0, u_sym))
            }
    order_table = {
            "green": qbx_order,
            "green_grad": qbx_order-1,
            "zero_calderon": qbx_order-1,
            }

    zero_op = zero_op_table[zero_op_name]

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    for nelements in [30, 50, 70]:
        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
        from pytential.qbx import QBXLayerPotentialSource
        density_discr = Discretization(
                cl_ctx, mesh,
                InterpolatoryQuadratureSimplexGroupFactory(target_order))

        qbx = QBXLayerPotentialSource(density_discr, 4*target_order,
                qbx_order,
                # Don't use FMM for now
                fmm_order=False)

        # {{{ compute values of a solution to the PDE

        nodes_host = density_discr.nodes().get(queue)
        normal = bind(density_discr, sym.normal())(queue).as_vector(np.object)
        normal_host = [normal[0].get(), normal[1].get()]

        if k != 0:
            angle = 0.3
            wave_vec = np.array([np.cos(angle), np.sin(angle)])
            u = np.exp(1j*k*np.tensordot(wave_vec, nodes_host, axes=1))
            grad_u = 1j*k*wave_vec[:, np.newaxis]*u
        else:
            center = np.array([3, 1])
            diff = nodes_host - center[:, np.newaxis]
            dist_squared = np.sum(diff**2, axis=0)
            dist = np.sqrt(dist_squared)
            u = np.log(dist)
            grad_u = diff/dist_squared

        dn_u = normal_host[0]*grad_u[0] + normal_host[1]*grad_u[1]

        # }}}

        u_dev = cl.array.to_device(queue, u)
        dn_u_dev = cl.array.to_device(queue, dn_u)
        grad_u_dev = cl.array.to_device(queue, grad_u)

        key = (qbx_order, curve_name, nelements, zero_op_name)

        bound_op = bind(qbx, zero_op)
        error = bound_op(
                queue, u=u_dev, dn_u=dn_u_dev, grad_u=grad_u_dev, k=k)
        if 0:
            pt.plot(error)
            pt.show()

        l2_error_norm = norm(density_discr, queue, error)
        print(key, l2_error_norm)

        eoc_rec.add_data_point(1/nelements, l2_error_norm)

    print(eoc_rec)
    tgt_order = order_table[zero_op_name]
    assert eoc_rec.order_estimate() > tgt_order - 1.3
Пример #56
0
def main():
    import logging
    logging.basicConfig(level=logging.WARNING)  # INFO for more progress info

    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.mesh.generation import (  # noqa
            make_curve_mesh, starfish, ellipse, drop)
    mesh = make_curve_mesh(
            #lambda t: ellipse(1, t),
            starfish,
            np.linspace(0, 1, nelements+1),
            target_order)

    from pytential.qbx import QBXLayerPotentialSource
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory

    pre_density_discr = Discretization(
            cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order))

    qbx, _ = QBXLayerPotentialSource(pre_density_discr, 4*target_order, qbx_order,
            fmm_order=qbx_order+3,
            target_association_tolerance=0.005).with_refinement()

    density_discr = qbx.density_discr

    nodes = density_discr.nodes().with_queue(queue)

    angle = cl.clmath.atan2(nodes[1], nodes[0])

    def op(**kwargs):
        kwargs.update(kernel_kwargs)

        #op = sym.d_dx(sym.S(kernel, sym.var("sigma"), **kwargs))
        return sym.D(kernel, sym.var("sigma"), **kwargs)
        #op = sym.S(kernel, sym.var("sigma"), qbx_forced_limit=None, **kwargs)

    sigma = cl.clmath.cos(mode_nr*angle)
    if 0:
        sigma = 0*angle
        from random import randrange
        for i in range(5):
            sigma[randrange(len(sigma))] = 1

    if isinstance(kernel, HelmholtzKernel):
        sigma = sigma.astype(np.complex128)

    bound_bdry_op = bind(qbx, op())
    #mlab.figure(bgcolor=(1, 1, 1))
    if 1:
        fplot = FieldPlotter(np.zeros(2), extent=5, npoints=1000)
        from pytential.target import PointsTarget

        targets_dev = cl.array.to_device(queue, fplot.points)
        fld_in_vol = bind(
                (qbx, PointsTarget(targets_dev)),
                op(qbx_forced_limit=None))(queue, sigma=sigma, k=k).get()

        if enable_mayavi:
            fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
        else:
            fplot.write_vtk_file(
                    "potential-2d.vts",
                    [
                        ("potential", fld_in_vol)
                        ]
                    )

    if 0:
        def apply_op(density):
            return bound_bdry_op(
                    queue, sigma=cl.array.to_device(queue, density), k=k).get()

        from sumpy.tools import build_matrix
        n = len(sigma)
        mat = build_matrix(apply_op, dtype=np.float64, shape=(n, n))

        import matplotlib.pyplot as pt
        pt.imshow(mat)
        pt.colorbar()
        pt.show()

    if enable_mayavi:
        # {{{ plot boundary field

        fld_on_bdry = bound_bdry_op(queue, sigma=sigma, k=k).get()

        nodes_host = density_discr.nodes().get(queue=queue)
        mlab.points3d(nodes_host[0], nodes_host[1],
                fld_on_bdry.real, scale_factor=0.03)

        # }}}

    if enable_mayavi:
        mlab.colorbar()
        mlab.show()
Пример #57
0
def run_dielectric_test(cl_ctx, queue, nelements, qbx_order,
        op_class, mode,
        k0=3, k1=2.9, mesh_order=10,
        bdry_quad_order=None, bdry_ovsmp_quad_order=None,
        use_l2_weighting=False,
        fmm_order=None, visualize=False):

    if fmm_order is None:
        fmm_order = qbx_order * 2
    if bdry_quad_order is None:
        bdry_quad_order = mesh_order
    if bdry_ovsmp_quad_order is None:
        bdry_ovsmp_quad_order = 4*bdry_quad_order

    from meshmode.mesh.generation import ellipse, make_curve_mesh
    from functools import partial
    mesh = make_curve_mesh(
            partial(ellipse, 3),
            np.linspace(0, 1, nelements+1),
            mesh_order)

    density_discr = Discretization(
            cl_ctx, mesh,
            InterpolatoryQuadratureSimplexGroupFactory(bdry_quad_order))

    logger.info("%d elements" % mesh.nelements)

    # from meshmode.discretization.visualization import make_visualizer
    # bdry_vis = make_visualizer(queue, density_discr, 20)

    # {{{ solve bvp

    from sumpy.kernel import HelmholtzKernel, AxisTargetDerivative
    kernel = HelmholtzKernel(2)

    beta = 2.5
    K0 = np.sqrt(k0**2-beta**2)  # noqa
    K1 = np.sqrt(k1**2-beta**2)  # noqa

    pde_op = op_class(
            mode,
            k_vacuum=1,
            interfaces=((0, 1, sym.DEFAULT_SOURCE),),
            domain_k_exprs=(k0, k1),
            beta=beta,
            use_l2_weighting=use_l2_weighting)

    op_unknown_sym = pde_op.make_unknown("unknown")

    representation0_sym = pde_op.representation(op_unknown_sym, 0)
    representation1_sym = pde_op.representation(op_unknown_sym, 1)

    from pytential.qbx import QBXLayerPotentialSource
    qbx = QBXLayerPotentialSource(
            density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order,
            fmm_order=fmm_order
            ).with_refinement()

    #print(sym.pretty(pde_op.operator(op_unknown_sym)))
    #1/0
    bound_pde_op = bind(qbx, pde_op.operator(op_unknown_sym))

    e_factor = float(pde_op.ez_enabled)
    h_factor = float(pde_op.hz_enabled)

    e_sources_0 = make_obj_array(list(np.array([
        [0.1, 0.2]
        ]).T.copy()))
    e_strengths_0 = np.array([1*e_factor])
    e_sources_1 = make_obj_array(list(np.array([
        [4, 4]
        ]).T.copy()))
    e_strengths_1 = np.array([1*e_factor])

    h_sources_0 = make_obj_array(list(np.array([
        [0.2, 0.1]
        ]).T.copy()))
    h_strengths_0 = np.array([1*h_factor])
    h_sources_1 = make_obj_array(list(np.array([
        [4, 5]
        ]).T.copy()))
    h_strengths_1 = np.array([1*h_factor])

    kernel_grad = [
        AxisTargetDerivative(i, kernel) for i in range(density_discr.ambient_dim)]

    from sumpy.p2p import P2P
    pot_p2p = P2P(cl_ctx, [kernel], exclude_self=False)
    pot_p2p_grad = P2P(cl_ctx, kernel_grad, exclude_self=False)

    normal = bind(density_discr, sym.normal())(queue).as_vector(np.object)
    tangent = bind(
        density_discr,
        sym.pseudoscalar()/sym.area_element())(queue).as_vector(np.object)

    _, (E0,) = pot_p2p(queue, density_discr.nodes(), e_sources_0, [e_strengths_0],
                    out_host=False, k=K0)
    _, (E1,) = pot_p2p(queue, density_discr.nodes(), e_sources_1, [e_strengths_1],
                    out_host=False, k=K1)
    _, (grad0_E0, grad1_E0) = pot_p2p_grad(
        queue, density_discr.nodes(), e_sources_0, [e_strengths_0],
        out_host=False, k=K0)
    _, (grad0_E1, grad1_E1) = pot_p2p_grad(
        queue, density_discr.nodes(), e_sources_1, [e_strengths_1],
        out_host=False, k=K1)

    _, (H0,) = pot_p2p(queue, density_discr.nodes(), h_sources_0, [h_strengths_0],
                    out_host=False, k=K0)
    _, (H1,) = pot_p2p(queue, density_discr.nodes(), h_sources_1, [h_strengths_1],
                    out_host=False, k=K1)
    _, (grad0_H0, grad1_H0) = pot_p2p_grad(
        queue, density_discr.nodes(), h_sources_0, [h_strengths_0],
        out_host=False, k=K0)
    _, (grad0_H1, grad1_H1) = pot_p2p_grad(
        queue, density_discr.nodes(), h_sources_1, [h_strengths_1],
        out_host=False, k=K1)

    E0_dntarget = (grad0_E0*normal[0] + grad1_E0*normal[1])  # noqa
    E1_dntarget = (grad0_E1*normal[0] + grad1_E1*normal[1])  # noqa

    H0_dntarget = (grad0_H0*normal[0] + grad1_H0*normal[1])  # noqa
    H1_dntarget = (grad0_H1*normal[0] + grad1_H1*normal[1])  # noqa

    E0_dttarget = (grad0_E0*tangent[0] + grad1_E0*tangent[1])  # noqa
    E1_dttarget = (grad0_E1*tangent[0] + grad1_E1*tangent[1])  # noqa

    H0_dttarget = (grad0_H0*tangent[0] + grad1_H0*tangent[1])  # noqa
    H1_dttarget = (grad0_H1*tangent[0] + grad1_H1*tangent[1])  # noqa

    sqrt_w = bind(density_discr, sym.sqrt_jac_q_weight())(queue)

    bvp_rhs = np.zeros(len(pde_op.bcs), dtype=np.object)
    for i_bc, terms in enumerate(pde_op.bcs):
        for term in terms:
            assert term.i_interface == 0
            if term.field_kind == pde_op.field_kind_e:

                if term.direction == pde_op.dir_none:
                    bvp_rhs[i_bc] += (
                        term.coeff_outer * E0
                        + term.coeff_inner * E1)
                elif term.direction == pde_op.dir_normal:
                    bvp_rhs[i_bc] += (
                        term.coeff_outer * E0_dntarget
                        + term.coeff_inner * E1_dntarget)
                elif term.direction == pde_op.dir_tangential:
                    bvp_rhs[i_bc] += (
                        term.coeff_outer * E0_dttarget
                        + term.coeff_inner * E1_dttarget)
                else:
                    raise NotImplementedError("direction spec in RHS")

            elif term.field_kind == pde_op.field_kind_h:
                if term.direction == pde_op.dir_none:
                    bvp_rhs[i_bc] += (
                        term.coeff_outer * H0
                        + term.coeff_inner * H1)
                elif term.direction == pde_op.dir_normal:
                    bvp_rhs[i_bc] += (
                        term.coeff_outer * H0_dntarget
                        + term.coeff_inner * H1_dntarget)
                elif term.direction == pde_op.dir_tangential:
                    bvp_rhs[i_bc] += (
                        term.coeff_outer * H0_dttarget
                        + term.coeff_inner * H1_dttarget)
                else:
                    raise NotImplementedError("direction spec in RHS")

            if use_l2_weighting:
                bvp_rhs[i_bc] *= sqrt_w

    scipy_op = bound_pde_op.scipy_op(queue, "unknown",
            domains=[sym.DEFAULT_TARGET]*len(pde_op.bcs), K0=K0, K1=K1,
            dtype=np.complex128)

    if mode == "tem" or op_class is SRep:
        from sumpy.tools import vector_from_device, vector_to_device
        from pytential.solve import lu
        unknown = lu(scipy_op, vector_from_device(queue, bvp_rhs))
        unknown = vector_to_device(queue, unknown)

    else:
        from pytential.solve import gmres
        gmres_result = gmres(scipy_op,
                bvp_rhs, tol=1e-14, progress=True,
                hard_failure=True, stall_iterations=0)

        unknown = gmres_result.solution

    # }}}

    targets_0 = make_obj_array(list(np.array([
        [3.2 + t, -4]
        for t in [0, 0.5, 1]
        ]).T.copy()))
    targets_1 = make_obj_array(list(np.array([
        [t*-0.3, t*-0.2]
        for t in [0, 0.5, 1]
        ]).T.copy()))

    from pytential.target import PointsTarget
    from sumpy.tools import vector_from_device
    F0_tgt = vector_from_device(queue, bind(  # noqa
            (qbx, PointsTarget(targets_0)),
            representation0_sym)(queue, unknown=unknown, K0=K0, K1=K1))
    F1_tgt = vector_from_device(queue, bind(  # noqa
            (qbx, PointsTarget(targets_1)),
            representation1_sym)(queue, unknown=unknown, K0=K0, K1=K1))

    _, (E0_tgt_true,) = pot_p2p(queue, targets_0, e_sources_0, [e_strengths_0],
                    out_host=True, k=K0)
    _, (E1_tgt_true,) = pot_p2p(queue, targets_1, e_sources_1, [e_strengths_1],
                    out_host=True, k=K1)

    _, (H0_tgt_true,) = pot_p2p(queue, targets_0, h_sources_0, [h_strengths_0],
                    out_host=True, k=K0)
    _, (H1_tgt_true,) = pot_p2p(queue, targets_1, h_sources_1, [h_strengths_1],
                    out_host=True, k=K1)

    err_F0_total = 0  # noqa
    err_F1_total = 0  # noqa

    i_field = 0

    def vec_norm(ary):
        return la.norm(ary.reshape(-1))

    def field_kind_to_string(field_kind):
        return {pde_op.field_kind_e: "E", pde_op.field_kind_h: "H"}[field_kind]

    for field_kind in pde_op.field_kinds:
        if not pde_op.is_field_present(field_kind):
            continue

        if field_kind == pde_op.field_kind_e:
            F0_tgt_true = E0_tgt_true  # noqa
            F1_tgt_true = E1_tgt_true  # noqa
        elif field_kind == pde_op.field_kind_h:
            F0_tgt_true = H0_tgt_true  # noqa
            F1_tgt_true = H1_tgt_true  # noqa
        else:
            assert False

        abs_err_F0 = vec_norm(F0_tgt[i_field] - F0_tgt_true)  # noqa
        abs_err_F1 = vec_norm(F1_tgt[i_field] - F1_tgt_true)  # noqa

        rel_err_F0 = abs_err_F0/vec_norm(F0_tgt_true)  # noqa
        rel_err_F1 = abs_err_F1/vec_norm(F1_tgt_true)  # noqa

        err_F0_total = max(rel_err_F0, err_F0_total)  # noqa
        err_F1_total = max(rel_err_F1, err_F1_total)  # noqa

        print("Abs Err %s0" % field_kind_to_string(field_kind), abs_err_F0)
        print("Abs Err %s1" % field_kind_to_string(field_kind), abs_err_F1)

        print("Rel Err %s0" % field_kind_to_string(field_kind), rel_err_F0)
        print("Rel Err %s1" % field_kind_to_string(field_kind), rel_err_F1)

        i_field += 1

    if visualize:
        from sumpy.visualization import FieldPlotter
        fplot = FieldPlotter(np.zeros(2), extent=5, npoints=300)
        from pytential.target import PointsTarget
        fld0 = bind(
                (qbx, PointsTarget(fplot.points)),
                representation0_sym)(queue, unknown=unknown, K0=K0)
        fld1 = bind(
                (qbx, PointsTarget(fplot.points)),
                representation1_sym)(queue, unknown=unknown, K1=K1)

        comp_fields = []
        i_field = 0
        for field_kind in pde_op.field_kinds:
            if not pde_op.is_field_present(field_kind):
                continue

            fld_str = field_kind_to_string(field_kind)
            comp_fields.extend([
                ("%s_fld0" % fld_str, fld0[i_field].get()),
                ("%s_fld1" % fld_str, fld1[i_field].get()),
                ])

            i_field += 0

        low_order_qbx = QBXLayerPotentialSource(
                density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=2,
                fmm_order=3).with_refinement()
        from sumpy.kernel import LaplaceKernel
        from pytential.target import PointsTarget
        ones = (cl.array.empty(queue, (density_discr.nnodes,), dtype=np.float64)
                .fill(1))
        ind_func = - bind((low_order_qbx, PointsTarget(fplot.points)),
                sym.D(LaplaceKernel(2), sym.var("u")))(
                        queue, u=ones).get()

        _, (e_fld0_true,) = pot_p2p(
                queue, fplot.points, e_sources_0, [e_strengths_0],
                out_host=True, k=K0)
        _, (e_fld1_true,) = pot_p2p(
                queue, fplot.points, e_sources_1, [e_strengths_1],
                out_host=True, k=K1)
        _, (h_fld0_true,) = pot_p2p(
                queue, fplot.points, h_sources_0, [h_strengths_0],
                out_host=True, k=K0)
        _, (h_fld1_true,) = pot_p2p(
                queue, fplot.points, h_sources_1, [h_strengths_1],
                out_host=True, k=K1)

        #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
        fplot.write_vtk_file(
                "potential-n%d.vts" % nelements,
                [
                    ("e_fld0_true", e_fld0_true),
                    ("e_fld1_true", e_fld1_true),
                    ("h_fld0_true", h_fld0_true),
                    ("h_fld1_true", h_fld1_true),
                    ("ind", ind_func),
                    ] + comp_fields
                )

    return err_F0_total, err_F1_total
Пример #58
0
 def get_mesh(self, resolution, target_order):
     return make_curve_mesh(
             self.curve_func,
             np.linspace(0, 1, resolution+1),
             target_order)
Пример #59
0
def test_ellipse_eigenvalues(ctx_getter, ellipse_aspect, mode_nr, qbx_order):
    logging.basicConfig(level=logging.INFO)

    print("ellipse_aspect: %s, mode_nr: %d, qbx_order: %d" % (
            ellipse_aspect, mode_nr, qbx_order))

    cl_ctx = ctx_getter()
    queue = cl.CommandQueue(cl_ctx)

    target_order = 7

    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
    from pytential.qbx import QBXLayerPotentialSource
    from pytools.convergence import EOCRecorder

    s_eoc_rec = EOCRecorder()
    d_eoc_rec = EOCRecorder()
    sp_eoc_rec = EOCRecorder()

    if ellipse_aspect != 1:
        nelements_values = [60, 100, 150, 200]
    else:
        nelements_values = [30, 70]

    # See
    #
    # [1] G. J. Rodin and O. Steinbach, "Boundary Element Preconditioners
    # for Problems Defined on Slender Domains", SIAM Journal on Scientific
    # Computing, Vol. 24, No. 4, pg. 1450, 2003.
    # http://dx.doi.org/10.1137/S1064827500372067

    for nelements in nelements_values:
        mesh = make_curve_mesh(partial(ellipse, ellipse_aspect),
                np.linspace(0, 1, nelements+1),
                target_order)

        fmm_order = qbx_order
        if fmm_order > 3:
            # FIXME: for now
            fmm_order = False

        density_discr = Discretization(
                cl_ctx, mesh,
                InterpolatoryQuadratureSimplexGroupFactory(target_order))
        qbx = QBXLayerPotentialSource(density_discr, 4*target_order,
                qbx_order, fmm_order=fmm_order)

        nodes = density_discr.nodes().with_queue(queue)

        if 0:
            # plot geometry, centers, normals
            centers = qbx.centers(density_discr, 1)
            nodes_h = nodes.get()
            centers_h = [centers[0].get(), centers[1].get()]
            pt.plot(nodes_h[0], nodes_h[1], "x-")
            pt.plot(centers_h[0], centers_h[1], "o")
            normal = bind(qbx, sym.normal())(queue).as_vector(np.object)
            pt.quiver(nodes_h[0], nodes_h[1],
                    normal[0].get(), normal[1].get())
            pt.gca().set_aspect("equal")
            pt.show()

        angle = cl.clmath.atan2(nodes[1]*ellipse_aspect, nodes[0])

        ellipse_fraction = ((1-ellipse_aspect)/(1+ellipse_aspect))**mode_nr

        # (2.6) in [1]
        J = cl.clmath.sqrt(  # noqa
                cl.clmath.sin(angle)**2
                + (1/ellipse_aspect)**2 * cl.clmath.cos(angle)**2)

        # {{{ single layer

        sigma = cl.clmath.cos(mode_nr*angle)/J

        s_sigma_op = bind(qbx, sym.S(0, sym.var("sigma")))
        s_sigma = s_sigma_op(queue=queue, sigma=sigma)

        # SIGN BINGO! :)
        s_eigval = 1/(2*mode_nr) * (1 + (-1)**mode_nr * ellipse_fraction)

        # (2.12) in [1]
        s_sigma_ref = s_eigval*J*sigma

        if 0:
            #pt.plot(s_sigma.get(), label="result")
            #pt.plot(s_sigma_ref.get(), label="ref")
            pt.plot((s_sigma_ref-s_sigma).get(), label="err")
            pt.legend()
            pt.show()

        s_err = (
                norm(density_discr, queue, s_sigma - s_sigma_ref)
                /
                norm(density_discr, queue, s_sigma_ref))
        s_eoc_rec.add_data_point(1/nelements, s_err)

        # }}}

        # {{{ double layer

        sigma = cl.clmath.cos(mode_nr*angle)

        d_sigma_op = bind(qbx, sym.D(0, sym.var("sigma")))
        d_sigma = d_sigma_op(queue=queue, sigma=sigma)

        # SIGN BINGO! :)
        d_eigval = -(-1)**mode_nr * 1/2*ellipse_fraction

        d_sigma_ref = d_eigval*sigma

        if 0:
            pt.plot(d_sigma.get(), label="result")
            pt.plot(d_sigma_ref.get(), label="ref")
            pt.legend()
            pt.show()

        if ellipse_aspect == 1:
            d_ref_norm = norm(density_discr, queue, sigma)
        else:
            d_ref_norm = norm(density_discr, queue, d_sigma_ref)

        d_err = (
                norm(density_discr, queue, d_sigma - d_sigma_ref)
                /
                d_ref_norm)
        d_eoc_rec.add_data_point(1/nelements, d_err)

        # }}}

        if ellipse_aspect == 1:
            # {{{ S'

            sigma = cl.clmath.cos(mode_nr*angle)

            sp_sigma_op = bind(qbx, sym.Sp(0, sym.var("sigma")))
            sp_sigma = sp_sigma_op(queue=queue, sigma=sigma)
            sp_eigval = 0

            sp_sigma_ref = sp_eigval*sigma

            sp_err = (
                    norm(density_discr, queue, sp_sigma - sp_sigma_ref)
                    /
                    norm(density_discr, queue, sigma))
            sp_eoc_rec.add_data_point(1/nelements, sp_err)

            # }}}

    print("Errors for S:")
    print(s_eoc_rec)
    required_order = qbx_order + 1
    assert s_eoc_rec.order_estimate() > required_order - 1.5

    print("Errors for D:")
    print(d_eoc_rec)
    required_order = qbx_order
    assert d_eoc_rec.order_estimate() > required_order - 1.5

    if ellipse_aspect == 1:
        print("Errors for S':")
        print(sp_eoc_rec)
        required_order = qbx_order
        assert sp_eoc_rec.order_estimate() > required_order - 1.5