def test_cli(): input_mesh = helpers.tri_mesh infile = tempfile.NamedTemporaryFile().name meshio.write(infile, input_mesh, file_format="gmsh4-ascii") outfile = tempfile.NamedTemporaryFile().name meshio.cli.main( [ infile, outfile, "--input-format", "gmsh-ascii", "--output-format", "vtk-binary", ] ) mesh = meshio.read(outfile, file_format="vtk-binary") atol = 1.0e-15 assert numpy.allclose(input_mesh.points, mesh.points, atol=atol, rtol=0.0) for cell_type, data in input_mesh.cells.items(): assert numpy.allclose(data, mesh.cells[cell_type]) return
def generate_mesh(geo_object, optimize=True, return_msh_fh=False, verbose=False): import meshio import os import subprocess import tempfile geo_handle = tempfile.NamedTemporaryFile(suffix='.geo', delete=True) geo_handle.write(geo_object.get_code()) geo_handle.flush() msh_handle = tempfile.NamedTemporaryFile(suffix='.msh', delete=True) cmd = ['gmsh', '-3', geo_handle.name, '-o', msh_handle.name] if optimize: cmd += ['-optimize'] out = subprocess.check_output(cmd, stderr=subprocess.STDOUT) if verbose: print(out) if return_msh_fh: return msh_handle points, cells, _, _, _ = meshio.read(msh_handle.name) return points, cells
def gmsh(geo_object, optimize=True, verbose=10, name="", ident=0): ''' Run gmsh, return resulting mesh. ''' import meshio import os import subprocess import tempfile handle, filename = tempfile.mkstemp(suffix='.geo') os.write(handle, geo_object.get_code()) os.close(handle) handle, outname = tempfile.mkstemp(suffix='.msh') cmd = ['gmsh', '-3', filename, '-o', outname, '-v', str(verbose)] if optimize: cmd += ['-optimize'] out = subprocess.check_output(cmd, stderr=subprocess.STDOUT) if verbose: print(out) dat = meshio.read(outname) return gmsh2mesh(name=name, ident=ident, point=dat[0], **dat[1])
def test_reference_file_readonly(filename, md5, ref_sum, ref_num_cells): filename = helpers.download(filename, md5) mesh = meshio.read(filename) tol = 1.0e-2 s = mesh.points.sum() assert abs(s - ref_sum) < tol * ref_sum assert {k: len(v) for k, v in mesh.cells.items()} == ref_num_cells assert { k: len(v["gmsh:physical"]) for k, v in mesh.cell_data.items() } == ref_num_cells
def test_reference_file(filename, md5, ref_sum, ref_num_cells, write_binary): filename = helpers.download(filename, md5) mesh = meshio.read(filename) tol = 1.0e-2 s = numpy.sum(mesh.points) assert abs(s - ref_sum) < tol * ref_sum assert len(mesh.cells["triangle"]) == ref_num_cells writer = partial(meshio.vtk_io.write, write_binary=write_binary) helpers.write_read(writer, meshio.vtk_io.read, mesh, 1.0e-15) return
def generate(verbose=False): cache_file = "cruc_cache.msh" if os.path.isfile(cache_file): print("Using mesh from cache '{}'.".format(cache_file)) mesh = meshio.read(cache_file) out = mesh.points, mesh.cells, mesh.point_data, mesh.cell_data, mesh.field_data else: out = pygmsh.generate_mesh(_define(), verbose=verbose) points, cells, point_data, cell_data, _ = out meshio.write_points_cells( cache_file, points, cells, point_data=point_data, cell_data=cell_data ) return out
def read_write(): X, cells = generate_mesh() formats = [ "ansys-ascii", "ansys-binary", "exodus", "dolfin-xml", "gmsh-ascii", "gmsh-binary", "med", "medit", "permas", "moab", "off", "stl-ascii", "stl-binary", "vtk-ascii", "vtk-binary", "vtu-ascii", "vtu-binary", "xdmf", ] filename = "foo" print() print("format write (s) read(s)") print() for fmt in formats: t = time.time() meshio.write(filename, X, cells, file_format=fmt) elapsed_write = time.time() - t t = time.time() meshio.read(filename, file_format=fmt) elapsed_read = time.time() - t print("{0: <12} {1:e} {2:e}".format(fmt, elapsed_write, elapsed_read)) return
def writeVTKFile(self,fn="",sub=False): """Writes mesh into vtk file. Uses *meshIO* (https://github.com/nschloe/meshio), to convert the mesh saved in ``fnMesh`` to a .vtk file. If ``sub==True``, will start a seperate subprocess and submit ``pyfrp_meshIO_script.py`` to it. This can be sometimes useful, since PyFRAP sometimes tends to crash otherwise. If no output path is given via ``fn``, will use same path as ``fnMesh``. .. note:: *meshIO* only gets imported inside this function, making PyFRAP running even without the package installed. However, this feature will only run with *meshIO*. Keyword Args: fn (str): Optional output path. sub (bool): Subprocess flag. Returns: str: Used output path. """ if not os.path.isfile(self.fnMesh): printWarning("Filepath to meshfile has not been specified yet. Cannot write VTK file.") if fn=="": fn=self.fnMesh.replace('.msh','.vtk') if sub: cmd = "python pyfrp_meshIO_script.py "+ self.fnMesh import shlex import subprocess args = shlex.split(cmd) p = subprocess.Popen(args) p.wait() else: #MeshIO import meshio points, cells, point_data, cell_data, field_data = meshio.read(self.fnMesh) meshio.write(fn,points,cells,point_data=point_data,cell_data=cell_data,field_data=field_data) return fn
def test_reference_file(filename, md5, ref_sum, ref_num_cells, write_binary): filename = helpers.download(filename, md5) mesh = meshio.read(filename) tol = 1.0e-2 s = mesh.points.sum() assert abs(s - ref_sum) < tol * ref_sum assert {k: len(v) for k, v in mesh.cells.items()} == ref_num_cells assert { k: len(v["gmsh:physical"]) for k, v in mesh.cell_data.items() } == ref_num_cells writer = partial(meshio.msh_io.write, fmt_version="2", write_binary=write_binary) helpers.write_read(writer, meshio.msh_io.read, mesh, 1.0e-15)
def test_reference_file_with_mixed_cells(): filename = "med/cylinder.med" md5 = "e36b365542c72ef470b83fc21f4dad58" filename = helpers.download(filename, md5) mesh = meshio.read(filename) # Points assert numpy.isclose(mesh.points.sum(), 16.53169892762988) # Cells ref_num_cells = {"pyramid": 18, "quad": 18, "line": 17, "tetra": 63, "triangle": 4} assert {k: len(v) for k, v in mesh.cells.items()} == ref_num_cells # Point tags assert mesh.point_data["point_tags"].sum() == 52 ref_point_tags_info = {2: ["Side"], 3: ["Side", "Top"], 4: ["Top"]} assert mesh.point_tags == ref_point_tags_info # Cell tags ref_sum_cell_tags = { "pyramid": -116, "quad": -75, "line": -48, "tetra": -24, "triangle": -30, } assert { k: v["cell_tags"].sum() for k, v in mesh.cell_data.items() } == ref_sum_cell_tags ref_cell_tags_info = { -6: ["Top circle"], -7: ["Top", "Top and down"], -8: ["Top and down"], -9: ["A", "B"], -10: ["B"], -11: ["B", "C"], -12: ["C"], } assert mesh.cell_tags == ref_cell_tags_info helpers.write_read(meshio.med_io.write, meshio.med_io.read, mesh, 1.0e-15)
def test_reference_file_with_point_cell_data(): filename = "med/box.med" md5 = "0867fb11bd14b83ad11ab20e2b1fd57d" filename = helpers.download(filename, md5) mesh = meshio.read(filename) # Points assert numpy.isclose(mesh.points.sum(), 12) # Cells assert {k: len(v) for k, v in mesh.cells.items()} == {"hexahedron": 1} # Point data data_u = mesh.point_data["resu____DEPL"] assert data_u.shape == (8, 3) assert numpy.isclose(data_u.sum(), 12) # Cell data # ELNO (1 data point for every node of each element) data_eps = mesh.cell_data["hexahedron"]["resu____EPSI_ELNO"] assert data_eps.shape == (1, 8, 6) # (n_cells, n_nodes_per_element, n_components) data_eps_mean = numpy.mean(data_eps, axis=1)[0] eps_ref = numpy.array([1, 0, 0, 0.5, 0.5, 0]) assert numpy.allclose(data_eps_mean, eps_ref) data_sig = mesh.cell_data["hexahedron"]["resu____SIEF_ELNO"] assert data_sig.shape == (1, 8, 6) # (n_cells, n_nodes_per_element, n_components) data_sig_mean = numpy.mean(data_sig, axis=1)[0] sig_ref = numpy.array( [7328.44611253, 2645.87030114, 2034.06063679, 1202.6, 569.752, 0] ) assert numpy.allclose(data_sig_mean, sig_ref) data_psi = mesh.cell_data["hexahedron"]["resu____ENEL_ELNO"] assert data_psi.shape == (1, 8) # (n_cells, n_nodes_per_element, ) with 1 cut off # ELEM (1 data point for each element) data_psi_elem = mesh.cell_data["hexahedron"]["resu____ENEL_ELEM"] assert numpy.isclose(numpy.mean(data_psi, axis=1)[0], data_psi_elem[0]) helpers.write_read(meshio.med_io.write, meshio.med_io.read, mesh, 1.0e-15)
def generate_mesh(geo_object, optimize=True): import meshio import os import subprocess import tempfile handle, filename = tempfile.mkstemp(suffix='.geo') os.write(handle, geo_object.get_code()) os.close(handle) handle, outname = tempfile.mkstemp(suffix='.msh') cmd = ['gmsh', '-3', filename, '-o', outname] if optimize: cmd += ['-optimize'] out = subprocess.check_output(cmd, stderr=subprocess.STDOUT) print(out) points, cells, _, _, _ = meshio.read(outname) return points, cells
def _write_read(filename, mesh): '''Write and read a file, and make sure the data is the same as before. ''' try: input_point_data = mesh['point_data'] except KeyError: input_point_data = {} try: input_cell_data = mesh['cell_data'] except KeyError: input_cell_data = {} meshio.write( filename, mesh['points'], mesh['cells'], point_data=input_point_data, cell_data=input_cell_data ) points, cells, point_data, cell_data, _ = meshio.read(filename) # Numpy's array_equal is too strict here, cf. # <https://mail.scipy.org/pipermail/numpy-discussion/2015-December/074410.html>. # Use allclose. # We cannot compare the exact rows here since the order of the points might # have changes. Just compare the sums assert numpy.allclose(mesh['points'], points) for key, data in mesh['cells'].items(): assert numpy.allclose(data, cells[key]) for key, data in input_point_data.items(): assert numpy.allclose(data, point_data[key]) for key, data in input_cell_data.items(): assert numpy.allclose(data, cell_data[key]) os.remove(filename) return
def test_reference_file(): this_dir = os.path.dirname(os.path.abspath(__file__)) filename = os.path.join(this_dir, "meshes", "flac3d", "flac3d_mesh_ex.f3grid") mesh = meshio.read(filename) # Points assert numpy.isclose(mesh.points.sum(), 306.9999999999999) # Cells ref_num_cells = {"tetra": 3, "pyramid": 15, "wedge": 15, "hexahedron": 75} assert {k: len(v) for k, v in mesh.cells.items()} == ref_num_cells # Cell data ref_sum_cell_data = { "tetra": 9, "pyramid": 36, "wedge": 54, "hexahedron": 171 } assert {k: v["flac3d:zone"].sum() for k, v in mesh.cell_data.items()} == ref_sum_cell_data
def read(filename): '''Reads an unstructured mesh with added data. :param filenames: The files to read from. :type filenames: str :returns mesh{2,3}d: The mesh data. :returns point_data: Point data read from file. :type point_data: dict :returns field_data: Field data read from file. :type field_data: dict ''' points, cells_nodes, point_data, cell_data, field_data = \ meshio.read(filename) if 'triangle' in cells_nodes: return pyfvm.meshTri.meshTri(points, cells_nodes['triangle']), \ point_data, field_data elif 'tetra' in cells_nodes: return pyfvm.meshTetra.meshTetra(points, cells_nodes['tetra']), \ point_data, field_data else: raise RuntimeError('Unknown mesh type.')
def _write_read(filename, mesh): '''Write and read a file, and make sure the data is the same as before. ''' meshio.write( filename, mesh['points'], mesh['cells'], point_data=mesh['point_data'], cell_data=mesh['cell_data'] ) points, cells, point_data, cell_data, _ = meshio.read(filename) # We cannot compare the exact rows here since the order of the points might # have changes. Just compare the sums assert numpy.allclose(mesh['points'], points) for key, data in mesh['cells'].items(): assert numpy.array_equal(data, cells[key]) for key, data in mesh['point_data'].items(): assert numpy.array_equal(data, point_data[key]) for key, data in mesh['cell_data'].items(): assert numpy.array_equal(data, cell_data[key]) return
def __check_data(self, filename): """Read data using meshio to get min and max and make sure levels are within data bounds. Input: ------ filename: string, path to mesh vtk file to check Return: ------- arbmin: float, value that is lower than minimum data arbmax: float, value that is greater than the max data mins: list of floats, minimum x, y, z values of the geometry [xmin, ymin, zmin] maxs: list of floats, maximum x, y, z values of the geometry [xmax, ymax, zmax] """ # read in Cartesian mesh file mf = meshio.read(filename) # get min and max data values mindata = min(mf.cell_data['hexahedron'][self.data]) maxdata = max(mf.cell_data['hexahedron'][self.data]) arbmin = mindata - 10 # lower than lowest data arbmax = maxdata + 10 # higher than highest data all_levels = list(self.levels) for level in all_levels: if (level <= mindata) or (level >= maxdata): warnings.warn("Level {} is out of data bounds.".format(level)) self.levels.remove(level) if len(self.levels) == 0: raise RuntimeError("No data exists within provided levels.") # get extents of the geometric space (min/max x, y, z values) mins = mf.points.min(axis=0) maxs = mf.points.max(axis=0) return arbmin, arbmax, mins, maxs
def generate_from_inr( inr_filename, lloyd=False, odt=False, perturb=True, exude=True, edge_size=0.0, facet_angle=0.0, facet_size=0.0, facet_distance=0.0, cell_radius_edge_ratio=0.0, cell_size=0.0, verbose=True, seed=0, ): fh, outfile = tempfile.mkstemp(suffix=".mesh") os.close(fh) _generate_from_inr( inr_filename, outfile, lloyd=lloyd, odt=odt, perturb=perturb, exude=exude, edge_size=edge_size, facet_angle=facet_angle, facet_size=facet_size, facet_distance=facet_distance, cell_radius_edge_ratio=cell_radius_edge_ratio, cell_size=cell_size, verbose=verbose, seed=seed, ) mesh = meshio.read(outfile) os.remove(outfile) return mesh
def test_fem(): mesh_path = "tests/data/msh/test.msh" element_type = "triangle" integration_points = 1 load_condition = "plane stress" # "plane stress" or "plane strain" thickness = 0.5 steel = base.Material("steel", 3e7, 0.25, load_condition) mesh = meshio.read(mesh_path) elements = mesh.cells_dict[element_type] nodal_coord = mesh.points[:, :2] num_elements = elements.shape[0] num_nodes = nodal_coord.shape[0] material_map = mesh.cell_data_dict["gmsh:physical"][ element_type] - 1 # element-material map left_side = bc.DirichletBC("left side", mesh, [0, 1], 0.0) br_corner = bc.DirichletBC("bottom right corner", mesh, [1], 0.0) tr_corner = bc.NeumannBC("top right corner", mesh, [1], -1000.0) E_array = vector.compute_E_array(num_elements, material_map, mesh.field_data, steel) R = np.zeros(num_nodes * 2) K = vector.assembly(num_elements, num_nodes, elements, nodal_coord, E_array, thickness) K, R = bc.sp_apply_dirichlet(num_nodes, K, R, left_side, br_corner) R = bc.apply_neumann(R, tr_corner) D = linalg.spsolve(K, R) D_true = np.array([ 0.0, 0.0, 1.90773874e-05, 0.0, 8.73032981e-06, -7.41539125e-05, 0.0, 0.0 ]) # np.testing.assert_allclose(D_true, D) # FIXME some zeros are 1.0e-20 why?? np.testing.assert_almost_equal(D_true, D)
def test_f(filename, control_values): filename = download_mesh(filename) mesh = meshplex.read(filename) mu = 1.0e-2 V = -1.0 g = 1.0 keo = pyfvm.get_fvm_matrix(mesh, edge_kernels=[Energy(mu)]) # compute the Ginzburg-Landau residual m2 = meshio.read(filename) psi = m2.point_data["psi"][:, 0] + 1j * m2.point_data["psi"][:, 1] cv = mesh.control_volumes # One divides by the control volumes here. No idea why this has been done in pynosh. # Perhaps to make sure that even the small control volumes have a significant # contribution to the residual? r = keo * psi / cv + psi * (V + g * abs(psi)**2) # scale with D for compliance with the Nosh (C++) tests if mesh.control_volumes is None: mesh.compute_control_volumes() r *= mesh.control_volumes tol = 1.0e-13 # For C++ Nosh compatibility: # Compute 1-norm of vector (Re(psi[0]), Im(psi[0]), Re(psi[1]), ... ) alpha = numpy.linalg.norm(r.real, ord=1) + numpy.linalg.norm(r.imag, ord=1) assert abs(control_values[0] - alpha) < tol assert abs(control_values[1] - numpy.linalg.norm(r, ord=2)) < tol # For C++ Nosh compatibility: # Compute inf-norm of vector (Re(psi[0]), Im(psi[0]), Re(psi[1]), ... ) alpha = max( numpy.linalg.norm(r.real, ord=numpy.inf), numpy.linalg.norm(r.imag, ord=numpy.inf), ) assert abs(control_values[2] - alpha) < tol return
def test_volume_from_surface(): this_dir = pathlib.Path(__file__).resolve().parent # mesh = pygalmesh.generate_volume_mesh_from_surface_mesh( # this_dir / "meshes" / "elephant.vtu", # facet_angle=25.0, # facet_size=0.15, # facet_distance=0.008, # cell_radius_edge_ratio=3.0, # verbose=False, # ) with tempfile.TemporaryDirectory() as tmp: out_filename = str(pathlib.Path(tmp) / "out.vtk") pygalmesh._cli.volume_from_surface([ str(this_dir / "meshes" / "elephant.vtu"), out_filename, "--facet-angle", "0.5", "--facet-size", "0.15", "--facet-distance", "0.008", "--cell-radius-edge-ratio", "3.0", "--quiet", ]) mesh = meshio.read(out_filename) tol = 2.0e-2 assert abs(max(mesh.points[:, 0]) - 0.357612477657) < tol assert abs(min(mesh.points[:, 0]) + 0.358747130015) < tol assert abs(max(mesh.points[:, 1]) - 0.496137874959) < tol assert abs(min(mesh.points[:, 1]) + 0.495301051456) < tol assert abs(max(mesh.points[:, 2]) - 0.298780230629) < tol assert abs(min(mesh.points[:, 2]) + 0.300472866512) < tol vol = sum( helpers.compute_volumes(mesh.points, mesh.get_cells_type("tetra"))) assert abs(vol - 0.044164693065) < tol
def get_mesh(self, indices=[]): """Return the pyvista mesh object (or submesh). Parameters ---------- self : MeshVTK a MeshVTK object indices : list list of the points to extract (optional) Returns ------- mesh : pyvista.core.pointset.UnstructuredGrid a pyvista UnstructuredGrid object """ # Already available => Return if self.mesh is not None: return self.mesh # Read mesh file else: if self.format != "vtk": # Write vtk files with meshio mesh = read(self.path + "/" + self.name + "." + self.format) mesh.write(self.path + "/" + self.name + ".vtk") # Read .vtk file with pyvista mesh = pv.read(self.path + "/" + self.name + ".vtk") # Extract submesh if indices != []: mesh = mesh.extract_points(indices) if self.is_pyvista_mesh: self.mesh = mesh return mesh
def test_extrude(): p = pygalmesh.Polygon2D([[-0.5, -0.3], [0.5, -0.3], [0.0, 0.5]]) domain = pygalmesh.Extrude(p, [0.0, 0.3, 1.0]) pygalmesh.generate_mesh(domain, 'out.mesh', cell_size=0.1, edge_size=0.1, verbose=False) vertices, cells, _, _, _ = meshio.read('out.mesh') tol = 1.0e-3 assert abs(max(vertices[:, 0]) - 0.5) < tol assert abs(min(vertices[:, 0]) + 0.5) < tol assert abs(max(vertices[:, 1]) - 0.8) < tol assert abs(min(vertices[:, 1]) + 0.3) < tol assert abs(max(vertices[:, 2]) - 1.0) < tol assert abs(min(vertices[:, 2]) + 0.0) < tol vol = sum(compute_volumes(vertices, cells['tetra'])) assert abs(vol - 0.4) < tol return
def test_scaling(): alpha = 1.3 s = pygalmesh.Scale(pygalmesh.Cuboid([0, 0, 0], [1, 2, 3]), alpha) pygalmesh.generate_mesh(s, 'out.mesh', cell_size=0.2, edge_size=0.1, verbose=False) vertices, cells, _, _, _ = meshio.read('out.mesh') tol = 1.0e-3 assert abs(max(vertices[:, 0]) - 1 * alpha) < tol assert abs(min(vertices[:, 0]) + 0.0) < tol assert abs(max(vertices[:, 1]) - 2 * alpha) < tol assert abs(min(vertices[:, 1]) + 0.0) < tol assert abs(max(vertices[:, 2]) - 3 * alpha) < tol assert abs(min(vertices[:, 2]) + 0.0) < tol vol = sum(compute_volumes(vertices, cells['tetra'])) assert abs(vol - 6.0 * alpha**3) < tol return
def test_ring_extrude(): p = pygalmesh.Polygon2D([[0.5, -0.3], [1.5, -0.3], [1.0, 0.5]]) edge_size = 0.1 domain = pygalmesh.RingExtrude(p, edge_size) pygalmesh.generate_mesh(domain, "out.mesh", cell_size=0.1, edge_size=edge_size, verbose=False) mesh = meshio.read("out.mesh") tol = 1.0e-3 assert abs(max(mesh.points[:, 0]) - 1.5) < tol assert abs(min(mesh.points[:, 0]) + 1.5) < tol assert abs(max(mesh.points[:, 1]) - 1.5) < tol assert abs(min(mesh.points[:, 1]) + 1.5) < tol assert abs(max(mesh.points[:, 2]) - 0.5) < tol assert abs(min(mesh.points[:, 2]) + 0.3) < tol vol = sum(compute_volumes(mesh.points, mesh.cells["tetra"])) assert abs(vol - 2 * numpy.pi * 0.4) < 0.05 return
def cmd_gen_dmap(ctx, config): """Generate domain/pixel map from msh file""" import meshio mesh = meshio.read(ctx.obj['mesh_filename']) domains = dict() for nam, val in mesh.field_data.iteritems(): domains[nam] = val[0] import pixsim.geometry as geometry pixcoll = geometry.make_pixels_center(**ctx.obj['cfg'][config]) import numpy as np arrs = list() for pix in pixcoll: name, hdim, center, shape = pix.info() print name dom = domains[name] pid = int(name[5:]) # assuming name = pixel# arrs.append([dom, pid, center]) arr = [Array(name='domain_map', typename='tuples', data=np.asarray(arrs))] res = Result(name='domain_map', typename='geometry', data=arr) save_result(ctx, res)
def encodes(self, x): # get sitk objs im_path, segm_path = x folder = Path(segm_path).parent.name ras_adj = int(folder) in range(50455, 50464) mr = sitk.ReadImage(im_path, sitk.sitkFloat32) segm = meshio.read(segm_path) mask_arr = seg2mask(mr, segm, ras_adj) # resize so isotropic spacing orig_sp = mr.GetSpacing() orig_sz = mr.GetSize() new_sz = [int(round(osz*ospc/self.new_sp)) for osz,ospc in zip(orig_sz, orig_sp)] im = torch.swapaxes(torch.tensor(sitk.GetArrayFromImage(mr)), 0, 2) mk = torch.tensor(mask_arr).float() while im.ndim < 5: im = im.unsqueeze(0) mk = mk.unsqueeze(0) return F.interpolate(im, size = new_sz, mode = 'trilinear', align_corners=False).squeeze(), F.interpolate(mk, size = new_sz, mode = 'nearest').squeeze().long()
def test_torus(): major_radius = 1.0 minor_radius = 0.5 s0 = frentos.Torus(major_radius, minor_radius) frentos.generate_mesh(s0, 'out.mesh', cell_size=0.1, verbose=False) vertices, cells, _, _, _ = meshio.read('out.mesh') tol = 1.0e-2 radii_sum = major_radius + minor_radius assert abs(max(vertices[:, 0]) - radii_sum) < tol assert abs(min(vertices[:, 0]) + radii_sum) < tol assert abs(max(vertices[:, 1]) - radii_sum) < tol assert abs(min(vertices[:, 1]) + radii_sum) < tol assert abs(max(vertices[:, 2]) - minor_radius) < tol assert abs(min(vertices[:, 2]) + minor_radius) < tol vol = sum(compute_volumes(vertices, cells['tetra'])) ref_vol = (numpy.pi * minor_radius * minor_radius) * \ (2 * numpy.pi * major_radius) assert abs(vol - ref_vol) < 1.0e-1 return
def test_tetrahedron(): s0 = pygalmesh.Tetrahedron([0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]) pygalmesh.generate_mesh(s0, 'out.mesh', cell_size=0.1, edge_size=0.1, verbose=False) vertices, cells, _, _, _ = meshio.read('out.mesh') tol = 1.0e-4 assert abs(max(vertices[:, 0]) - 1.0) < tol assert abs(min(vertices[:, 0]) + 0.0) < tol assert abs(max(vertices[:, 1]) - 1.0) < tol assert abs(min(vertices[:, 1]) + 0.0) < tol assert abs(max(vertices[:, 2]) - 1.0) < tol assert abs(min(vertices[:, 2]) + 0.0) < tol vol = sum(compute_volumes(vertices, cells['tetra'])) assert abs(vol - 1.0 / 6.0) < tol return
def create_mesh(lcar): geom = pygmsh.Geometry() cache_file = 'karman.msh' if os.path.isfile(cache_file): print('Using mesh from cache \'{}\'.'.format(cache_file)) points, cells, _, _, _ = meshio.read(cache_file) else: # slightly off-center circle circle = geom.add_circle([0.1, 1.0e-2, 0.0], 0.5 * obstacle_diameter, lcar, make_surface=False) geom.add_rectangle(x0, x1, y0, y1, 0.0, lcar, holes=[circle]) points, cells, _, _, _ = pygmsh.generate_mesh(geom) meshio.write(cache_file, points, cells) # https://fenicsproject.org/qa/12891/initialize-mesh-from-vertices-connectivities-at-once meshio.write('test.xml', points, cells) return Mesh('test.xml')
def read(filename, file_format=None, **kwargs): """Read unstructured mesh from file. Parameters ---------- filename : str Input file name. file_format : str or None, optional, default None Input file format. Returns ------- toughio.Mesh Imported mesh. """ # Check file format if not isinstance(filename, str): raise TypeError() fmt = file_format if file_format else _filetype_from_filename(filename) # Call custom readers format_to_reader = { "tough": (tough, (), {}), "avsucd": (avsucd, (), {}), "flac3d": (flac3d, (), {}), "pickle": (pickle, (), {}), "tecplot": (tecplot, (), {}), } if fmt in format_to_reader.keys(): interface, args, default_kwargs = format_to_reader[fmt] _kwargs = default_kwargs.copy() _kwargs.update(kwargs) return interface.read(filename, *args, **_kwargs) else: mesh = meshio.read(filename, file_format) return from_meshio(mesh)
def read_and_convert_mesh(file_locations): # Convert the mesh to xdmf format msh = meshio.read(file_locations.path_to_msh_file) # Create directory if doesn't exist if not os.path.isdir(file_locations.mesh_folder): os.makedirs(file_locations.mesh_folder) # Write all triangles meshio.write( file_locations.mesh_folder + "mesh.xdmf", meshio.Mesh(points=msh.points, cells={"triangle": msh.cells["triangle"]})) # Write the triangle subdomains meshio.write( file_locations.mesh_folder + "subdomains.xdmf", meshio.Mesh(points=msh.points, cells={"triangle": msh.cells["triangle"]}, cell_data={ "triangle": { "name_to_read": msh.cell_data["triangle"]["gmsh:physical"] } })) # Write the lines meshio.write( file_locations.mesh_folder + "lines.xdmf", meshio.Mesh(points=msh.points, cells={"line": msh.cells["line"]}, cell_data={ "line": { "name_to_read": msh.cell_data["line"]["gmsh:physical"] } }))
def read(cls, *args, **kwargs): """Wrapper for `meshio.read`. For gmsh: - remaps `gmsh:physical` -> `physical` - remaps `gmsh:geometrical` -> `geometrical` """ from meshio import read mesh = read(*args, **kwargs) cell_data = {} for key, value in mesh.cell_data.items(): if key in ('gmsh:physical', 'gmsh:geometrical'): key = key.replace('gmsh:', '') cell_data[key] = value point_data = {} for key, value in mesh.point_data.items(): if key in ('gmsh:physical', 'gmsh:geometrical'): key = key.replace('gmsh:', '') point_data[key] = value ret = cls( mesh.points, mesh.cells, point_data=point_data, cell_data=cell_data, field_data=mesh.field_data, point_sets=mesh.point_sets, cell_sets=mesh.cell_sets, gmsh_periodic=mesh.gmsh_periodic, info=mesh.info, ) ret.prune_z_0() return ret
def import_grid(filename): """ Import a grid. This routine uses the meshio library to export grids. A number of types are supported, including vtk, vtu, gmsh, dolphin xml. For a full list see https://github.com/nschloe/meshio """ from bempp.api.grid.grid import Grid mesh = _meshio.read(filename) vertices = mesh.points.T elements = mesh.cells_dict["triangle"].T.astype("uint32") try: domain_indices = mesh.cell_data_dict["gmsh:physical"]["triangle"] except: domain_indices = None return Grid(vertices, elements, domain_indices=domain_indices)
def generate_mesh(self, verbose=False): import meshio import os import subprocess import tempfile gmsh_executable = 'gmsh' handle, filename = tempfile.mkstemp(suffix='.geo') os.write(handle, self.get_code().encode()) os.close(handle) handle, outname = tempfile.mkstemp(suffix='.msh') cmd = [gmsh_executable, '-2', filename, '-o', outname] try: out = subprocess.check_output(cmd, stderr=subprocess.STDOUT) except: out = os.system(" ".join(cmd)) if verbose: print(out.decode()) #points,cells = meshio.read(outname) mesh = meshio.read(outname) #return points, cells return mesh.points, mesh.cells["triangle"]
def write_mesh_to_xdmf(meshfile, xdmfdir): import meshio # Read the .mesh file into meshio mesh = meshio.read(meshfile) # Extract subdomains and boundaries between regions # into appropriate containers points = mesh.points tetra = {"tetra": mesh.cells_dict["tetra"]} triangles = {"triangle": mesh.cells_dict["triangle"]} subdomains = {"subdomains": [mesh.cell_data_dict["medit:ref"]["tetra"]]} boundaries = {"boundaries": [mesh.cell_data_dict["medit:ref"]["triangle"]]} # Write the mesh to xdmfdir/mesh.xdmf xdmf = meshio.Mesh(points, tetra) meshio.write("%s/mesh.xdmf" % xdmfdir, xdmf) # Write the subdomains of the mesh xdmf = meshio.Mesh(points, tetra, cell_data=subdomains) meshio.write("%s/subdomains.xdmf" % xdmfdir, xdmf) # Write the boundaries/interfaces of the mesh xdmf = meshio.Mesh(points, triangles,cell_data=boundaries) meshio.write("%s/boundaries.xdmf" % xdmfdir, xdmf)
def test_reference_file_with_entities( filename, ref_sum, ref_num_cells, ref_num_cells_in_cell_sets, binary ): this_dir = pathlib.Path(__file__).resolve().parent filename = this_dir / "meshes" / "msh" / filename mesh = meshio.read(filename) tol = 1.0e-2 s = mesh.points.sum() assert abs(s - ref_sum) < tol * ref_sum assert {k: len(v) for k, v in mesh.cells_dict.items()} == ref_num_cells assert { k: len(v) for k, v in mesh.cell_data_dict["gmsh:physical"].items() } == ref_num_cells writer = partial(meshio.gmsh.write, fmt_version="4.1", binary=binary) num_cells = {k: 0 for k in ref_num_cells_in_cell_sets} for vv in mesh.cell_sets_dict.values(): for k, v in vv.items(): num_cells[k] += len(v) assert num_cells == ref_num_cells_in_cell_sets helpers.write_read(writer, meshio.gmsh.read, mesh, 1.0e-15)
def generate_surface_mesh( domain, bounding_sphere_radius=0.0, angle_bound=0.0, radius_bound=0.0, distance_bound=0.0, verbose=True, ): fh, outfile = tempfile.mkstemp(suffix=".off") os.close(fh) _generate_surface_mesh( domain, outfile, bounding_sphere_radius=bounding_sphere_radius, angle_bound=angle_bound, radius_bound=radius_bound, distance_bound=distance_bound, verbose=verbose, ) mesh = meshio.read(outfile) os.remove(outfile) return mesh
def test_ring_extrude(): p = pygalmesh.Polygon2D([[0.5, -0.3], [1.5, -0.3], [1.0, 0.5]]) edge_size = 0.1 domain = pygalmesh.RingExtrude(p, edge_size) pygalmesh.generate_mesh(domain, 'out.mesh', cell_size=0.1, edge_size=edge_size, verbose=False) vertices, cells, _, _, _ = meshio.read('out.mesh') tol = 1.0e-3 assert abs(max(vertices[:, 0]) - 1.5) < tol assert abs(min(vertices[:, 0]) + 1.5) < tol assert abs(max(vertices[:, 1]) - 1.5) < tol assert abs(min(vertices[:, 1]) + 1.5) < tol assert abs(max(vertices[:, 2]) - 0.5) < tol assert abs(min(vertices[:, 2]) + 0.3) < tol vol = sum(compute_volumes(vertices, cells['tetra'])) assert abs(vol - 2 * numpy.pi * 0.4) < 0.05 return
def test_segment_domain(self): for element, element_type, meshfile in [ (Segment, 'line', '1D_linear.vtk'), (Segment3, 'line3', '1D_quadratic.vtk') ]: m = meshio.read(os.path.join(meshfolder, meshfile)) mesh = Mesh(m.points[:, 0]) if type(m.cells) == dict: cells = m.cells[element_type] else: cells = m.cells_dict[element_type] # Creation with name domain = mesh.add_domain("segments", element(Caribou._1D), cells) self.assertEqual(domain.number_of_elements(), 10) self.assertMatrixEqual(domain.element_indices(0), cells[0]) self.assertMatrixEqual(domain.element_indices(9), cells[9]) # Creation without name domain = mesh.add_domain(element(Caribou._1D), cells) self.assertEqual(domain.number_of_elements(), 10) self.assertMatrixEqual(domain.element_indices(0), cells[0]) self.assertMatrixEqual(domain.element_indices(9), cells[9])
def save_boundary_vtk(ses, mshfile, outname, res_id): ''' Save a boundary result into a VTK file. ''' print 'Saving boundary results...' #res_id = input('Enter the boundary result ID: ') result = get_result(ses, id=res_id) if result is None: print 'No matching results for ID = {}'.format(res_id) return mesh = meshio.read(mshfile) barrs = result.array_data_by_name() from tvtk.api import tvtk, write_data pd = tvtk.PolyData() pd.points = mesh.points pd.polys = mesh.cells['triangle'] pd.cell_data.add_array(mesh.cell_data['triangle']['gmsh:physical']) pd.cell_data.get_array(0).name = 'domains' for count, name in enumerate(['dirichlet', 'neumann']): pd.cell_data.add_array(barrs[name]) pd.cell_data.get_array(count + 1).name = name outname = outname+'.vtk' write_data(pd, outname)
def convert(self): msh = meshio.read("{}.msh".format(self.filename)) # meshio.write("mesh.xdmf", meshio.Mesh(points=msh.points, cells={"tetra": msh.cells["tetra"]})) # meshio.write("mf.xdmf", meshio.Mesh(points=msh.points, cells={"triangle": msh.cells["triangle"]}, cell_data={"triangle": {"name_to_read": msh.cell_data["triangle"]["gmsh:physical"]}})) for cell in msh.cells: if cell.type == "triangle": triangle_cells = cell.data elif cell.type == "tetra": tetra_cells = cell.data for key in msh.cell_data_dict["gmsh:physical"].keys(): if key == "triangle": triangle_data = msh.cell_data_dict["gmsh:physical"][key] elif key == "tetra": tetra_data = msh.cell_data_dict["gmsh:physical"][key] triangle_mesh = meshio.Mesh(points=msh.points, cells=[("triangle", triangle_cells)], cell_data={"name_to_read":[triangle_data]}) tetra_mesh =meshio.Mesh(points=msh.points, cells=[("tetra", tetra_cells)], cell_data={"name_to_read":[tetra_data]}) meshio.write("{}_tetra.xdmf".format(self.filename), tetra_mesh) meshio.write("{}_triangle.xdmf".format(self.filename), triangle_mesh) mesh = Mesh() # with XDMFFile("mesh.xdmf") as infile: # infile.read(mesh) mesh_file = XDMFFile(MPI.comm_world, "{}_triangle.xdmf".format(self.filename)) mesh = Mesh() mesh_file.read(mesh); # mvc = MeshValueCollection("size_t", mesh, 2) mvc = MeshValueCollection("size_t", mesh, 3) mesh_file.read(mvc, "name_to_read") # with XDMFFile("mf.xdmf") as infile: # infile.read(mvc, "name_to_read") mf = cpp.mesh.MeshFunctionSizet(mesh, mvc) File("{}_domains.pvd".format(self.filename)).write(mf)
def test_stretch(): alpha = 2.0 s = pygalmesh.Stretch(pygalmesh.Cuboid([0, 0, 0], [1, 2, 3]), [alpha, 0.0, 0.0]) pygalmesh.generate_mesh(s, 'out.mesh', cell_size=0.2, edge_size=0.2, verbose=False) vertices, cells, _, _, _ = meshio.read('out.mesh') tol = 1.0e-3 assert abs(max(vertices[:, 0]) - alpha) < tol assert abs(min(vertices[:, 0]) + 0.0) < tol assert abs(max(vertices[:, 1]) - 2.0) < tol assert abs(min(vertices[:, 1]) + 0.0) < tol assert abs(max(vertices[:, 2]) - 3.0) < tol assert abs(min(vertices[:, 2]) + 0.0) < tol vol = sum(compute_volumes(vertices, cells['tetra'])) assert abs(vol - 12.0) < tol return
def test_cli(): input_mesh = helpers.tri_mesh infile = tempfile.NamedTemporaryFile().name meshio.write(infile, input_mesh, file_format="gmsh-ascii") outfile = tempfile.NamedTemporaryFile().name meshio.cli.main([ infile, outfile, "--input-format", "gmsh-ascii", "--output-format", "vtk-binary", ]) mesh = meshio.read(outfile, file_format="vtk-binary") atol = 1.0e-15 assert numpy.allclose(input_mesh.points, mesh.points, atol=atol, rtol=0.0) for cell_type, data in input_mesh.cells.items(): assert numpy.allclose(data, mesh.cells[cell_type]) return
def wing(): # creation of a volumic wing with the extrusion of a 2d profile on a # generatrix defined by a 3d-spline sys.path.append('./profiles') from splineProfileMultiParam import Profile from scipy import interpolate from mpl_toolkits.mplot3d import Axes3D # creation of the geometry pygmsh geom = pg.built_in.Geometry() # control points of the generatrix x = [0.0, 0.1, 0.4, 0.6, 0.9] y = [0.0, 0.05, 0.09, 0.11, 0.4] z = [0.0, 0.3, 0.8, 1.2, 2.9] # tck, u represent the parametric 3d curve tck, u = interpolate.splprep([x,y,z], s=2) name = 'wingZero' Nslices = 100 # number of slices npt = 63 # points of the profile t = np.linspace(0., 1., Nslices) # parametric space pf = Profile(typ = 'fon',par = [0.82,0.21,0.13,0.08,0.029],npt = npt) # creation of the 2d profile fi = Frame(t[0], tck, type = 'Xnat') pol = pf.polyline() pol.to_frame(fi, scale = 0.5) li = pol.add_to_geom(geom) lloop = [] for l in li : lloop.append(l) ll = geom.add_line_loop(lloop) li0 = li sf = geom.add_plane_surface(ll) phys = [] geom.add_physical_surface(sf) phys.append(sf) for i in range(Nslices-1): si = t[i] sip1 = t[i+1] #pf = Profile(typ = 'fon',par = [0.82,0.21,0.13,0.08,0.029],npt = npt) fip1 = Frame(sip1, tck, type = 'Xnat') pol = pf.polyline() pol.to_frame(fip1, scale = 0.5*np.cos(sip1*0.4*np.pi)) lip1 = pol.add_to_geom(geom) for j in range(len(li)): lij = li0[j] lip1j = lip1[j] lti = geom.add_line(lij.points[0], lip1j.points[0]) ltip1 = geom.add_line(lij.points[1], lip1j.points[1]) lloop = geom.add_line_loop([lti, lip1j, -ltip1, -lij]) sf = geom.add_ruled_surface(lloop) phys.append(sf) li0 = lip1 lloop = [] for l in lip1 : lloop.append(-l) ll = geom.add_line_loop(lloop) li0 = li sf = geom.add_plane_surface(ll) phys.append(sf) physS = geom.add_surface_loop(phys) geom.add_physical_surface(phys, label = 'profile') write_geo(name, geom) import subprocess exe_gmsh = '/home/fon/gmsh-2.16.0-Linux/bin/gmsh' subprocess.call([exe_gmsh,name+'.geo','-2','-o',name+'.msh','>',name+'.mshlog']) X, cells, pt_data, cell_data, field_data = meshio.read(name+'.msh') box3D(10.,10., 10., [0]) print X print cells['triangle'] import readMSH as rmsh d = rmsh.read_msh_file(name) rmsh.write_fms_file(name,**d) d = read_msh_triangulation(name+'.msh') d.write_obj_file(name)
def load_mshfile(self, mshfile): "Load self from a MSH file." self.points, self.elements,_,_,_ = meshio.read(mshfile)
def generate_mesh( geo_object, verbose=True, dim=3, prune_vertices=True, prune_z_0=False, remove_faces=False, gmsh_path=None, extra_gmsh_arguments=None, # for debugging purposes: geo_filename=None, mesh_file_type="msh", ): """Return a meshio.Mesh, storing the mesh points, cells, and data, generated by Gmsh from the `geo_object`, written to a temporary file, and reread by `meshio`. Gmsh's native "msh" format is ill-suited to fast I/O. This can greatly reduce the performance of pygmsh. As alternatives, try `mesh_file_type=`: - "vtk"`, though Gmsh doesn't write the physical tags to VTK <https://gitlab.onelab.info/gmsh/gmsh/issues/389> or - `"mesh"`, though this only supports a few basic elements - "line", "triangle", "quad", "tetra", "hexahedron" - and doesn't preserve the `$PhysicalNames`, just the `int` tags. """ if extra_gmsh_arguments is None: extra_gmsh_arguments = [] # For format "mesh", ask Gmsh to save the physical tags # http://gmsh.info/doc/texinfo/gmsh.html#index-Mesh_002eSaveElementTagType if mesh_file_type == "mesh": extra_gmsh_arguments += ["-string", "Mesh.SaveElementTagType=2;"] preserve_geo = geo_filename is not None if geo_filename is None: with tempfile.NamedTemporaryFile(suffix=".geo") as f: geo_filename = f.name with open(geo_filename, "w") as f: f.write(geo_object.get_code()) # As of Gmsh 4.1.3, the mesh format options are # ``` # auto, msh1, msh2, msh3, msh4, msh, unv, vtk, wrl, mail, stl, p3d, mesh, bdf, cgns, # med, diff, ir3, inp, ply2, celum, su2, x3d, dat, neu, m, key # ``` # Pick the correct filename suffix. filename_suffix = "msh" if mesh_file_type[:3] == "msh" else mesh_file_type with tempfile.NamedTemporaryFile(suffix="." + filename_suffix) as handle: msh_filename = handle.name gmsh_executable = gmsh_path if gmsh_path is not None else _get_gmsh_exe() args = [ "-{}".format(dim), geo_filename, "-format", mesh_file_type, "-bin", "-o", msh_filename, ] + extra_gmsh_arguments # https://stackoverflow.com/a/803421/353337 p = subprocess.Popen( [gmsh_executable] + args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) if verbose: while True: line = p.stdout.readline() if not line: break print(line.decode("utf-8"), end="") p.communicate() assert p.returncode == 0, "Gmsh exited with error (return code {}).".format( p.returncode ) mesh = meshio.read(msh_filename) if remove_faces: # Only keep the cells of highest topological dimension; discard faces # and such. two_d_cells = set(["triangle", "quad"]) three_d_cells = set( ["tetra", "hexahedron", "wedge", "pyramid", "penta_prism", "hexa_prism"] ) if any(k in mesh.cells for k in three_d_cells): keep_keys = three_d_cells.intersection(mesh.cells.keys()) elif any(k in mesh.cells for k in two_d_cells): keep_keys = two_d_cells.intersection(mesh.cells.keys()) else: keep_keys = mesh.cells.keys() mesh.cells = {key: mesh.cells[key] for key in keep_keys} mesh.cell_data = {key: mesh.cell_data[key] for key in keep_keys} if prune_vertices: # Make sure to include only those vertices which belong to a cell. ncells = numpy.concatenate([numpy.concatenate(c) for c in mesh.cells.values()]) uvertices, uidx = numpy.unique(ncells, return_inverse=True) k = 0 for key in mesh.cells.keys(): n = numpy.prod(mesh.cells[key].shape) mesh.cells[key] = uidx[k : k + n].reshape(mesh.cells[key].shape) k += n mesh.points = mesh.points[uvertices] for key in mesh.point_data: mesh.point_data[key] = mesh.point_data[key][uvertices] # clean up os.remove(msh_filename) if preserve_geo: print("\ngeo file: {}".format(geo_filename)) else: os.remove(geo_filename) if ( prune_z_0 and mesh.points.shape[1] == 3 and numpy.all(numpy.abs(mesh.points[:, 2]) < 1.0e-13) ): mesh.points = mesh.points[:, :2] return mesh
# -*- coding: utf-8 -*- """ Load a GMSH mesh and plot contours for its height. """ import meshio import numpy as np import matplotlib.pyplot as plt from matplotlib.tri import Triangulation from matplotlib import rcParams rcParams['font.family'] = 'serif' rcParams['font.size'] = 14 rcParams['image.cmap'] = "YlGnBu_r" points, cells, point_data, cell_data, field_data = \ meshio.read("../MESHES/DAM/dam.msh") x = points[:, 0] y = points[:, 1] tri = Triangulation(x, y, cells['triangle']) plt.tricontourf(tri, y, 12, shading="gourad") plt.axis("image") plt.show()