Ejemplo n.º 1
0
    def get_observation_mesh(self, target_order):
        from meshmode.mesh.generation import generate_icosphere

        if self.is_interior:
            return generate_icosphere(5, target_order)
        else:
            return generate_icosphere(0.5, target_order)
Ejemplo n.º 2
0
    def get_observation_mesh(self, target_order):
        from meshmode.mesh.generation import generate_icosphere

        if self.is_interior:
            return generate_icosphere(5, target_order)
        else:
            return generate_icosphere(0.5, target_order)
Ejemplo n.º 3
0
def test_mesh_without_vertices(ctx_factory):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    # create a mesh
    from meshmode.mesh.generation import generate_icosphere
    mesh = generate_icosphere(r=1.0, order=4)

    # create one without the vertices
    from meshmode.mesh import Mesh
    grp, = mesh.groups
    groups = [
        grp.copy(nodes=grp.nodes, vertex_indices=None) for grp in mesh.groups
    ]
    mesh = Mesh(None, groups, is_conforming=False)

    # try refining it
    from meshmode.mesh.refinement import refine_uniformly
    mesh = refine_uniformly(mesh, 1)

    # make sure the world doesn't end
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory as GroupFactory
    discr = Discretization(ctx, mesh, GroupFactory(4))
    discr.nodes().with_queue(queue)

    from meshmode.discretization.visualization import make_visualizer
    make_visualizer(queue, discr, 4)
Ejemplo n.º 4
0
def test_mesh_without_vertices(actx_factory):
    actx = actx_factory()

    # create a mesh
    mesh = mgen.generate_icosphere(r=1.0, order=4)

    # create one without the vertices
    grp, = mesh.groups
    groups = [
        grp.copy(nodes=grp.nodes, vertex_indices=None) for grp in mesh.groups
    ]
    mesh = Mesh(None, groups, is_conforming=False)

    # try refining it
    from meshmode.mesh.refinement import refine_uniformly
    mesh = refine_uniformly(mesh, 1)

    # make sure the world doesn't end
    from meshmode.discretization import Discretization
    discr = Discretization(actx, mesh,
                           InterpolatoryQuadratureSimplexGroupFactory(4))
    thaw(discr.nodes(), actx)

    from meshmode.discretization.visualization import make_visualizer
    make_visualizer(actx, discr, 4)
Ejemplo n.º 5
0
    def get_mesh(self, resolution, target_order):
        from meshmode.mesh.generation import generate_icosphere
        from meshmode.mesh.refinement import refine_uniformly
        mesh = refine_uniformly(generate_icosphere(1, target_order),
                                resolution)

        return mesh
Ejemplo n.º 6
0
    def get_mesh(self, resolution, target_order):
        from meshmode.mesh.generation import generate_icosphere
        from meshmode.mesh.refinement import refine_uniformly
        mesh = refine_uniformly(
                generate_icosphere(1, target_order),
                resolution)

        return mesh
Ejemplo n.º 7
0
def test_conformity_of_uniform_mesh(refinement_rounds):
    mesh = mgen.generate_icosphere(r=1.0,
                                   order=4,
                                   uniform_refinement_rounds=refinement_rounds)

    assert mesh.is_conforming

    from meshmode.mesh import is_boundary_tag_empty, BTAG_ALL
    assert is_boundary_tag_empty(mesh, BTAG_ALL)
Ejemplo n.º 8
0
def get_unit_sphere_with_ref_mean_curvature(cl_ctx):
    order = 8

    from meshmode.mesh.generation import generate_icosphere
    mesh = generate_icosphere(1, order)

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

    return discr, 1
Ejemplo n.º 9
0
def get_sphere_mesh(refinement_increment, target_order):
    from meshmode.mesh.generation import generate_icosphere
    mesh = generate_icosphere(1, target_order)
    from meshmode.mesh.refinement import Refiner

    refiner = Refiner(mesh)
    for i in range(refinement_increment):
        flags = np.ones(mesh.nelements, dtype=bool)
        refiner.refine(flags)
        mesh = refiner.get_current_mesh()

    return mesh
Ejemplo n.º 10
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
Ejemplo n.º 11
0
def get_sphere_mesh(refinement_increment, target_order):
    from meshmode.mesh.generation import generate_icosphere
    mesh = generate_icosphere(1, target_order)
    from meshmode.mesh.refinement import Refiner

    refiner = Refiner(mesh)
    for i in range(refinement_increment):
        flags = np.ones(mesh.nelements, dtype=bool)
        refiner.refine(flags)
        mesh = refiner.get_current_mesh()

    return mesh
Ejemplo n.º 12
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)
Ejemplo n.º 13
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
Ejemplo n.º 14
0
def test_refine_surfaces(actx_factory, mesh_name, visualize=False):
    if mesh_name == "torus":
        mesh = mgen.generate_torus(10, 1, 40, 4, order=4)
    elif mesh_name == "icosphere":
        mesh = mgen.generate_icosphere(1, order=4)
    else:
        raise ValueError(f"invalid mesh name '{mesh_name}'")

    if visualize:
        actx = actx_factory()
        from meshmode.mesh.visualization import vtk_visualize_mesh
        vtk_visualize_mesh(actx, mesh, "surface.vtu")

    # check for absence of node-vertex consistency error
    from meshmode.mesh.refinement import refine_uniformly
    refined_mesh = refine_uniformly(mesh, 1)

    if visualize:
        actx = actx_factory()
        from meshmode.mesh.visualization import vtk_visualize_mesh
        vtk_visualize_mesh(actx, refined_mesh, "surface-refined.vtu")
Ejemplo n.º 15
0
def get_sphere_lpot_source(queue):
    from meshmode.discretization import Discretization
    from meshmode.discretization.poly_element import (
        InterpolatoryQuadratureSimplexGroupFactory)

    target_order = 8
    from meshmode.mesh.generation import generate_icosphere
    mesh = generate_icosphere(1, target_order)

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

    from pytential.qbx import QBXLayerPotentialSource
    lpot_source = QBXLayerPotentialSource(pre_density_discr,
                                          qbx_order=5,
                                          fmm_order=10,
                                          fine_order=4 * target_order,
                                          fmm_backend="fmmlib")
    lpot_source, _ = lpot_source.with_refinement()

    return lpot_source
Ejemplo n.º 16
0
 def get_mesh(self, resolution, mesh_order):
     from meshmode.mesh.generation import generate_icosphere
     return generate_icosphere(self.radius,
                               order=mesh_order,
                               uniform_refinement_rounds=resolution)
def test_sphere_eigenvalues(ctx_factory, mode_m, mode_n, qbx_order,
                            fmm_backend):
    logging.basicConfig(level=logging.INFO)

    special = pytest.importorskip("scipy.special")

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

    target_order = 8

    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()
    dp_eoc_rec = EOCRecorder()

    def rel_err(comp, ref):
        return (norm(density_discr, comp - ref) / norm(density_discr, ref))

    for nrefinements in [0, 1]:
        from meshmode.mesh.generation import generate_icosphere
        mesh = generate_icosphere(1, target_order)
        from meshmode.mesh.refinement import Refiner

        refiner = Refiner(mesh)
        for i in range(nrefinements):
            flags = np.ones(mesh.nelements, dtype=bool)
            refiner.refine(flags)
            mesh = refiner.get_current_mesh()

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

        from meshmode.dof_array import flatten, unflatten, thaw

        density_discr = places.get_discretization(places.auto_source.geometry)
        nodes = thaw(actx, density_discr.nodes())
        r = actx.np.sqrt(nodes[0] * nodes[0] + nodes[1] * nodes[1] +
                         nodes[2] * nodes[2])
        phi = actx.np.arccos(nodes[2] / r)
        theta = actx.np.arctan2(nodes[0], nodes[1])

        ymn = unflatten(
            actx, density_discr,
            actx.from_numpy(
                special.sph_harm(mode_m, mode_n, actx.to_numpy(flatten(theta)),
                                 actx.to_numpy(flatten(phi)))))

        from sumpy.kernel import LaplaceKernel
        lap_knl = LaplaceKernel(3)

        # {{{ single layer

        s_sigma_op = bind(
            places, sym.S(lap_knl, sym.var("sigma"), qbx_forced_limit=+1))
        s_sigma = s_sigma_op(actx, sigma=ymn)
        s_eigval = 1 / (2 * mode_n + 1)

        h_max = bind(places, sym.h_max(qbx.ambient_dim))(actx)
        s_eoc_rec.add_data_point(h_max, rel_err(s_sigma, s_eigval * ymn))

        # }}}

        # {{{ double layer

        d_sigma_op = bind(
            places, sym.D(lap_knl, sym.var("sigma"), qbx_forced_limit="avg"))
        d_sigma = d_sigma_op(actx, sigma=ymn)
        d_eigval = -1 / (2 * (2 * mode_n + 1))
        d_eoc_rec.add_data_point(h_max, rel_err(d_sigma, d_eigval * ymn))

        # }}}

        # {{{ S'

        sp_sigma_op = bind(
            places, sym.Sp(lap_knl, sym.var("sigma"), qbx_forced_limit="avg"))
        sp_sigma = sp_sigma_op(actx, sigma=ymn)
        sp_eigval = -1 / (2 * (2 * mode_n + 1))

        sp_eoc_rec.add_data_point(h_max, rel_err(sp_sigma, sp_eigval * ymn))

        # }}}

        # {{{ D'

        dp_sigma_op = bind(
            places, sym.Dp(lap_knl, sym.var("sigma"), qbx_forced_limit="avg"))
        dp_sigma = dp_sigma_op(actx, sigma=ymn)
        dp_eigval = -(mode_n * (mode_n + 1)) / (2 * mode_n + 1)

        dp_eoc_rec.add_data_point(h_max, rel_err(dp_sigma, dp_eigval * ymn))

        # }}}

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

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

    print("Errors for D':")
    print(dp_eoc_rec)
    required_order = qbx_order
    assert dp_eoc_rec.order_estimate() > required_order - 1.5
Ejemplo n.º 18
0
def run(actx, *,
        ambient_dim: int = 3,
        resolution: int = None,
        target_order: int = 4,
        tmax: float = 1.0,
        timestep: float = 1.0e-2,
        group_factory_name: str = "warp_and_blend",
        visualize: bool = True):
    if ambient_dim not in (2, 3):
        raise ValueError(f"unsupported dimension: {ambient_dim}")

    mesh_order = target_order
    radius = 1.0

    # {{{ geometry

    # {{{ element groups

    import modepy as mp
    import meshmode.discretization.poly_element as poly

    # NOTE: picking the same unit nodes for the mesh and the discr saves
    # a bit of work when reconstructing after a time step

    if group_factory_name == "warp_and_blend":
        group_factory_cls = poly.PolynomialWarpAndBlendGroupFactory

        unit_nodes = mp.warp_and_blend_nodes(ambient_dim - 1, mesh_order)
    elif group_factory_name == "quadrature":
        group_factory_cls = poly.InterpolatoryQuadratureSimplexGroupFactory

        if ambient_dim == 2:
            unit_nodes = mp.LegendreGaussQuadrature(
                    mesh_order, force_dim_axis=True).nodes
        else:
            unit_nodes = mp.VioreanuRokhlinSimplexQuadrature(mesh_order, 2).nodes
    else:
        raise ValueError(f"unknown group factory: '{group_factory_name}'")

    # }}}

    # {{{ discretization

    import meshmode.mesh.generation as gen
    if ambient_dim == 2:
        nelements = 8192 if resolution is None else resolution
        mesh = gen.make_curve_mesh(
                lambda t: radius * gen.ellipse(1.0, t),
                np.linspace(0.0, 1.0, nelements + 1),
                order=mesh_order,
                unit_nodes=unit_nodes)
    else:
        nrounds = 4 if resolution is None else resolution
        mesh = gen.generate_icosphere(radius,
                uniform_refinement_rounds=nrounds,
                order=mesh_order,
                unit_nodes=unit_nodes)

    from meshmode.discretization import Discretization
    discr0 = Discretization(actx, mesh, group_factory_cls(target_order))

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

    # }}}

    if visualize:
        from meshmode.discretization.visualization import make_visualizer
        vis = make_visualizer(actx, discr0,
                vis_order=target_order,
                # NOTE: setting this to True will add some unnecessary
                # resampling in Discretization.nodes for the vis_discr underneath
                force_equidistant=False)

    # }}}

    # {{{ ode

    def velocity_field(nodes, alpha=1.0):
        return make_obj_array([
            alpha * nodes[0], -alpha * nodes[1], 0.0 * nodes[0]
            ][:ambient_dim])

    def source(t, x):
        discr = reconstruct_discr_from_nodes(actx, discr0, x)
        u = velocity_field(thaw(discr.nodes(), actx))

        # {{{

        # NOTE: these are just here because this was at some point used to
        # profile some more operators (turned out well!)

        from meshmode.discretization import num_reference_derivative
        x = thaw(discr.nodes()[0], actx)
        gradx = sum(
                num_reference_derivative(discr, (i,), x)
                for i in range(discr.dim))
        intx = sum(actx.np.sum(xi * wi) for xi, wi in zip(x, discr.quad_weights()))

        assert gradx is not None
        assert intx is not None

        # }}}

        return u

    # }}}

    # {{{ evolve

    maxiter = int(tmax // timestep) + 1
    dt = tmax / maxiter + 1.0e-15

    x = thaw(discr0.nodes(), actx)
    t = 0.0

    if visualize:
        filename = f"moving-geometry-{0:09d}.vtu"
        plot_solution(actx, vis, filename, discr0, t, x)

    for n in range(1, maxiter + 1):
        x = advance(actx, dt, t, x, source)
        t += dt

        if visualize:
            discr = reconstruct_discr_from_nodes(actx, discr0, x)
            vis = make_visualizer(actx, discr, vis_order=target_order)
            # vis = vis.copy_with_same_connectivity(actx, discr)

            filename = f"moving-geometry-{n:09d}.vtu"
            plot_solution(actx, vis, filename, discr, t, x)

        logger.info("[%05d/%05d] t = %.5e/%.5e dt = %.5e",
                n, maxiter, t, tmax, dt)
Ejemplo n.º 19
0
                pt.ylim([-1.5, 1.5])

                filename = "test_proxy_generator_{}d_{:04}.png".format(
                    ambient_dim, i)
                pt.savefig(filename, dpi=300)
                pt.clf()
        else:
            from meshmode.discretization.visualization import make_visualizer
            from meshmode.mesh.processing import (  # noqa
                affine_map, merge_disjoint_meshes)
            from meshmode.discretization import Discretization
            from meshmode.discretization.poly_element import \
                InterpolatoryQuadratureSimplexGroupFactory

            from meshmode.mesh.generation import generate_icosphere
            ref_mesh = generate_icosphere(1, generator.nproxy)

            # NOTE: this does not plot the actual proxy points
            for i in range(srcindices.nblocks):
                mesh = affine_map(ref_mesh,
                                  A=(pxyradii[i] * np.eye(ambient_dim)),
                                  b=pxycenters[:, i].reshape(-1))

                mesh = merge_disjoint_meshes([mesh, density_discr.mesh])
                discr = Discretization(
                    actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(10))

                vis = make_visualizer(actx, discr, 10)
                filename = "test_proxy_generator_{}d_{:04}.vtu".format(
                    ambient_dim, i)
                vis.write_vtk_file(filename, [])
Ejemplo n.º 20
0
def test_harmonic_extension_exterior_3d(ctx_factory):

    dim = 3  # noqa: F841
    mesh_order = 8
    fmm_order = 3
    bdry_quad_order = mesh_order
    bdry_ovsmp_quad_order = 4 * bdry_quad_order
    qbx_order = mesh_order

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

    from meshmode.mesh.generation import generate_icosphere
    from meshmode.mesh.refinement import refine_uniformly

    radius = 2.5
    base_mesh = generate_icosphere(radius, order=mesh_order)
    mesh = refine_uniformly(base_mesh, 1)

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

    from pytential.qbx import QBXLayerPotentialSource
    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

    ntgts = 200
    rho = np.random.rand(ntgts) * 3 + radius + 0.05
    theta = np.random.rand(ntgts) * 2 * np.pi
    phi = (np.random.rand(ntgts) - 0.5) * np.pi

    nodes = density_discr.nodes().with_queue(queue)
    source = np.array([0, 1, 2])

    def test_func(x):
        return 1.0 / la.norm(x.get() - source[:, None], axis=0)

    f = cl.array.to_device(queue, test_func(nodes))

    targets = cl.array.to_device(
        queue,
        np.array([
            rho * np.cos(phi) * np.cos(theta),
            rho * np.cos(phi) * np.sin(theta), rho * np.sin(phi)
        ]))

    exact_f = test_func(targets)

    ext_f, _ = compute_harmonic_extension(queue,
                                          PointsTarget(targets),
                                          qbx,
                                          density_discr,
                                          f,
                                          loc_sign=1)

    assert np.linalg.norm(exact_f -
                          ext_f.get()) < 1e-3 * np.linalg.norm(exact_f)
Ejemplo n.º 21
0
def test_proxy_generator(ctx_factory, ndim, factor, visualize=False):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    qbx = _build_qbx_discr(queue, ndim=ndim)
    srcindices = _build_block_index(qbx.density_discr, factor=factor)

    from pytential.linalg.proxy import ProxyGenerator
    generator = ProxyGenerator(qbx, ratio=1.1)
    proxies, pxyranges, pxycenters, pxyradii = generator(queue, srcindices)

    proxies = np.vstack([p.get() for p in proxies])
    pxyranges = pxyranges.get()
    pxycenters = np.vstack([c.get() for c in pxycenters])
    pxyradii = pxyradii.get()

    for i in range(srcindices.nblocks):
        ipxy = np.s_[pxyranges[i]:pxyranges[i + 1]]

        r = la.norm(proxies[:, ipxy] - pxycenters[:, i].reshape(-1, 1), axis=0)
        assert np.allclose(r - pxyradii[i], 0.0, atol=1.0e-14)

    srcindices = srcindices.get(queue)
    if visualize:
        if qbx.ambient_dim == 2:
            import matplotlib.pyplot as pt

            density_nodes = qbx.density_discr.nodes().get(queue)
            ci = bind(qbx, sym.expansion_centers(qbx.ambient_dim, -1))(queue)
            ci = np.vstack([c.get(queue) for c in ci])
            ce = bind(qbx, sym.expansion_centers(qbx.ambient_dim, +1))(queue)
            ce = np.vstack([c.get(queue) for c in ce])
            r = bind(qbx, sym.expansion_radii(qbx.ambient_dim))(queue).get()

            for i in range(srcindices.nblocks):
                isrc = srcindices.block_indices(i)
                ipxy = np.s_[pxyranges[i]:pxyranges[i + 1]]

                pt.figure(figsize=(10, 8))
                axis = pt.gca()
                for j in isrc:
                    c = pt.Circle(ci[:, j], r[j], color='k', alpha=0.1)
                    axis.add_artist(c)
                    c = pt.Circle(ce[:, j], r[j], color='k', alpha=0.1)
                    axis.add_artist(c)

                pt.plot(density_nodes[0],
                        density_nodes[1],
                        'ko',
                        ms=2.0,
                        alpha=0.5)
                pt.plot(density_nodes[0, srcindices.indices],
                        density_nodes[1, srcindices.indices],
                        'o',
                        ms=2.0)
                pt.plot(density_nodes[0, isrc],
                        density_nodes[1, isrc],
                        'o',
                        ms=2.0)
                pt.plot(proxies[0, ipxy], proxies[1, ipxy], 'o', ms=2.0)
                pt.xlim([-1.5, 1.5])
                pt.ylim([-1.5, 1.5])

                filename = "test_proxy_generator_{}d_{:04}.png".format(ndim, i)
                pt.savefig(filename, dpi=300)
                pt.clf()
        else:
            from meshmode.discretization.visualization import make_visualizer
            from meshmode.mesh.processing import (  # noqa
                affine_map, merge_disjoint_meshes)
            from meshmode.discretization import Discretization
            from meshmode.discretization.poly_element import \
                InterpolatoryQuadratureSimplexGroupFactory

            from meshmode.mesh.generation import generate_icosphere
            ref_mesh = generate_icosphere(1, generator.nproxy)

            # NOTE: this does not plot the actual proxy points
            for i in range(srcindices.nblocks):
                mesh = affine_map(ref_mesh,
                                  A=(pxyradii[i] * np.eye(ndim)),
                                  b=pxycenters[:, i].reshape(-1))

                mesh = merge_disjoint_meshes([mesh, qbx.density_discr.mesh])
                discr = Discretization(
                    ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(10))

                vis = make_visualizer(queue, discr, 10)
                filename = "test_proxy_generator_{}d_{:04}.vtu".format(ndim, i)
                vis.write_vtk_file(filename, [])
Ejemplo n.º 22
0
def test_sphere_eigenvalues(ctx_getter, mode_m, mode_n, qbx_order,
        fmm_backend):
    logging.basicConfig(level=logging.INFO)

    special = pytest.importorskip("scipy.special")

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

    target_order = 8

    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()
    dp_eoc_rec = EOCRecorder()

    def rel_err(comp, ref):
        return (
                norm(density_discr, queue, comp - ref)
                / norm(density_discr, queue, ref))

    for nrefinements in [0, 1]:
        from meshmode.mesh.generation import generate_icosphere
        mesh = generate_icosphere(1, target_order)
        from meshmode.mesh.refinement import Refiner

        refiner = Refiner(mesh)
        for i in range(nrefinements):
            flags = np.ones(mesh.nelements, dtype=bool)
            refiner.refine(flags)
            mesh = refiner.get_current_mesh()

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

        density_discr = qbx.density_discr
        nodes = density_discr.nodes().with_queue(queue)
        r = cl.clmath.sqrt(nodes[0]**2 + nodes[1]**2 + nodes[2]**2)
        phi = cl.clmath.acos(nodes[2]/r)
        theta = cl.clmath.atan2(nodes[0], nodes[1])

        ymn = cl.array.to_device(queue,
                special.sph_harm(mode_m, mode_n, theta.get(), phi.get()))

        from sumpy.kernel import LaplaceKernel
        lap_knl = LaplaceKernel(3)

        # {{{ single layer

        s_sigma_op = bind(qbx, sym.S(lap_knl, sym.var("sigma")))
        s_sigma = s_sigma_op(queue=queue, sigma=ymn)
        s_eigval = 1/(2*mode_n + 1)
        s_eoc_rec.add_data_point(qbx.h_max, rel_err(s_sigma, s_eigval*ymn))

        # }}}

        # {{{ double layer

        d_sigma_op = bind(qbx, sym.D(lap_knl, sym.var("sigma")))
        d_sigma = d_sigma_op(queue=queue, sigma=ymn)
        d_eigval = -1/(2*(2*mode_n + 1))
        d_eoc_rec.add_data_point(qbx.h_max, rel_err(d_sigma, d_eigval*ymn))

        # }}}

        # {{{ S'

        sp_sigma_op = bind(qbx, sym.Sp(lap_knl, sym.var("sigma")))
        sp_sigma = sp_sigma_op(queue=queue, sigma=ymn)
        sp_eigval = -1/(2*(2*mode_n + 1))
        sp_eoc_rec.add_data_point(qbx.h_max, rel_err(sp_sigma, sp_eigval*ymn))

        # }}}

        # {{{ D'

        dp_sigma_op = bind(qbx, sym.Dp(lap_knl, sym.var("sigma")))
        dp_sigma = dp_sigma_op(queue=queue, sigma=ymn)
        dp_eigval = -(mode_n*(mode_n+1))/(2*mode_n + 1)
        dp_eoc_rec.add_data_point(qbx.h_max, rel_err(dp_sigma, dp_eigval*ymn))

        # }}}

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

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

    print("Errors for D':")
    print(dp_eoc_rec)
    required_order = qbx_order
    assert dp_eoc_rec.order_estimate() > required_order - 1.5
Ejemplo n.º 23
0
def test_proxy_generator(ctx_factory, ndim, factor, visualize=False):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)

    qbx = _build_qbx_discr(queue, ndim=ndim)
    srcindices = _build_block_index(qbx.density_discr,
            method='nodes', factor=factor)

    from pytential.linalg.proxy import ProxyGenerator
    generator = ProxyGenerator(qbx, ratio=1.1)
    proxies, pxyranges, pxycenters, pxyradii = generator(queue, srcindices)

    proxies = np.vstack([p.get() for p in proxies])
    pxyranges = pxyranges.get()
    pxycenters = np.vstack([c.get() for c in pxycenters])
    pxyradii = pxyradii.get()

    for i in range(srcindices.nblocks):
        ipxy = np.s_[pxyranges[i]:pxyranges[i + 1]]

        r = la.norm(proxies[:, ipxy] - pxycenters[:, i].reshape(-1, 1), axis=0)
        assert np.allclose(r - pxyradii[i], 0.0, atol=1.0e-14)

    srcindices = srcindices.get(queue)
    if visualize:
        if qbx.ambient_dim == 2:
            import matplotlib.pyplot as pt
            from pytential.qbx.utils import get_centers_on_side

            density_nodes = qbx.density_discr.nodes().get(queue)
            ci = get_centers_on_side(qbx, -1)
            ci = np.vstack([c.get(queue) for c in ci])
            ce = get_centers_on_side(qbx, +1)
            ce = np.vstack([c.get(queue) for c in ce])
            r = qbx._expansion_radii("nsources").get(queue)

            for i in range(srcindices.nblocks):
                isrc = srcindices.block_indices(i)
                ipxy = np.s_[pxyranges[i]:pxyranges[i + 1]]

                pt.figure(figsize=(10, 8))
                axis = pt.gca()
                for j in isrc:
                    c = pt.Circle(ci[:, j], r[j], color='k', alpha=0.1)
                    axis.add_artist(c)
                    c = pt.Circle(ce[:, j], r[j], color='k', alpha=0.1)
                    axis.add_artist(c)

                pt.plot(density_nodes[0], density_nodes[1],
                        'ko', ms=2.0, alpha=0.5)
                pt.plot(density_nodes[0, srcindices.indices],
                        density_nodes[1, srcindices.indices],
                        'o', ms=2.0)
                pt.plot(density_nodes[0, isrc], density_nodes[1, isrc],
                        'o', ms=2.0)
                pt.plot(proxies[0, ipxy], proxies[1, ipxy],
                        'o', ms=2.0)
                pt.xlim([-1.5, 1.5])
                pt.ylim([-1.5, 1.5])

                filename = "test_proxy_generator_{}d_{:04}.png".format(ndim, i)
                pt.savefig(filename, dpi=300)
                pt.clf()
        else:
            from meshmode.discretization.visualization import make_visualizer
            from meshmode.mesh.processing import ( # noqa
                    affine_map, merge_disjoint_meshes)
            from meshmode.discretization import Discretization
            from meshmode.discretization.poly_element import \
                InterpolatoryQuadratureSimplexGroupFactory

            from meshmode.mesh.generation import generate_icosphere
            ref_mesh = generate_icosphere(1, generator.nproxy)

            # NOTE: this does not plot the actual proxy points
            for i in range(srcindices.nblocks):
                mesh = affine_map(ref_mesh,
                    A=(pxyradii[i] * np.eye(ndim)),
                    b=pxycenters[:, i].reshape(-1))

                mesh = merge_disjoint_meshes([mesh, qbx.density_discr.mesh])
                discr = Discretization(ctx, mesh,
                    InterpolatoryQuadratureSimplexGroupFactory(10))

                vis = make_visualizer(queue, discr, 10)
                filename = "test_proxy_generator_{}d_{:04}.vtu".format(ndim, i)
                if os.path.isfile(filename):
                    os.remove(filename)
                vis.write_vtk_file(filename, [])
Ejemplo n.º 24
0
def main(ctx_factory, dim=2, order=4, use_quad=False, visualize=False):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(
        queue,
        allocator=cl_tools.MemoryPool(cl_tools.ImmediateAllocator(queue)),
        force_device_scalars=True,
    )

    # {{{ parameters

    # sphere radius
    radius = 1.0
    # sphere resolution
    resolution = 64 if dim == 2 else 1

    # final time
    final_time = np.pi

    # flux
    flux_type = "lf"

    # }}}

    # {{{ discretization

    if dim == 2:
        from meshmode.mesh.generation import make_curve_mesh, ellipse
        mesh = make_curve_mesh(
                lambda t: radius * ellipse(1.0, t),
                np.linspace(0.0, 1.0, resolution + 1),
                order)
    elif dim == 3:
        from meshmode.mesh.generation import generate_icosphere
        mesh = generate_icosphere(radius, order=4 * order,
                uniform_refinement_rounds=resolution)
    else:
        raise ValueError("unsupported dimension")

    discr_tag_to_group_factory = {}
    if use_quad:
        qtag = dof_desc.DISCR_TAG_QUAD
    else:
        qtag = None

    from meshmode.discretization.poly_element import \
            default_simplex_group_factory, \
            QuadratureSimplexGroupFactory

    discr_tag_to_group_factory[dof_desc.DISCR_TAG_BASE] = \
        default_simplex_group_factory(base_dim=dim-1, order=order)

    if use_quad:
        discr_tag_to_group_factory[qtag] = \
            QuadratureSimplexGroupFactory(order=4*order)

    from grudge import DiscretizationCollection

    dcoll = DiscretizationCollection(
        actx, mesh,
        discr_tag_to_group_factory=discr_tag_to_group_factory
    )

    volume_discr = dcoll.discr_from_dd(dof_desc.DD_VOLUME)
    logger.info("ndofs:     %d", volume_discr.ndofs)
    logger.info("nelements: %d", volume_discr.mesh.nelements)

    # }}}

    # {{{ Surface advection operator

    # velocity field
    x = thaw(dcoll.nodes(), actx)
    c = make_obj_array([-x[1], x[0], 0.0])[:dim]

    def f_initial_condition(x):
        return x[0]

    from grudge.models.advection import SurfaceAdvectionOperator
    adv_operator = SurfaceAdvectionOperator(
        dcoll,
        c,
        flux_type=flux_type,
        quad_tag=qtag
    )

    u0 = f_initial_condition(x)

    def rhs(t, u):
        return adv_operator.operator(t, u)

    # check velocity is tangential
    from grudge.geometry import normal

    surf_normal = normal(actx, dcoll, dd=dof_desc.DD_VOLUME)

    error = op.norm(dcoll, c.dot(surf_normal), 2)
    logger.info("u_dot_n:   %.5e", error)

    # }}}

    # {{{ time stepping

    # FIXME: dt estimate is not necessarily valid for surfaces
    dt = actx.to_numpy(
        0.45 * adv_operator.estimate_rk4_timestep(actx, dcoll, fields=u0))
    nsteps = int(final_time // dt) + 1

    logger.info("dt:        %.5e", dt)
    logger.info("nsteps:    %d", nsteps)

    from grudge.shortcuts import set_up_rk4
    dt_stepper = set_up_rk4("u", dt, u0, rhs)
    plot = Plotter(actx, dcoll, order, visualize=visualize)

    norm_u = actx.to_numpy(op.norm(dcoll, u0, 2))

    step = 0

    event = dt_stepper.StateComputed(0.0, 0, 0, u0)
    plot(event, "fld-surface-%04d" % 0)

    if visualize and dim == 3:
        from grudge.shortcuts import make_visualizer
        vis = make_visualizer(dcoll)
        vis.write_vtk_file(
            "fld-surface-velocity.vtu",
            [
                ("u", c),
                ("n", surf_normal)
            ],
            overwrite=True
        )

        df = dof_desc.DOFDesc(FACE_RESTR_INTERIOR)
        face_discr = dcoll.discr_from_dd(df)
        face_normal = thaw(dcoll.normal(dd=df), actx)

        from meshmode.discretization.visualization import make_visualizer
        vis = make_visualizer(actx, face_discr)
        vis.write_vtk_file("fld-surface-face-normals.vtu", [
            ("n", face_normal)
            ], overwrite=True)

    for event in dt_stepper.run(t_end=final_time, max_steps=nsteps + 1):
        if not isinstance(event, dt_stepper.StateComputed):
            continue

        step += 1
        if step % 10 == 0:
            norm_u = actx.to_numpy(op.norm(dcoll, event.state_component, 2))
            plot(event, "fld-surface-%04d" % step)

        logger.info("[%04d] t = %.5f |u| = %.5e", step, event.t, norm_u)

        # NOTE: These are here to ensure the solution is bounded for the
        # time interval specified
        assert norm_u < 3
Ejemplo n.º 25
0
def main():
    # cl.array.to_device(queue, numpy_array)
    from meshmode.mesh.io import generate_gmsh, FileSource
    from meshmode.mesh.generation import generate_icosphere
    from meshmode.mesh.refinement import Refiner
    mesh = generate_icosphere(1,target_order)

    refinement_increment = 1
    refiner = Refiner(mesh)
    for i in range(refinement_increment):
        flags = np.ones(mesh.nelements, dtype=bool)
        refiner.refine(flags)
        mesh = refiner.get_current_mesh()


    from meshmode.mesh.processing import perform_flips
    # Flip elements--gmsh generates inside-out geometry.
    mesh = perform_flips(mesh, np.ones(mesh.nelements))

    print("%d elements" % mesh.nelements)

    from meshmode.mesh.processing import find_bounding_box
    bbox_min, bbox_max = find_bounding_box(mesh)
    bbox_center = 0.5*(bbox_min+bbox_max)
    bbox_size = max(bbox_max-bbox_min) / 2

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

    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=False, fmm_backend="fmmlib")

    from pytential.symbolic.pde.maxwell import MuellerAugmentedMFIEOperator
    pde_op = MuellerAugmentedMFIEOperator(
            omega=1.0,
            epss=[1.0, 1.0],
            mus=[1.0, 1.0],
            )
    from pytential import bind, sym

    unk = pde_op.make_unknown("sigma")
    sym_operator = pde_op.operator(unk)
    sym_rhs = pde_op.rhs(
            sym.make_sym_vector("Einc", 3),
            sym.make_sym_vector("Hinc", 3))
    sym_repr = pde_op.representation(1, unk)

    if 1:
        expr = sym_repr
        print(sym.pretty(expr))

        print("#"*80)
        from pytential.target import PointsTarget

        tgt_points=np.zeros((3,1))
        tgt_points[0,0] = 100
        tgt_points[1,0] = -200
        tgt_points[2,0] = 300

        bound_op = bind((qbx, PointsTarget(tgt_points)), expr)
        print(bound_op.code)

    if 1:

        def green3e(x,y,z,source,strength,k):
        # electric field corresponding to dyadic green's function
        # due to monochromatic electric dipole located at "source".
        # "strength" is the the intensity of the dipole.
        #  E = (I + Hess)(exp(ikr)/r) dot (strength)
        #
            dx = x - source[0]
            dy = y - source[1]
            dz = z - source[2]
            rr = np.sqrt(dx**2 + dy**2 + dz**2)

            fout = np.exp(1j*k*rr)/rr
            evec = fout*strength
            qmat = np.zeros((3,3),dtype=np.complex128)

            qmat[0,0]=(2*dx**2-dy**2-dz**2)*(1-1j*k*rr)
            qmat[1,1]=(2*dy**2-dz**2-dx**2)*(1-1j*k*rr)
            qmat[2,2]=(2*dz**2-dx**2-dy**2)*(1-1j*k*rr)

            qmat[0,0]=qmat[0,0]+(-k**2*dx**2*rr**2)
            qmat[1,1]=qmat[1,1]+(-k**2*dy**2*rr**2)
            qmat[2,2]=qmat[2,2]+(-k**2*dz**2*rr**2)

            qmat[0,1]=(3-k**2*rr**2-3*1j*k*rr)*(dx*dy)
            qmat[1,2]=(3-k**2*rr**2-3*1j*k*rr)*(dy*dz)
            qmat[2,0]=(3-k**2*rr**2-3*1j*k*rr)*(dz*dx)

            qmat[1,0]=qmat[0,1]
            qmat[2,1]=qmat[1,2]
            qmat[0,2]=qmat[2,0]

            fout=np.exp(1j*k*rr)/rr**5/k**2

            fvec = fout*np.dot(qmat,strength)
            evec = evec + fvec
            return evec

        def green3m(x,y,z,source,strength,k):
        # magnetic field corresponding to dyadic green's function
        # due to monochromatic electric dipole located at "source".
        # "strength" is the the intensity of the dipole.
        #  H = curl((I + Hess)(exp(ikr)/r) dot (strength)) = 
        #  strength \cross \grad (exp(ikr)/r)
        #
            dx = x - source[0]
            dy = y - source[1]
            dz = z - source[2]
            rr = np.sqrt(dx**2 + dy**2 + dz**2)

            fout=(1-1j*k*rr)*np.exp(1j*k*rr)/rr**3
            fvec = np.zeros(3,dtype=np.complex128)
            fvec[0] = fout*dx
            fvec[1] = fout*dy
            fvec[2] = fout*dz

            hvec = np.cross(strength,fvec)

            return hvec

        def dipole3e(x,y,z,source,strength,k):
        #
        #  evalaute electric and magnetic field due
        #  to monochromatic electric dipole located at "source"
        #  with intensity "strength"

            evec = green3e(x,y,z,source,strength,k)
            evec = evec*1j*k
            hvec = green3m(x,y,z,source,strength,k)
#            print(hvec)
#            print(strength)
            return evec,hvec
            
        def dipole3m(x,y,z,source,strength,k):
        #
        #  evalaute electric and magnetic field due
        #  to monochromatic magnetic dipole located at "source"
        #  with intensity "strength"
            evec = green3m(x,y,z,source,strength,k)
            hvec = green3e(x,y,z,source,strength,k)
            hvec = -hvec*1j*k
            return evec,hvec
            

        def dipole3eall(x,y,z,sources,strengths,k):
            ns = len(strengths)
            evec = np.zeros(3,dtype=np.complex128)
            hvec = np.zeros(3,dtype=np.complex128)

            for i in range(ns):
                evect,hvect = dipole3e(x,y,z,sources[i],strengths[i],k)
                evec = evec + evect
                hvec = hvec + hvect

        nodes = density_discr.nodes().with_queue(queue).get()
        source = [0.01,-0.03,0.02]
#        source = cl.array.to_device(queue,np.zeros(3))
#        source[0] = 0.01
#        source[1] =-0.03
#        source[2] = 0.02
        strength = np.ones(3)
       
#        evec = cl.array.to_device(queue,np.zeros((3,len(nodes[0])),dtype=np.complex128))
#        hvec = cl.array.to_device(queue,np.zeros((3,len(nodes[0])),dtype=np.complex128))

        evec = np.zeros((3,len(nodes[0])),dtype=np.complex128)
        hvec = np.zeros((3,len(nodes[0])),dtype=np.complex128)
        for i in range(len(nodes[0])):
            evec[:,i],hvec[:,i] = dipole3e(nodes[0][i],nodes[1][i],nodes[2][i],source,strength,k)
        print(np.shape(hvec))
        print(type(evec))
        print(type(hvec))

        evec = cl.array.to_device(queue,evec)
        hvec = cl.array.to_device(queue,hvec)

        bvp_rhs = bind(qbx, sym_rhs)(queue,Einc=evec,Hinc=hvec)
        print(np.shape(bvp_rhs))
        print(type(bvp_rhs))
#        print(bvp_rhs)
        1/-1

        bound_op = bind(qbx, sym_operator)

        from pytential.solve import gmres
        if 1:
            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)

            sigma = gmres_result.solution

        fld_at_tgt = bind((qbx, PointsTarget(tgt_points)), sym_repr)(queue,
        sigma=sigma,k=k)
        fld_at_tgt = np.array([
            fi.get() for fi in fld_at_tgt
            ])
        print(fld_at_tgt)
        fld_exact_e,fld_exact_h = dipole3e(tgt_points[0,0],tgt_points[1,0],tgt_points[2,0],source,strength,k)
        print(fld_exact_e)
        print(fld_exact_h)
        1/0

    # }}}

    #mlab.figure(bgcolor=(1, 1, 1))
    if 1:
        from meshmode.discretization.visualization import make_visualizer
        bdry_vis = make_visualizer(queue, density_discr, target_order)

        bdry_normals = bind(density_discr, sym.normal(3))(queue)\
                .as_vector(dtype=object)

        bdry_vis.write_vtk_file("source.vtu", [
            ("sigma", sigma),
            ("bdry_normals", bdry_normals),
            ])

        fplot = FieldPlotter(bbox_center, extent=2*bbox_size, npoints=(150, 150, 1))

        qbx_stick_out = qbx.copy(target_stick_out_factor=0.1)
        from pytential.target import PointsTarget
        from pytential.qbx import QBXTargetAssociationFailedException

        rho_sym = sym.var("rho")

        try:
            fld_in_vol = bind(
                    (qbx_stick_out, PointsTarget(fplot.points)),
                    sym.make_obj_array([
                        sym.S(pde_op.kernel, rho_sym, k=sym.var("k"),
                            qbx_forced_limit=None),
                        sym.d_dx(3, sym.S(pde_op.kernel, rho_sym, k=sym.var("k"),
                            qbx_forced_limit=None)),
                        sym.d_dy(3, sym.S(pde_op.kernel, rho_sym, k=sym.var("k"),
                            qbx_forced_limit=None)),
                        sym.d_dz(3, sym.S(pde_op.kernel, rho_sym, k=sym.var("k"),
                            qbx_forced_limit=None)),
                        ])
                    )(queue, jt=jt, rho=rho, k=k)
        except QBXTargetAssociationFailedException as e:
            fplot.write_vtk_file(
                    "failed-targets.vts",
                    [
                        ("failed_targets", e.failed_target_flags.get(queue))
                        ])
            raise

        fld_in_vol = sym.make_obj_array(
            [fiv.get() for fiv in fld_in_vol])

        #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
        fplot.write_vtk_file(
                "potential.vts",
                [
                    ("potential", fld_in_vol[0]),
                    ("grad", fld_in_vol[1:]),
                    ]
                )
Ejemplo n.º 26
0
def run_exterior_stokes(
        ctx_factory,
        *,
        ambient_dim,
        target_order,
        qbx_order,
        resolution,
        fmm_order=False,  # FIXME: FMM is slower than direct evaluation
        source_ovsmp=None,
        radius=1.5,
        mu=1.0,
        visualize=False,
        _target_association_tolerance=0.05,
        _expansions_in_tree_have_extent=True):
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    # {{{ geometry

    if source_ovsmp is None:
        source_ovsmp = 4 if ambient_dim == 2 else 8

    places = {}

    if ambient_dim == 2:
        from meshmode.mesh.generation import make_curve_mesh, ellipse
        mesh = make_curve_mesh(lambda t: radius * ellipse(1.0, t),
                               np.linspace(0.0, 1.0, resolution + 1),
                               target_order)
    elif ambient_dim == 3:
        from meshmode.mesh.generation import generate_icosphere
        mesh = generate_icosphere(radius,
                                  target_order + 1,
                                  uniform_refinement_rounds=resolution)
    else:
        raise ValueError(f"unsupported dimension: {ambient_dim}")

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

    from pytential.qbx import QBXLayerPotentialSource
    qbx = QBXLayerPotentialSource(
        pre_density_discr,
        fine_order=source_ovsmp * target_order,
        qbx_order=qbx_order,
        fmm_order=fmm_order,
        target_association_tolerance=_target_association_tolerance,
        _expansions_in_tree_have_extent=_expansions_in_tree_have_extent)
    places["source"] = qbx

    from extra_int_eq_data import make_source_and_target_points
    point_source, point_target = make_source_and_target_points(
        side=+1,
        inner_radius=0.5 * radius,
        outer_radius=2.0 * radius,
        ambient_dim=ambient_dim,
    )
    places["point_source"] = point_source
    places["point_target"] = point_target

    if visualize:
        from sumpy.visualization import make_field_plotter_from_bbox
        from meshmode.mesh.processing import find_bounding_box
        fplot = make_field_plotter_from_bbox(find_bounding_box(mesh),
                                             h=0.1,
                                             extend_factor=1.0)
        mask = np.linalg.norm(fplot.points, ord=2, axis=0) > (radius + 0.25)

        from pytential.target import PointsTarget
        plot_target = PointsTarget(fplot.points[:, mask].copy())
        places["plot_target"] = plot_target

        del mask

    places = GeometryCollection(places, auto_where="source")

    density_discr = places.get_discretization("source")
    logger.info("ndofs:     %d", density_discr.ndofs)
    logger.info("nelements: %d", density_discr.mesh.nelements)

    # }}}

    # {{{ symbolic

    sym_normal = sym.make_sym_vector("normal", ambient_dim)
    sym_mu = sym.var("mu")

    if ambient_dim == 2:
        from pytential.symbolic.stokes import HsiaoKressExteriorStokesOperator
        sym_omega = sym.make_sym_vector("omega", ambient_dim)
        op = HsiaoKressExteriorStokesOperator(omega=sym_omega)
    elif ambient_dim == 3:
        from pytential.symbolic.stokes import HebekerExteriorStokesOperator
        op = HebekerExteriorStokesOperator()
    else:
        assert False

    sym_sigma = op.get_density_var("sigma")
    sym_bc = op.get_density_var("bc")

    sym_op = op.operator(sym_sigma, normal=sym_normal, mu=sym_mu)
    sym_rhs = op.prepare_rhs(sym_bc, mu=mu)

    sym_velocity = op.velocity(sym_sigma, normal=sym_normal, mu=sym_mu)

    sym_source_pot = op.stokeslet.apply(sym_sigma,
                                        sym_mu,
                                        qbx_forced_limit=None)

    # }}}

    # {{{ boundary conditions

    normal = bind(places, sym.normal(ambient_dim).as_vector())(actx)

    np.random.seed(42)
    charges = make_obj_array([
        actx.from_numpy(np.random.randn(point_source.ndofs))
        for _ in range(ambient_dim)
    ])

    if ambient_dim == 2:
        total_charge = make_obj_array([actx.np.sum(c) for c in charges])
        omega = bind(places, total_charge * sym.Ones())(actx)

    if ambient_dim == 2:
        bc_context = {"mu": mu, "omega": omega}
        op_context = {"mu": mu, "omega": omega, "normal": normal}
    else:
        bc_context = {}
        op_context = {"mu": mu, "normal": normal}

    bc = bind(places, sym_source_pot,
              auto_where=("point_source", "source"))(actx,
                                                     sigma=charges,
                                                     mu=mu)

    rhs = bind(places, sym_rhs)(actx, bc=bc, **bc_context)
    bound_op = bind(places, sym_op)

    # }}}

    # {{{ solve

    from pytential.solve import gmres
    gmres_tol = 1.0e-9
    result = gmres(bound_op.scipy_op(actx, "sigma", np.float64, **op_context),
                   rhs,
                   x0=rhs,
                   tol=gmres_tol,
                   progress=visualize,
                   stall_iterations=0,
                   hard_failure=True)

    sigma = result.solution

    # }}}

    # {{{ check velocity at "point_target"

    def rnorm2(x, y):
        y_norm = actx.np.linalg.norm(y.dot(y), ord=2)
        if y_norm < 1.0e-14:
            y_norm = 1.0

        d = x - y
        return actx.np.linalg.norm(d.dot(d), ord=2) / y_norm

    ps_velocity = bind(places,
                       sym_velocity,
                       auto_where=("source", "point_target"))(actx,
                                                              sigma=sigma,
                                                              **op_context)
    ex_velocity = bind(places,
                       sym_source_pot,
                       auto_where=("point_source",
                                   "point_target"))(actx, sigma=charges, mu=mu)

    v_error = rnorm2(ps_velocity, ex_velocity)
    h_max = bind(places, sym.h_max(ambient_dim))(actx)

    logger.info("resolution %4d h_max %.5e error %.5e", resolution, h_max,
                v_error)

    # }}}}

    # {{{ visualize

    if not visualize:
        return h_max, v_error

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

    filename = "stokes_solution_{}d_{}_ovsmp_{}.vtu".format(
        ambient_dim, resolution, source_ovsmp)

    vis.write_vtk_file(filename, [
        ("density", sigma),
        ("bc", bc),
        ("rhs", rhs),
    ],
                       overwrite=True)

    # }}}

    return h_max, v_error
Ejemplo n.º 27
0
def test_target_specific_qbx(ctx_factory, op, helmholtz_k, qbx_order):
    logging.basicConfig(level=logging.INFO)

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

    target_order = 4
    fmm_tol = 1e-3

    from meshmode.mesh.generation import generate_icosphere
    mesh = generate_icosphere(1, target_order)

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

    from sumpy.expansion.level_to_order import SimpleExpansionOrderFinder
    qbx = QBXLayerPotentialSource(
            pre_density_discr, 4*target_order,
            qbx_order=qbx_order,
            fmm_level_to_order=SimpleExpansionOrderFinder(fmm_tol),
            fmm_backend="fmmlib",
            _expansions_in_tree_have_extent=True,
            _expansion_stick_out_factor=0.9,
            _use_target_specific_qbx=False,
            )

    kernel_length_scale = 5 / abs(helmholtz_k) if helmholtz_k else None
    places = {
        "qbx": qbx,
        "qbx_target_specific": qbx.copy(_use_target_specific_qbx=True)
        }

    from pytential.qbx.refinement import refine_geometry_collection
    places = GeometryCollection(places, auto_where="qbx")
    places = refine_geometry_collection(places,
            kernel_length_scale=kernel_length_scale)

    density_discr = places.get_discretization("qbx")
    from meshmode.dof_array import thaw
    nodes = thaw(actx, density_discr.nodes())
    u_dev = actx.np.sin(nodes[0])

    if helmholtz_k == 0:
        kernel = LaplaceKernel(3)
        kernel_kwargs = {}
    else:
        kernel = HelmholtzKernel(3, allow_evanescent=True)
        kernel_kwargs = {"k": sym.var("k")}

    u_sym = sym.var("u")

    if op == "S":
        op = sym.S
    elif op == "D":
        op = sym.D
    elif op == "Sp":
        op = sym.Sp
    else:
        raise ValueError("unknown operator: '%s'" % op)

    expr = op(kernel, u_sym, qbx_forced_limit=-1, **kernel_kwargs)

    from meshmode.dof_array import flatten
    bound_op = bind(places, expr)
    pot_ref = actx.to_numpy(flatten(bound_op(actx, u=u_dev, k=helmholtz_k)))

    bound_op = bind(places, expr, auto_where="qbx_target_specific")
    pot_tsqbx = actx.to_numpy(flatten(bound_op(actx, u=u_dev, k=helmholtz_k)))

    assert np.allclose(pot_tsqbx, pot_ref, atol=1e-13, rtol=1e-13)
Ejemplo n.º 28
0
def test_target_specific_qbx(ctx_getter, op, helmholtz_k, qbx_order):
    logging.basicConfig(level=logging.INFO)

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

    target_order = 4
    fmm_tol = 1e-3

    from meshmode.mesh.generation import generate_icosphere
    mesh = generate_icosphere(1, target_order)

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

    from sumpy.expansion.level_to_order import SimpleExpansionOrderFinder

    refiner_extra_kwargs = {}

    if helmholtz_k != 0:
        refiner_extra_kwargs["kernel_length_scale"] = 5 / abs(helmholtz_k)

    qbx, _ = QBXLayerPotentialSource(
        pre_density_discr,
        4 * target_order,
        qbx_order=qbx_order,
        fmm_level_to_order=SimpleExpansionOrderFinder(fmm_tol),
        fmm_backend="fmmlib",
        _expansions_in_tree_have_extent=True,
        _expansion_stick_out_factor=0.9,
        _use_target_specific_qbx=False,
    ).with_refinement(**refiner_extra_kwargs)

    density_discr = qbx.density_discr

    nodes = density_discr.nodes().with_queue(queue)
    u_dev = clmath.sin(nodes[0])

    if helmholtz_k == 0:
        kernel = LaplaceKernel(3)
        kernel_kwargs = {}
    else:
        kernel = HelmholtzKernel(3, allow_evanescent=True)
        kernel_kwargs = {"k": sym.var("k")}

    u_sym = sym.var("u")

    if op == "S":
        op = sym.S
    elif op == "D":
        op = sym.D
    elif op == "Sp":
        op = sym.Sp
    else:
        raise ValueError("unknown operator: '%s'" % op)

    expr = op(kernel, u_sym, qbx_forced_limit=-1, **kernel_kwargs)

    bound_op = bind(qbx, expr)
    pot_ref = bound_op(queue, u=u_dev, k=helmholtz_k).get()

    qbx = qbx.copy(_use_target_specific_qbx=True)
    bound_op = bind(qbx, expr)
    pot_tsqbx = bound_op(queue, u=u_dev, k=helmholtz_k).get()

    assert np.allclose(pot_tsqbx, pot_ref, atol=1e-13, rtol=1e-13)
Ejemplo n.º 29
0
def main(ctx_factory, dim=2, order=4, product_tag=None, visualize=False):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    # {{{ parameters

    # sphere radius
    radius = 1.0
    # sphere resolution
    resolution = 64 if dim == 2 else 1

    # cfl
    dt_factor = 2.0
    # final time
    final_time = np.pi

    # velocity field
    sym_x = sym.nodes(dim)
    c = make_obj_array([-sym_x[1], sym_x[0], 0.0])[:dim]
    # flux
    flux_type = "lf"

    # }}}

    # {{{ discretization

    if dim == 2:
        from meshmode.mesh.generation import make_curve_mesh, ellipse
        mesh = make_curve_mesh(lambda t: radius * ellipse(1.0, t),
                               np.linspace(0.0, 1.0, resolution + 1), order)
    elif dim == 3:
        from meshmode.mesh.generation import generate_icosphere
        mesh = generate_icosphere(radius,
                                  order=4 * order,
                                  uniform_refinement_rounds=resolution)
    else:
        raise ValueError("unsupported dimension")

    discr_tag_to_group_factory = {}
    if product_tag == "none":
        product_tag = None
    else:
        product_tag = dof_desc.DISCR_TAG_QUAD

    from meshmode.discretization.poly_element import \
            PolynomialWarpAndBlendGroupFactory, \
            QuadratureSimplexGroupFactory

    discr_tag_to_group_factory[dof_desc.DISCR_TAG_BASE] = \
        PolynomialWarpAndBlendGroupFactory(order)

    if product_tag:
        discr_tag_to_group_factory[product_tag] = \
            QuadratureSimplexGroupFactory(order=4*order)

    from grudge import DiscretizationCollection
    discr = DiscretizationCollection(
        actx, mesh, discr_tag_to_group_factory=discr_tag_to_group_factory)

    volume_discr = discr.discr_from_dd(dof_desc.DD_VOLUME)
    logger.info("ndofs:     %d", volume_discr.ndofs)
    logger.info("nelements: %d", volume_discr.mesh.nelements)

    # }}}

    # {{{ symbolic operators

    def f_initial_condition(x):
        return x[0]

    from grudge.models.advection import SurfaceAdvectionOperator
    op = SurfaceAdvectionOperator(c, flux_type=flux_type, quad_tag=product_tag)

    bound_op = bind(discr, op.sym_operator())
    u0 = bind(discr, f_initial_condition(sym_x))(actx, t=0)

    def rhs(t, u):
        return bound_op(actx, t=t, u=u)

    # check velocity is tangential
    sym_normal = sym.surface_normal(dim, dim=dim - 1,
                                    dd=dof_desc.DD_VOLUME).as_vector()
    error = bind(discr, sym.norm(2, c.dot(sym_normal)))(actx)
    logger.info("u_dot_n:   %.5e", error)

    # }}}

    # {{{ time stepping

    # compute time step
    h_min = bind(discr, sym.h_max_from_volume(discr.ambient_dim,
                                              dim=discr.dim))(actx)
    dt = dt_factor * h_min / order**2
    nsteps = int(final_time // dt) + 1
    dt = final_time / nsteps + 1.0e-15

    logger.info("dt:        %.5e", dt)
    logger.info("nsteps:    %d", nsteps)

    from grudge.shortcuts import set_up_rk4
    dt_stepper = set_up_rk4("u", dt, u0, rhs)
    plot = Plotter(actx, discr, order, visualize=visualize)

    norm = bind(discr, sym.norm(2, sym.var("u")))
    norm_u = norm(actx, u=u0)

    step = 0

    event = dt_stepper.StateComputed(0.0, 0, 0, u0)
    plot(event, "fld-surface-%04d" % 0)

    if visualize and dim == 3:
        from grudge.shortcuts import make_visualizer
        vis = make_visualizer(discr)
        vis.write_vtk_file("fld-surface-velocity.vtu",
                           [("u", bind(discr, c)(actx)),
                            ("n", bind(discr, sym_normal)(actx))],
                           overwrite=True)

        df = dof_desc.DOFDesc(FACE_RESTR_INTERIOR)
        face_discr = discr.connection_from_dds(dof_desc.DD_VOLUME, df).to_discr

        face_normal = bind(
            discr, sym.normal(df, face_discr.ambient_dim,
                              dim=face_discr.dim))(actx)

        from meshmode.discretization.visualization import make_visualizer
        vis = make_visualizer(actx, face_discr)
        vis.write_vtk_file("fld-surface-face-normals.vtu",
                           [("n", face_normal)],
                           overwrite=True)

    for event in dt_stepper.run(t_end=final_time, max_steps=nsteps + 1):
        if not isinstance(event, dt_stepper.StateComputed):
            continue

        step += 1
        if step % 10 == 0:
            norm_u = norm(actx, u=event.state_component)
            plot(event, "fld-surface-%04d" % step)

        logger.info("[%04d] t = %.5f |u| = %.5e", step, event.t, norm_u)

    plot(event, "fld-surface-%04d" % step)
Ejemplo n.º 30
0
def main():
    # cl.array.to_device(queue, numpy_array)
    from meshmode.mesh.io import generate_gmsh, FileSource
    from meshmode.mesh.generation import generate_icosphere
    from meshmode.mesh.refinement import Refiner
    mesh = generate_icosphere(1, target_order)

    refinement_increment = 1
    refiner = Refiner(mesh)
    for i in range(refinement_increment):
        flags = np.ones(mesh.nelements, dtype=bool)
        refiner.refine(flags)
        mesh = refiner.get_current_mesh()

    from meshmode.mesh.processing import perform_flips
    # Flip elements--gmsh generates inside-out geometry.
    mesh = perform_flips(mesh, np.ones(mesh.nelements))

    print("%d elements" % mesh.nelements)

    from meshmode.mesh.processing import find_bounding_box
    bbox_min, bbox_max = find_bounding_box(mesh)
    bbox_center = 0.5 * (bbox_min + bbox_max)
    bbox_size = max(bbox_max - bbox_min) / 2

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

    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=False,
                                  fmm_backend="fmmlib")

    from pytential.symbolic.pde.maxwell import MuellerAugmentedMFIEOperator
    pde_op = MuellerAugmentedMFIEOperator(
        omega=1.0,
        epss=[1.0, 1.0],
        mus=[1.0, 1.0],
    )
    from pytential import bind, sym

    unk = pde_op.make_unknown("sigma")
    sym_operator = pde_op.operator(unk)
    sym_rhs = pde_op.rhs(sym.make_sym_vector("Einc", 3),
                         sym.make_sym_vector("Hinc", 3))
    sym_repr = pde_op.representation(1, unk)

    if 1:
        expr = sym_repr
        print(sym.pretty(expr))

        print("#" * 80)
        from pytential.target import PointsTarget

        tgt_points = np.zeros((3, 1))
        tgt_points[0, 0] = 100
        tgt_points[1, 0] = -200
        tgt_points[2, 0] = 300

        bound_op = bind((qbx, PointsTarget(tgt_points)), expr)
        print(bound_op.code)

    if 1:

        def green3e(x, y, z, source, strength, k):
            # electric field corresponding to dyadic green's function
            # due to monochromatic electric dipole located at "source".
            # "strength" is the the intensity of the dipole.
            #  E = (I + Hess)(exp(ikr)/r) dot (strength)
            #
            dx = x - source[0]
            dy = y - source[1]
            dz = z - source[2]
            rr = np.sqrt(dx**2 + dy**2 + dz**2)

            fout = np.exp(1j * k * rr) / rr
            evec = fout * strength
            qmat = np.zeros((3, 3), dtype=np.complex128)

            qmat[0, 0] = (2 * dx**2 - dy**2 - dz**2) * (1 - 1j * k * rr)
            qmat[1, 1] = (2 * dy**2 - dz**2 - dx**2) * (1 - 1j * k * rr)
            qmat[2, 2] = (2 * dz**2 - dx**2 - dy**2) * (1 - 1j * k * rr)

            qmat[0, 0] = qmat[0, 0] + (-k**2 * dx**2 * rr**2)
            qmat[1, 1] = qmat[1, 1] + (-k**2 * dy**2 * rr**2)
            qmat[2, 2] = qmat[2, 2] + (-k**2 * dz**2 * rr**2)

            qmat[0, 1] = (3 - k**2 * rr**2 - 3 * 1j * k * rr) * (dx * dy)
            qmat[1, 2] = (3 - k**2 * rr**2 - 3 * 1j * k * rr) * (dy * dz)
            qmat[2, 0] = (3 - k**2 * rr**2 - 3 * 1j * k * rr) * (dz * dx)

            qmat[1, 0] = qmat[0, 1]
            qmat[2, 1] = qmat[1, 2]
            qmat[0, 2] = qmat[2, 0]

            fout = np.exp(1j * k * rr) / rr**5 / k**2

            fvec = fout * np.dot(qmat, strength)
            evec = evec + fvec
            return evec

        def green3m(x, y, z, source, strength, k):
            # magnetic field corresponding to dyadic green's function
            # due to monochromatic electric dipole located at "source".
            # "strength" is the the intensity of the dipole.
            #  H = curl((I + Hess)(exp(ikr)/r) dot (strength)) =
            #  strength \cross \grad (exp(ikr)/r)
            #
            dx = x - source[0]
            dy = y - source[1]
            dz = z - source[2]
            rr = np.sqrt(dx**2 + dy**2 + dz**2)

            fout = (1 - 1j * k * rr) * np.exp(1j * k * rr) / rr**3
            fvec = np.zeros(3, dtype=np.complex128)
            fvec[0] = fout * dx
            fvec[1] = fout * dy
            fvec[2] = fout * dz

            hvec = np.cross(strength, fvec)

            return hvec

        def dipole3e(x, y, z, source, strength, k):
            #
            #  evalaute electric and magnetic field due
            #  to monochromatic electric dipole located at "source"
            #  with intensity "strength"

            evec = green3e(x, y, z, source, strength, k)
            evec = evec * 1j * k
            hvec = green3m(x, y, z, source, strength, k)
            #            print(hvec)
            #            print(strength)
            return evec, hvec

        def dipole3m(x, y, z, source, strength, k):
            #
            #  evalaute electric and magnetic field due
            #  to monochromatic magnetic dipole located at "source"
            #  with intensity "strength"
            evec = green3m(x, y, z, source, strength, k)
            hvec = green3e(x, y, z, source, strength, k)
            hvec = -hvec * 1j * k
            return evec, hvec

        def dipole3eall(x, y, z, sources, strengths, k):
            ns = len(strengths)
            evec = np.zeros(3, dtype=np.complex128)
            hvec = np.zeros(3, dtype=np.complex128)

            for i in range(ns):
                evect, hvect = dipole3e(x, y, z, sources[i], strengths[i], k)
                evec = evec + evect
                hvec = hvec + hvect

        nodes = density_discr.nodes().with_queue(queue).get()
        source = [0.01, -0.03, 0.02]
        #        source = cl.array.to_device(queue,np.zeros(3))
        #        source[0] = 0.01
        #        source[1] =-0.03
        #        source[2] = 0.02
        strength = np.ones(3)

        #        evec = cl.array.to_device(queue,np.zeros((3,len(nodes[0])),dtype=np.complex128))
        #        hvec = cl.array.to_device(queue,np.zeros((3,len(nodes[0])),dtype=np.complex128))

        evec = np.zeros((3, len(nodes[0])), dtype=np.complex128)
        hvec = np.zeros((3, len(nodes[0])), dtype=np.complex128)
        for i in range(len(nodes[0])):
            evec[:, i], hvec[:, i] = dipole3e(nodes[0][i], nodes[1][i],
                                              nodes[2][i], source, strength, k)
        print(np.shape(hvec))
        print(type(evec))
        print(type(hvec))

        evec = cl.array.to_device(queue, evec)
        hvec = cl.array.to_device(queue, hvec)

        bvp_rhs = bind(qbx, sym_rhs)(queue, Einc=evec, Hinc=hvec)
        print(np.shape(bvp_rhs))
        print(type(bvp_rhs))
        #        print(bvp_rhs)
        1 / -1

        bound_op = bind(qbx, sym_operator)

        from pytential.solve import gmres
        if 1:
            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)

            sigma = gmres_result.solution

        fld_at_tgt = bind((qbx, PointsTarget(tgt_points)),
                          sym_repr)(queue, sigma=sigma, k=k)
        fld_at_tgt = np.array([fi.get() for fi in fld_at_tgt])
        print(fld_at_tgt)
        fld_exact_e, fld_exact_h = dipole3e(tgt_points[0, 0], tgt_points[1, 0],
                                            tgt_points[2,
                                                       0], source, strength, k)
        print(fld_exact_e)
        print(fld_exact_h)
        1 / 0

    # }}}

    #mlab.figure(bgcolor=(1, 1, 1))
    if 1:
        from meshmode.discretization.visualization import make_visualizer
        bdry_vis = make_visualizer(queue, density_discr, target_order)

        bdry_normals = bind(density_discr, sym.normal(3))(queue)\
                .as_vector(dtype=object)

        bdry_vis.write_vtk_file("source.vtu", [
            ("sigma", sigma),
            ("bdry_normals", bdry_normals),
        ])

        fplot = FieldPlotter(bbox_center,
                             extent=2 * bbox_size,
                             npoints=(150, 150, 1))

        qbx_stick_out = qbx.copy(target_stick_out_factor=0.1)
        from pytential.target import PointsTarget
        from pytential.qbx import QBXTargetAssociationFailedException

        rho_sym = sym.var("rho")

        try:
            fld_in_vol = bind((qbx_stick_out, PointsTarget(fplot.points)),
                              sym.make_obj_array([
                                  sym.S(pde_op.kernel,
                                        rho_sym,
                                        k=sym.var("k"),
                                        qbx_forced_limit=None),
                                  sym.d_dx(
                                      3,
                                      sym.S(pde_op.kernel,
                                            rho_sym,
                                            k=sym.var("k"),
                                            qbx_forced_limit=None)),
                                  sym.d_dy(
                                      3,
                                      sym.S(pde_op.kernel,
                                            rho_sym,
                                            k=sym.var("k"),
                                            qbx_forced_limit=None)),
                                  sym.d_dz(
                                      3,
                                      sym.S(pde_op.kernel,
                                            rho_sym,
                                            k=sym.var("k"),
                                            qbx_forced_limit=None)),
                              ]))(queue, jt=jt, rho=rho, k=k)
        except QBXTargetAssociationFailedException as e:
            fplot.write_vtk_file(
                "failed-targets.vts",
                [("failed_targets", e.failed_target_flags.get(queue))])
            raise

        fld_in_vol = sym.make_obj_array([fiv.get() for fiv in fld_in_vol])

        #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5)
        fplot.write_vtk_file("potential.vts", [
            ("potential", fld_in_vol[0]),
            ("grad", fld_in_vol[1:]),
        ])