def get_mesh(self, resolution, target_order): from meshmode.mesh.io import generate_gmsh, FileSource base_mesh = generate_gmsh(FileSource("ellipsoid.step"), 2, order=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %g;" % resolution ]) from meshmode.mesh.processing import perform_flips # Flip elements--gmsh generates inside-out geometry. base_mesh = perform_flips(base_mesh, np.ones(base_mesh.nelements)) from meshmode.mesh.processing import affine_map, merge_disjoint_meshes from meshmode.mesh.tools import rand_rotation_matrix pitch = 10 meshes = [ affine_map(base_mesh, A=rand_rotation_matrix(3), b=pitch * np.array([(ix - self.nx // 2), (iy - self.ny // 2), (iz - self.ny // 2)])) for ix in range(self.nx) for iy in range(self.ny) for iz in range(self.nz) ] mesh = merge_disjoint_meshes(meshes, single_group=True) return mesh
def test_circle_mesh(visualize=False): from meshmode.mesh.io import generate_gmsh, FileSource logger.info("BEGIN GEN") mesh = generate_gmsh( FileSource("circle.step"), 2, order=2, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = 0.05;"], target_unit="MM", ) logger.info("END GEN") logger.info("nelements: %d", mesh.nelements) from meshmode.mesh.processing import affine_map mesh = affine_map(mesh, A=3 * np.eye(2)) if visualize: from meshmode.mesh.visualization import draw_2d_mesh draw_2d_mesh(mesh, fill=None, draw_vertex_numbers=False, draw_nodal_adjacency=True, set_bounding_box=True) import matplotlib.pyplot as pt pt.axis("equal") pt.savefig("circle_mesh", dpi=300)
def test_element_orientation(): from meshmode.mesh.io import generate_gmsh, FileSource mesh_order = 3 mesh = generate_gmsh( FileSource("blob-2d.step"), 2, order=mesh_order, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = 0.02;"]) from meshmode.mesh.processing import (perform_flips, find_volume_mesh_element_orientations ) mesh_orient = find_volume_mesh_element_orientations(mesh) assert (mesh_orient > 0).all() from random import randrange flippy = np.zeros(mesh.nelements, np.int8) for i in range(int(0.3 * mesh.nelements)): flippy[randrange(0, mesh.nelements)] = 1 mesh = perform_flips(mesh, flippy, skip_tests=True) mesh_orient = find_volume_mesh_element_orientations(mesh) assert ((mesh_orient < 0) == (flippy > 0)).all()
def test_merge_and_map(ctx_getter, visualize=False): from meshmode.mesh.io import generate_gmsh, FileSource mesh_order = 3 mesh = generate_gmsh( FileSource("blob-2d.step"), 2, order=mesh_order, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = 0.02;"]) from meshmode.mesh.processing import merge_disjoint_meshes, affine_map mesh2 = affine_map(mesh, A=np.eye(2), b=np.array([5, 0])) mesh3 = merge_disjoint_meshes((mesh2, mesh)) if visualize: from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) discr = Discretization(cl_ctx, mesh3, PolynomialWarpAndBlendGroupFactory(3)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr, 1) vis.write_vtk_file("merged.vtu", [])
def gen_blob_mesh(h=0.2, order=1): from meshmode.mesh.io import generate_gmsh, FileSource return generate_gmsh( FileSource("blob-2d.step"), 2, order=order, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = %s;" % h])
def test_merge_and_map(ctx_factory, visualize=False): from meshmode.mesh.io import generate_gmsh, FileSource from meshmode.mesh.generation import generate_box_mesh from meshmode.mesh import TensorProductElementGroup from meshmode.discretization.poly_element import ( PolynomialWarpAndBlendGroupFactory, LegendreGaussLobattoTensorProductGroupFactory) mesh_order = 3 if 1: mesh = generate_gmsh( FileSource("blob-2d.step"), 2, order=mesh_order, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = 0.02;"]) discr_grp_factory = PolynomialWarpAndBlendGroupFactory(3) else: mesh = generate_box_mesh(( np.linspace(0, 1, 4), np.linspace(0, 1, 4), np.linspace(0, 1, 4), ), 10, group_factory=TensorProductElementGroup) discr_grp_factory = LegendreGaussLobattoTensorProductGroupFactory(3) from meshmode.mesh.processing import merge_disjoint_meshes, affine_map mesh2 = affine_map(mesh, A=np.eye(mesh.ambient_dim), b=np.array([5, 0, 0])[:mesh.ambient_dim]) mesh3 = merge_disjoint_meshes((mesh2, mesh)) mesh3.facial_adjacency_groups mesh3.copy() if visualize: from meshmode.discretization import Discretization cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) discr = Discretization(cl_ctx, mesh3, discr_grp_factory) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr, 3, element_shrink_factor=0.8) vis.write_vtk_file("merged.vtu", [])
def get_mesh(self, resolution, target_order): from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh(FileSource("ellipsoid.step"), 2, order=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %g;" % resolution ]) from meshmode.mesh.processing import perform_flips # Flip elements--gmsh generates inside-out geometry. return perform_flips(mesh, np.ones(mesh.nelements))
def test_mesh_to_tikz(): from meshmode.mesh.io import generate_gmsh, FileSource h = 0.3 order = 1 mesh = generate_gmsh( FileSource("../test/blob-2d.step"), 2, order=order, force_ambient_dim=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %s;" % h] ) from meshmode.mesh.visualization import mesh_to_tikz mesh_to_tikz(mesh)
def get_mesh(self, resolution, target_order): from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh( FileSource("rounded-cube.step"), 2, order=3, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %g;" % resolution]) from meshmode.mesh.processing import perform_flips, affine_map mesh = affine_map(mesh, b=np.array([-0.5, -0.5, -0.5])) mesh = affine_map(mesh, A=np.eye(3)*2) # now centered at origin and extends to -1,1 # Flip elements--gmsh generates inside-out geometry. return perform_flips(mesh, np.ones(mesh.nelements))
def test_merge_and_map(actx_factory, group_cls, visualize=False): from meshmode.mesh.io import generate_gmsh, FileSource order = 3 mesh_order = 3 if group_cls is SimplexElementGroup: mesh = generate_gmsh( FileSource("blob-2d.step"), 2, order=mesh_order, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = 0.02;"], target_unit="MM", ) discr_grp_factory = PolynomialWarpAndBlendGroupFactory(order) else: ambient_dim = 3 mesh = mgen.generate_regular_rect_mesh(a=(0, ) * ambient_dim, b=(1, ) * ambient_dim, nelements_per_axis=(4, ) * ambient_dim, order=mesh_order, group_cls=group_cls) discr_grp_factory = LegendreGaussLobattoTensorProductGroupFactory( order) from meshmode.mesh.processing import merge_disjoint_meshes, affine_map mesh2 = affine_map(mesh, A=np.eye(mesh.ambient_dim), b=np.array([2, 0, 0])[:mesh.ambient_dim]) mesh3 = merge_disjoint_meshes((mesh2, mesh)) assert mesh3.facial_adjacency_groups mesh4 = mesh3.copy() if visualize: from meshmode.discretization import Discretization actx = actx_factory() discr = Discretization(actx, mesh4, discr_grp_factory) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, 3, element_shrink_factor=0.8) vis.write_vtk_file("merge_and_map.vtu", [])
def get_mesh(self, resolution, target_order): from pytools import download_from_web_if_not_present download_from_web_if_not_present( "https://raw.githubusercontent.com/inducer/geometries/master/" "surface-3d/elliptiplane.brep") from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh( FileSource("elliptiplane.brep"), 2, order=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %g;" % resolution]) # now centered at origin and extends to -1,1 # Flip elements--gmsh generates inside-out geometry. from meshmode.mesh.processing import perform_flips return perform_flips(mesh, np.ones(mesh.nelements))
def test_circle_mesh(do_plot=False): from meshmode.mesh.io import generate_gmsh, FileSource print("BEGIN GEN") mesh = generate_gmsh( FileSource("circle.step"), 2, order=2, force_ambient_dim=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = 0.05;"] ) print("END GEN") print(mesh.nelements) from meshmode.mesh.processing import affine_map mesh = affine_map(mesh, A=3*np.eye(2)) if do_plot: from meshmode.mesh.visualization import draw_2d_mesh draw_2d_mesh(mesh, fill=None, draw_nodal_adjacency=True, set_bounding_box=True) import matplotlib.pyplot as pt pt.show()
def test_interpolatory_error_reporting(ctx_factory): logging.basicConfig(level=logging.INFO) ctx = ctx_factory() queue = cl.CommandQueue(ctx) h = 0.2 from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh( FileSource("circle.step"), 2, order=4, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = %g;" % h], target_unit="mm", ) logger.info("%d elements" % mesh.nelements) # {{{ discretizations and connections from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ QuadratureSimplexGroupFactory vol_discr = Discretization(ctx, mesh, QuadratureSimplexGroupFactory(5)) vol_x = vol_discr.nodes().with_queue(queue) # }}} from pytential import integral rhs = 1 + 0 * vol_x[0] one = rhs.copy() one.fill(1) with pytest.raises(TypeError): print("AREA", integral(vol_discr, queue, one), 0.25**2 * np.pi)
def test_interpolatory_error_reporting(ctx_factory): logging.basicConfig(level=logging.INFO) ctx = ctx_factory() queue = cl.CommandQueue(ctx) actx = PyOpenCLArrayContext(queue) h = 0.2 from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh( FileSource("circle.step"), 2, order=4, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = %g;" % h], target_unit="mm", ) logger.info("%d elements" % mesh.nelements) # {{{ discretizations and connections from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ QuadratureSimplexGroupFactory vol_discr = Discretization(actx, mesh, QuadratureSimplexGroupFactory(5)) from meshmode.dof_array import thaw vol_x = thaw(actx, vol_discr.nodes()) # }}} from pytential import integral one = 1 + 0 * vol_x[0] from meshmode.discretization import NoninterpolatoryElementGroupError with pytest.raises(NoninterpolatoryElementGroupError): print("AREA", integral(vol_discr, one), 0.25**2 * np.pi)
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:]), ])
def main(mesh_name="ellipsoid"): import logging logger = logging.getLogger(__name__) logging.basicConfig(level=logging.WARNING) # INFO for more progress info cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) if mesh_name == "ellipsoid": cad_file_name = "geometries/ellipsoid.step" h = 0.6 elif mesh_name == "two-cylinders": cad_file_name = "geometries/two-cylinders-smooth.step" h = 0.4 else: raise ValueError("unknown mesh name: %s" % mesh_name) from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh( FileSource(cad_file_name), 2, order=2, other_options=["-string", "Mesh.CharacteristicLengthMax = %g;" % h], target_unit="MM") from meshmode.mesh.processing import perform_flips # Flip elements--gmsh generates inside-out geometry. mesh = perform_flips(mesh, np.ones(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( actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order)) qbx = QBXLayerPotentialSource(density_discr, 4 * target_order, qbx_order, fmm_order=qbx_order + 3, target_association_tolerance=0.15) from pytential.target import PointsTarget fplot = FieldPlotter(bbox_center, extent=3.5 * bbox_size, npoints=150) from pytential import GeometryCollection places = GeometryCollection( { "qbx": qbx, "targets": PointsTarget(fplot.points) }, auto_where="qbx") density_discr = places.get_discretization("qbx") nodes = thaw(actx, density_discr.nodes()) angle = actx.np.arctan2(nodes[1], nodes[0]) if k: kernel = HelmholtzKernel(3) else: kernel = LaplaceKernel(3) #op = sym.d_dx(sym.S(kernel, sym.var("sigma"), qbx_forced_limit=None)) op = sym.D(kernel, sym.var("sigma"), qbx_forced_limit=None) #op = sym.S(kernel, sym.var("sigma"), qbx_forced_limit=None) sigma = actx.np.cos(mode_nr * angle) if 0: from meshmode.dof_array import flatten, unflatten sigma = flatten(0 * angle) from random import randrange for i in range(5): sigma[randrange(len(sigma))] = 1 sigma = unflatten(actx, density_discr, sigma) if isinstance(kernel, HelmholtzKernel): for i, elem in np.ndenumerate(sigma): sigma[i] = elem.astype(np.complex128) fld_in_vol = actx.to_numpy( bind(places, op, auto_where=("qbx", "targets"))(actx, sigma=sigma, k=k)) #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5) fplot.write_vtk_file("layerpot-3d-potential.vts", [("potential", fld_in_vol)]) bdry_normals = bind(places, sym.normal( density_discr.ambient_dim))(actx).as_vector(dtype=object) from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(actx, density_discr, target_order) bdry_vis.write_vtk_file("layerpot-3d-density.vtu", [ ("sigma", sigma), ("bdry_normals", bdry_normals), ])
def test_boundary_interpolation(ctx_getter, group_factory, boundary_tag, mesh_name, dim, mesh_pars, per_face_groups): cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) from meshmode.discretization import Discretization from meshmode.discretization.connection import (make_face_restriction, check_connection) from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() order = 4 def f(x): return 0.1 * cl.clmath.sin(30 * x) for mesh_par in mesh_pars: # {{{ get mesh if mesh_name == "blob": assert dim == 2 h = mesh_par from meshmode.mesh.io import generate_gmsh, FileSource print("BEGIN GEN") mesh = generate_gmsh(FileSource("blob-2d.step"), 2, order=order, force_ambient_dim=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %s;" % h ]) print("END GEN") elif mesh_name == "warp": from meshmode.mesh.generation import generate_warped_rect_mesh mesh = generate_warped_rect_mesh(dim, order=4, n=mesh_par) h = 1 / mesh_par else: raise ValueError("mesh_name not recognized") # }}} vol_discr = Discretization(cl_ctx, mesh, group_factory(order)) print("h=%s -> %d elements" % (h, sum(mgrp.nelements for mgrp in mesh.groups))) x = vol_discr.nodes()[0].with_queue(queue) vol_f = f(x) bdry_connection = make_face_restriction( vol_discr, group_factory(order), boundary_tag, per_face_groups=per_face_groups) check_connection(bdry_connection) bdry_discr = bdry_connection.to_discr bdry_x = bdry_discr.nodes()[0].with_queue(queue) bdry_f = f(bdry_x) bdry_f_2 = bdry_connection(queue, vol_f) if mesh_name == "blob" and dim == 2: mat = bdry_connection.full_resample_matrix(queue).get(queue) bdry_f_2_by_mat = mat.dot(vol_f.get()) mat_error = la.norm(bdry_f_2.get(queue=queue) - bdry_f_2_by_mat) assert mat_error < 1e-14, mat_error err = la.norm((bdry_f - bdry_f_2).get(), np.inf) eoc_rec.add_data_point(h, err) print(eoc_rec) assert (eoc_rec.order_estimate() >= order - 0.5 or eoc_rec.max_error() < 1e-14)
def test_sanity_balls(ctx_getter, src_file, dim, mesh_order, visualize=False): pytest.importorskip("pytential") logging.basicConfig(level=logging.INFO) ctx = ctx_getter() queue = cl.CommandQueue(ctx) from pytools.convergence import EOCRecorder vol_eoc_rec = EOCRecorder() surf_eoc_rec = EOCRecorder() # overkill quad_order = mesh_order from pytential import bind, sym for h in [0.2, 0.14, 0.1]: from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh(FileSource(src_file), dim, order=mesh_order, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %g;" % h ], force_ambient_dim=dim) logger.info("%d elements" % mesh.nelements) # {{{ discretizations and connections from meshmode.discretization import Discretization vol_discr = Discretization( ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(quad_order)) from meshmode.discretization.connection import make_face_restriction bdry_connection = make_face_restriction( vol_discr, InterpolatoryQuadratureSimplexGroupFactory(quad_order), BTAG_ALL) bdry_discr = bdry_connection.to_discr # }}} # {{{ visualizers from meshmode.discretization.visualization import make_visualizer vol_vis = make_visualizer(queue, vol_discr, 20) bdry_vis = make_visualizer(queue, bdry_discr, 20) # }}} from math import gamma true_surf = 2 * np.pi**(dim / 2) / gamma(dim / 2) true_vol = true_surf / dim vol_x = vol_discr.nodes().with_queue(queue) vol_one = vol_x[0].copy() vol_one.fill(1) from pytential import norm, integral # noqa comp_vol = integral(vol_discr, queue, vol_one) rel_vol_err = abs(true_vol - comp_vol) / true_vol vol_eoc_rec.add_data_point(h, rel_vol_err) print("VOL", true_vol, comp_vol) bdry_x = bdry_discr.nodes().with_queue(queue) bdry_one_exact = bdry_x[0].copy() bdry_one_exact.fill(1) bdry_one = bdry_connection(queue, vol_one).with_queue(queue) intp_err = norm(bdry_discr, queue, bdry_one - bdry_one_exact) assert intp_err < 1e-14 comp_surf = integral(bdry_discr, queue, bdry_one) rel_surf_err = abs(true_surf - comp_surf) / true_surf surf_eoc_rec.add_data_point(h, rel_surf_err) print("SURF", true_surf, comp_surf) if visualize: vol_vis.write_vtk_file("volume-h=%g.vtu" % h, [ ("f", vol_one), ("area_el", bind(vol_discr, sym.area_element())(queue)), ]) bdry_vis.write_vtk_file("boundary-h=%g.vtu" % h, [("f", bdry_one)]) # {{{ check normals point outward normal_outward_check = bind( bdry_discr, sym.normal(mesh.ambient_dim) | sym.nodes(mesh.ambient_dim), )(queue).as_scalar() > 0 assert normal_outward_check.get().all(), normal_outward_check.get() # }}} print("---------------------------------") print("VOLUME") print("---------------------------------") print(vol_eoc_rec) assert vol_eoc_rec.order_estimate() >= mesh_order print("---------------------------------") print("SURFACE") print("---------------------------------") print(surf_eoc_rec) assert surf_eoc_rec.order_estimate() >= mesh_order
def test_opposite_face_interpolation(ctx_getter, group_factory, mesh_name, dim, mesh_pars): logging.basicConfig(level=logging.INFO) cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) from meshmode.discretization import Discretization from meshmode.discretization.connection import ( make_face_restriction, make_opposite_face_connection, check_connection) from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() order = 5 def f(x): return 0.1 * cl.clmath.sin(30 * x) for mesh_par in mesh_pars: # {{{ get mesh if mesh_name == "blob": assert dim == 2 h = mesh_par from meshmode.mesh.io import generate_gmsh, FileSource print("BEGIN GEN") mesh = generate_gmsh(FileSource("blob-2d.step"), 2, order=order, force_ambient_dim=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %s;" % h ]) print("END GEN") elif mesh_name == "warp": from meshmode.mesh.generation import generate_warped_rect_mesh mesh = generate_warped_rect_mesh(dim, order=4, n=mesh_par) h = 1 / mesh_par else: raise ValueError("mesh_name not recognized") # }}} vol_discr = Discretization(cl_ctx, mesh, group_factory(order)) print("h=%s -> %d elements" % (h, sum(mgrp.nelements for mgrp in mesh.groups))) bdry_connection = make_face_restriction(vol_discr, group_factory(order), FRESTR_INTERIOR_FACES) bdry_discr = bdry_connection.to_discr opp_face = make_opposite_face_connection(bdry_connection) check_connection(opp_face) bdry_x = bdry_discr.nodes()[0].with_queue(queue) bdry_f = f(bdry_x) bdry_f_2 = opp_face(queue, bdry_f) err = la.norm((bdry_f - bdry_f_2).get(), np.inf) eoc_rec.add_data_point(h, err) print(eoc_rec) assert (eoc_rec.order_estimate() >= order - 0.5 or eoc_rec.max_error() < 1e-13)
def test_all_faces_interpolation(ctx_getter, mesh_name, dim, mesh_pars, per_face_groups): cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) from meshmode.discretization import Discretization from meshmode.discretization.connection import ( make_face_restriction, make_face_to_all_faces_embedding, check_connection) from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() order = 4 def f(x): return 0.1 * cl.clmath.sin(30 * x) for mesh_par in mesh_pars: # {{{ get mesh if mesh_name == "blob": assert dim == 2 h = mesh_par from meshmode.mesh.io import generate_gmsh, FileSource print("BEGIN GEN") mesh = generate_gmsh(FileSource("blob-2d.step"), 2, order=order, force_ambient_dim=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %s;" % h ]) print("END GEN") elif mesh_name == "warp": from meshmode.mesh.generation import generate_warped_rect_mesh mesh = generate_warped_rect_mesh(dim, order=4, n=mesh_par) h = 1 / mesh_par else: raise ValueError("mesh_name not recognized") # }}} vol_discr = Discretization(cl_ctx, mesh, PolynomialWarpAndBlendGroupFactory(order)) print("h=%s -> %d elements" % (h, sum(mgrp.nelements for mgrp in mesh.groups))) all_face_bdry_connection = make_face_restriction( vol_discr, PolynomialWarpAndBlendGroupFactory(order), FRESTR_ALL_FACES, per_face_groups=per_face_groups) all_face_bdry_discr = all_face_bdry_connection.to_discr for ito_grp, ceg in enumerate(all_face_bdry_connection.groups): for ibatch, batch in enumerate(ceg.batches): assert np.array_equal(batch.from_element_indices.get(queue), np.arange(vol_discr.mesh.nelements)) if per_face_groups: assert ito_grp == batch.to_element_face else: assert ibatch == batch.to_element_face all_face_x = all_face_bdry_discr.nodes()[0].with_queue(queue) all_face_f = f(all_face_x) all_face_f_2 = all_face_bdry_discr.zeros(queue) for boundary_tag in [ BTAG_ALL, FRESTR_INTERIOR_FACES, ]: bdry_connection = make_face_restriction( vol_discr, PolynomialWarpAndBlendGroupFactory(order), boundary_tag, per_face_groups=per_face_groups) bdry_discr = bdry_connection.to_discr bdry_x = bdry_discr.nodes()[0].with_queue(queue) bdry_f = f(bdry_x) all_face_embedding = make_face_to_all_faces_embedding( bdry_connection, all_face_bdry_discr) check_connection(all_face_embedding) all_face_f_2 += all_face_embedding(queue, bdry_f) err = la.norm((all_face_f - all_face_f_2).get(), np.inf) eoc_rec.add_data_point(h, err) print(eoc_rec) assert (eoc_rec.order_estimate() >= order - 0.5 or eoc_rec.max_error() < 1e-14)
def test_sanity_balls(actx_factory, src_file, dim, mesh_order, visualize=False): pytest.importorskip("pytential") logging.basicConfig(level=logging.INFO) actx = actx_factory() from pytools.convergence import EOCRecorder vol_eoc_rec = EOCRecorder() surf_eoc_rec = EOCRecorder() # overkill quad_order = mesh_order from pytential import bind, sym for h in [0.2, 0.1, 0.05]: from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh(FileSource(src_file), dim, order=mesh_order, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %g;" % h ], force_ambient_dim=dim, target_unit="MM") logger.info("%d elements", mesh.nelements) # {{{ discretizations and connections from meshmode.discretization import Discretization vol_discr = Discretization( actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(quad_order)) from meshmode.discretization.connection import make_face_restriction bdry_connection = make_face_restriction( actx, vol_discr, InterpolatoryQuadratureSimplexGroupFactory(quad_order), BTAG_ALL) bdry_discr = bdry_connection.to_discr # }}} from math import gamma true_surf = 2 * np.pi**(dim / 2) / gamma(dim / 2) true_vol = true_surf / dim vol_x = thaw(vol_discr.nodes(), actx) vol_one = vol_x[0] * 0 + 1 from pytential import norm, integral # noqa comp_vol = integral(vol_discr, vol_one) rel_vol_err = abs(true_vol - comp_vol) / true_vol vol_eoc_rec.add_data_point(h, rel_vol_err) print("VOL", true_vol, comp_vol) bdry_x = thaw(bdry_discr.nodes(), actx) bdry_one_exact = bdry_x[0] * 0 + 1 bdry_one = bdry_connection(vol_one) intp_err = norm(bdry_discr, bdry_one - bdry_one_exact) assert intp_err < 1e-14 comp_surf = integral(bdry_discr, bdry_one) rel_surf_err = abs(true_surf - comp_surf) / true_surf surf_eoc_rec.add_data_point(h, rel_surf_err) print("SURF", true_surf, comp_surf) if visualize: from meshmode.discretization.visualization import make_visualizer vol_vis = make_visualizer(actx, vol_discr, 7) bdry_vis = make_visualizer(actx, bdry_discr, 7) name = src_file.split("-")[0] vol_vis.write_vtk_file(f"sanity_balls_volume_{name}_{h:g}.vtu", [ ("f", vol_one), ("area_el", bind(vol_discr, sym.area_element(mesh.ambient_dim, mesh.ambient_dim))(actx)), ]) bdry_vis.write_vtk_file(f"sanity_balls_boundary_{name}_{h:g}.vtu", [("f", bdry_one)]) # {{{ check normals point outward normal_outward_check = bind( bdry_discr, sym.normal(mesh.ambient_dim) | sym.nodes(mesh.ambient_dim), )(actx).as_scalar() normal_outward_check = flatten_to_numpy(actx, normal_outward_check > 0) assert normal_outward_check.all(), normal_outward_check # }}} print("---------------------------------") print("VOLUME") print("---------------------------------") print(vol_eoc_rec) assert vol_eoc_rec.order_estimate() >= mesh_order print("---------------------------------") print("SURFACE") print("---------------------------------") print(surf_eoc_rec) assert surf_eoc_rec.order_estimate() >= mesh_order
def test_opposite_face_interpolation(actx_factory, group_factory, mesh_name, dim, mesh_pars): if (group_factory is LegendreGaussLobattoTensorProductGroupFactory and mesh_name in ["segment", "blob"]): pytest.skip("tensor products not implemented on blobs") logging.basicConfig(level=logging.INFO) actx = actx_factory() if group_factory is LegendreGaussLobattoTensorProductGroupFactory: group_cls = TensorProductElementGroup else: group_cls = SimplexElementGroup from meshmode.discretization import Discretization from meshmode.discretization.connection import ( make_face_restriction, make_opposite_face_connection, check_connection) from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() order = 5 def f(x): return 0.1 * actx.np.sin(30 * x) for mesh_par in mesh_pars: # {{{ get mesh if mesh_name == "segment": assert dim == 1 mesh = mgen.generate_box_mesh([np.linspace(-0.5, 0.5, mesh_par)], order=order, group_cls=group_cls) h = 1.0 / mesh_par elif mesh_name == "blob": assert dim == 2 h = mesh_par from meshmode.mesh.io import generate_gmsh, FileSource print("BEGIN GEN") mesh = generate_gmsh( FileSource("blob-2d.step"), 2, order=order, force_ambient_dim=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %s;" % h ], target_unit="MM", ) print("END GEN") elif mesh_name == "warp": mesh = mgen.generate_warped_rect_mesh(dim, order=order, nelements_side=mesh_par, group_cls=group_cls) h = 1 / mesh_par else: raise ValueError("mesh_name not recognized") # }}} vol_discr = Discretization(actx, mesh, group_factory(order)) print("h=%s -> %d elements" % (h, sum(mgrp.nelements for mgrp in mesh.groups))) bdry_connection = make_face_restriction(actx, vol_discr, group_factory(order), FACE_RESTR_INTERIOR) bdry_discr = bdry_connection.to_discr opp_face = make_opposite_face_connection(actx, bdry_connection) check_connection(actx, opp_face) bdry_x = thaw(bdry_discr.nodes()[0], actx) bdry_f = f(bdry_x) bdry_f_2 = opp_face(bdry_f) err = flat_norm(bdry_f - bdry_f_2, np.inf) eoc_rec.add_data_point(h, err) print(eoc_rec) assert (eoc_rec.order_estimate() >= order - 0.5 or eoc_rec.max_error() < 1.7e-13)
def main(): import logging logging.basicConfig(level=logging.INFO) ctx = cl.create_some_context() queue = cl.CommandQueue(ctx) if 1: ext = 0.5 mesh = generate_regular_rect_mesh(a=(-ext / 2, -ext / 2), b=(ext / 2, ext / 2), n=(int(ext / h), int(ext / h))) else: mesh = generate_gmsh(FileSource("circle.step"), 2, order=mesh_order, force_ambient_dim=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %g;" % h ]) logger.info("%d elements" % mesh.nelements) # {{{ discretizations and connections vol_discr = Discretization( ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(vol_quad_order)) ovsmp_vol_discr = Discretization( ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(vol_ovsmp_quad_order)) from meshmode.mesh import BTAG_ALL from meshmode.discretization.connection import (make_face_restriction, make_same_mesh_connection) bdry_connection = make_face_restriction( vol_discr, InterpolatoryQuadratureSimplexGroupFactory(bdry_quad_order), BTAG_ALL) bdry_discr = bdry_connection.to_discr vol_to_ovsmp_vol = make_same_mesh_connection(ovsmp_vol_discr, vol_discr) # }}} # {{{ visualizers vol_vis = make_visualizer(queue, vol_discr, 20) bdry_vis = make_visualizer(queue, bdry_discr, 20) # }}} vol_x = vol_discr.nodes().with_queue(queue) ovsmp_vol_x = ovsmp_vol_discr.nodes().with_queue(queue) rhs = rhs_func(vol_x[0], vol_x[1]) poisson_true_sol = sol_func(vol_x[0], vol_x[1]) vol_vis.write_vtk_file("volume.vtu", [("f", rhs)]) bdry_normals = bind(bdry_discr, p.normal( mesh.ambient_dim))(queue).as_vector(dtype=object) bdry_vis.write_vtk_file("boundary.vtu", [("normals", bdry_normals)]) bdry_nodes = bdry_discr.nodes().with_queue(queue) bdry_f = rhs_func(bdry_nodes[0], bdry_nodes[1]) bdry_f_2 = bdry_connection(queue, rhs) bdry_vis.write_vtk_file("y.vtu", [("f", bdry_f_2)]) if 0: vol_vis.show_scalar_in_mayavi(rhs, do_show=False) bdry_vis.show_scalar_in_mayavi(bdry_f - bdry_f_2, line_width=10, do_show=False) import mayavi.mlab as mlab mlab.colorbar() mlab.show() # {{{ compute volume potential from sumpy.qbx import LayerPotential from sumpy.expansion.local import LineTaylorLocalExpansion def get_kernel(): from sumpy.symbolic import pymbolic_real_norm_2 from pymbolic.primitives import make_sym_vector from pymbolic import var d = make_sym_vector("d", 3) r = pymbolic_real_norm_2(d[:-1]) # r3d = pymbolic_real_norm_2(d) #expr = var("log")(r3d) log = var("log") sqrt = var("sqrt") a = d[-1] expr = log(r) expr = log(sqrt(r**2 + a**2)) expr = log(sqrt(r + a**2)) #expr = log(sqrt(r**2 + a**2))-a**2/2/(r**2+a**2) #expr = 2*log(sqrt(r**2 + a**2)) scaling = 1 / (2 * var("pi")) from sumpy.kernel import ExpressionKernel return ExpressionKernel(dim=3, expression=expr, global_scaling_const=scaling, is_complex_valued=False) laplace_2d_in_3d_kernel = get_kernel() layer_pot = LayerPotential( ctx, [LineTaylorLocalExpansion(laplace_2d_in_3d_kernel, order=0)]) targets = cl.array.zeros(queue, (3, ) + vol_x.shape[1:], vol_x.dtype) targets[:2] = vol_x center_dist = 0.125 * np.min( cl.clmath.sqrt( bind(vol_discr, p.area_element(mesh.ambient_dim, mesh.dim))(queue)).get()) centers = make_obj_array( [ci.copy().reshape(vol_discr.nnodes) for ci in targets]) centers[2][:] = center_dist print(center_dist) sources = cl.array.zeros(queue, (3, ) + ovsmp_vol_x.shape[1:], ovsmp_vol_x.dtype) sources[:2] = ovsmp_vol_x ovsmp_rhs = vol_to_ovsmp_vol(queue, rhs) ovsmp_vol_weights = bind( ovsmp_vol_discr, p.area_element(mesh.ambient_dim, mesh.dim) * p.QWeight())(queue) print("volume: %d source nodes, %d target nodes" % (ovsmp_vol_discr.nnodes, vol_discr.nnodes)) evt, (vol_pot, ) = layer_pot( queue, targets=targets.reshape(3, vol_discr.nnodes), centers=centers, sources=sources.reshape(3, ovsmp_vol_discr.nnodes), strengths=((ovsmp_vol_weights * ovsmp_rhs).reshape( ovsmp_vol_discr.nnodes), ), expansion_radii=np.zeros(vol_discr.nnodes), ) vol_pot_bdry = bdry_connection(queue, vol_pot) # }}} # {{{ solve bvp from sumpy.kernel import LaplaceKernel from pytential.symbolic.pde.scalar import DirichletOperator op = DirichletOperator(LaplaceKernel(2), -1, use_l2_weighting=True) sym_sigma = sym.var("sigma") op_sigma = op.operator(sym_sigma) from pytential.qbx import QBXLayerPotentialSource qbx = QBXLayerPotentialSource( bdry_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order, fmm_order=fmm_order, ) bound_op = bind(qbx, op_sigma) poisson_bc = poisson_bc_func(bdry_nodes[0], bdry_nodes[1]) bvp_bc = poisson_bc - vol_pot_bdry bdry_f = rhs_func(bdry_nodes[0], bdry_nodes[1]) bvp_rhs = bind(bdry_discr, op.prepare_rhs(sym.var("bc")))(queue, bc=bvp_bc) from pytential.solve import gmres gmres_result = gmres(bound_op.scipy_op(queue, "sigma", dtype=np.float64), bvp_rhs, tol=1e-14, progress=True, hard_failure=False) sigma = gmres_result.solution print("gmres state:", gmres_result.state) # }}} bvp_sol = bind((qbx, vol_discr), op.representation(sym_sigma))(queue, sigma=sigma) poisson_sol = bvp_sol + vol_pot poisson_err = poisson_sol - poisson_true_sol rel_err = (norm(vol_discr, queue, poisson_err) / norm(vol_discr, queue, poisson_true_sol)) bdry_vis.write_vtk_file("poisson-boundary.vtu", [ ("vol_pot_bdry", vol_pot_bdry), ("sigma", sigma), ]) vol_vis.write_vtk_file("poisson-volume.vtu", [ ("bvp_sol", bvp_sol), ("poisson_sol", poisson_sol), ("poisson_true_sol", poisson_true_sol), ("poisson_err", poisson_err), ("vol_pot", vol_pot), ("rhs", rhs), ]) print("h = %s" % h) print("mesh_order = %s" % mesh_order) print("vol_quad_order = %s" % vol_quad_order) print("vol_ovsmp_quad_order = %s" % vol_ovsmp_quad_order) print("bdry_quad_order = %s" % bdry_quad_order) print("bdry_ovsmp_quad_order = %s" % bdry_ovsmp_quad_order) print("qbx_order = %s" % qbx_order) #print("vol_qbx_order = %s" % vol_qbx_order) print("fmm_order = %s" % fmm_order) print() print("rel err: %g" % rel_err)
from meshmode.mesh.io import generate_gmsh, FileSource from meshmode.mesh.visualization import mesh_to_tikz h = 0.3 order = 1 mesh = generate_gmsh( FileSource("../test/blob-2d.step"), 2, order=order, force_ambient_dim=2, other_options=["-string", "Mesh.CharacteristicLengthMax = %s;" % h]) print(mesh_to_tikz(mesh))
def main(): import logging logger = logging.getLogger(__name__) logging.basicConfig(level=logging.WARNING) # INFO for more progress info from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh( FileSource(cad_file_name), 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)) 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 + 3, target_association_tolerance=0.15).with_refinement() nodes = density_discr.nodes().with_queue(queue) angle = cl.clmath.atan2(nodes[1], nodes[0]) from pytential import bind, sym #op = sym.d_dx(sym.S(kernel, sym.var("sigma"), qbx_forced_limit=None)) op = sym.D(kernel, sym.var("sigma"), qbx_forced_limit=None) #op = sym.S(kernel, sym.var("sigma"), qbx_forced_limit=None) sigma = cl.clmath.cos(mode_nr*angle) if 0: sigma = 0*angle from random import randrange for i in range(5): sigma[randrange(len(sigma))] = 1 if isinstance(kernel, HelmholtzKernel): sigma = sigma.astype(np.complex128) fplot = FieldPlotter(bbox_center, extent=3.5*bbox_size, npoints=150) from pytential.target import PointsTarget fld_in_vol = bind( (qbx, PointsTarget(fplot.points)), op)(queue, sigma=sigma, k=k).get() #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5) fplot.write_vtk_file( "potential-3d.vts", [ ("potential", fld_in_vol) ] ) bdry_normals = bind( density_discr, sym.normal(density_discr.ambient_dim))(queue).as_vector(dtype=object) from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(queue, density_discr, target_order) bdry_vis.write_vtk_file("source-3d.vtu", [ ("sigma", sigma), ("bdry_normals", bdry_normals), ])
def test_all_faces_interpolation(actx_factory, group_factory, mesh_name, dim, mesh_pars, per_face_groups): if (group_factory is LegendreGaussLobattoTensorProductGroupFactory and mesh_name == "blob"): pytest.skip("tensor products not implemented on blobs") actx = actx_factory() if group_factory is LegendreGaussLobattoTensorProductGroupFactory: group_cls = TensorProductElementGroup else: group_cls = SimplexElementGroup from meshmode.discretization import Discretization from meshmode.discretization.connection import ( make_face_restriction, make_face_to_all_faces_embedding, check_connection) from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() order = 4 def f(x): return 0.1 * actx.np.sin(30 * x) for mesh_par in mesh_pars: # {{{ get mesh if mesh_name == "blob": assert dim == 2 h = mesh_par from meshmode.mesh.io import generate_gmsh, FileSource print("BEGIN GEN") mesh = generate_gmsh( FileSource("blob-2d.step"), 2, order=order, force_ambient_dim=2, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %s;" % h ], target_unit="MM", ) print("END GEN") elif mesh_name == "warp": mesh = mgen.generate_warped_rect_mesh(dim, order=4, nelements_side=mesh_par, group_cls=group_cls) h = 1 / mesh_par else: raise ValueError("mesh_name not recognized") # }}} vol_discr = Discretization(actx, mesh, group_factory(order)) print("h=%s -> %d elements" % (h, sum(mgrp.nelements for mgrp in mesh.groups))) all_face_bdry_connection = make_face_restriction( actx, vol_discr, group_factory(order), FACE_RESTR_ALL, per_face_groups=per_face_groups) all_face_bdry_discr = all_face_bdry_connection.to_discr for ito_grp, ceg in enumerate(all_face_bdry_connection.groups): for ibatch, batch in enumerate(ceg.batches): assert np.array_equal( actx.to_numpy(actx.thaw(batch.from_element_indices)), np.arange(vol_discr.mesh.nelements)) if per_face_groups: assert ito_grp == batch.to_element_face else: assert ibatch == batch.to_element_face all_face_x = thaw(all_face_bdry_discr.nodes()[0], actx) all_face_f = f(all_face_x) all_face_f_2 = all_face_bdry_discr.zeros(actx) for boundary_tag in [ BTAG_ALL, FACE_RESTR_INTERIOR, ]: bdry_connection = make_face_restriction( actx, vol_discr, group_factory(order), boundary_tag, per_face_groups=per_face_groups) bdry_discr = bdry_connection.to_discr bdry_x = thaw(bdry_discr.nodes()[0], actx) bdry_f = f(bdry_x) all_face_embedding = make_face_to_all_faces_embedding( actx, bdry_connection, all_face_bdry_discr) check_connection(actx, all_face_embedding) all_face_f_2 = all_face_f_2 + all_face_embedding(bdry_f) err = flat_norm(all_face_f - all_face_f_2, np.inf) eoc_rec.add_data_point(h, err) print(eoc_rec) assert (eoc_rec.order_estimate() >= order - 0.5 or eoc_rec.max_error() < 1e-14)