def test_mesh_without_vertices(actx_factory): actx = actx_factory() # create a mesh mesh = mgen.generate_icosphere(r=1.0, order=4) # create one without the vertices grp, = mesh.groups groups = [ grp.copy(nodes=grp.nodes, vertex_indices=None) for grp in mesh.groups ] mesh = Mesh(None, groups, is_conforming=False) # try refining it from meshmode.mesh.refinement import refine_uniformly mesh = refine_uniformly(mesh, 1) # make sure the world doesn't end from meshmode.discretization import Discretization discr = Discretization(actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(4)) thaw(discr.nodes(), actx) from meshmode.discretization.visualization import make_visualizer make_visualizer(actx, discr, 4)
def test_mesh_without_vertices(ctx_factory): ctx = ctx_factory() queue = cl.CommandQueue(ctx) # create a mesh from meshmode.mesh.generation import generate_icosphere mesh = generate_icosphere(r=1.0, order=4) # create one without the vertices from meshmode.mesh import Mesh grp, = mesh.groups groups = [ grp.copy(nodes=grp.nodes, vertex_indices=None) for grp in mesh.groups ] mesh = Mesh(None, groups, is_conforming=False) # try refining it from meshmode.mesh.refinement import refine_uniformly mesh = refine_uniformly(mesh, 1) # make sure the world doesn't end from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory as GroupFactory discr = Discretization(ctx, mesh, GroupFactory(4)) discr.nodes().with_queue(queue) from meshmode.discretization.visualization import make_visualizer make_visualizer(queue, discr, 4)
def main(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from meshmode.mesh.generation import ( # noqa generate_icosphere, generate_icosahedron, generate_torus) #mesh = generate_icosphere(1, order=order) mesh = generate_icosahedron(1, order=order) #mesh = generate_torus(3, 1, order=order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory discr = Discretization( cl_ctx, mesh, PolynomialWarpAndBlendGroupFactory(order)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr, order) vis.write_vtk_file("geometry.vtu", [ ("f", discr.nodes()[0]), ]) from meshmode.discretization.visualization import \ write_mesh_connectivity_vtk_file write_mesh_connectivity_vtk_file("connectivity.vtu", mesh)
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 main(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from meshmode.mesh.generation import ( # noqa generate_icosphere, generate_icosahedron, generate_torus) #mesh = generate_icosphere(1, order=order) mesh = generate_icosahedron(1, order=order) #mesh = generate_torus(3, 1, order=order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory discr = Discretization(cl_ctx, mesh, PolynomialWarpAndBlendGroupFactory(order)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr, order) vis.write_vtk_file("geometry.vtu", [ ("f", discr.nodes()[0]), ]) from meshmode.discretization.visualization import \ write_nodal_adjacency_vtk_file write_nodal_adjacency_vtk_file("adjacency.vtu", mesh)
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 test_nonequal_rect_mesh_generation(actx_factory, dim, mesh_type, visualize=False): """Test that ``generate_regular_rect_mesh`` works with non-equal arguments across axes. """ actx = actx_factory() mesh = mgen.generate_regular_rect_mesh(a=(0, ) * dim, b=(5, 3, 4)[:dim], npoints_per_axis=(10, 6, 7)[:dim], order=3, mesh_type=mesh_type) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory as GroupFactory discr = Discretization(actx, mesh, GroupFactory(3)) if visualize: from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, 3) vis.write_vtk_file("nonuniform.vtu", [], overwrite=True)
def test_parallel_vtk_file(actx_factory, dim): r""" Simple test just generates a sample parallel PVTU file and checks it against the expected result. The expected result is just a file in the tests directory. """ logging.basicConfig(level=logging.INFO) actx = actx_factory() nelements = 64 target_order = 4 if dim == 1: mesh = mgen.make_curve_mesh(mgen.NArmedStarfish(5, 0.25), np.linspace(0.0, 1.0, nelements + 1), target_order) elif dim == 2: mesh = mgen.generate_torus(5.0, 1.0, order=target_order) elif dim == 3: mesh = mgen.generate_warped_rect_mesh(dim, target_order, nelements_side=4) else: raise ValueError("unknown dimensionality") from meshmode.discretization import Discretization discr = Discretization( actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, target_order) class FakeComm: def Get_rank(self): # noqa: N802 return 0 def Get_size(self): # noqa: N802 return 2 file_name_pattern = f"visualizer_vtk_linear_{dim}_{{rank}}.vtu" pvtu_filename = file_name_pattern.format(rank=0).replace("vtu", "pvtu") vis.write_parallel_vtk_file( FakeComm(), file_name_pattern, [("scalar", discr.zeros(actx)), ("vector", make_obj_array([discr.zeros(actx) for i in range(dim)]))], overwrite=True) import os assert os.path.exists(pvtu_filename) import filecmp assert filecmp.cmp(f"ref-{pvtu_filename}", pvtu_filename)
def _plot_partition_indices(queue, discr, indices, **kwargs): import matplotlib.pyplot as pt indices = indices.get(queue) args = [ kwargs.get("method", "unknown"), "tree" if kwargs.get("use_tree", False) else "linear", kwargs.get("pid", "stage1"), discr.ambient_dim ] pt.figure(figsize=(10, 8), dpi=300) pt.plot(np.diff(indices.ranges)) pt.savefig("test_partition_{0}_{1}_{3}d_ranges_{2}.png".format(*args)) pt.clf() if discr.ambient_dim == 2: sources = discr.nodes().get(queue) pt.figure(figsize=(10, 8), dpi=300) if indices.indices.shape[0] != discr.nnodes: pt.plot(sources[0], sources[1], 'ko', alpha=0.5) for i in range(indices.nblocks): isrc = indices.block_indices(i) pt.plot(sources[0][isrc], sources[1][isrc], 'o') pt.xlim([-1.5, 1.5]) pt.ylim([-1.5, 1.5]) pt.savefig("test_partition_{0}_{1}_{3}d_{2}.png".format(*args)) pt.clf() elif discr.ambient_dim == 3: from meshmode.discretization import NoninterpolatoryElementGroupError try: discr.groups[0].basis() except NoninterpolatoryElementGroupError: return from meshmode.discretization.visualization import make_visualizer marker = -42.0 * np.ones(discr.nnodes) for i in range(indices.nblocks): isrc = indices.block_indices(i) marker[isrc] = 10.0 * (i + 1.0) vis = make_visualizer(queue, discr, 10) filename = "test_partition_{0}_{1}_{3}d_{2}.png".format(*args) if os.path.isfile(filename): os.remove(filename) vis.write_vtk_file(filename, [ ("marker", cl.array.to_device(queue, marker)) ])
def vtk_visualize_mesh(actx, mesh, filename, vtk_high_order=True): order = max(mgrp.order for mgrp in mesh.groups) from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory from meshmode.discretization import Discretization discr = Discretization(actx, mesh, PolynomialWarpAndBlendGroupFactory(order)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, order, force_equidistant=vtk_high_order) vis.write_vtk_file(filename, [], use_high_order=vtk_high_order)
def main(): logging.basicConfig(level=logging.INFO) cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) nel_1d = 16 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5), nelements_per_axis=(nel_1d, nel_1d)) order = 3 # no deep meaning here, just a fudge factor dt = 0.7 / (nel_1d * order**2) logger.info("%d elements", mesh.nelements) discr = DGDiscretization(actx, mesh, order=order) fields = WaveState( u=bump(actx, discr), v=make_obj_array([discr.zeros(actx) for i in range(discr.dim)]), ) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr.volume_discr) def rhs(t, q): return wave_operator(actx, discr, c=1, q=q) t = 0 t_final = 3 istep = 0 while t < t_final: fields = rk4_step(fields, t, dt, rhs) if istep % 10 == 0: # FIXME: Maybe an integral function to go with the # DOFArray would be nice? assert len(fields.u) == 1 logger.info("[%05d] t %.5e / %.5e norm %.5e", istep, t, t_final, flat_norm(fields.u, 2)) vis.write_vtk_file("fld-wave-min-%04d.vtu" % istep, [ ("q", fields), ]) t += dt istep += 1 assert flat_norm(fields.u, 2) < 100
def test_box_mesh(actx_factory, visualize=False): mesh = mgen.generate_box_mesh(3 * (np.linspace(0, 1, 5), )) if visualize: from meshmode.discretization import Discretization actx = actx_factory() discr = Discretization(actx, mesh, PolynomialWarpAndBlendGroupFactory(7)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, 7) vis.write_vtk_file("box_mesh.vtu", [])
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 _plot_partition_indices(queue, discr, indices, **kwargs): import matplotlib.pyplot as pt indices = indices.get(queue) args = [ kwargs.get("method", "unknown"), "tree" if kwargs.get("use_tree", False) else "linear", kwargs.get("pid", "stage1"), discr.ambient_dim ] pt.figure(figsize=(10, 8), dpi=300) pt.plot(np.diff(indices.ranges)) pt.savefig("test_partition_{0}_{1}_{3}d_ranges_{2}.png".format(*args)) pt.clf() if discr.ambient_dim == 2: sources = discr.nodes().get(queue) pt.figure(figsize=(10, 8), dpi=300) if indices.indices.shape[0] != discr.nnodes: pt.plot(sources[0], sources[1], 'ko', alpha=0.5) for i in range(indices.nblocks): isrc = indices.block_indices(i) pt.plot(sources[0][isrc], sources[1][isrc], 'o') pt.xlim([-1.5, 1.5]) pt.ylim([-1.5, 1.5]) pt.savefig("test_partition_{0}_{1}_{3}d_{2}.png".format(*args)) pt.clf() elif discr.ambient_dim == 3: from meshmode.discretization import NoninterpolatoryElementGroupError try: discr.groups[0].basis() except NoninterpolatoryElementGroupError: return from meshmode.discretization.visualization import make_visualizer marker = -42.0 * np.ones(discr.nnodes) for i in range(indices.nblocks): isrc = indices.block_indices(i) marker[isrc] = 10.0 * (i + 1.0) vis = make_visualizer(queue, discr, 10) filename = "test_partition_{0}_{1}_{3}d_{2}.png".format(*args) vis.write_vtk_file(filename, [("marker", cl.array.to_device(queue, marker))])
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_3d_orientation(ctx_factory, what, mesh_gen_func, visualize=False): pytest.importorskip("pytential") logging.basicConfig(level=logging.INFO) ctx = ctx_factory() queue = cl.CommandQueue(ctx) mesh = mesh_gen_func() logger.info("%d elements" % mesh.nelements) from meshmode.discretization import Discretization discr = Discretization(ctx, mesh, PolynomialWarpAndBlendGroupFactory(1)) from pytential import bind, sym # {{{ check normals point outward if what == "torus": nodes = sym.nodes(mesh.ambient_dim).as_vector() angle = sym.atan2(nodes[1], nodes[0]) center_nodes = sym.make_obj_array([ 5*sym.cos(angle), 5*sym.sin(angle), 0*angle]) normal_outward_expr = ( sym.normal(mesh.ambient_dim) | (nodes-center_nodes)) else: normal_outward_expr = ( sym.normal(mesh.ambient_dim) | sym.nodes(mesh.ambient_dim)) normal_outward_check = bind(discr, normal_outward_expr)(queue).as_scalar() > 0 assert normal_outward_check.get().all(), normal_outward_check.get() # }}} normals = bind(discr, sym.normal(mesh.ambient_dim).xproject(1))(queue) if visualize: from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr, 1) vis.write_vtk_file("normals.vtu", [ ("normals", normals), ])
def test_vtk_overwrite(ctx_getter): pytest.importorskip("pyvisfile") def _try_write_vtk(writer, obj): import os from meshmode import FileExistsError filename = "test_vtk_overwrite.vtu" if os.path.exists(filename): os.remove(filename) writer(filename, []) with pytest.raises(FileExistsError): writer(filename, []) writer(filename, [], overwrite=True) if os.path.exists(filename): os.remove(filename) ctx = ctx_getter() queue = cl.CommandQueue(ctx) target_order = 7 from meshmode.mesh.generation import generate_torus mesh = generate_torus(10.0, 2.0, order=target_order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory discr = Discretization( queue.context, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order)) from meshmode.discretization.visualization import make_visualizer from meshmode.discretization.visualization import \ write_nodal_adjacency_vtk_file from meshmode.mesh.visualization import write_vertex_vtk_file vis = make_visualizer(queue, discr, 1) _try_write_vtk(vis.write_vtk_file, discr) _try_write_vtk( lambda x, y, **kwargs: write_vertex_vtk_file(discr.mesh, x, **kwargs), discr.mesh) _try_write_vtk( lambda x, y, **kwargs: write_nodal_adjacency_vtk_file( x, discr.mesh, **kwargs), discr.mesh)
def plot_partition_indices(actx, discr, indices, **kwargs): try: import matplotlib.pyplot as pt except ImportError: return indices = indices.get(actx.queue) args = [ kwargs.get("tree_kind", "linear").replace("-", "_"), kwargs.get("discr_stage", "stage1"), discr.ambient_dim ] pt.figure(figsize=(10, 8), dpi=300) pt.plot(np.diff(indices.ranges)) pt.savefig("test_partition_{1}_{3}d_ranges_{2}.png".format(*args)) pt.clf() from pytential.utils import flatten_to_numpy if discr.ambient_dim == 2: sources = flatten_to_numpy(actx, discr.nodes()) pt.figure(figsize=(10, 8), dpi=300) if indices.indices.shape[0] != discr.ndofs: pt.plot(sources[0], sources[1], 'ko', alpha=0.5) for i in range(indices.nblocks): isrc = indices.block_indices(i) pt.plot(sources[0][isrc], sources[1][isrc], 'o') pt.xlim([-1.5, 1.5]) pt.ylim([-1.5, 1.5]) pt.savefig("test_partition_{1}_{3}d_{2}.png".format(*args)) pt.clf() elif discr.ambient_dim == 3: from meshmode.discretization.visualization import make_visualizer marker = -42.0 * np.ones(discr.ndofs) for i in range(indices.nblocks): isrc = indices.block_indices(i) marker[isrc] = 10.0 * (i + 1.0) from meshmode.dof_array import unflatten marker = unflatten(actx, discr, actx.from_numpy(marker)) vis = make_visualizer(actx, discr, 10) filename = "test_partition_{0}_{1}_{3}d_{2}.vtu".format(*args) vis.write_vtk_file(filename, [("marker", marker)])
def test_copy_visualizer(actx_factory, ambient_dim, visualize=True): actx = actx_factory() target_order = 4 if ambient_dim == 2: nelements = 128 mesh = mgen.make_curve_mesh(partial(mgen.ellipse, 1.0), np.linspace(0.0, 1.0, nelements + 1), target_order) elif ambient_dim == 3: mesh = mgen.generate_icosphere(1.0, target_order, uniform_refinement_rounds=2) else: raise ValueError(f"unsupported dimension: {ambient_dim}") from meshmode.mesh.processing import affine_map translated_mesh = affine_map(mesh, b=np.array([2.5, 0.0, 0.0][:ambient_dim])) from meshmode.discretization import Discretization discr = Discretization(actx, mesh, PolynomialWarpAndBlendGroupFactory(target_order)) translated_discr = Discretization( actx, translated_mesh, PolynomialWarpAndBlendGroupFactory(target_order)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, target_order, force_equidistant=True) assert vis._vtk_connectivity assert vis._vtk_lagrange_connectivity translated_vis = vis.copy_with_same_connectivity(actx, translated_discr) assert translated_vis._cached_vtk_connectivity is not None assert translated_vis._cached_vtk_lagrange_connectivity is not None assert translated_vis._vtk_connectivity \ is vis._vtk_connectivity assert translated_vis._vtk_lagrange_connectivity \ is vis._vtk_lagrange_connectivity if not visualize: return vis.write_vtk_file(f"visualizer_copy_{ambient_dim}d_orig.vtu", [], overwrite=True) translated_vis.write_vtk_file( f"visualizer_copy_{ambient_dim}d_translated.vtu", [], overwrite=True)
def main(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) nel_1d = 16 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5), n=(nel_1d, nel_1d)) order = 3 # no deep meaning here, just a fudge factor dt = 0.75 / (nel_1d * order**2) print("%d elements" % mesh.nelements) discr = DGDiscretization(actx, mesh, order=order) fields = flat_obj_array(bump(actx, discr), [discr.zeros(actx) for i in range(discr.dim)]) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr.volume_discr, discr.order + 3) def rhs(t, w): return wave_operator(actx, discr, c=1, w=w) t = 0 t_final = 3 istep = 0 while t < t_final: fields = rk4_step(fields, t, dt, rhs) if istep % 10 == 0: # FIXME: Maybe an integral function to go with the # DOFArray would be nice? assert len(fields[0]) == 1 print(istep, t, la.norm(actx.to_numpy(fields[0][0]))) vis.write_vtk_file("fld-wave-min-%04d.vtu" % istep, [ ("u", fields[0]), ("v", fields[1:]), ]) t += dt istep += 1
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_vtk_overwrite(ctx_getter): pytest.importorskip("pyvisfile") def _try_write_vtk(writer, obj): import os from meshmode import FileExistsError filename = "test_vtk_overwrite.vtu" if os.path.exists(filename): os.remove(filename) writer(filename, []) with pytest.raises(FileExistsError): writer(filename, []) writer(filename, [], overwrite=True) if os.path.exists(filename): os.remove(filename) ctx = ctx_getter() queue = cl.CommandQueue(ctx) target_order = 7 from meshmode.mesh.generation import generate_torus mesh = generate_torus(10.0, 2.0, order=target_order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory discr = Discretization( queue.context, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order)) from meshmode.discretization.visualization import make_visualizer from meshmode.discretization.visualization import \ write_nodal_adjacency_vtk_file from meshmode.mesh.visualization import write_vertex_vtk_file vis = make_visualizer(queue, discr, 1) _try_write_vtk(vis.write_vtk_file, discr) _try_write_vtk(lambda x, y, **kwargs: write_vertex_vtk_file(discr.mesh, x, **kwargs), discr.mesh) _try_write_vtk(lambda x, y, **kwargs: write_nodal_adjacency_vtk_file(x, discr.mesh, **kwargs), discr.mesh)
def test_box_mesh(ctx_getter, visualize=False): from meshmode.mesh.generation import generate_box_mesh mesh = generate_box_mesh(3*(np.linspace(0, 1, 5),)) 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, mesh, PolynomialWarpAndBlendGroupFactory(1)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr, 1) vis.write_vtk_file("box.vtu", [])
def test_box_mesh(ctx_getter, visualize=False): from meshmode.mesh.generation import generate_box_mesh mesh = generate_box_mesh(3 * (np.linspace(0, 1, 5), )) 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, mesh, PolynomialWarpAndBlendGroupFactory(1)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr, 1) vis.write_vtk_file("box.vtu", [])
def _visualize_refinement(actx: PyOpenCLArrayContext, discr, niter, stage_nr, stage_name, flags, visualize=False): if not visualize: return if stage_nr not in (1, 2): raise ValueError("unexpected stage number") flags = flags.get() logger.info("for stage %s: splitting %d/%d stage-%d elements", stage_name, np.sum(flags), discr.mesh.nelements, stage_nr) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, 3) assert len(flags) == discr.mesh.nelements flags = flags.astype(bool) nodes_flags_template = discr.zeros(actx) nodes_flags = [] for grp in discr.groups: meg = grp.mesh_el_group nodes_flags_grp = actx.to_numpy(nodes_flags_template[grp.index]) nodes_flags_grp[flags[meg.element_nr_base:meg.nelements + meg.element_nr_base]] = 1 nodes_flags.append(actx.from_numpy(nodes_flags_grp)) nodes_flags = DOFArray(actx, tuple(nodes_flags)) vis_data = [ ("refine_flags", nodes_flags), ] if 0: from pytential import sym, bind bdry_normals = bind(discr, sym.normal( discr.ambient_dim))(actx).as_vector(dtype=object) vis_data.append(("bdry_normals", bdry_normals), ) vis.write_vtk_file(f"refinement-{stage_name}-{niter:03d}.vtu", vis_data)
def _visualize_quad_resolution(_places, dd, suffix): if dd.discr_stage is None: vis_discr = lpot_source.density_discr else: vis_discr = _places.get_discretization(dd.geometry, dd.discr_stage) stretch = bind(_places, sym._simplex_mapping_max_stretch_factor( _places.ambient_dim, with_elementwise_max=False), auto_where=dd)(actx) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, vis_discr, order, force_equidistant=True) vis.write_vtk_file( f"global-qbx-source-refinement-{surface_name}-{order}-{suffix}.vtu", [("stretch", stretch)], overwrite=True, use_high_order=True)
def main(): cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) nel_1d = 16 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(-0.5, -0.5), b=(0.5, 0.5), n=(nel_1d, nel_1d)) order = 3 # no deep meaning here, just a fudge factor dt = 0.75 / (nel_1d * order**2) print("%d elements" % mesh.nelements) discr = DGDiscretization(cl_ctx, mesh, order=order) fields = join_fields(bump(discr, queue), [discr.zeros(queue) for i in range(discr.dim)]) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr.volume_discr, discr.order + 3) def rhs(t, w): return wave_operator(discr, c=1, w=w) t = 0 t_final = 3 istep = 0 while t < t_final: fields = rk4_step(fields, t, dt, rhs) if istep % 10 == 0: print(istep, t, la.norm(fields[0].get())) vis.write_vtk_file("fld-wave-min-%04d.vtu" % istep, [ ("u", fields[0]), ("v", fields[1:]), ]) t += dt istep += 1
def test_vtk_overwrite(actx_factory): pytest.importorskip("pyvisfile") def _try_write_vtk(writer, obj): import os filename = "vtk_overwrite_temp.vtu" if os.path.exists(filename): os.remove(filename) writer(filename, []) with pytest.raises(FileExistsError): writer(filename, []) writer(filename, [], overwrite=True) if os.path.exists(filename): os.remove(filename) actx = actx_factory() target_order = 7 mesh = mgen.generate_torus(10.0, 2.0, order=target_order) from meshmode.discretization import Discretization discr = Discretization( actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order)) from meshmode.discretization.visualization import make_visualizer from meshmode.discretization.visualization import \ write_nodal_adjacency_vtk_file from meshmode.mesh.visualization import write_vertex_vtk_file vis = make_visualizer(actx, discr, 1) _try_write_vtk(vis.write_vtk_file, discr) _try_write_vtk( lambda x, y, **kwargs: write_vertex_vtk_file(discr.mesh, x, **kwargs), discr.mesh) _try_write_vtk( lambda x, y, **kwargs: write_nodal_adjacency_vtk_file( x, discr.mesh, **kwargs), discr.mesh)
def visualize_refinement(niter, stage_nr, stage_name, flags): if not visualize: return if stage_nr == 1: discr = lpot_source.density_discr elif stage_nr == 2: discr = lpot_source.stage2_density_discr else: raise ValueError("unexpected stage number") flags = flags.get() logger.info("for stage %s: splitting %d/%d stage-%d elements", stage_name, np.sum(flags), discr.mesh.nelements, stage_nr) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(wrangler.queue, discr, 3) assert len(flags) == discr.mesh.nelements flags = flags.astype(np.bool) nodes_flags = np.zeros(discr.nnodes) for grp in discr.groups: meg = grp.mesh_el_group grp.view(nodes_flags)[flags[meg.element_nr_base:meg.nelements + meg.element_nr_base]] = 1 nodes_flags = cl.array.to_device(wrangler.queue, nodes_flags) vis_data = [ ("refine_flags", nodes_flags), ] if 0: from pytential import sym, bind bdry_normals = bind(discr, sym.normal(discr.ambient_dim))( wrangler.queue).as_vector(dtype=object) vis_data.append(("bdry_normals", bdry_normals), ) vis.write_vtk_file("refinement-%s-%03d.vtu" % (stage_name, niter), vis_data)
def visualize_refinement(niter, stage_nr, stage_name, flags): if not visualize: return if stage_nr == 1: discr = lpot_source.density_discr elif stage_nr == 2: discr = lpot_source.stage2_density_discr else: raise ValueError("unexpected stage number") flags = flags.get() logger.info("for stage %s: splitting %d/%d stage-%d elements", stage_name, np.sum(flags), discr.mesh.nelements, stage_nr) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(wrangler.queue, discr, 3) assert len(flags) == discr.mesh.nelements flags = flags.astype(np.bool) nodes_flags = np.zeros(discr.nnodes) for grp in discr.groups: meg = grp.mesh_el_group grp.view(nodes_flags)[ flags[meg.element_nr_base:meg.nelements+meg.element_nr_base]] = 1 nodes_flags = cl.array.to_device(wrangler.queue, nodes_flags) vis_data = [ ("refine_flags", nodes_flags), ] if 0: from pytential import sym, bind bdry_normals = bind(discr, sym.normal(discr.ambient_dim))( wrangler.queue).as_vector(dtype=object) vis_data.append(("bdry_normals", bdry_normals),) vis.write_vtk_file("refinement-%s-%03d.vtu" % (stage_name, niter), vis_data)
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(): 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_3d_jump_relations(ctx_factory, relation, visualize=False): # logging.basicConfig(level=logging.INFO) cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) if relation == "div_s": target_order = 3 else: target_order = 4 qbx_order = target_order from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() for nel_factor in [6, 10, 14]: from meshmode.mesh.generation import generate_torus mesh = generate_torus( 5, 2, order=target_order, n_major=2*nel_factor, n_minor=nel_factor) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory pre_discr = Discretization( actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(3)) from pytential.qbx import QBXLayerPotentialSource qbx = QBXLayerPotentialSource( pre_discr, fine_order=4*target_order, qbx_order=qbx_order, fmm_order=qbx_order + 5, fmm_backend="fmmlib" ) places = GeometryCollection(qbx) density_discr = places.get_discretization(places.auto_source.geometry) from sumpy.kernel import LaplaceKernel knl = LaplaceKernel(3) def nxcurlS(qbx_forced_limit): return sym.n_cross(sym.curl(sym.S( knl, sym.cse(sym.tangential_to_xyz(density_sym), "jxyz"), qbx_forced_limit=qbx_forced_limit))) from meshmode.dof_array import thaw x, y, z = thaw(actx, density_discr.nodes()) m = actx.np if relation == "nxcurls": density_sym = sym.make_sym_vector("density", 2) jump_identity_sym = ( nxcurlS(+1) - (nxcurlS("avg") + 0.5*sym.tangential_to_xyz(density_sym))) # The tangential coordinate system is element-local, so we can't just # conjure up some globally smooth functions, interpret their values # in the tangential coordinate system, and be done. Instead, generate # an XYZ function and project it. density = bind(places, sym.xyz_to_tangential(sym.make_sym_vector("jxyz", 3)))( actx, jxyz=sym.make_obj_array([ m.cos(0.5*x) * m.cos(0.5*y) * m.cos(0.5*z), m.sin(0.5*x) * m.cos(0.5*y) * m.sin(0.5*z), m.sin(0.5*x) * m.cos(0.5*y) * m.cos(0.5*z), ])) elif relation == "sp": density = m.cos(2*x) * m.cos(2*y) * m.cos(z) density_sym = sym.var("density") jump_identity_sym = ( sym.Sp(knl, density_sym, qbx_forced_limit=+1) - (sym.Sp(knl, density_sym, qbx_forced_limit="avg") - 0.5*density_sym)) elif relation == "div_s": density = m.cos(2*x) * m.cos(2*y) * m.cos(z) density_sym = sym.var("density") jump_identity_sym = ( sym.div(sym.S(knl, sym.normal(3).as_vector()*density_sym, qbx_forced_limit="avg")) + sym.D(knl, density_sym, qbx_forced_limit="avg")) else: raise ValueError("unexpected value of 'relation': %s" % relation) bound_jump_identity = bind(places, jump_identity_sym) jump_identity = bound_jump_identity(actx, density=density) h_max = bind(places, sym.h_max(qbx.ambient_dim))(actx) err = ( norm(density_discr, jump_identity, np.inf) / norm(density_discr, density, np.inf)) print("ERROR", h_max, err) eoc_rec.add_data_point(h_max, err) # {{{ visualization if visualize and relation == "nxcurls": nxcurlS_ext = bind(places, nxcurlS(+1))(actx, density=density) nxcurlS_avg = bind(places, nxcurlS("avg"))(actx, density=density) jtxyz = bind(places, sym.tangential_to_xyz(density_sym))( actx, density=density) from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(actx, qbx.density_discr, target_order+3) bdry_normals = bind(places, sym.normal(3))(actx)\ .as_vector(dtype=object) bdry_vis.write_vtk_file("source-%s.vtu" % nel_factor, [ ("jt", jtxyz), ("nxcurlS_ext", nxcurlS_ext), ("nxcurlS_avg", nxcurlS_avg), ("bdry_normals", bdry_normals), ]) if visualize and relation == "sp": op = sym.Sp(knl, density_sym, qbx_forced_limit=+1) sp_ext = bind(places, op)(actx, density=density) op = sym.Sp(knl, density_sym, qbx_forced_limit="avg") sp_avg = bind(places, op)(actx, density=density) from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(actx, qbx.density_discr, target_order+3) bdry_normals = bind(places, sym.normal(3))(actx).as_vector(dtype=object) bdry_vis.write_vtk_file("source-%s.vtu" % nel_factor, [ ("density", density), ("sp_ext", sp_ext), ("sp_avg", sp_avg), ("bdry_normals", bdry_normals), ]) # }}} print(eoc_rec) assert eoc_rec.order_estimate() >= qbx_order - 1.5
def test_3d_jump_relations(ctx_factory, relation, visualize=False): # logging.basicConfig(level=logging.INFO) cl_ctx = ctx_factory() queue = cl.CommandQueue(cl_ctx) if relation == "div_s": target_order = 3 else: target_order = 4 qbx_order = target_order from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() for nel_factor in [6, 10, 14]: from meshmode.mesh.generation import generate_torus mesh = generate_torus( 5, 2, order=target_order, n_outer=2*nel_factor, n_inner=nel_factor) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory pre_discr = Discretization( cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(3)) from pytential.qbx import QBXLayerPotentialSource qbx, _ = QBXLayerPotentialSource( pre_discr, fine_order=4*target_order, qbx_order=qbx_order, fmm_order=qbx_order + 5, fmm_backend="fmmlib" ).with_refinement() from sumpy.kernel import LaplaceKernel knl = LaplaceKernel(3) def nxcurlS(qbx_forced_limit): return sym.n_cross(sym.curl(sym.S( knl, sym.cse(sym.tangential_to_xyz(density_sym), "jxyz"), qbx_forced_limit=qbx_forced_limit))) x, y, z = qbx.density_discr.nodes().with_queue(queue) m = cl.clmath if relation == "nxcurls": density_sym = sym.make_sym_vector("density", 2) jump_identity_sym = ( nxcurlS(+1) - (nxcurlS("avg") + 0.5*sym.tangential_to_xyz(density_sym))) # The tangential coordinate system is element-local, so we can't just # conjure up some globally smooth functions, interpret their values # in the tangential coordinate system, and be done. Instead, generate # an XYZ function and project it. density = bind( qbx, sym.xyz_to_tangential(sym.make_sym_vector("jxyz", 3)))( queue, jxyz=sym.make_obj_array([ m.cos(0.5*x) * m.cos(0.5*y) * m.cos(0.5*z), m.sin(0.5*x) * m.cos(0.5*y) * m.sin(0.5*z), m.sin(0.5*x) * m.cos(0.5*y) * m.cos(0.5*z), ])) elif relation == "sp": density = m.cos(2*x) * m.cos(2*y) * m.cos(z) density_sym = sym.var("density") jump_identity_sym = ( sym.Sp(knl, density_sym, qbx_forced_limit=+1) - (sym.Sp(knl, density_sym, qbx_forced_limit="avg") - 0.5*density_sym)) elif relation == "div_s": density = m.cos(2*x) * m.cos(2*y) * m.cos(z) density_sym = sym.var("density") jump_identity_sym = ( sym.div(sym.S(knl, sym.normal(3).as_vector()*density_sym, qbx_forced_limit="avg")) + sym.D(knl, density_sym, qbx_forced_limit="avg")) else: raise ValueError("unexpected value of 'relation': %s" % relation) bound_jump_identity = bind(qbx, jump_identity_sym) jump_identity = bound_jump_identity(queue, density=density) err = ( norm(qbx, queue, jump_identity, np.inf) / norm(qbx, queue, density, np.inf)) print("ERROR", qbx.h_max, err) eoc_rec.add_data_point(qbx.h_max, err) # {{{ visualization if visualize and relation == "nxcurls": nxcurlS_ext = bind(qbx, nxcurlS(+1))(queue, density=density) nxcurlS_avg = bind(qbx, nxcurlS("avg"))(queue, density=density) jtxyz = bind(qbx, sym.tangential_to_xyz(density_sym))( queue, density=density) from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(queue, qbx.density_discr, target_order+3) bdry_normals = bind(qbx, sym.normal(3))(queue)\ .as_vector(dtype=object) bdry_vis.write_vtk_file("source-%s.vtu" % nel_factor, [ ("jt", jtxyz), ("nxcurlS_ext", nxcurlS_ext), ("nxcurlS_avg", nxcurlS_avg), ("bdry_normals", bdry_normals), ]) if visualize and relation == "sp": sp_ext = bind(qbx, sym.Sp(knl, density_sym, qbx_forced_limit=+1))( queue, density=density) sp_avg = bind(qbx, sym.Sp(knl, density_sym, qbx_forced_limit="avg"))( queue, density=density) from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(queue, qbx.density_discr, target_order+3) bdry_normals = bind(qbx, sym.normal(3))(queue)\ .as_vector(dtype=object) bdry_vis.write_vtk_file("source-%s.vtu" % nel_factor, [ ("density", density), ("sp_ext", sp_ext), ("sp_avg", sp_avg), ("bdry_normals", bdry_normals), ]) # }}} print(eoc_rec) assert eoc_rec.order_estimate() >= qbx_order - 1.5
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), ])
if isinstance(kernel, HelmholtzKernel): sigma = sigma.astype(np.complex128) bound_bdry_op = bind(qbx, op) #mlab.figure(bgcolor=(1, 1, 1)) if 1: fplot = FieldPlotter(bbox_center, extent=1.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.vts", [ ("potential", fld_in_vol) ] ) bdry_normals = bind(density_discr, sym.normal())(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.vtu", [ ("sigma", sigma), ("bdry_normals", bdry_normals), ])
def refine_and_generate_chart_function(mesh, filename, function): from time import clock cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) print("NELEMENTS: ", mesh.nelements) #print mesh for i in range(len(mesh.groups[0].vertex_indices[0])): for k in range(len(mesh.vertices)): print(mesh.vertices[k, i]) #check_nodal_adj_against_geometry(mesh); r = Refiner(mesh) #random.seed(0) #times = 3 num_elements = [] time_t = [] #nelements = mesh.nelements while True: print("NELS:", mesh.nelements) #flags = get_corner_flags(mesh) flags = get_function_flags(mesh, function) nels = 0 for i in flags: if i: nels += 1 if nels == 0: break print("LKJASLFKJALKASF:", nels) num_elements.append(nels) #flags = get_corner_flags(mesh) beg = clock() mesh = r.refine(flags) end = clock() time_taken = end - beg time_t.append(time_taken) #if nelements == mesh.nelements: #break #nelements = mesh.nelements #from meshmode.mesh.visualization import draw_2d_mesh #draw_2d_mesh(mesh, True, True, True, fill=None) #import matplotlib.pyplot as pt #pt.show() #poss_flags = np.zeros(len(mesh.groups[0].vertex_indices)) #for i in range(0, len(flags)): # poss_flags[i] = flags[i] #for i in range(len(flags), len(poss_flags)): # poss_flags[i] = 1 import matplotlib.pyplot as pt pt.xlabel('Number of elements being refined') pt.ylabel('Time taken') pt.plot(num_elements, time_t, "o") pt.savefig(filename, format='pdf') pt.clf() print('DONE REFINING') ''' flags = np.zeros(len(mesh.groups[0].vertex_indices)) flags[0] = 1 flags[1] = 1 mesh = r.refine(flags) flags = np.zeros(len(mesh.groups[0].vertex_indices)) flags[0] = 1 flags[1] = 1 flags[2] = 1 mesh = r.refine(flags) ''' #check_nodal_adj_against_geometry(mesh) #r.print_rays(70) #r.print_rays(117) #r.print_hanging_elements(10) #r.print_hanging_elements(117) #r.print_hanging_elements(757) #from meshmode.mesh.visualization import draw_2d_mesh #draw_2d_mesh(mesh, False, False, False, fill=None) #import matplotlib.pyplot as pt #pt.show() from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory discr = Discretization( cl_ctx, mesh, PolynomialWarpAndBlendGroupFactory(order)) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(queue, discr, order) remove_if_exists("connectivity2.vtu") remove_if_exists("geometry2.vtu") vis.write_vtk_file("geometry2.vtu", [ ("f", discr.nodes()[0]), ]) from meshmode.discretization.visualization import \ write_nodal_adjacency_vtk_file write_nodal_adjacency_vtk_file("connectivity2.vtu", mesh)
def main(): # If can't import firedrake, do nothing # # filename MUST include "firedrake" (i.e. match *firedrake*.py) in order # to be run during CI try: import firedrake # noqa : F401 except ImportError: return 0 from meshmode.interop.firedrake import build_connection_from_firedrake from firedrake import (UnitSquareMesh, FunctionSpace, SpatialCoordinate, Function, cos) # Create a firedrake mesh and interpolate cos(x+y) onto it fd_mesh = UnitSquareMesh(10, 10) fd_fspace = FunctionSpace(fd_mesh, "DG", 2) spatial_coord = SpatialCoordinate(fd_mesh) fd_fntn = Function(fd_fspace).interpolate(cos(sum(spatial_coord))) # Make connections cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) fd_connection = build_connection_from_firedrake(actx, fd_fspace) fd_bdy_connection = \ build_connection_from_firedrake(actx, fd_fspace, restrict_to_boundary="on_boundary") # Plot the meshmode meshes that the connections connect to import matplotlib.pyplot as plt from meshmode.mesh.visualization import draw_2d_mesh fig, (ax1, ax2) = plt.subplots(1, 2) ax1.set_title("FiredrakeConnection") plt.sca(ax1) draw_2d_mesh(fd_connection.discr.mesh, draw_vertex_numbers=False, draw_element_numbers=False, set_bounding_box=True) ax2.set_title("FiredrakeConnection 'on_boundary'") plt.sca(ax2) draw_2d_mesh(fd_bdy_connection.discr.mesh, draw_vertex_numbers=False, draw_element_numbers=False, set_bounding_box=True) plt.show() # Plot fd_fntn using unrestricted FiredrakeConnection from meshmode.discretization.visualization import make_visualizer discr = fd_connection.discr vis = make_visualizer(actx, discr, discr.groups[0].order + 3) field = fd_connection.from_firedrake(fd_fntn, actx=actx) fig = plt.figure() ax1 = fig.add_subplot(1, 2, 1, projection="3d") ax1.set_title("cos(x+y) in\nFiredrakeConnection") vis.show_scalar_in_matplotlib_3d(field, do_show=False) # Now repeat using FiredrakeConnection restricted to "on_boundary" bdy_discr = fd_bdy_connection.discr bdy_vis = make_visualizer(actx, bdy_discr, bdy_discr.groups[0].order + 3) bdy_field = fd_bdy_connection.from_firedrake(fd_fntn, actx=actx) ax2 = fig.add_subplot(1, 2, 2, projection="3d") plt.sca(ax2) ax2.set_title("cos(x+y) in\nFiredrakeConnection 'on_boundary'") bdy_vis.show_scalar_in_matplotlib_3d(bdy_field, do_show=False) import matplotlib.cm as cm fig.colorbar(cm.ScalarMappable()) plt.show()
def test_sanity_single_element(ctx_getter, dim, order, visualize=False): pytest.importorskip("pytential") cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) from modepy.tools import unit_vertices vertices = unit_vertices(dim).T.copy() center = np.empty(dim, np.float64) center.fill(-0.5) import modepy as mp from meshmode.mesh import SimplexElementGroup, Mesh, BTAG_ALL mg = SimplexElementGroup( order=order, vertex_indices=np.arange(dim + 1, dtype=np.int32).reshape(1, -1), nodes=mp.warp_and_blend_nodes(dim, order).reshape(dim, 1, -1), dim=dim) mesh = Mesh(vertices, [mg], nodal_adjacency=None, facial_adjacency_groups=None) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory vol_discr = Discretization(cl_ctx, mesh, PolynomialWarpAndBlendGroupFactory(order + 3)) # {{{ volume calculation check vol_x = vol_discr.nodes().with_queue(queue) vol_one = vol_x[0].copy() vol_one.fill(1) from pytential import norm, integral # noqa from pytools import factorial true_vol = 1 / factorial(dim) * 2**dim comp_vol = integral(vol_discr, queue, vol_one) rel_vol_err = abs(true_vol - comp_vol) / true_vol assert rel_vol_err < 1e-12 # }}} # {{{ boundary discretization from meshmode.discretization.connection import make_face_restriction bdry_connection = make_face_restriction( vol_discr, PolynomialWarpAndBlendGroupFactory(order + 3), BTAG_ALL) bdry_discr = bdry_connection.to_discr # }}} # {{{ visualizers from meshmode.discretization.visualization import make_visualizer #vol_vis = make_visualizer(queue, vol_discr, 4) bdry_vis = make_visualizer(queue, bdry_discr, 4) # }}} from pytential import bind, sym bdry_normals = bind(bdry_discr, sym.normal(dim))(queue).as_vector(dtype=object) if visualize: bdry_vis.write_vtk_file("boundary.vtu", [("bdry_normals", bdry_normals)]) from pytential import bind, sym normal_outward_check = bind( bdry_discr, sym.normal(dim) | (sym.nodes(dim) + 0.5 * sym.ones_vec(dim)), )(queue).as_scalar() > 0 assert normal_outward_check.get().all(), normal_outward_check.get()
def test_refinement_connection( ctx_getter, refiner_cls, group_factory, mesh_name, dim, mesh_pars, mesh_order, refine_flags, visualize=False): from random import seed seed(13) # Discretization order order = 5 cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) from meshmode.discretization import Discretization from meshmode.discretization.connection import ( make_refinement_connection, check_connection) from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() for mesh_par in mesh_pars: # {{{ get mesh if mesh_name == "circle": assert dim == 1 h = 1 / mesh_par mesh = make_curve_mesh( partial(ellipse, 1), np.linspace(0, 1, mesh_par + 1), order=mesh_order) elif mesh_name == "blob": if mesh_order == 5: pytest.xfail("https://gitlab.tiker.net/inducer/meshmode/issues/2") assert dim == 2 mesh = get_blob_mesh(mesh_par, mesh_order) h = float(mesh_par) elif mesh_name == "warp": from meshmode.mesh.generation import generate_warped_rect_mesh mesh = generate_warped_rect_mesh(dim, order=mesh_order, n=mesh_par) h = 1/mesh_par else: raise ValueError("mesh_name not recognized") # }}} from meshmode.mesh.processing import find_bounding_box mesh_bbox_low, mesh_bbox_high = find_bounding_box(mesh) mesh_ext = mesh_bbox_high-mesh_bbox_low def f(x): result = 1 if mesh_name == "blob": factor = 15 else: factor = 9 for iaxis in range(len(x)): result = result * cl.clmath.sin(factor * (x[iaxis]/mesh_ext[iaxis])) return result discr = Discretization(cl_ctx, mesh, group_factory(order)) refiner = refiner_cls(mesh) flags = refine_flags(mesh) refiner.refine(flags) connection = make_refinement_connection( refiner, discr, group_factory(order)) check_connection(connection) fine_discr = connection.to_discr x = discr.nodes().with_queue(queue) x_fine = fine_discr.nodes().with_queue(queue) f_coarse = f(x) f_interp = connection(queue, f_coarse).with_queue(queue) f_true = f(x_fine).with_queue(queue) if visualize == "dots": import matplotlib.pyplot as plt x = x.get(queue) err = np.array(np.log10( 1e-16 + np.abs((f_interp - f_true).get(queue))), dtype=float) import matplotlib.cm as cm cmap = cm.ScalarMappable(cmap=cm.jet) cmap.set_array(err) plt.scatter(x[0], x[1], c=cmap.to_rgba(err), s=20, cmap=cmap) plt.colorbar(cmap) plt.show() elif visualize == "vtk": from meshmode.discretization.visualization import make_visualizer fine_vis = make_visualizer(queue, fine_discr, mesh_order) fine_vis.write_vtk_file( "refine-fine-%s-%dd-%s.vtu" % (mesh_name, dim, mesh_par), [ ("f_interp", f_interp), ("f_true", f_true), ]) import numpy.linalg as la err = la.norm((f_interp - f_true).get(queue), np.inf) eoc_rec.add_data_point(h, err) order_slack = 0.5 if mesh_name == "blob" and order > 1: order_slack = 1 print(eoc_rec) assert ( eoc_rec.order_estimate() >= order-order_slack or eoc_rec.max_error() < 1e-14)
def main(): import logging logging.basicConfig(level=logging.WARNING) # INFO for more progress info cl_ctx = cl.create_some_context() queue = cl.CommandQueue(cl_ctx) from meshmode.mesh.generation import generate_torus rout = 10 rin = 1 if 1: base_mesh = generate_torus( rout, rin, 40, 4, mesh_order) from meshmode.mesh.processing import affine_map, merge_disjoint_meshes # nx = 1 # ny = 1 nz = 1 dz = 0 meshes = [ affine_map( base_mesh, A=np.diag([1, 1, 1]), b=np.array([0, 0, iz*dz])) for iz in range(nz)] mesh = merge_disjoint_meshes(meshes, single_group=True) if 0: from meshmode.mesh.visualization import draw_curve draw_curve(mesh) import matplotlib.pyplot as plt plt.show() pre_density_discr = Discretization( cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(bdry_quad_order)) from pytential.qbx import ( QBXLayerPotentialSource, QBXTargetAssociationFailedException) qbx, _ = QBXLayerPotentialSource( pre_density_discr, fine_order=bdry_ovsmp_quad_order, qbx_order=qbx_order, fmm_order=fmm_order ).with_refinement() density_discr = qbx.density_discr # {{{ describe bvp from sumpy.kernel import LaplaceKernel kernel = LaplaceKernel(3) cse = sym.cse sigma_sym = sym.var("sigma") #sqrt_w = sym.sqrt_jac_q_weight(3) sqrt_w = 1 inv_sqrt_w_sigma = cse(sigma_sym/sqrt_w) # -1 for interior Dirichlet # +1 for exterior Dirichlet loc_sign = +1 bdry_op_sym = (loc_sign*0.5*sigma_sym + sqrt_w*( sym.S(kernel, inv_sqrt_w_sigma) + sym.D(kernel, inv_sqrt_w_sigma) )) # }}} bound_op = bind(qbx, bdry_op_sym) # {{{ fix rhs and solve nodes = density_discr.nodes().with_queue(queue) source = np.array([rout, 0, 0]) def u_incoming_func(x): # return 1/cl.clmath.sqrt( (x[0] - source[0])**2 # +(x[1] - source[1])**2 # +(x[2] - source[2])**2 ) return 1.0/la.norm(x.get()-source[:, None], axis=0) bc = cl.array.to_device(queue, u_incoming_func(nodes)) bvp_rhs = bind(qbx, sqrt_w*sym.var("bc"))(queue, bc=bc) from pytential.solve import gmres gmres_result = gmres( bound_op.scipy_op(queue, "sigma", dtype=np.float64), bvp_rhs, tol=1e-14, progress=True, stall_iterations=0, hard_failure=True) sigma = bind(qbx, sym.var("sigma")/sqrt_w)(queue, sigma=gmres_result.solution) # }}} from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(queue, density_discr, 20) bdry_vis.write_vtk_file("laplace.vtu", [ ("sigma", sigma), ]) # {{{ postprocess/visualize repr_kwargs = dict(qbx_forced_limit=None) representation_sym = ( sym.S(kernel, inv_sqrt_w_sigma, **repr_kwargs) + sym.D(kernel, inv_sqrt_w_sigma, **repr_kwargs)) from sumpy.visualization import FieldPlotter fplot = FieldPlotter(np.zeros(3), extent=20, npoints=50) targets = cl.array.to_device(queue, fplot.points) qbx_stick_out = qbx.copy(target_stick_out_factor=0.2) try: fld_in_vol = bind( (qbx_stick_out, PointsTarget(targets)), representation_sym)(queue, sigma=sigma).get() except QBXTargetAssociationFailedException as e: fplot.write_vtk_file( "failed-targets.vts", [ ("failed", e.failed_target_flags.get(queue)) ] ) raise #fplot.show_scalar_in_mayavi(fld_in_vol.real, max_val=5) fplot.write_vtk_file( "potential-laplace-3d.vts", [ ("potential", fld_in_vol), ] )
def test_interaction_points(ctx_factory, ndim, factor, visualize=False): ctx = ctx_factory() queue = cl.CommandQueue(ctx) qbx = _build_qbx_discr(queue, ndim=ndim) srcindices = _build_block_index(qbx.density_discr, method='nodes', factor=factor) # generate proxy points from pytential.linalg.proxy import ProxyGenerator generator = ProxyGenerator(qbx) _, _, pxycenters, pxyradii = generator(queue, srcindices) from pytential.linalg.proxy import ( # noqa gather_block_neighbor_points, gather_block_interaction_points) nbrindices = gather_block_neighbor_points(qbx.density_discr, srcindices, pxycenters, pxyradii) nodes, ranges = gather_block_interaction_points(qbx, srcindices) srcindices = srcindices.get(queue) nbrindices = nbrindices.get(queue) for i in range(srcindices.nblocks): isrc = srcindices.block_indices(i) inbr = nbrindices.block_indices(i) assert not np.any(np.isin(inbr, isrc)) if visualize: if ndim == 2: import matplotlib.pyplot as pt density_nodes = qbx.density_discr.nodes().get(queue) nodes = nodes.get(queue) ranges = ranges.get(queue) for i in range(srcindices.nblocks): isrc = srcindices.block_indices(i) inbr = nbrindices.block_indices(i) iall = np.s_[ranges[i]:ranges[i + 1]] pt.figure(figsize=(10, 8)) pt.plot(density_nodes[0], density_nodes[1], 'ko', ms=2.0, alpha=0.5) pt.plot(density_nodes[0, srcindices.indices], density_nodes[1, srcindices.indices], 'o', ms=2.0) pt.plot(density_nodes[0, isrc], density_nodes[1, isrc], 'o', ms=2.0) pt.plot(density_nodes[0, inbr], density_nodes[1, inbr], 'o', ms=2.0) pt.plot(nodes[0, iall], nodes[1, iall], 'x', ms=2.0) pt.xlim([-1.5, 1.5]) pt.ylim([-1.5, 1.5]) filename = "test_area_query_{}d_{:04}.png".format(ndim, i) pt.savefig(filename, dpi=300) pt.clf() elif ndim == 3: from meshmode.discretization.visualization import make_visualizer marker = np.empty(qbx.density_discr.nnodes) for i in range(srcindices.nblocks): isrc = srcindices.block_indices(i) inbr = nbrindices.block_indices(i) # TODO: some way to turn off some of the interpolations # would help visualize this better. marker.fill(0.0) marker[srcindices.indices] = 0.0 marker[isrc] = -42.0 marker[inbr] = +42.0 marker_dev = cl.array.to_device(queue, marker) vis = make_visualizer(queue, qbx.density_discr, 10) filename = "test_area_query_{}d_{:04}.vtu".format(ndim, i) if os.path.isfile(filename): os.remove(filename) vis.write_vtk_file(filename, [ ("marker", marker_dev), ])
def test_proxy_generator(ctx_factory, ndim, factor, visualize=False): ctx = ctx_factory() queue = cl.CommandQueue(ctx) qbx = _build_qbx_discr(queue, ndim=ndim) srcindices = _build_block_index(qbx.density_discr, method='nodes', factor=factor) from pytential.linalg.proxy import ProxyGenerator generator = ProxyGenerator(qbx, ratio=1.1) proxies, pxyranges, pxycenters, pxyradii = generator(queue, srcindices) proxies = np.vstack([p.get() for p in proxies]) pxyranges = pxyranges.get() pxycenters = np.vstack([c.get() for c in pxycenters]) pxyradii = pxyradii.get() for i in range(srcindices.nblocks): ipxy = np.s_[pxyranges[i]:pxyranges[i + 1]] r = la.norm(proxies[:, ipxy] - pxycenters[:, i].reshape(-1, 1), axis=0) assert np.allclose(r - pxyradii[i], 0.0, atol=1.0e-14) srcindices = srcindices.get(queue) if visualize: if qbx.ambient_dim == 2: import matplotlib.pyplot as pt from pytential.qbx.utils import get_centers_on_side density_nodes = qbx.density_discr.nodes().get(queue) ci = get_centers_on_side(qbx, -1) ci = np.vstack([c.get(queue) for c in ci]) ce = get_centers_on_side(qbx, +1) ce = np.vstack([c.get(queue) for c in ce]) r = qbx._expansion_radii("nsources").get(queue) for i in range(srcindices.nblocks): isrc = srcindices.block_indices(i) ipxy = np.s_[pxyranges[i]:pxyranges[i + 1]] pt.figure(figsize=(10, 8)) axis = pt.gca() for j in isrc: c = pt.Circle(ci[:, j], r[j], color='k', alpha=0.1) axis.add_artist(c) c = pt.Circle(ce[:, j], r[j], color='k', alpha=0.1) axis.add_artist(c) pt.plot(density_nodes[0], density_nodes[1], 'ko', ms=2.0, alpha=0.5) pt.plot(density_nodes[0, srcindices.indices], density_nodes[1, srcindices.indices], 'o', ms=2.0) pt.plot(density_nodes[0, isrc], density_nodes[1, isrc], 'o', ms=2.0) pt.plot(proxies[0, ipxy], proxies[1, ipxy], 'o', ms=2.0) pt.xlim([-1.5, 1.5]) pt.ylim([-1.5, 1.5]) filename = "test_proxy_generator_{}d_{:04}.png".format(ndim, i) pt.savefig(filename, dpi=300) pt.clf() else: from meshmode.discretization.visualization import make_visualizer from meshmode.mesh.processing import ( # noqa affine_map, merge_disjoint_meshes) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory from meshmode.mesh.generation import generate_icosphere ref_mesh = generate_icosphere(1, generator.nproxy) # NOTE: this does not plot the actual proxy points for i in range(srcindices.nblocks): mesh = affine_map(ref_mesh, A=(pxyradii[i] * np.eye(ndim)), b=pxycenters[:, i].reshape(-1)) mesh = merge_disjoint_meshes([mesh, qbx.density_discr.mesh]) discr = Discretization(ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(10)) vis = make_visualizer(queue, discr, 10) filename = "test_proxy_generator_{}d_{:04}.vtu".format(ndim, i) if os.path.isfile(filename): os.remove(filename) vis.write_vtk_file(filename, [])
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_sanity_single_element(ctx_getter, dim, order, visualize=False): pytest.importorskip("pytential") cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) from modepy.tools import UNIT_VERTICES vertices = UNIT_VERTICES[dim].T.copy() center = np.empty(dim, np.float64) center.fill(-0.5) import modepy as mp from meshmode.mesh import SimplexElementGroup, Mesh mg = SimplexElementGroup( order=order, vertex_indices=np.arange(dim+1, dtype=np.int32).reshape(1, -1), nodes=mp.warp_and_blend_nodes(dim, order).reshape(dim, 1, -1), dim=dim) mesh = Mesh(vertices, [mg]) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ PolynomialWarpAndBlendGroupFactory vol_discr = Discretization(cl_ctx, mesh, PolynomialWarpAndBlendGroupFactory(order+3)) # {{{ volume calculation check vol_x = vol_discr.nodes().with_queue(queue) vol_one = vol_x[0].copy() vol_one.fill(1) from pytential import norm, integral # noqa from pytools import factorial true_vol = 1/factorial(dim) * 2**dim comp_vol = integral(vol_discr, queue, vol_one) rel_vol_err = abs(true_vol - comp_vol) / true_vol assert rel_vol_err < 1e-12 # }}} # {{{ boundary discretization from meshmode.discretization.connection import make_boundary_restriction bdry_mesh, bdry_discr, bdry_connection = make_boundary_restriction( queue, vol_discr, PolynomialWarpAndBlendGroupFactory(order + 3)) # }}} # {{{ visualizers from meshmode.discretization.visualization import make_visualizer #vol_vis = make_visualizer(queue, vol_discr, 4) bdry_vis = make_visualizer(queue, bdry_discr, 4) # }}} from pytential import bind, sym bdry_normals = bind(bdry_discr, sym.normal())(queue).as_vector(dtype=object) if visualize: bdry_vis.write_vtk_file("boundary.vtu", [ ("bdry_normals", bdry_normals) ]) from pytential import bind, sym normal_outward_check = bind(bdry_discr, sym.normal() | (sym.Nodes() + 0.5*sym.ones_vec(dim)), )(queue).as_scalar() > 0 assert normal_outward_check.get().all(), normal_outward_check.get()
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_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 run_int_eq_test(cl_ctx, queue, case, resolution, visualize): mesh = case.get_mesh(resolution, case.target_order) print("%d elements" % mesh.nelements) from pytential.qbx import QBXLayerPotentialSource from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory pre_density_discr = Discretization( cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(case.target_order)) source_order = 4*case.target_order refiner_extra_kwargs = {} qbx_lpot_kwargs = {} if case.fmm_backend is None: qbx_lpot_kwargs["fmm_order"] = False else: if hasattr(case, "fmm_tol"): from sumpy.expansion.level_to_order import SimpleExpansionOrderFinder qbx_lpot_kwargs["fmm_level_to_order"] = SimpleExpansionOrderFinder( case.fmm_tol) elif hasattr(case, "fmm_order"): qbx_lpot_kwargs["fmm_order"] = case.fmm_order else: qbx_lpot_kwargs["fmm_order"] = case.qbx_order + 5 qbx = QBXLayerPotentialSource( pre_density_discr, fine_order=source_order, qbx_order=case.qbx_order, _box_extent_norm=getattr(case, "box_extent_norm", None), _from_sep_smaller_crit=getattr(case, "from_sep_smaller_crit", None), _from_sep_smaller_min_nsources_cumul=30, fmm_backend=case.fmm_backend, **qbx_lpot_kwargs) if case.use_refinement: if case.k != 0 and getattr(case, "refine_on_helmholtz_k", True): refiner_extra_kwargs["kernel_length_scale"] = 5/case.k if hasattr(case, "scaled_max_curvature_threshold"): refiner_extra_kwargs["_scaled_max_curvature_threshold"] = \ case.scaled_max_curvature_threshold if hasattr(case, "expansion_disturbance_tolerance"): refiner_extra_kwargs["_expansion_disturbance_tolerance"] = \ case.expansion_disturbance_tolerance if hasattr(case, "refinement_maxiter"): refiner_extra_kwargs["maxiter"] = case.refinement_maxiter #refiner_extra_kwargs["visualize"] = True print("%d elements before refinement" % pre_density_discr.mesh.nelements) qbx, _ = qbx.with_refinement(**refiner_extra_kwargs) print("%d stage-1 elements after refinement" % qbx.density_discr.mesh.nelements) print("%d stage-2 elements after refinement" % qbx.stage2_density_discr.mesh.nelements) print("quad stage-2 elements have %d nodes" % qbx.quad_stage2_density_discr.groups[0].nunit_nodes) density_discr = qbx.density_discr if hasattr(case, "visualize_geometry") and case.visualize_geometry: bdry_normals = bind( density_discr, sym.normal(mesh.ambient_dim) )(queue).as_vector(dtype=object) bdry_vis = make_visualizer(queue, density_discr, case.target_order) bdry_vis.write_vtk_file("geometry.vtu", [ ("normals", bdry_normals) ]) # {{{ plot geometry if 0: if mesh.ambient_dim == 2: # show geometry, centers, normals nodes_h = density_discr.nodes().get(queue=queue) pt.plot(nodes_h[0], nodes_h[1], "x-") normal = bind(density_discr, sym.normal(2))(queue).as_vector(np.object) pt.quiver(nodes_h[0], nodes_h[1], normal[0].get(queue), normal[1].get(queue)) pt.gca().set_aspect("equal") pt.show() elif mesh.ambient_dim == 3: bdry_vis = make_visualizer(queue, density_discr, case.target_order+3) bdry_normals = bind(density_discr, sym.normal(3))(queue)\ .as_vector(dtype=object) bdry_vis.write_vtk_file("pre-solve-source-%s.vtu" % resolution, [ ("bdry_normals", bdry_normals), ]) else: raise ValueError("invalid mesh dim") # }}} # {{{ set up operator from pytential.symbolic.pde.scalar import ( DirichletOperator, NeumannOperator) from sumpy.kernel import LaplaceKernel, HelmholtzKernel if case.k: knl = HelmholtzKernel(mesh.ambient_dim) knl_kwargs = {"k": sym.var("k")} concrete_knl_kwargs = {"k": case.k} else: knl = LaplaceKernel(mesh.ambient_dim) knl_kwargs = {} concrete_knl_kwargs = {} if knl.is_complex_valued: dtype = np.complex128 else: dtype = np.float64 loc_sign = +1 if case.prob_side in [+1, "scat"] else -1 if case.bc_type == "dirichlet": op = DirichletOperator(knl, loc_sign, use_l2_weighting=True, kernel_arguments=knl_kwargs) elif case.bc_type == "neumann": op = NeumannOperator(knl, loc_sign, use_l2_weighting=True, use_improved_operator=False, kernel_arguments=knl_kwargs) else: assert False op_u = op.operator(sym.var("u")) # }}} # {{{ set up test data if case.prob_side == -1: test_src_geo_radius = case.outer_radius test_tgt_geo_radius = case.inner_radius elif case.prob_side == +1: test_src_geo_radius = case.inner_radius test_tgt_geo_radius = case.outer_radius elif case.prob_side == "scat": test_src_geo_radius = case.outer_radius test_tgt_geo_radius = case.outer_radius else: raise ValueError("unknown problem_side") point_sources = make_circular_point_group( mesh.ambient_dim, 10, test_src_geo_radius, func=lambda x: x**1.5) test_targets = make_circular_point_group( mesh.ambient_dim, 20, test_tgt_geo_radius) np.random.seed(22) source_charges = np.random.randn(point_sources.shape[1]) source_charges[-1] = -np.sum(source_charges[:-1]) source_charges = source_charges.astype(dtype) assert np.sum(source_charges) < 1e-15 source_charges_dev = cl.array.to_device(queue, source_charges) # }}} # {{{ establish BCs from pytential.source import PointPotentialSource from pytential.target import PointsTarget point_source = PointPotentialSource(cl_ctx, point_sources) pot_src = sym.IntG( # FIXME: qbx_forced_limit--really? knl, sym.var("charges"), qbx_forced_limit=None, **knl_kwargs) test_direct = bind((point_source, PointsTarget(test_targets)), pot_src)( queue, charges=source_charges_dev, **concrete_knl_kwargs) if case.bc_type == "dirichlet": bc = bind((point_source, density_discr), pot_src)( queue, charges=source_charges_dev, **concrete_knl_kwargs) elif case.bc_type == "neumann": bc = bind( (point_source, density_discr), sym.normal_derivative( qbx.ambient_dim, pot_src, where=sym.DEFAULT_TARGET) )(queue, charges=source_charges_dev, **concrete_knl_kwargs) # }}} # {{{ solve bound_op = bind(qbx, op_u) rhs = bind(density_discr, op.prepare_rhs(sym.var("bc")))(queue, bc=bc) try: from pytential.solve import gmres gmres_result = gmres( bound_op.scipy_op(queue, "u", dtype, **concrete_knl_kwargs), rhs, tol=case.gmres_tol, progress=True, hard_failure=True, stall_iterations=50, no_progress_factor=1.05) except QBXTargetAssociationFailedException as e: bdry_vis = make_visualizer(queue, density_discr, case.target_order+3) bdry_vis.write_vtk_file("failed-targets-%s.vtu" % resolution, [ ("failed_targets", e.failed_target_flags), ]) raise print("gmres state:", gmres_result.state) weighted_u = gmres_result.solution # }}} # {{{ build matrix for spectrum check if 0: from sumpy.tools import build_matrix mat = build_matrix( bound_op.scipy_op( queue, arg_name="u", dtype=dtype, k=case.k)) w, v = la.eig(mat) if 0: pt.imshow(np.log10(1e-20+np.abs(mat))) pt.colorbar() pt.show() #assert abs(s[-1]) < 1e-13, "h #assert abs(s[-2]) > 1e-7 #from pudb import set_trace; set_trace() # }}} if case.prob_side != "scat": # {{{ error check points_target = PointsTarget(test_targets) bound_tgt_op = bind((qbx, points_target), op.representation(sym.var("u"))) test_via_bdry = bound_tgt_op(queue, u=weighted_u, k=case.k) err = test_via_bdry - test_direct err = err.get() test_direct = test_direct.get() test_via_bdry = test_via_bdry.get() # {{{ remove effect of net source charge if case.k == 0 and case.bc_type == "neumann" and loc_sign == -1: # remove constant offset in interior Laplace Neumann error tgt_ones = np.ones_like(test_direct) tgt_ones = tgt_ones/la.norm(tgt_ones) err = err - np.vdot(tgt_ones, err)*tgt_ones # }}} rel_err_2 = la.norm(err)/la.norm(test_direct) rel_err_inf = la.norm(err, np.inf)/la.norm(test_direct, np.inf) # }}} print("rel_err_2: %g rel_err_inf: %g" % (rel_err_2, rel_err_inf)) else: rel_err_2 = None rel_err_inf = None # {{{ test gradient if case.check_gradient and case.prob_side != "scat": bound_grad_op = bind((qbx, points_target), op.representation( sym.var("u"), map_potentials=lambda pot: sym.grad(mesh.ambient_dim, pot), qbx_forced_limit=None)) #print(bound_t_deriv_op.code) grad_from_src = bound_grad_op( queue, u=weighted_u, **concrete_knl_kwargs) grad_ref = (bind( (point_source, points_target), sym.grad(mesh.ambient_dim, pot_src) )(queue, charges=source_charges_dev, **concrete_knl_kwargs) ) grad_err = (grad_from_src - grad_ref) rel_grad_err_inf = ( la.norm(grad_err[0].get(), np.inf) / la.norm(grad_ref[0].get(), np.inf)) print("rel_grad_err_inf: %g" % rel_grad_err_inf) # }}} # {{{ test tangential derivative if case.check_tangential_deriv and case.prob_side != "scat": bound_t_deriv_op = bind(qbx, op.representation( sym.var("u"), map_potentials=lambda pot: sym.tangential_derivative(2, pot), qbx_forced_limit=loc_sign)) #print(bound_t_deriv_op.code) tang_deriv_from_src = bound_t_deriv_op( queue, u=weighted_u, **concrete_knl_kwargs).as_scalar().get() tang_deriv_ref = (bind( (point_source, density_discr), sym.tangential_derivative(2, pot_src) )(queue, charges=source_charges_dev, **concrete_knl_kwargs) .as_scalar().get()) if 0: pt.plot(tang_deriv_ref.real) pt.plot(tang_deriv_from_src.real) pt.show() td_err = (tang_deriv_from_src - tang_deriv_ref) rel_td_err_inf = la.norm(td_err, np.inf)/la.norm(tang_deriv_ref, np.inf) print("rel_td_err_inf: %g" % rel_td_err_inf) else: rel_td_err_inf = None # }}} # {{{ any-D file plotting if visualize: bdry_vis = make_visualizer(queue, density_discr, case.target_order+3) bdry_normals = bind(density_discr, sym.normal(qbx.ambient_dim))(queue)\ .as_vector(dtype=object) sym_sqrt_j = sym.sqrt_jac_q_weight(density_discr.ambient_dim) u = bind(density_discr, sym.var("u")/sym_sqrt_j)(queue, u=weighted_u) bdry_vis.write_vtk_file("source-%s.vtu" % resolution, [ ("u", u), ("bc", bc), #("bdry_normals", bdry_normals), ]) from sumpy.visualization import make_field_plotter_from_bbox # noqa from meshmode.mesh.processing import find_bounding_box vis_grid_spacing = (0.1, 0.1, 0.1)[:qbx.ambient_dim] if hasattr(case, "vis_grid_spacing"): vis_grid_spacing = case.vis_grid_spacing vis_extend_factor = 0.2 if hasattr(case, "vis_extend_factor"): vis_grid_spacing = case.vis_grid_spacing fplot = make_field_plotter_from_bbox( find_bounding_box(mesh), h=vis_grid_spacing, extend_factor=vis_extend_factor) qbx_tgt_tol = qbx.copy(target_association_tolerance=0.15) from pytential.target import PointsTarget try: solved_pot = bind( (qbx_tgt_tol, PointsTarget(fplot.points)), op.representation(sym.var("u")) )(queue, u=weighted_u, k=case.k) except QBXTargetAssociationFailedException as e: fplot.write_vtk_file( "failed-targets.vts", [ ("failed_targets", e.failed_target_flags.get(queue)) ]) raise from sumpy.kernel import LaplaceKernel ones_density = density_discr.zeros(queue) ones_density.fill(1) indicator = bind( (qbx_tgt_tol, PointsTarget(fplot.points)), -sym.D(LaplaceKernel(density_discr.ambient_dim), sym.var("sigma"), qbx_forced_limit=None))( queue, sigma=ones_density).get() solved_pot = solved_pot.get() true_pot = bind((point_source, PointsTarget(fplot.points)), pot_src)( queue, charges=source_charges_dev, **concrete_knl_kwargs).get() #fplot.show_scalar_in_mayavi(solved_pot.real, max_val=5) if case.prob_side == "scat": fplot.write_vtk_file( "potential-%s.vts" % resolution, [ ("pot_scattered", solved_pot), ("pot_incoming", -true_pot), ("indicator", indicator), ] ) else: fplot.write_vtk_file( "potential-%s.vts" % resolution, [ ("solved_pot", solved_pot), ("true_pot", true_pot), ("indicator", indicator), ] ) # }}} class Result(Record): pass return Result( h_max=qbx.h_max, rel_err_2=rel_err_2, rel_err_inf=rel_err_inf, rel_td_err_inf=rel_td_err_inf, gmres_result=gmres_result)
def test_pec_mfie_extinction(ctx_getter, case, visualize=False): """For (say) is_interior=False (the 'exterior' MFIE), this test verifies extinction of the combined (incoming + scattered) field on the interior of the scatterer. """ logging.basicConfig(level=logging.INFO) cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) np.random.seed(12) knl_kwargs = {"k": case.k} # {{{ come up with a solution to Maxwell's equations j_sym = sym.make_sym_vector("j", 3) jt_sym = sym.make_sym_vector("jt", 2) rho_sym = sym.var("rho") from pytential.symbolic.pde.maxwell import ( PECChargeCurrentMFIEOperator, get_sym_maxwell_point_source, get_sym_maxwell_plane_wave) mfie = PECChargeCurrentMFIEOperator() test_source = case.get_source(queue) calc_patch = CalculusPatch(np.array([-3, 0, 0]), h=0.01) calc_patch_tgt = PointsTarget(cl.array.to_device(queue, calc_patch.points)) rng = cl.clrandom.PhiloxGenerator(cl_ctx, seed=12) src_j = rng.normal(queue, (3, test_source.nnodes), dtype=np.float64) def eval_inc_field_at(tgt): if 0: # plane wave return bind( tgt, get_sym_maxwell_plane_wave( amplitude_vec=np.array([1, 1, 1]), v=np.array([1, 0, 0]), omega=case.k) )(queue) else: # point source return bind( (test_source, tgt), get_sym_maxwell_point_source(mfie.kernel, j_sym, mfie.k) )(queue, j=src_j, k=case.k) pde_test_inc = EHField( vector_from_device(queue, eval_inc_field_at(calc_patch_tgt))) source_maxwell_resids = [ calc_patch.norm(x, np.inf) / calc_patch.norm(pde_test_inc.e, np.inf) for x in frequency_domain_maxwell( calc_patch, pde_test_inc.e, pde_test_inc.h, case.k)] print("Source Maxwell residuals:", source_maxwell_resids) assert max(source_maxwell_resids) < 1e-6 # }}} loc_sign = -1 if case.is_interior else +1 from pytools.convergence import EOCRecorder eoc_rec_repr_maxwell = EOCRecorder() eoc_pec_bc = EOCRecorder() eoc_rec_e = EOCRecorder() eoc_rec_h = EOCRecorder() from pytential.qbx import QBXLayerPotentialSource from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory from sumpy.expansion.level_to_order import SimpleExpansionOrderFinder for resolution in case.resolutions: scat_mesh = case.get_mesh(resolution, case.target_order) observation_mesh = case.get_observation_mesh(case.target_order) pre_scat_discr = Discretization( cl_ctx, scat_mesh, InterpolatoryQuadratureSimplexGroupFactory(case.target_order)) qbx, _ = QBXLayerPotentialSource( pre_scat_discr, fine_order=4*case.target_order, qbx_order=case.qbx_order, fmm_level_to_order=SimpleExpansionOrderFinder( case.fmm_tolerance), fmm_backend=case.fmm_backend ).with_refinement(_expansion_disturbance_tolerance=0.05) h_max = qbx.h_max scat_discr = qbx.density_discr obs_discr = Discretization( cl_ctx, observation_mesh, InterpolatoryQuadratureSimplexGroupFactory(case.target_order)) inc_field_scat = EHField(eval_inc_field_at(scat_discr)) inc_field_obs = EHField(eval_inc_field_at(obs_discr)) # {{{ system solve inc_xyz_sym = EHField(sym.make_sym_vector("inc_fld", 6)) bound_j_op = bind(qbx, mfie.j_operator(loc_sign, jt_sym)) j_rhs = bind(qbx, mfie.j_rhs(inc_xyz_sym.h))( queue, inc_fld=inc_field_scat.field, **knl_kwargs) gmres_settings = dict( tol=case.gmres_tol, progress=True, hard_failure=True, stall_iterations=50, no_progress_factor=1.05) from pytential.solve import gmres gmres_result = gmres( bound_j_op.scipy_op(queue, "jt", np.complex128, **knl_kwargs), j_rhs, **gmres_settings) jt = gmres_result.solution bound_rho_op = bind(qbx, mfie.rho_operator(loc_sign, rho_sym)) rho_rhs = bind(qbx, mfie.rho_rhs(jt_sym, inc_xyz_sym.e))( queue, jt=jt, inc_fld=inc_field_scat.field, **knl_kwargs) gmres_result = gmres( bound_rho_op.scipy_op(queue, "rho", np.complex128, **knl_kwargs), rho_rhs, **gmres_settings) rho = gmres_result.solution # }}} jxyz = bind(qbx, sym.tangential_to_xyz(jt_sym))(queue, jt=jt) # {{{ volume eval sym_repr = mfie.scattered_volume_field(jt_sym, rho_sym) def eval_repr_at(tgt, source=None): if source is None: source = qbx return bind((source, tgt), sym_repr)(queue, jt=jt, rho=rho, **knl_kwargs) pde_test_repr = EHField( vector_from_device(queue, eval_repr_at(calc_patch_tgt))) maxwell_residuals = [ calc_patch.norm(x, np.inf) / calc_patch.norm(pde_test_repr.e, np.inf) for x in frequency_domain_maxwell( calc_patch, pde_test_repr.e, pde_test_repr.h, case.k)] print("Maxwell residuals:", maxwell_residuals) eoc_rec_repr_maxwell.add_data_point(h_max, max(maxwell_residuals)) # }}} # {{{ check PEC BC on total field bc_repr = EHField(mfie.scattered_volume_field( jt_sym, rho_sym, qbx_forced_limit=loc_sign)) pec_bc_e = sym.n_cross(bc_repr.e + inc_xyz_sym.e) pec_bc_h = sym.normal(3).as_vector().dot(bc_repr.h + inc_xyz_sym.h) eh_bc_values = bind(qbx, sym.join_fields(pec_bc_e, pec_bc_h))( queue, jt=jt, rho=rho, inc_fld=inc_field_scat.field, **knl_kwargs) def scat_norm(f): return norm(qbx, queue, f, p=np.inf) e_bc_residual = scat_norm(eh_bc_values[:3]) / scat_norm(inc_field_scat.e) h_bc_residual = scat_norm(eh_bc_values[3]) / scat_norm(inc_field_scat.h) print("E/H PEC BC residuals:", h_max, e_bc_residual, h_bc_residual) eoc_pec_bc.add_data_point(h_max, max(e_bc_residual, h_bc_residual)) # }}} # {{{ visualization if visualize: from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(queue, scat_discr, case.target_order+3) bdry_normals = bind(scat_discr, sym.normal(3))(queue)\ .as_vector(dtype=object) bdry_vis.write_vtk_file("source-%s.vtu" % resolution, [ ("j", jxyz), ("rho", rho), ("Einc", inc_field_scat.e), ("Hinc", inc_field_scat.h), ("bdry_normals", bdry_normals), ("e_bc_residual", eh_bc_values[:3]), ("h_bc_residual", eh_bc_values[3]), ]) fplot = make_field_plotter_from_bbox( find_bounding_box(scat_discr.mesh), h=(0.05, 0.05, 0.3), extend_factor=0.3) from pytential.qbx import QBXTargetAssociationFailedException qbx_tgt_tol = qbx.copy(target_association_tolerance=0.2) fplot_tgt = PointsTarget(cl.array.to_device(queue, fplot.points)) try: fplot_repr = eval_repr_at(fplot_tgt, source=qbx_tgt_tol) except QBXTargetAssociationFailedException as e: fplot.write_vtk_file( "failed-targets.vts", [ ("failed_targets", e.failed_target_flags.get(queue)) ]) raise fplot_repr = EHField(vector_from_device(queue, fplot_repr)) fplot_inc = EHField( vector_from_device(queue, eval_inc_field_at(fplot_tgt))) fplot.write_vtk_file( "potential-%s.vts" % resolution, [ ("E", fplot_repr.e), ("H", fplot_repr.h), ("Einc", fplot_inc.e), ("Hinc", fplot_inc.h), ] ) # }}} # {{{ error in E, H obs_repr = EHField(eval_repr_at(obs_discr)) def obs_norm(f): return norm(obs_discr, queue, f, p=np.inf) rel_err_e = (obs_norm(inc_field_obs.e + obs_repr.e) / obs_norm(inc_field_obs.e)) rel_err_h = (obs_norm(inc_field_obs.h + obs_repr.h) / obs_norm(inc_field_obs.h)) # }}} print("ERR", h_max, rel_err_h, rel_err_e) eoc_rec_h.add_data_point(h_max, rel_err_h) eoc_rec_e.add_data_point(h_max, rel_err_e) print("--------------------------------------------------------") print("is_interior=%s" % case.is_interior) print("--------------------------------------------------------") good = True for which_eoc, eoc_rec, order_tol in [ ("maxwell", eoc_rec_repr_maxwell, 1.5), ("PEC BC", eoc_pec_bc, 1.5), ("H", eoc_rec_h, 1.5), ("E", eoc_rec_e, 1.5)]: print(which_eoc) print(eoc_rec.pretty_print()) if len(eoc_rec.history) > 1: if eoc_rec.order_estimate() < case.qbx_order - order_tol: good = False assert good
def test_identity_convergence(ctx_getter, case, visualize=False): logging.basicConfig(level=logging.INFO) case.check() cl_ctx = ctx_getter() queue = cl.CommandQueue(cl_ctx) # prevent cache 'splosion from sympy.core.cache import clear_cache clear_cache() target_order = 8 from pytools.convergence import EOCRecorder eoc_rec = EOCRecorder() for resolution in ( getattr(case, "resolutions", None) or case.geometry.resolutions ): mesh = case.geometry.get_mesh(resolution, target_order) if mesh is None: break d = mesh.ambient_dim k = case.k lap_k_sym = LaplaceKernel(d) if k == 0: k_sym = lap_k_sym knl_kwargs = {} else: k_sym = HelmholtzKernel(d) knl_kwargs = {"k": sym.var("k")} from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ InterpolatoryQuadratureSimplexGroupFactory from pytential.qbx import QBXLayerPotentialSource pre_density_discr = Discretization( cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(target_order)) refiner_extra_kwargs = {} if case.k != 0: refiner_extra_kwargs["kernel_length_scale"] = 5/case.k qbx, _ = QBXLayerPotentialSource( pre_density_discr, 4*target_order, case.qbx_order, fmm_order=case.fmm_order, fmm_backend=case.fmm_backend, _expansions_in_tree_have_extent=True, _expansion_stick_out_factor=getattr( case, "_expansion_stick_out_factor", 0), ).with_refinement(**refiner_extra_kwargs) density_discr = qbx.density_discr # {{{ compute values of a solution to the PDE nodes_host = density_discr.nodes().get(queue) normal = bind(density_discr, sym.normal(d))(queue).as_vector(np.object) normal_host = [normal[j].get() for j in range(d)] if k != 0: if d == 2: angle = 0.3 wave_vec = np.array([np.cos(angle), np.sin(angle)]) u = np.exp(1j*k*np.tensordot(wave_vec, nodes_host, axes=1)) grad_u = 1j*k*wave_vec[:, np.newaxis]*u elif d == 3: center = np.array([3, 1, 2]) diff = nodes_host - center[:, np.newaxis] r = la.norm(diff, axis=0) u = np.exp(1j*k*r) / r grad_u = diff * (1j*k*u/r - u/r**2) else: raise ValueError("invalid dim") else: center = np.array([3, 1, 2])[:d] diff = nodes_host - center[:, np.newaxis] dist_squared = np.sum(diff**2, axis=0) dist = np.sqrt(dist_squared) if d == 2: u = np.log(dist) grad_u = diff/dist_squared elif d == 3: u = 1/dist grad_u = -diff/dist**3 else: assert False dn_u = 0 for i in range(d): dn_u = dn_u + normal_host[i]*grad_u[i] # }}} u_dev = cl.array.to_device(queue, u) dn_u_dev = cl.array.to_device(queue, dn_u) grad_u_dev = cl.array.to_device(queue, grad_u) key = (case.qbx_order, case.geometry.mesh_name, resolution, case.expr.zero_op_name) bound_op = bind(qbx, case.expr.get_zero_op(k_sym, **knl_kwargs)) error = bound_op( queue, u=u_dev, dn_u=dn_u_dev, grad_u=grad_u_dev, k=case.k) if 0: pt.plot(error) pt.show() linf_error_norm = norm(density_discr, queue, error, p=np.inf) print("--->", key, linf_error_norm) eoc_rec.add_data_point(qbx.h_max, linf_error_norm) if visualize: from meshmode.discretization.visualization import make_visualizer bdry_vis = make_visualizer(queue, density_discr, target_order) bdry_normals = bind(density_discr, sym.normal(mesh.ambient_dim))(queue)\ .as_vector(dtype=object) bdry_vis.write_vtk_file("source-%s.vtu" % resolution, [ ("u", u_dev), ("bdry_normals", bdry_normals), ("error", error), ]) print(eoc_rec) tgt_order = case.qbx_order - case.expr.order_drop assert eoc_rec.order_estimate() > tgt_order - 1.6
def test_mesh_multiple_groups(actx_factory, ambient_dim, visualize=False): actx = actx_factory() order = 4 mesh = mgen.generate_regular_rect_mesh(a=(-0.5, ) * ambient_dim, b=(0.5, ) * ambient_dim, nelements_per_axis=(8, ) * ambient_dim, order=order) assert len(mesh.groups) == 1 from meshmode.mesh.processing import split_mesh_groups element_flags = np.any( mesh.vertices[0, mesh.groups[0].vertex_indices] < 0.0, axis=1).astype(np.int64) mesh = split_mesh_groups(mesh, element_flags) assert len(mesh.groups) == 2 # pylint: disable=no-member assert mesh.facial_adjacency_groups assert mesh.nodal_adjacency if visualize and ambient_dim == 2: from meshmode.mesh.visualization import draw_2d_mesh draw_2d_mesh(mesh, draw_vertex_numbers=False, draw_element_numbers=True, draw_face_numbers=False, set_bounding_box=True) import matplotlib.pyplot as plt plt.savefig("test_mesh_multiple_groups_2d_elements.png", dpi=300) from meshmode.discretization import Discretization discr = Discretization(actx, mesh, PolynomialWarpAndBlendGroupFactory(order)) if visualize: group_id = discr.empty(actx, dtype=np.int32) for igrp, vec in enumerate(group_id): vec.fill(igrp) from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, vis_order=order) vis.write_vtk_file("mesh_multiple_groups.vtu", [("group_id", group_id)], overwrite=True) # check face restrictions from meshmode.discretization.connection import ( make_face_restriction, make_face_to_all_faces_embedding, make_opposite_face_connection, check_connection) for boundary_tag in [BTAG_ALL, FACE_RESTR_INTERIOR, FACE_RESTR_ALL]: conn = make_face_restriction( actx, discr, group_factory=PolynomialWarpAndBlendGroupFactory(order), boundary_tag=boundary_tag, per_face_groups=False) check_connection(actx, conn) bdry_f = conn.to_discr.zeros(actx) + 1 if boundary_tag == FACE_RESTR_INTERIOR: opposite = make_opposite_face_connection(actx, conn) check_connection(actx, opposite) op_bdry_f = opposite(bdry_f) error = flat_norm(bdry_f - op_bdry_f, np.inf) assert error < 1.0e-11, error if boundary_tag == FACE_RESTR_ALL: embedding = make_face_to_all_faces_embedding( actx, conn, conn.to_discr) check_connection(actx, embedding) em_bdry_f = embedding(bdry_f) error = flat_norm(bdry_f - em_bdry_f) assert error < 1.0e-11, error # check some derivatives (nb: flatten is a generator) import pytools ref_axes = pytools.flatten([[i] for i in range(ambient_dim)]) from meshmode.discretization import num_reference_derivative x = thaw(discr.nodes(), actx) num_reference_derivative(discr, ref_axes, x[0])