Esempio n. 1
0
def test_tangential_onb(ctx_factory):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.mesh.generation import generate_torus
    mesh = generate_torus(5, 2, order=3)

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

    tob = sym.tangential_onb(mesh.ambient_dim)
    nvecs = tob.shape[1]

    # make sure tangential_onb is mutually orthogonal and normalized
    orth_check = bind(
        discr,
        sym.make_obj_array([
            np.dot(tob[:, i], tob[:, j]) - (1 if i == j else 0)
            for i in range(nvecs) for j in range(nvecs)
        ]))(queue)

    for i, orth_i in enumerate(orth_check):
        assert (cl.clmath.fabs(orth_i) < 1e-13).get().all()

    # make sure tangential_onb is orthogonal to normal
    orth_check = bind(
        discr,
        sym.make_obj_array([
            np.dot(tob[:, i],
                   sym.normal(mesh.ambient_dim).as_vector())
            for i in range(nvecs)
        ]))(queue)

    for i, orth_i in enumerate(orth_check):
        assert (cl.clmath.fabs(orth_i) < 1e-13).get().all()
Esempio n. 2
0
def test_tangential_onb(ctx_factory):
    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)

    from meshmode.mesh.generation import generate_torus
    mesh = generate_torus(5, 2, order=3)

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

    tob = sym.tangential_onb(mesh.ambient_dim)
    nvecs = tob.shape[1]

    # make sure tangential_onb is mutually orthogonal and normalized
    orth_check = bind(discr, sym.make_obj_array([
        np.dot(tob[:, i], tob[:, j]) - (1 if i == j else 0)
        for i in range(nvecs) for j in range(nvecs)])
        )(queue)

    for i, orth_i in enumerate(orth_check):
        assert (cl.clmath.fabs(orth_i) < 1e-13).get().all()

    # make sure tangential_onb is orthogonal to normal
    orth_check = bind(discr, sym.make_obj_array([
        np.dot(tob[:, i], sym.normal(mesh.ambient_dim).as_vector())
        for i in range(nvecs)])
        )(queue)

    for i, orth_i in enumerate(orth_check):
        assert (cl.clmath.fabs(orth_i) < 1e-13).get().all()
Esempio n. 3
0
def test_tangential_onb(actx_factory):
    actx = actx_factory()

    from meshmode.mesh.generation import generate_torus
    mesh = generate_torus(5, 2, order=3)

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

    tob = sym.tangential_onb(mesh.ambient_dim)
    nvecs = tob.shape[1]

    # make sure tangential_onb is mutually orthogonal and normalized
    orth_check = bind(discr, sym.make_obj_array([
        np.dot(tob[:, i], tob[:, j]) - (1 if i == j else 0)
        for i in range(nvecs) for j in range(nvecs)])
        )(actx)

    for orth_i in orth_check:
        assert actx.to_numpy(
                actx.np.all(actx.np.abs(orth_i) < 1e-13)
                )

    # make sure tangential_onb is orthogonal to normal
    orth_check = bind(discr, sym.make_obj_array([
        np.dot(tob[:, i], sym.normal(mesh.ambient_dim).as_vector())
        for i in range(nvecs)])
        )(actx)

    for orth_i in orth_check:
        assert actx.to_numpy(
                actx.np.all(actx.np.abs(orth_i) < 1e-13)
                )
Esempio n. 4
0
    def operator(self, unknown):
        sig1, sig2 = unknown
        lam1, lam2 = self.lambdas
        S_G = partial(self.S_G, qbx_forced_limit=1)  # noqa: N806

        c = self.c

        def Sn_G(i, density):  # noqa
            return self.S_G(i,
                            density,
                            qbx_forced_limit="avg",
                            op_map=partial(sym.normal_derivative, 2))

        d = sym.make_obj_array([0.5 * sig1, 0.5 * lam2**2 * sig1 - 0.5 * sig2])
        a = sym.make_obj_array([
            # A11
            Sn_G(1, sig1) + c * S_G(1, sig1)
            # A12
            + Sn_G(0, sig2) + c * S_G(0, sig2),

            # A21
            lam2**2 * Sn_G(1, sig1)
            # A22
            - Sn_G(1, sig2) + lam1**2 * Sn_G(0, sig2)
        ])

        return d + a
Esempio n. 5
0
    def operator(self, unknown):
        sig1, sig2 = unknown
        lam1, lam2 = self.lambdas
        S_G = partial(self.S_G, qbx_forced_limit=1)  # noqa: N806

        c = self.c

        def Sn_G(i, density):  # noqa
            return self.S_G(i, density,
                        qbx_forced_limit="avg",
                        op_map=partial(sym.normal_derivative, 2))

        d = sym.make_obj_array([
            0.5*sig1,
            0.5*lam2**2*sig1 - 0.5*sig2
            ])
        a = sym.make_obj_array([
            # A11
            Sn_G(1, sig1) + c*S_G(1, sig1)
            # A12
            + Sn_G(0, sig2) + c*S_G(0, sig2),

            # A21
            lam2**2*Sn_G(1, sig1)
            # A22
            - Sn_G(1, sig2) + lam1**2*Sn_G(0, sig2)
            ])

        return d+a
Esempio n. 6
0
def test_3d_orientation(ctx_factory, what, mesh_gen_func, visualize=False):
    pytest.importorskip("pytential")

    logging.basicConfig(level=logging.INFO)

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

    mesh = mesh_gen_func()

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

    from meshmode.discretization import Discretization
    discr = Discretization(ctx, mesh,
            PolynomialWarpAndBlendGroupFactory(1))

    from pytential import bind, sym

    # {{{ check normals point outward

    if what == "torus":
        nodes = sym.nodes(mesh.ambient_dim).as_vector()
        angle = sym.atan2(nodes[1], nodes[0])
        center_nodes = sym.make_obj_array([
                5*sym.cos(angle),
                5*sym.sin(angle),
                0*angle])
        normal_outward_expr = (
                sym.normal(mesh.ambient_dim) | (nodes-center_nodes))

    else:
        normal_outward_expr = (
                sym.normal(mesh.ambient_dim) | sym.nodes(mesh.ambient_dim))

    normal_outward_check = bind(discr, normal_outward_expr)(queue).as_scalar() > 0

    assert normal_outward_check.get().all(), normal_outward_check.get()

    # }}}

    normals = bind(discr, sym.normal(mesh.ambient_dim).xproject(1))(queue)

    if visualize:
        from meshmode.discretization.visualization import make_visualizer
        vis = make_visualizer(queue, discr, 1)

        vis.write_vtk_file("normals.vtu", [
            ("normals", normals),
            ])
Esempio n. 7
0
def main():
    # cl.array.to_device(queue, numpy_array)
    from meshmode.mesh.io import generate_gmsh, FileSource
    mesh = generate_gmsh(
            FileSource("ellipsoid.step"), 2, order=2,
            other_options=["-string", "Mesh.CharacteristicLengthMax = %g;" % h])

    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=qbx_order + 10, fmm_backend="fmmlib")

    from pytential.symbolic.pde.maxwell import MuellerAugmentedMFIEOperator
    pde_op = MuellerAugmentedMFIEOperator(
            omega=0.4,
            epss=[1.4, 1.0],
            mus=[1.2, 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(0, 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)
            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 0:
            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=bvp_rhs,k=k)
        fld_at_tgt = np.array([
            fi.get() for fi in fld_at_tgt
            ])
        print(fld_at_tgt)
        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_tgt_tol = qbx.copy(target_association_tolerance=0.1)
        from pytential.target import PointsTarget
        from pytential.qbx import QBXTargetAssociationFailedException

        rho_sym = sym.var("rho")

        try:
            fld_in_vol = bind(
                    (qbx_tgt_tol, 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:]),
                    ]
                )
Esempio n. 8
0
def test_3d_jump_relations(ctx_factory, relation, visualize=False):
    # logging.basicConfig(level=logging.INFO)

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

    if relation == "div_s":
        target_order = 3
    else:
        target_order = 4

    qbx_order = target_order

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    for nel_factor in [6, 10, 14]:
        from meshmode.mesh.generation import generate_torus
        mesh = generate_torus(
                5, 2, order=target_order,
                n_outer=2*nel_factor, n_inner=nel_factor)

        from meshmode.discretization import Discretization
        from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
        pre_discr = Discretization(
                cl_ctx, mesh,
                InterpolatoryQuadratureSimplexGroupFactory(3))

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

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

        def nxcurlS(qbx_forced_limit):

            return sym.n_cross(sym.curl(sym.S(
                knl,
                sym.cse(sym.tangential_to_xyz(density_sym), "jxyz"),
                qbx_forced_limit=qbx_forced_limit)))

        x, y, z = qbx.density_discr.nodes().with_queue(queue)
        m = cl.clmath

        if relation == "nxcurls":
            density_sym = sym.make_sym_vector("density", 2)

            jump_identity_sym = (
                    nxcurlS(+1)
                    - (nxcurlS("avg") + 0.5*sym.tangential_to_xyz(density_sym)))

            # The tangential coordinate system is element-local, so we can't just
            # conjure up some globally smooth functions, interpret their values
            # in the tangential coordinate system, and be done. Instead, generate
            # an XYZ function and project it.
            density = bind(
                    qbx,
                    sym.xyz_to_tangential(sym.make_sym_vector("jxyz", 3)))(
                            queue,
                            jxyz=sym.make_obj_array([
                                m.cos(0.5*x) * m.cos(0.5*y) * m.cos(0.5*z),
                                m.sin(0.5*x) * m.cos(0.5*y) * m.sin(0.5*z),
                                m.sin(0.5*x) * m.cos(0.5*y) * m.cos(0.5*z),
                                ]))

        elif relation == "sp":

            density = m.cos(2*x) * m.cos(2*y) * m.cos(z)
            density_sym = sym.var("density")

            jump_identity_sym = (
                    sym.Sp(knl, density_sym, qbx_forced_limit=+1)
                    - (sym.Sp(knl, density_sym, qbx_forced_limit="avg")
                        - 0.5*density_sym))

        elif relation == "div_s":

            density = m.cos(2*x) * m.cos(2*y) * m.cos(z)
            density_sym = sym.var("density")

            jump_identity_sym = (
                    sym.div(sym.S(knl, sym.normal(3).as_vector()*density_sym,
                        qbx_forced_limit="avg"))
                    + sym.D(knl, density_sym, qbx_forced_limit="avg"))

        else:
            raise ValueError("unexpected value of 'relation': %s" % relation)

        bound_jump_identity = bind(qbx, jump_identity_sym)
        jump_identity = bound_jump_identity(queue, density=density)

        err = (
                norm(qbx, queue, jump_identity, np.inf)
                / norm(qbx, queue, density, np.inf))
        print("ERROR", qbx.h_max, err)

        eoc_rec.add_data_point(qbx.h_max, err)

        # {{{ visualization

        if visualize and relation == "nxcurls":
            nxcurlS_ext = bind(qbx, nxcurlS(+1))(queue, density=density)
            nxcurlS_avg = bind(qbx, nxcurlS("avg"))(queue, density=density)
            jtxyz = bind(qbx, sym.tangential_to_xyz(density_sym))(
                    queue, density=density)

            from meshmode.discretization.visualization import make_visualizer
            bdry_vis = make_visualizer(queue, qbx.density_discr, target_order+3)

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

            bdry_vis.write_vtk_file("source-%s.vtu" % nel_factor, [
                ("jt", jtxyz),
                ("nxcurlS_ext", nxcurlS_ext),
                ("nxcurlS_avg", nxcurlS_avg),
                ("bdry_normals", bdry_normals),
                ])

        if visualize and relation == "sp":
            sp_ext = bind(qbx, sym.Sp(knl, density_sym, qbx_forced_limit=+1))(
                    queue, density=density)
            sp_avg = bind(qbx, sym.Sp(knl, density_sym, qbx_forced_limit="avg"))(
                    queue, density=density)

            from meshmode.discretization.visualization import make_visualizer
            bdry_vis = make_visualizer(queue, qbx.density_discr, target_order+3)

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

            bdry_vis.write_vtk_file("source-%s.vtu" % nel_factor, [
                ("density", density),
                ("sp_ext", sp_ext),
                ("sp_avg", sp_avg),
                ("bdry_normals", bdry_normals),
                ])

        # }}}

    print(eoc_rec)

    assert eoc_rec.order_estimate() >= qbx_order - 1.5
Esempio n. 9
0
def test_3d_jump_relations(ctx_factory, relation, visualize=False):
    # logging.basicConfig(level=logging.INFO)

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

    if relation == "div_s":
        target_order = 3
    else:
        target_order = 4

    qbx_order = target_order

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    for nel_factor in [6, 10, 14]:
        from meshmode.mesh.generation import generate_torus
        mesh = generate_torus(
                5, 2, order=target_order,
                n_major=2*nel_factor, n_minor=nel_factor)

        from meshmode.discretization import Discretization
        from meshmode.discretization.poly_element import \
            InterpolatoryQuadratureSimplexGroupFactory
        pre_discr = Discretization(
                actx, mesh,
                InterpolatoryQuadratureSimplexGroupFactory(3))

        from pytential.qbx import QBXLayerPotentialSource
        qbx = QBXLayerPotentialSource(
                pre_discr, fine_order=4*target_order,
                qbx_order=qbx_order,
                fmm_order=qbx_order + 5,
                fmm_backend="fmmlib"
                )

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

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

        def nxcurlS(qbx_forced_limit):

            return sym.n_cross(sym.curl(sym.S(
                knl,
                sym.cse(sym.tangential_to_xyz(density_sym), "jxyz"),
                qbx_forced_limit=qbx_forced_limit)))

        from meshmode.dof_array import thaw
        x, y, z = thaw(actx, density_discr.nodes())
        m = actx.np

        if relation == "nxcurls":
            density_sym = sym.make_sym_vector("density", 2)

            jump_identity_sym = (
                    nxcurlS(+1)
                    - (nxcurlS("avg") + 0.5*sym.tangential_to_xyz(density_sym)))

            # The tangential coordinate system is element-local, so we can't just
            # conjure up some globally smooth functions, interpret their values
            # in the tangential coordinate system, and be done. Instead, generate
            # an XYZ function and project it.
            density = bind(places,
                    sym.xyz_to_tangential(sym.make_sym_vector("jxyz", 3)))(
                            actx,
                            jxyz=sym.make_obj_array([
                                m.cos(0.5*x) * m.cos(0.5*y) * m.cos(0.5*z),
                                m.sin(0.5*x) * m.cos(0.5*y) * m.sin(0.5*z),
                                m.sin(0.5*x) * m.cos(0.5*y) * m.cos(0.5*z),
                                ]))

        elif relation == "sp":

            density = m.cos(2*x) * m.cos(2*y) * m.cos(z)
            density_sym = sym.var("density")

            jump_identity_sym = (
                    sym.Sp(knl, density_sym, qbx_forced_limit=+1)
                    - (sym.Sp(knl, density_sym, qbx_forced_limit="avg")
                        - 0.5*density_sym))

        elif relation == "div_s":

            density = m.cos(2*x) * m.cos(2*y) * m.cos(z)
            density_sym = sym.var("density")

            jump_identity_sym = (
                    sym.div(sym.S(knl, sym.normal(3).as_vector()*density_sym,
                        qbx_forced_limit="avg"))
                    + sym.D(knl, density_sym, qbx_forced_limit="avg"))

        else:
            raise ValueError("unexpected value of 'relation': %s" % relation)

        bound_jump_identity = bind(places, jump_identity_sym)
        jump_identity = bound_jump_identity(actx, density=density)

        h_max = bind(places, sym.h_max(qbx.ambient_dim))(actx)
        err = (
                norm(density_discr, jump_identity, np.inf)
                / norm(density_discr, density, np.inf))
        print("ERROR", h_max, err)

        eoc_rec.add_data_point(h_max, err)

        # {{{ visualization

        if visualize and relation == "nxcurls":
            nxcurlS_ext = bind(places, nxcurlS(+1))(actx, density=density)
            nxcurlS_avg = bind(places, nxcurlS("avg"))(actx, density=density)
            jtxyz = bind(places, sym.tangential_to_xyz(density_sym))(
                    actx, density=density)

            from meshmode.discretization.visualization import make_visualizer
            bdry_vis = make_visualizer(actx, qbx.density_discr, target_order+3)

            bdry_normals = bind(places, sym.normal(3))(actx)\
                    .as_vector(dtype=object)

            bdry_vis.write_vtk_file("source-%s.vtu" % nel_factor, [
                ("jt", jtxyz),
                ("nxcurlS_ext", nxcurlS_ext),
                ("nxcurlS_avg", nxcurlS_avg),
                ("bdry_normals", bdry_normals),
                ])

        if visualize and relation == "sp":
            op = sym.Sp(knl, density_sym, qbx_forced_limit=+1)
            sp_ext = bind(places, op)(actx, density=density)
            op = sym.Sp(knl, density_sym, qbx_forced_limit="avg")
            sp_avg = bind(places, op)(actx, density=density)

            from meshmode.discretization.visualization import make_visualizer
            bdry_vis = make_visualizer(actx, qbx.density_discr, target_order+3)

            bdry_normals = bind(places,
                    sym.normal(3))(actx).as_vector(dtype=object)

            bdry_vis.write_vtk_file("source-%s.vtu" % nel_factor, [
                ("density", density),
                ("sp_ext", sp_ext),
                ("sp_avg", sp_avg),
                ("bdry_normals", bdry_normals),
                ])

        # }}}

    print(eoc_rec)

    assert eoc_rec.order_estimate() >= qbx_order - 1.5
Esempio n. 10
0
def main():
    # cl.array.to_device(queue, numpy_array)
    from meshmode.mesh.io import generate_gmsh, FileSource
    mesh = generate_gmsh(
        FileSource("ellipsoid.step"),
        2,
        order=2,
        other_options=["-string",
                       "Mesh.CharacteristicLengthMax = %g;" % h])

    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=qbx_order + 10,
                                  fmm_backend="fmmlib")

    from pytential.symbolic.pde.maxwell import MuellerAugmentedMFIEOperator
    pde_op = MuellerAugmentedMFIEOperator(
        omega=0.4,
        epss=[1.4, 1.0],
        mus=[1.2, 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(0, 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)
            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 0:
            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=bvp_rhs, k=k)
        fld_at_tgt = np.array([fi.get() for fi in fld_at_tgt])
        print(fld_at_tgt)
        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_tgt_tol = qbx.copy(target_association_tolerance=0.1)
        from pytential.target import PointsTarget
        from pytential.qbx import QBXTargetAssociationFailedException

        rho_sym = sym.var("rho")

        try:
            fld_in_vol = bind((qbx_tgt_tol, 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:]),
        ])
Esempio n. 11
0
def test_3d_jump_relations(actx_factory, relation, visualize=False):
    # logging.basicConfig(level=logging.INFO)
    actx = actx_factory()

    if relation == "div_s":
        target_order = 3
    else:
        target_order = 4

    qbx_order = target_order

    if relation == "sp":
        resolutions = [10, 14, 18]
    else:
        resolutions = [6, 10, 14]

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    for nel_factor in resolutions:
        from meshmode.mesh.generation import generate_torus
        mesh = generate_torus(
            5,
            2,
            n_major=2 * nel_factor,
            n_minor=nel_factor,
            order=target_order,
        )

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

        from pytential.qbx import QBXLayerPotentialSource
        qbx = QBXLayerPotentialSource(pre_density_discr,
                                      fine_order=5 * target_order,
                                      qbx_order=qbx_order,
                                      fmm_order=qbx_order + 5,
                                      fmm_backend="fmmlib")

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

        from sumpy.kernel import LaplaceKernel
        knl = LaplaceKernel(places.ambient_dim)

        def nxcurlS(qbx_forced_limit):
            sigma_sym = sym.cse(sym.tangential_to_xyz(density_sym), "jxyz")
            return sym.n_cross(
                sym.curl(
                    sym.S(knl, sigma_sym, qbx_forced_limit=qbx_forced_limit)))

        x, y, z = thaw(density_discr.nodes(), actx)
        if relation == "nxcurls":
            density_sym = sym.make_sym_vector("density", 2)
            jump_identity_sym = (nxcurlS(+1) - nxcurlS("avg") -
                                 0.5 * sym.tangential_to_xyz(density_sym))

            # The tangential coordinate system is element-local, so we can't just
            # conjure up some globally smooth functions, interpret their values
            # in the tangential coordinate system, and be done. Instead, generate
            # an XYZ function and project it.
            jxyz = sym.make_obj_array([
                actx.np.cos(0.5 * x) * actx.np.cos(0.5 * y) *
                actx.np.cos(0.5 * z),
                actx.np.sin(0.5 * x) * actx.np.cos(0.5 * y) *
                actx.np.sin(0.5 * z),
                actx.np.sin(0.5 * x) * actx.np.cos(0.5 * y) *
                actx.np.cos(0.5 * z),
            ])
            density = bind(
                places,
                sym.xyz_to_tangential(sym.make_sym_vector("jxyz",
                                                          3)))(actx, jxyz=jxyz)

        elif relation == "sp":
            density_sym = sym.var("density")
            jump_identity_sym = (
                0.5 * density_sym +
                sym.Sp(knl, density_sym, qbx_forced_limit=+1) -
                sym.Sp(knl, density_sym, qbx_forced_limit="avg"))

            density = actx.np.cos(2 * x) * actx.np.cos(2 * y) * actx.np.cos(z)

        elif relation == "div_s":
            density_sym = sym.var("density")
            sigma_sym = sym.normal(
                places.ambient_dim).as_vector() * density_sym
            jump_identity_sym = (
                sym.div(sym.S(knl, sigma_sym, qbx_forced_limit="avg")) +
                sym.D(knl, density_sym, qbx_forced_limit="avg"))

            density = actx.np.cos(2 * x) * actx.np.cos(2 * y) * actx.np.cos(z)

        else:
            raise ValueError(f"unexpected value of 'relation': '{relation}'")

        bound_jump_identity = bind(places, jump_identity_sym)
        jump_identity = bound_jump_identity(actx, density=density)

        h_max = actx.to_numpy(
            bind(places, sym.h_max(places.ambient_dim))(actx))
        err = actx.to_numpy(
            norm(density_discr, jump_identity, np.inf) /
            norm(density_discr, density, np.inf))
        eoc_rec.add_data_point(h_max, err)

        logging.info("error: nel %d h_max %.5e %.5e", nel_factor, h_max, err)

        # {{{ visualization

        if not visualize:
            continue

        from meshmode.discretization.visualization import make_visualizer
        vis = make_visualizer(actx, density_discr, target_order)
        normals = bind(places,
                       sym.normal(places.ambient_dim).as_vector())(actx)
        error = actx.np.log10(actx.np.abs(jump_identity) + 1.0e-15)

        if relation == "nxcurls":
            nxcurlS_ext = bind(places, nxcurlS(+1))(actx, density=density)
            nxcurlS_avg = bind(places, nxcurlS("avg"))(actx, density=density)
            jtxyz = bind(places,
                         sym.tangential_to_xyz(density_sym))(actx,
                                                             density=density)

            vis.write_vtk_file(f"source-nxcurls-{nel_factor:03d}.vtu", [
                ("jt", jtxyz),
                ("nxcurlS_ext", nxcurlS_ext),
                ("nxcurlS_avg", nxcurlS_avg),
                ("bdry_normals", normals),
                ("error", error),
            ])

        elif relation == "sp":
            op = sym.Sp(knl, density_sym, qbx_forced_limit=+1)
            sp_ext = bind(places, op)(actx, density=density)
            op = sym.Sp(knl, density_sym, qbx_forced_limit="avg")
            sp_avg = bind(places, op)(actx, density=density)

            vis.write_vtk_file(f"source-sp-{nel_factor:03d}.vtu", [
                ("density", density),
                ("sp_ext", sp_ext),
                ("sp_avg", sp_avg),
                ("bdry_normals", normals),
                ("error", error),
            ])

        elif relation == "div_s":
            vis.write_vtk_file(f"source-div-{nel_factor:03d}.vtu", [
                ("density", density),
                ("bdry_normals", normals),
                ("error", error),
            ])

        # }}}

    logger.info("\n%s", str(eoc_rec))
    assert eoc_rec.order_estimate() >= qbx_order - 1.5
Esempio n. 12
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),
                ]
            )