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_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_dijsoint_meshes, affine_map mesh2 = affine_map(mesh, A=np.eye(2), b=np.array([5, 0])) mesh3 = merge_dijsoint_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 get_mesh(self, resolution, mesh_order): from meshmode.mesh.io import generate_gmsh, FileSource base_mesh = generate_gmsh(FileSource("ellipsoid.step"), 2, order=mesh_order, other_options=[ "-string", "Mesh.CharacteristicLengthMax = %g;" % resolution ]) from meshmode.mesh.processing import perform_flips 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 meshes = [ affine_map(base_mesh, A=rand_rotation_matrix(3), b=self.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) ] return merge_disjoint_meshes(meshes, single_group=True)
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_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_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 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 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_quad_mesh_3d(mesh_name, order=3, visualize=False): if mesh_name == "ball": from meshmode.mesh.io import ScriptWithFilesSource script = ScriptWithFilesSource( """ Merge "ball-radius-1.step"; // Mesh.CharacteristicLengthMax = 0.1; Mesh.RecombineAll = 1; Mesh.Recombine3DAll = 1; Mesh.Recombine3DLevel = 2; Mesh.Algorithm = 8; Mesh.Algorithm3D = 8; Mesh 3; Save "output.msh"; """, ["ball-radius-1.step"]) with open("ball-quad.geo", "w") as f: f.write(script.source) elif mesh_name == "cube": from meshmode.mesh.io import ScriptSource script = ScriptSource( """ SetFactory("OpenCASCADE"); Box(1) = {0, 0, 0, 1, 1, 1}; Transfinite Line "*" = 8; Transfinite Surface "*"; Transfinite Volume "*"; Mesh.RecombineAll = 1; Mesh.Recombine3DAll = 1; Mesh.Recombine3DLevel = 2; """, "geo") else: raise ValueError(f"unknown mesh name: '{mesh_name}'") np.set_printoptions(linewidth=200) from meshmode.mesh.io import generate_gmsh logger.info("BEGIN GEN") mesh = generate_gmsh(script, 3, order=order, target_unit="MM") logger.info("END GEN") if visualize: from meshmode.mesh.visualization import write_vertex_vtk_file write_vertex_vtk_file(mesh, f"quad_mesh_3d_{mesh_name}.vtu", overwrite=True)
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_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 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_quad_mesh_2d(): from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource print("BEGIN GEN") mesh = generate_gmsh( ScriptWithFilesSource( """ Merge "blob-2d.step"; Mesh.CharacteristicLengthMax = 0.05; Recombine Surface "*" = 0.0001; Mesh 2; Save "output.msh"; """, ["blob-2d.step"]), force_ambient_dim=2, ) print("END GEN") print(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 test_quad_mesh(): from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource print("BEGIN GEN") mesh = generate_gmsh( ScriptWithFilesSource( """ Merge "blob-2d.step"; Mesh.CharacteristicLengthMax = 0.05; Recombine Surface "*" = 0.0001; Mesh 2; Save "output.msh"; """, ["blob-2d.step"]), force_ambient_dim=2, ) print("END GEN") print(mesh.nelements)
def test_boundary_interpolation(ctx_getter): cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) from meshmode.mesh.io import generate_gmsh, FileSource from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory from meshmode.discretization.connection import make_boundary_restriction from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() order = 4 for h in [1e-1, 3e-2, 1e-2]: 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") vol_discr = Discretization(cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(order)) print("h=%s -> %d elements" % ( h, sum(mgrp.nelements for mgrp in mesh.groups))) x = vol_discr.nodes()[0].with_queue(queue) f = 0.1*cl.clmath.sin(30*x) bdry_mesh, bdry_discr, bdry_connection = make_boundary_restriction( queue, vol_discr, InterpolatoryQuadratureSimplexGroupFactory(order)) bdry_x = bdry_discr.nodes()[0].with_queue(queue) bdry_f = 0.1*cl.clmath.sin(30*bdry_x) bdry_f_2 = bdry_connection(queue, 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
def test_quad_mesh_2d(ambient_dim, filename, visualize=False): from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource logger.info("BEGIN GEN") mesh = generate_gmsh( ScriptWithFilesSource( f""" Merge "{filename}"; Mesh.CharacteristicLengthMax = 0.05; Recombine Surface "*" = 0.0001; Mesh 2; Save "output.msh"; """, [filename]), order=1, force_ambient_dim=ambient_dim, target_unit="MM", ) logger.info("END GEN") logger.info("nelements: %d", mesh.nelements) groups = [] for grp in mesh.groups: if not isinstance(grp, TensorProductElementGroup): # NOTE: gmsh isn't guaranteed to recombine all elements, so we # could still have some simplices sitting around, so skip them groups.append(grp.copy()) continue g = mgen.make_group_from_vertices(mesh.vertices, grp.vertex_indices, grp.order, group_cls=TensorProductElementGroup) assert g.nodes.shape == (mesh.ambient_dim, grp.nelements, grp.nunit_nodes) groups.append(g) mesh_from_vertices = Mesh(mesh.vertices, groups=groups, is_conforming=True) if visualize: from meshmode.mesh.visualization import write_vertex_vtk_file write_vertex_vtk_file(mesh, "quad_mesh_2d_orig.vtu") write_vertex_vtk_file(mesh_from_vertices, "quad_mesh_2d_groups.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_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_connectivity=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 no_test_quad_mesh_3d(): from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource print("BEGIN GEN") mesh = generate_gmsh( ScriptWithFilesSource( """ Merge "ball-radius-1.step"; // Mesh.CharacteristicLengthMax = 0.1; Mesh.RecombineAll=1; Mesh.Recombine3DAll=1; Mesh.Algorithm = 8; Mesh.Algorithm3D = 9; // Mesh.Smoothing = 0; // Mesh.ElementOrder = 3; Mesh 3; Save "output.msh"; """, ["ball-radius-1.step"]), ) print("END GEN") print(mesh.nelements)
def get_mesh(self, resolution, mesh_order): from meshmode.mesh.io import ScriptSource source = ScriptSource( """ SetFactory("OpenCASCADE"); Sphere(1) = {{0, 0, 0, {r}}}; Dilate {{ {{0, 0, 0}}, {{ {r}, {r}, {rr} }} }} {{ Volume{{1}}; }} """.format(r=self.diameter, rr=self.aspect_ratio * self.diameter), "geo") from meshmode.mesh.io import generate_gmsh mesh = generate_gmsh(source, 2, order=mesh_order, other_options=[ "-optimize_ho", "-string", "Mesh.CharacteristicLengthMax = %g;" % resolution ], target_unit="MM") from meshmode.mesh.processing import perform_flips return perform_flips(mesh, np.ones(mesh.nelements))
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_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 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/a869fc3/" "surface-3d/betterplane.brep") from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource mesh = generate_gmsh( ScriptWithFilesSource( """ Merge "betterplane.brep"; Mesh.CharacteristicLengthMax = %(lcmax)f; Mesh.ElementOrder = 2; Mesh.CharacteristicLengthExtendFromBoundary = 0; // 2D mesh optimization // Mesh.Lloyd = 1; l_superfine() = Unique(Abs(Boundary{ Surface{ 27, 25, 17, 13, 18 }; })); l_fine() = Unique(Abs(Boundary{ Surface{ 2, 6, 7}; })); l_coarse() = Unique(Abs(Boundary{ Surface{ 14, 16 }; })); // p() = Unique(Abs(Boundary{ Line{l_fine()}; })); // Characteristic Length{p()} = 0.05; Field[1] = Attractor; Field[1].NNodesByEdge = 100; Field[1].EdgesList = {l_superfine()}; Field[2] = Threshold; Field[2].IField = 1; Field[2].LcMin = 0.075; Field[2].LcMax = %(lcmax)f; Field[2].DistMin = 0.1; Field[2].DistMax = 0.4; Field[3] = Attractor; Field[3].NNodesByEdge = 100; Field[3].EdgesList = {l_fine()}; Field[4] = Threshold; Field[4].IField = 3; Field[4].LcMin = 0.1; Field[4].LcMax = %(lcmax)f; Field[4].DistMin = 0.15; Field[4].DistMax = 0.4; Field[5] = Attractor; Field[5].NNodesByEdge = 100; Field[5].EdgesList = {l_coarse()}; Field[6] = Threshold; Field[6].IField = 5; Field[6].LcMin = 0.15; Field[6].LcMax = %(lcmax)f; Field[6].DistMin = 0.2; Field[6].DistMax = 0.4; Field[7] = Min; Field[7].FieldsList = {2, 4, 6}; Background Field = 7; """ % { "lcmax": resolution, }, ["betterplane.brep"]), 2) # Flip elements--gmsh generates inside-out geometry. from meshmode.mesh.processing import perform_flips return perform_flips(mesh, np.ones(mesh.nelements))
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 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)
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 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 from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory vol_discr = Discretization(ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(quad_order)) from meshmode.discretization.connection import make_boundary_restriction bdry_mesh, bdry_discr, bdry_connection = make_boundary_restriction( queue, vol_discr, InterpolatoryQuadratureSimplexGroupFactory(quad_order)) # }}} # {{{ 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() | sym.Nodes(), )(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_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)
qbx_order = 2 nelements = 60 mode_nr = 0 h = 0.4 k = 0 if k: kernel = HelmholtzKernel("k") else: kernel = LaplaceKernel() #kernel = OneKernel() from meshmode.mesh.io import generate_gmsh, FileSource mesh = generate_gmsh( FileSource("molecule.step"), 2, order=2, other_options=["-string", "Mesh.CharacteristicLengthMax = %g;" % h]) 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(
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 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/a869fc3/" "surface-3d/betterplane.brep") from meshmode.mesh.io import generate_gmsh, ScriptWithFilesSource mesh = generate_gmsh( ScriptWithFilesSource(""" Merge "betterplane.brep"; Mesh.CharacteristicLengthMax = %(lcmax)f; Mesh.ElementOrder = 2; Mesh.CharacteristicLengthExtendFromBoundary = 0; // 2D mesh optimization // Mesh.Lloyd = 1; l_superfine() = Unique(Abs(Boundary{ Surface{ 27, 25, 17, 13, 18 }; })); l_fine() = Unique(Abs(Boundary{ Surface{ 2, 6, 7}; })); l_coarse() = Unique(Abs(Boundary{ Surface{ 14, 16 }; })); // p() = Unique(Abs(Boundary{ Line{l_fine()}; })); // Characteristic Length{p()} = 0.05; Field[1] = Attractor; Field[1].NNodesByEdge = 100; Field[1].EdgesList = {l_superfine()}; Field[2] = Threshold; Field[2].IField = 1; Field[2].LcMin = 0.075; Field[2].LcMax = %(lcmax)f; Field[2].DistMin = 0.1; Field[2].DistMax = 0.4; Field[3] = Attractor; Field[3].NNodesByEdge = 100; Field[3].EdgesList = {l_fine()}; Field[4] = Threshold; Field[4].IField = 3; Field[4].LcMin = 0.1; Field[4].LcMax = %(lcmax)f; Field[4].DistMin = 0.15; Field[4].DistMax = 0.4; Field[5] = Attractor; Field[5].NNodesByEdge = 100; Field[5].EdgesList = {l_coarse()}; Field[6] = Threshold; Field[6].IField = 5; Field[6].LcMin = 0.15; Field[6].LcMax = %(lcmax)f; Field[6].DistMin = 0.2; Field[6].DistMax = 0.4; Field[7] = Min; Field[7].FieldsList = {2, 4, 6}; Background Field = 7; """ % { "lcmax": resolution, }, ["betterplane.brep"]), 2) # Flip elements--gmsh generates inside-out geometry. from meshmode.mesh.processing import perform_flips return perform_flips(mesh, np.ones(mesh.nelements))
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 print(mesh_to_tikz(mesh))
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 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 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 main(): import logging logging.basicConfig(level=logging.INFO) ctx = cl.create_some_context() queue = cl.CommandQueue(ctx) 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.discretization.connection import ( make_boundary_restriction, make_same_mesh_connection) bdry_mesh, bdry_discr, bdry_connection = make_boundary_restriction( queue, vol_discr, InterpolatoryQuadratureSimplexGroupFactory(bdry_quad_order)) vol_to_ovsmp_vol = make_same_mesh_connection( queue, 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())(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, Variable as var) r = pymbolic_real_norm_2(make_sym_vector("d", 3)) expr = var("log")(r) scaling = 1/(2*var("pi")) from sumpy.kernel import ExpressionKernel return ExpressionKernel( dim=3, expression=expr, scaling=scaling, is_complex_valued=False) laplace_2d_in_3d_kernel = get_kernel() layer_pot = LayerPotential(ctx, [ LineTaylorLocalExpansion(laplace_2d_in_3d_kernel, order=vol_qbx_order)]) targets = cl.array.zeros(queue, (3,) + vol_x.shape[1:], vol_x.dtype) targets[:2] = vol_x center_dist = np.min( cl.clmath.sqrt( bind(vol_discr, p.area_element())(queue)).get()) centers = make_obj_array([ci.copy().reshape(vol_discr.nnodes) for ci in targets]) centers[2][:] = 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() * p.QWeight())(queue) 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),) ) 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"), 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)
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 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), ])
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))