def generic_io(filename): with tempfile.TemporaryDirectory() as temp_dir: filepath = os.path.join(temp_dir, filename) meshio.write_points_cells(filepath, tri_mesh.points, tri_mesh.cells) out_mesh = meshio.helpers.read(filepath) assert (abs(out_mesh.points - tri_mesh.points) < 1.0e-15).all() assert (tri_mesh.cells["triangle"] == out_mesh.cells["triangle"]).all() 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 _from_nastran(source, filename): import meshio points = [] point_index = 0 point_indexes = {} cells = {"triangle": [], "quad": []} shell_ids = {"triangle": [], "quad": []} shell_material_ids = {} with open(source) as file: while True: line = file.readline() if not line or line.strip().startswith("BEGIN BULK"): break while True: line = file.readline() if not line or line.startswith("ENDDATA"): break if line.strip().startswith("$"): continue fields = [line[i:i + 8] for i in range(0, len(line), 8)] if fields[0].startswith("GRID"): point_indexes[int(fields[1])] = point_index point_index += 1 points.append( [_nastran_real_to_float(f) / 1000 for f in fields[3:6]]) elif fields[0].startswith("CTRIA3"): cells["triangle"].append( [point_indexes[int(f)] for f in fields[3:6]]) shell_ids["triangle"].append(int(fields[2])) elif fields[0].startswith("CQUAD4"): cells["quad"].append( [point_indexes[int(f)] for f in fields[3:7]]) shell_ids["quad"].append(int(fields[2])) elif fields[0].startswith("PSHELL"): shell_material_ids[int(fields[1])] = int(fields[2]) meshio_cells = [] meshio_cell_data = defaultdict(list) if cells["triangle"]: meshio_cells.append(("triangle", np.array(cells["triangle"]))) meshio_cell_data["gmsh:geometrical"].append( np.array(shell_ids["triangle"])) meshio_cell_data["gmsh:physical"].append( np.array(shell_ids["triangle"])) if cells["quad"]: meshio_cells.append(("quad", np.array(cells["quad"]))) meshio_cell_data["gmsh:geometrical"].append(np.array( shell_ids["quad"])) meshio_cell_data["gmsh:physical"].append(np.array(shell_ids["quad"])) meshio.write_points_cells( filename, np.array(points), meshio_cells, cell_data=meshio_cell_data, field_data={ f"{str(n)}": (n, 2) for n in sorted(list(set(shell_material_ids))) }, file_format="gmsh22", binary=False)
def save_meshio(filename, mesh, file_format = None, **kwargs): """Save mesh to file using meshio. Parameters ---------- mesh : pyvista.Common Any PyVista mesh/spatial data type. file_format : str File type for meshio to save. """ import meshio from meshio.vtk._vtk import vtk_to_meshio_type # Make sure relative paths will work filename = os.path.abspath(os.path.expanduser(str(filename))) # Cast to pyvista.UnstructuredGrid if not isinstance(mesh, pyvista.UnstructuredGrid): mesh = mesh.cast_to_unstructured_grid() # Copy useful arrays to avoid repeated calls to properties vtk_offset = mesh.offset vtk_cells = mesh.cells vtk_cell_type = mesh.celltypes # Check that meshio supports all cell types in input mesh pixel_voxel = {8, 11} # Handle pixels and voxels for cell_type in np.unique(vtk_cell_type): if cell_type not in vtk_to_meshio_type.keys() and cell_type not in pixel_voxel: raise TypeError(f"meshio does not support VTK type {cell_type}.") # Get cells cells = [] c = 0 for offset, cell_type in zip(vtk_offset, vtk_cell_type): numnodes = vtk_cells[offset+c] if VTK9: # must offset by cell count cell = vtk_cells[offset+1+c:offset+1+c+numnodes] c += 1 else: cell = vtk_cells[offset+1:offset+1+numnodes] cell = ( cell if cell_type not in pixel_voxel else cell[[0, 1, 3, 2]] if cell_type == 8 else cell[[0, 1, 3, 2, 4, 5, 7, 6]] ) cell_type = cell_type if cell_type not in pixel_voxel else cell_type+1 cell_type = ( vtk_to_meshio_type[cell_type] if cell_type != 7 else f"polygon{numnodes}" ) if len(cells) > 0 and cells[-1][0] == cell_type: cells[-1][1].append(cell) else: cells.append((cell_type, [cell])) for k, c in enumerate(cells): cells[k] = (c[0], np.array(c[1])) # Get point data point_data = {k.replace(" ", "_"): v for k, v in mesh.point_arrays.items()} # Get cell data vtk_cell_data = mesh.cell_arrays n_cells = np.cumsum([len(c[1]) for c in cells[:-1]]) cell_data = ( {k.replace(" ", "_"): np.split(v, n_cells) for k, v in vtk_cell_data.items()} if vtk_cell_data else {} ) # Save using meshio meshio.write_points_cells( filename=filename, points=np.array(mesh.points), cells=cells, point_data=point_data, cell_data=cell_data, file_format=file_format, **kwargs )
circ = geom.add_circle([0.0, 0.0, 0.0], 0.1, lcar=lcar, make_surface=False) poly = geom.add_polygon( [ [+0.0, +0.5, 0.0], [-0.1, +0.1, 0.0], [-0.5, +0.0, 0.0], [-0.1, -0.1, 0.0], [+0.0, -0.5, 0.0], [+0.1, -0.1, 0.0], [+0.5, +0.0, 0.0], [+0.1, +0.1, 0.0], ], lcar=lcar, holes=[circ], ) axis = [0, 0, 1.0] geom.extrude(poly, translation_axis=axis, num_layers=1) ref = 0.16951514066385628 points, cells, _, _, _ = pygmsh.generate_mesh(geom) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells if __name__ == "__main__": import meshio meshio.write_points_cells("layers.vtu", *test())
def write_off(data, save_path): points = data[0] cells = [("triangle", data[1])] meshio.write_points_cells(save_path, points, cells)
def run(self, inputSetup): """Run a postprocessing task. :param obj inputSetup: inputSetup object. :return: None """ # --------------------------------------------------------------- # Obtain the MPI environment # --------------------------------------------------------------- parEnv = MPIEnvironment() # --------------------------------------------------------------- # Initialization # --------------------------------------------------------------- # Start timer Timers()["Postprocessing"].start() # Parameters shortcut (for code legibility) model = inputSetup.model run = inputSetup.run output = inputSetup.output out_dir_scratch = output.get('directory_scratch') out_dir = output.get('directory') # --------------------------------------------------------------- # Postprocessing (sequential task) # --------------------------------------------------------------- if (parEnv.rank == 0): # --------------------------------------------------------------- # Define constants # --------------------------------------------------------------- num_nodes_per_element = 4 #num_edges_per_element = 6 #num_faces_per_element = 4 #num_nodes_per_face = 3 num_edges_per_face = 3 #num_nodes_per_edge = 2 #num_dimensions = 3 basis_order = run.get('nord') num_polarizations = run.get('num_polarizations') num_dof_in_element = np.int(basis_order * (basis_order + 2) * (basis_order + 3) / 2) if (model.get('mode') == 'csem'): mode = 'csem' data_model = model.get(mode) # Get data model frequency = data_model.get('source').get('frequency') elif (model.get('mode') == 'mt'): mode = 'mt' data_model = model.get(mode) # Get data model frequency = data_model.get('frequency') omega = frequency * 2. * np.pi mu = 4. * np.pi * 1e-7 Const = np.sqrt(-1. + 0.j) * omega * mu # Get version code version_file = open('petgem/VERSION') code_version = version_file.read().strip() version_file.close() # --------------------------------------------------------------- # Import mesh file # --------------------------------------------------------------- mesh_file = model.get('mesh') # Import mesh mesh = meshio.read(mesh_file) # Number of elements size = mesh.cells[0][1][:].shape nElems = size[0] # Number of nodes size = mesh.points.shape nNodes = size[0] # --------------------------------------------------------------- # Build data structures for edge elements # --------------------------------------------------------------- # Compute edges elemsE, edgesN = computeEdges(mesh.cells[0][1][:], nElems) #nEdges = edgesN.shape[0] # Compute faces elemsF, facesN = computeFaces(mesh.cells[0][1][:], nElems) nFaces = facesN.shape[0] # Compute faces-edges facesE = computeFacesEdges(elemsF, elemsE, nFaces, nElems) # Compute degrees of freedom connectivity dofs, dof_edges, dof_faces, _, total_num_dofs = computeConnectivityDOFS( elemsE, elemsF, basis_order) # --------------------------------------------------------------- # Read receivers file # --------------------------------------------------------------- # Open receivers_file receivers_file = model.get('receivers') fileID = h5py.File(receivers_file, 'r') # Read receivers receivers = fileID.get('data')[()] # Number of receivers if receivers.ndim == 1: nReceivers = 1 else: dim = receivers.shape nReceivers = dim[0] # --------------------------------------------------------------- # Read vector solution # --------------------------------------------------------------- x = [] for i in np.arange(num_polarizations): input_file = out_dir_scratch + '/x' + str(i) + '.dat' x.append( readPetscVector(input_file, communicator=PETSc.COMM_SELF)) # --------------------------------------------------------------- # Compute solution for each point and each polarization mode # --------------------------------------------------------------- # Allocate array to save field components (Ex, Ey, Ez, Hx, Hy, Hz) fields_receivers = [] for i in np.arange(num_polarizations): fields_receivers.append( fieldInterpolator(x[i], mesh.points, mesh.cells[0][1][:], elemsE, edgesN, elemsF, facesE, dofs, receivers, inputSetup)) # --------------------------------------------------------------- # Compute apparent resistivity # --------------------------------------------------------------- if (mode == 'mt'): apparent_res, phase, tipper, impedance = computeImpedance( fields_receivers, omega, mu) # --------------------------------------------------------------- # Compute solution for entire mesh # --------------------------------------------------------------- if (output.get('vtk')): # Allocate array for points scaledCoord = np.zeros((4, 3), dtype=np.float) local_contribution = np.zeros((num_nodes_per_element, 6), dtype=np.complex) # Scale factor for tetrahedral element scaleFactor = .9999 # Allocate array to save field components (Ex, Ey, Ez, Hx, Hy, Hz) fields_nodes = [] for i in np.arange(num_polarizations): # Allocate arrays for electromagnetic responses computation fields_tmp = np.zeros((nNodes, 6), dtype=np.complex) for j in np.arange(nElems): # Get dofs of element dofsEle = dofs[j, :] # Get indexes of nodes for iEle nodesEle = mesh.cells[0][1][j, :] # Get nodes coordinates for iEle coordEle = mesh.points[nodesEle, :] # Get indexes of faces for iEle facesEle = elemsF[j, :] # Get edges indexes for faces edgesFace = facesE[facesEle, :] # Get indexes of edges for iEle edgesEle = elemsE[j, :] # Get node indexes for edges in i and insert edgesNodesEle = edgesN[edgesEle, :] # Compute jacobian for i jacobian, invjacobian = computeJacobian(coordEle) # Compute global orientation for i edge_orientation, face_orientation = computeElementOrientation( edgesEle, nodesEle, edgesNodesEle, edgesFace) # Compute element centroid centroid = np.sum(coordEle, axis=0) / 4. # Apply small scaling to element coordinates scaledCoord[:, 0] = centroid[0] + ( coordEle[:, 0] - centroid[0]) * scaleFactor scaledCoord[:, 1] = centroid[1] + ( coordEle[:, 1] - centroid[1]) * scaleFactor scaledCoord[:, 2] = centroid[2] + ( coordEle[:, 2] - centroid[2]) * scaleFactor # Transform xyz source position to XiEtaZeta coordinates (reference tetrahedral element) XiEtaZeta = tetrahedronXYZToXiEtaZeta( coordEle, scaledCoord) # Compute basis for i basis, curl_basis = computeBasisFunctions( edge_orientation, face_orientation, jacobian, invjacobian, basis_order, XiEtaZeta) # Get global dofs from x vector realField = np.real(x[i].getValues( dofsEle.astype(PETSc.IntType))) imagField = np.imag(x[i].getValues( dofsEle.astype(PETSc.IntType))) # Interpolate field for nodes in i for k in np.arange(num_nodes_per_element): for l in np.arange(num_dof_in_element): # Exyz[i] = Exyz[i] + real_part*basis + imag_part*basis local_contribution[k, 0] += realField[ l] * basis[0, l, k] + np.sqrt( -1. + 0.j) * imagField[l] * basis[0, l, k] local_contribution[k, 1] += realField[ l] * basis[1, l, k] + np.sqrt( -1. + 0.j) * imagField[l] * basis[1, l, k] local_contribution[k, 2] += realField[ l] * basis[2, l, k] + np.sqrt( -1. + 0.j) * imagField[l] * basis[2, l, k] # Hxyz[i] = Hxyz[i] + real_part*curl_basis + imag_part*curl_basis local_contribution[k, 3] += realField[ l] * curl_basis[0, l, k] + np.sqrt( -1. + 0.j) * imagField[l] * curl_basis[ 0, l, k] local_contribution[k, 4] += realField[ l] * curl_basis[1, l, k] + np.sqrt( -1. + 0.j) * imagField[l] * curl_basis[ 1, l, k] local_contribution[k, 5] += realField[ l] * curl_basis[2, l, k] + np.sqrt( -1. + 0.j) * imagField[l] * curl_basis[ 2, l, k] # Add local contribution to global array fields_tmp[nodesEle, :] += local_contribution # Clean variable for next iteration local_contribution[:] = 0. fields_nodes.append(fields_tmp) # Compute number of elements that share each node num_elems_shared_node = np.zeros(nNodes, dtype=np.float) for i in np.arange(nNodes): num_elems_shared_node[i] = np.count_nonzero( mesh.cells[0][1][:] == i) # Divide the field of each node by the number of elements that share it num_components = 6 # Six electromagnetic field components (Ex, Ey, Ez, Hx, Hy, Hz) for i in np.arange(num_polarizations): for j in np.arange(num_components): fields_nodes[i][:, j] /= num_elems_shared_node # Following Maxwell equations, apply constant factor to magnetic field for j in np.arange(3, 6): fields_nodes[i][:, j] /= Const # Conductivity model to vtk input_file = out_dir_scratch + '/conductivityModel.dat' tmpSigmaModel = readPetscMatrix(input_file, communicator=PETSc.COMM_SELF) sigmaModel = np.zeros((nElems, 2), dtype=np.float) for i in np.arange(nElems): sigmaEle = tmpSigmaModel.getRow(i)[1].real sigmaModel[i:] = sigmaEle # Set conductivity model to elements mesh.cell_data = { "sigma_horizontal": sigmaModel[:, 0], "sigma_vertical": sigmaModel[:, 0] } # For each polarization and each component, write data to vtk file # meshio doesn't support complex number, then fields are decoupled # in real and imaginary part if (mode == 'csem'): mesh.point_data = { 'csem_Ex_real': np.real(fields_nodes[0][:, 0]), 'csem_Ey_real': np.real(fields_nodes[0][:, 1]), 'csem_Ez_real': np.real(fields_nodes[0][:, 2]), 'csem_Hx_real': np.real(fields_nodes[0][:, 3]), 'csem_Hy_real': np.real(fields_nodes[0][:, 4]), 'csem_Hz_real': np.real(fields_nodes[0][:, 5]), 'csem_Ex_imag': np.imag(fields_nodes[0][:, 0]), 'csem_Ey_imag': np.imag(fields_nodes[0][:, 1]), 'csem_Ez_imag': np.imag(fields_nodes[0][:, 2]), 'csem_Hx_imag': np.imag(fields_nodes[0][:, 3]), 'csem_Hy_imag': np.imag(fields_nodes[0][:, 4]), 'csem_Hz_imag': np.imag(fields_nodes[0][:, 5]) } elif (mode == 'mt'): # Get polarization mode polatization_mode = data_model.get('polarization') if (num_polarizations == 1): mesh.point_data = { 'mt_Ex_real_mode' + polatization_mode: np.real(fields_nodes[0][:, 0]), 'mt_Ey_real_mode' + polatization_mode: np.real(fields_nodes[0][:, 1]), 'mt_Ez_real_mode' + polatization_mode: np.real(fields_nodes[0][:, 2]), 'mt_Hx_real_mode' + polatization_mode: np.real(fields_nodes[0][:, 3]), 'mt_Hy_real_mode' + polatization_mode: np.real(fields_nodes[0][:, 4]), 'mt_Hz_real_mode' + polatization_mode: np.real(fields_nodes[0][:, 5]), 'mt_Ex_imag_mode' + polatization_mode: np.imag(fields_nodes[0][:, 0]), 'mt_Ey_imag_mode' + polatization_mode: np.imag(fields_nodes[0][:, 1]), 'mt_Ez_imag_mode' + polatization_mode: np.imag(fields_nodes[0][:, 2]), 'mt_Hx_imag_mode' + polatization_mode: np.imag(fields_nodes[0][:, 3]), 'mt_Hy_imag_mode' + polatization_mode: np.imag(fields_nodes[0][:, 4]), 'mt_Hz_imag_mode' + polatization_mode: np.imag(fields_nodes[0][:, 5]) } elif (num_polarizations == 2): mesh.point_data = { 'mt_Ex_real_mode' + polatization_mode[0]: np.real(fields_nodes[0][:, 0]), 'mt_Ey_real_mode' + polatization_mode[0]: np.real(fields_nodes[0][:, 1]), 'mt_Ez_real_mode' + polatization_mode[0]: np.real(fields_nodes[0][:, 2]), 'mt_Hx_real_mode' + polatization_mode[0]: np.real(fields_nodes[0][:, 3]), 'mt_Hy_real_mode' + polatization_mode[0]: np.real(fields_nodes[0][:, 4]), 'mt_Hz_real_mode' + polatization_mode[0]: np.real(fields_nodes[0][:, 5]), 'mt_Ex_real_mode' + polatization_mode[1]: np.real(fields_nodes[1][:, 0]), 'mt_Ey_real_mode' + polatization_mode[1]: np.real(fields_nodes[1][:, 1]), 'mt_Ez_real_mode' + polatization_mode[1]: np.real(fields_nodes[1][:, 2]), 'mt_Hx_real_mode' + polatization_mode[1]: np.real(fields_nodes[1][:, 3]), 'mt_Hy_real_mode' + polatization_mode[1]: np.real(fields_nodes[1][:, 4]), 'mt_Hz_real_mode' + polatization_mode[1]: np.real(fields_nodes[1][:, 5]), 'mt_Ex_imag_mode' + polatization_mode[0]: np.imag(fields_nodes[0][:, 0]), 'mt_Ey_imag_mode' + polatization_mode[0]: np.imag(fields_nodes[0][:, 1]), 'mt_Ez_imag_mode' + polatization_mode[0]: np.imag(fields_nodes[0][:, 2]), 'mt_Hx_imag_mode' + polatization_mode[0]: np.imag(fields_nodes[0][:, 3]), 'mt_Hy_imag_mode' + polatization_mode[0]: np.imag(fields_nodes[0][:, 4]), 'mt_Hz_imag_mode' + polatization_mode[0]: np.imag(fields_nodes[0][:, 5]), 'mt_Ex_imag_mode' + polatization_mode[1]: np.imag(fields_nodes[1][:, 0]), 'mt_Ey_imag_mode' + polatization_mode[1]: np.imag(fields_nodes[1][:, 1]), 'mt_Ez_imag_mode' + polatization_mode[1]: np.imag(fields_nodes[1][:, 2]), 'mt_Hx_imag_mode' + polatization_mode[1]: np.imag(fields_nodes[1][:, 3]), 'mt_Hy_imag_mode' + polatization_mode[1]: np.imag(fields_nodes[1][:, 4]), 'mt_Hz_imag_mode' + polatization_mode[1]: np.imag(fields_nodes[1][:, 5]) } # Write vtk file vtk_filename = out_dir + '/' + mode + '_petgemV' + code_version + '_' + str( datetime.today().strftime('%Y-%m-%d')) + '.vtk' meshio.write_points_cells(vtk_filename, mesh.points, mesh.cells, mesh.point_data, mesh.cell_data) # --------------------------------------------------------------- # Save results and data provedance # --------------------------------------------------------------- # Create output file output_file_name = '/' + mode + '_' + 'petgemV' + code_version + '_' + str( datetime.today().strftime('%Y-%m-%d')) + '.h5' output_file = out_dir + output_file_name fileID = h5py.File(output_file, 'w') # Create group for data machine machine = fileID.create_group('machine') # Name uname = platform.uname() uname = uname.node + '. ' + uname.release + '. ' + uname.processor machine.create_dataset('machine', data=uname) # Number of cores machine.create_dataset('num_processors', data=parEnv.num_proc) # PETGEM version machine.create_dataset('petgem_version', data=code_version) # Create group for data model model_dataprovedance = fileID.create_group('model') # Modeling date model_dataprovedance.create_dataset( 'date', data=datetime.today().isoformat()) # Mesh file model_dataprovedance.create_dataset('mesh_file', data=model.get('mesh')) # Receivers file model_dataprovedance.create_dataset('receivers_file', data=model.get('receivers')) # Basis order model_dataprovedance.create_dataset('nord', data=run.get('nord')) # Number of dofs model_dataprovedance.create_dataset('dof', data=total_num_dofs) # Cuda support model_dataprovedance.create_dataset('cuda', data=run.get('cuda')) # vtk output model_dataprovedance.create_dataset('vtk', data=output.get('vtk')) # Modeling mode model_dataprovedance.create_dataset('mode', data=mode) # Number of polarizations model_dataprovedance.create_dataset('num-polarizations', data=num_polarizations) # Solver type OptDB = PETSc.Options() # get PETSc option DB solver_type = OptDB.getString('ksp_type', 'None') model_dataprovedance.create_dataset('solver', data=solver_type) # Run-time (assembly and solver) elapsed_time = Timers()["Assembly"].elapsed + Timers( )["Solver"].elapsed model_dataprovedance.create_dataset('run-time (s)', data=elapsed_time) # Create data model if (mode == 'csem'): if (run.get('conductivity_from_file')): model_dataprovedance.create_dataset( 'sigma-file', data=data_model.get('sigma').get('file')) else: model_dataprovedance.create_dataset( 'sigma_horizontal (S/m)', data=data_model.get('sigma').get('horizontal')) model_dataprovedance.create_dataset( 'sigma_vertical (S/m)', data=data_model.get('sigma').get('vertical')) model_dataprovedance.create_dataset( 'frequency (Hz)', data=data_model.get('source').get('frequency')) model_dataprovedance.create_dataset( 'source_position (m)', data=np.asarray(data_model.get('source').get('position'), dtype=np.float)) model_dataprovedance.create_dataset( 'source_azimuth (deg)', data=data_model.get('source').get('azimuth')) model_dataprovedance.create_dataset( 'source_dip (deg)', data=data_model.get('source').get('dip')) model_dataprovedance.create_dataset( 'source_current (Am)', data=data_model.get('source').get('current')) model_dataprovedance.create_dataset( 'source_length (m)', data=data_model.get('source').get('length')) elif (mode == 'mt'): if (run.get('conductivity_from_file')): model_dataprovedance.create_dataset( 'sigma-file', data=data_model.get('sigma').get('file')) else: model_dataprovedance.create_dataset( 'sigma_horizontal (S/m)', data=data_model.get('sigma').get('horizontal')) model_dataprovedance.create_dataset( 'sigma_vertical (S/m)', data=data_model.get('sigma').get('vertical')) model_dataprovedance.create_dataset( 'frequency (Hz)', data=data_model.get('frequency')) model_dataprovedance.create_dataset( 'polarization', data=data_model.get('polarization')) # Write electromagnetic responses if (mode == 'csem'): # Electric fields E_fields = model_dataprovedance.create_group('E-fields') E_fields.create_dataset('x', data=fields_receivers[0][:, 0]) E_fields.create_dataset('y', data=fields_receivers[0][:, 1]) E_fields.create_dataset('z', data=fields_receivers[0][:, 2]) # Magnetic fields H_fields = model_dataprovedance.create_group('H-fields') H_fields.create_dataset('x', data=fields_receivers[0][:, 3]) H_fields.create_dataset('y', data=fields_receivers[0][:, 4]) H_fields.create_dataset('z', data=fields_receivers[0][:, 5]) elif (mode == 'mt'): list_modes = data_model.get('polarization') for i in np.arange(num_polarizations): mode_E_i = 'E-fields_mode_' + list_modes[i] mode_H_i = 'H-fields_mode_' + list_modes[i] E_fields = model_dataprovedance.create_group(mode_E_i) E_fields.create_dataset('x', data=fields_receivers[i][:, 0]) E_fields.create_dataset('y', data=fields_receivers[i][:, 1]) E_fields.create_dataset('z', data=fields_receivers[i][:, 2]) # Magnetic fields H_fields = model_dataprovedance.create_group(mode_H_i) H_fields.create_dataset('x', data=fields_receivers[i][:, 3]) H_fields.create_dataset('y', data=fields_receivers[i][:, 4]) H_fields.create_dataset('z', data=fields_receivers[i][:, 5]) imp = model_dataprovedance.create_group('impedance') imp.create_dataset('xx', data=impedance[0]) imp.create_dataset('xy', data=impedance[1]) imp.create_dataset('yx', data=impedance[2]) imp.create_dataset('yy', data=impedance[3]) app_res = model_dataprovedance.create_group( 'apparent_resistivity') app_res.create_dataset('xx', data=apparent_res[0]) app_res.create_dataset('xy', data=apparent_res[1]) app_res.create_dataset('yx', data=apparent_res[2]) app_res.create_dataset('yy', data=apparent_res[3]) pha = model_dataprovedance.create_group('phase') pha.create_dataset('xx', data=phase[0]) pha.create_dataset('xy', data=phase[1]) pha.create_dataset('yx', data=phase[2]) pha.create_dataset('yy', data=phase[3]) tip = model_dataprovedance.create_group('tipper') tip.create_dataset('x', data=tipper[0]) tip.create_dataset('y', data=tipper[1]) # Close file fileID.close() # Remove temporal directory if (output.get('remove_scratch')): shutil.rmtree(out_dir_scratch) else: files_in_directory = os.listdir(out_dir_scratch) filtered_files = [ file for file in files_in_directory if (file.endswith(".dat") or file.endswith(".info")) ] for file in filtered_files: path_to_file = os.path.join(out_dir_scratch, file) os.remove(path_to_file) # Stop timer Timers()["Postprocessing"].stop() return
points, cells, _, _, _ = pygmsh.generate_mesh(geom) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells @pytest.mark.skipif(pygmsh.get_gmsh_major_version() < 3, reason="requires Gmsh >= 3") def test_all(): geom = pygmsh.opencascade.Geometry(characteristic_length_min=0.1, characteristic_length_max=0.1) rectangle = geom.add_rectangle([-1.0, -1.0, 0.0], 2.0, 2.0) disk1 = geom.add_disk([-1.0, 0.0, 0.0], 0.5) disk2 = geom.add_disk([+1.0, 0.0, 0.0], 0.5) union = geom.boolean_union([rectangle, disk1, disk2]) disk3 = geom.add_disk([0.0, -1.0, 0.0], 0.5) disk4 = geom.add_disk([0.0, +1.0, 0.0], 0.5) geom.boolean_difference([union], [disk3, disk4]) ref = 4.0 points, cells, _, _, _ = pygmsh.generate_mesh(geom) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells if __name__ == "__main__": import meshio meshio.write_points_cells("boolean.vtu", *test_all())
def __init__(self): # https://fenicsproject.org/qa/12891/initialize-mesh-from-vertices-connectivities-at-once points, cells, _, cell_data, _ = meshes.ball_in_tube_cyl.generate() # 2018.1 # self.mesh = Mesh( # dolfin.mpi_comm_world(), dolfin.cpp.mesh.CellType.Type_triangle, # points[:, :2], cells['triangle'] # ) with TemporaryDirectory() as temp_dir: tmp_filename = os.path.join(temp_dir, "test.xml") meshio.write_points_cells( tmp_filename, points, cells, cell_data=cell_data, file_format="dolfin-xml", ) self.mesh = Mesh(tmp_filename) V0_element = FiniteElement("CG", self.mesh.ufl_cell(), 2) V1_element = FiniteElement("B", self.mesh.ufl_cell(), 3) self.W = FunctionSpace(self.mesh, V0_element * V1_element) self.P = FunctionSpace(self.mesh, "CG", 1) # Define mesh and boundaries. class LeftBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[0] < GMSH_EPS left_boundary = LeftBoundary() class RightBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[0] > 1.0 - GMSH_EPS right_boundary = RightBoundary() class LowerBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[1] < GMSH_EPS lower_boundary = LowerBoundary() # class UpperBoundary(SubDomain): # # pylint: disable=no-self-use # def inside(self, x, on_boundary): # return on_boundary and x[1] > 5.0-GMSH_EPS class CoilBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): # One has to pay a little bit of attention when defining the # coil boundary; it's easy to miss the edges closest to x[0]=0. return ( on_boundary and x[1] > 1.0 - GMSH_EPS and x[1] < 2.0 + GMSH_EPS and x[0] < 1.0 - GMSH_EPS ) coil_boundary = CoilBoundary() self.u_bcs = [ DirichletBC(self.W, (0.0, 0.0), right_boundary), DirichletBC(self.W.sub(0), 0.0, left_boundary), DirichletBC(self.W, (0.0, 0.0), lower_boundary), DirichletBC(self.W, (0.0, 0.0), coil_boundary), ] self.p_bcs = [] # self.p_bcs = [DirichletBC(Q, 0.0, upper_boundary)] return
def get_poisson_steps_dolfin(pts, cells, tol): from dolfin import ( Constant, DirichletBC, Function, FunctionSpace, KrylovSolver, Mesh, TestFunction, TrialFunction, XDMFFile, assemble, dx, grad, inner, ) # Still can't initialize a mesh from points, cells filename = "mesh.xdmf" if cells.shape[1] == 3: meshio.write_points_cells(filename, pts, {"triangle": cells}) else: assert cells.shape[1] == 4 meshio.write_points_cells(filename, pts, {"tetra": cells}) mesh = Mesh() with XDMFFile(filename) as f: f.read(mesh) os.remove(filename) os.remove("mesh.h5") # build Laplace matrix with Dirichlet boundary using dolfin V = FunctionSpace(mesh, "Lagrange", 1) u = TrialFunction(V) v = TestFunction(V) a = inner(grad(u), grad(v)) * dx u0 = Constant(0.0) bc = DirichletBC(V, u0, "on_boundary") f = Constant(1.0) L = f * v * dx A = assemble(a) b = assemble(L) bc.apply(A, b) # solve(A, x, b, "cg") solver = KrylovSolver("cg", "none") solver.parameters["absolute_tolerance"] = 0.0 solver.parameters["relative_tolerance"] = tol x = Function(V) x_vec = x.vector() num_steps = solver.solve(A, x_vec, b) # # convert to scipy matrix # A = as_backend_type(A).mat() # ai, aj, av = A.getValuesCSR() # A = scipy.sparse.csr_matrix( # (av, aj, ai), shape=(A.getLocalSize()[0], A.getSize()[1]) # ) # # ev = eigvals(A.todense()) # ev_max = scipy.sparse.linalg.eigs(A, k=1, which="LM")[0][0] # assert numpy.abs(ev_max.imag) < 1.0e-15 # ev_max = ev_max.real # ev_min = scipy.sparse.linalg.eigs(A, k=1, which="SM")[0][0] # assert numpy.abs(ev_min.imag) < 1.0e-15 # ev_min = ev_min.real # cond = ev_max / ev_min # solve poisson system, count num steps # b = numpy.ones(A.shape[0]) # out = pykry.gmres(A, b) # num_steps = len(out.resnorms) return num_steps
def export( filename, grid=None, grid_function=None, data_type="node", transformation=None, write_binary=True, ): """ Exporter for grids and grid functions. This method internally uses the meshio library. For a full list of supported data types see https://github.com/nschloe/meshio Note that export of domain indices is only possible for Gmsh (.msh) format files. Parameters ---------- filename : string The name of the file to write out. The data type is chosen based on the file ending. grid : Grid object A grid object to export. grid_function : GridFunction object Grid function to export data_type : string Either 'node' for vertex data or 'element' for data at element centers. transformation : string or callable One of 'real', 'imag', 'abs', 'log_abs', None or a callable object. Transforms the data on input. A callable must return numpy arrays with the same number of dimensions as the input. If transformation is None the data is not modified. write_binary : Boolean Use binary format (write_binary=True) for the data if supported by the file format. """ import os _, extension = os.path.splitext(filename) file_format = None if extension == ".msh": # Ensure that we use Gmsh2 for output # to preserve domain indices. # meshio does not yet support domain # indices for gmsh4. gmsh = True if write_binary: file_format = "gmsh22" else: file_format = "gmsh22" else: gmsh = False if grid is not None and grid_function is not None: raise ValueError( "Exactly one of 'grid' and 'grid_function' must be supplied.") cell_data = {} point_data = None if grid_function is not None: grid = grid_function.space.grid if data_type == "node": data = _transform_array(grid_function.evaluate_on_vertices(), transformation).T if _np.iscomplexobj(data): point_data = {"real": _np.real(data), "imag": _np.imag(data)} else: point_data = {"data": data} elif data_type == "element": data = _transform_array( grid_function.evaluate_on_element_centers(), transformation).T if _np.iscomplexobj(data): cell_data["real"] = _np.real(data) cell_data["imag"] = _np.imag(data) else: cell_data["data"] = data.reshape(1, -1) else: raise ValueError("'data_type' must be one of 'element' or 'node'") cells = [("triangle", grid.elements.T.astype("int32"))] points = grid.vertices.T if gmsh: # physical and geometrical index must be 2 dim arrays with first dimension # equal to the number of different element types (here always 1 cell_data["gmsh:physical"] = grid.domain_indices.astype( "int32").reshape((1, -1)) unique_dom_indices = set(grid.domain_indices) unique_geom_indices = range(1, 1 + len(unique_dom_indices)) geom_indices_map = dict(zip(unique_dom_indices, unique_geom_indices)) geom_indices = _np.array( [geom_indices_map[dom_index] for dom_index in grid.domain_indices], dtype="int32", ) cell_data["gmsh:geometrical"] = geom_indices.reshape((1, -1)) else: cell_data["domain_index"] = grid.domain_indices.astype( "int32").reshape((1, -1)) _meshio.write_points_cells( filename, points, cells, point_data=point_data, cell_data=cell_data, file_format=file_format, binary=write_binary, )
edges_list=[poly.line_loop.lines[0]], hfar=0.1, hwall_n=0.01, ratio=1.1, thickness=0.2, anisomax=100.0, ) field1 = geom.add_boundary_layer( nodes_list=[poly.line_loop.lines[1].points[1]], hfar=0.1, hwall_n=0.01, ratio=1.1, thickness=0.2, anisomax=100.0, ) geom.add_background_field([field0, field1]) ref = 4.0 points, cells, _, _, _ = pygmsh.generate_mesh(geom) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells if __name__ == "__main__": import meshio out = test() meshio.write_points_cells("boundary_layers.vtu", *out)
def main(argv=None): parser = _get_parser() args = parser.parse_args(argv) if not (args.max_num_steps or args.tolerance): parser.error( "At least one of --max-num_steps or --tolerance required.") mesh = meshio.read(args.input_file) # Remove all nodes which do not belong to the highest-order simplex. Those would # lead to singular equations systems further down the line. mesh.cells = {"triangle": mesh.cells["triangle"]} prune(mesh) if args.subdomain_field_name: field = mesh.cell_data["triangle"][args.subdomain_field_name] subdomain_idx = numpy.unique(field) cell_sets = [idx == field for idx in subdomain_idx] else: cell_sets = [numpy.ones(mesh.cells["triangle"].shape[0], dtype=bool)] cells = mesh.cells["triangle"] method = { "cpt-dp": cpt.linear_solve_density_preserving, "cpt-uniform-fp": cpt.fixed_point_uniform, "cpt-uniform-qn": cpt.quasi_newton_uniform, # "cvt-uniform-lloyd": cvt.quasi_newton_uniform_lloyd, "cvt-uniform-qnb": cvt.quasi_newton_uniform_blocks, "cvt-uniform-qnf": cvt.quasi_newton_uniform_full, # "odt-dp-fp": odt.fixed_point_density_preserving, "odt-uniform-fp": odt.fixed_point_uniform, "odt-uniform-bfgs": odt.nonlinear_optimization_uniform, }[args.method] for cell_idx in cell_sets: if args.method in ["cvt-uniform-lloyd", "cvt-uniform-qnf"]: X, cls = method( mesh.points, cells[cell_idx], args.tolerance, args.max_num_steps, omega=args.omega, verbose=args.verbose, step_filename_format=args.step_filename_format, ) else: X, cls = method( mesh.points, cells[cell_idx], args.tolerance, args.max_num_steps, verbose=args.verbose, step_filename_format=args.step_filename_format, ) cells[cell_idx] = cls if X.shape[1] != 3: X = numpy.column_stack([X[:, 0], X[:, 1], numpy.zeros(X.shape[0])]) meshio.write_points_cells( args.output_file, X, {"triangle": cells}, # point_data=mesh.point_data, # cell_data=mesh.cell_data, ) return
# pip install meshio[all] --user import meshio meshio.write_points_cells( f"resultados_{nombre_archivo}.vtk", points=xnod, cells={"quad": LaG[:, [0, 1, 2, 3]]}, point_data={ 'ex': ex, 'ey': ey, 'ez': ez, 'gxy': gxy, 'sx': sx, 'sy': sy, 'txy': txy, 's1': s1, 's2': s2, 'tmax': tmax, 'sv': sv, 'uv': a.reshape((nno, 2)), 'reacciones': q.reshape((nno, 2)), 'n1': np.c_[np.cos(ang), np.sin(ang)], 'n2': np.c_[np.cos(ang + np.pi / 2), np.sin(ang + np.pi / 2)] }, cell_data={"quad": { "material": mat }}, ) # %%bye, bye!
def generate_mesh3D(model, G, comm): print('Entering mesh generation', flush=True) M = grid_point_to_mesh_point_converter_for_seismicmesh(model, G) method = model["opts"]["method"] Lz = model["mesh"]['Lz'] lz = model['BCs']['lz'] Lx = model["mesh"]['Lx'] lx = model['BCs']['lx'] Ly = model["mesh"]['Ly'] ly = model['BCs']['ly'] Real_Lz = Lz + lz Real_Lx = Lx + 2 * lx Real_Ly = Ly + 2 * ly minimum_mesh_velocity = model['testing_parameters'][ 'minimum_mesh_velocity'] frequency = model["acquisition"]['frequency'] lbda = minimum_mesh_velocity / frequency edge_length = lbda / M #print(Real_Lz) bbox = (-Real_Lz, 0.0, -lx, Real_Lx - lx, -ly, Real_Ly - ly) cube = SeismicMesh.Cube(bbox) if comm.comm.rank == 0: # Creating rectangular mesh points, cells = SeismicMesh.generate_mesh(domain=cube, edge_length=edge_length, mesh_improvement=False, max_iter=75, comm=comm.ensemble_comm, verbose=0) points, cells = SeismicMesh.sliver_removal(points=points, bbox=bbox, domain=cube, edge_length=edge_length, preserve=True, max_iter=200) print('entering spatial rank 0 after mesh generation') meshio.write_points_cells("meshes/3Dhomogeneous" + str(G) + ".msh", points, [("tetra", cells)], file_format="gmsh22", binary=False) meshio.write_points_cells("meshes/3Dhomogeneous" + str(G) + ".vtk", points, [("tetra", cells)], file_format="vtk") comm.comm.barrier() if method == "CG" or method == "KMV": mesh = fire.Mesh( "meshes/3Dhomogeneous" + str(G) + ".msh", distribution_parameters={ "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0) }, ) print('Finishing mesh generation', flush=True) return mesh
geom.add_raw_code("Mesh.LcIntegrationPrecision = 1.0e-3;") return geom 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 if __name__ == "__main__": points, cells, point_data, cell_data, _ = generate() meshio.write_points_cells( "out.vtu", points, cells, point_data=point_data, cell_data=cell_data, verbose=True, )
def test(mesh): with tempfile.TemporaryDirectory() as temp_dir: filepath = os.path.join(temp_dir, "out.svg") meshio.write_points_cells(filepath, mesh.points, mesh.cells) return
def generate_mesh2D(model, G, comm): if comm.comm.rank == 0: print('Entering mesh generation', flush=True) M = grid_point_to_mesh_point_converter_for_seismicmesh(model, G) method = model["opts"]["method"] Lz = model["mesh"]['Lz'] lz = model['BCs']['lz'] Lx = model["mesh"]['Lx'] lx = model['BCs']['lx'] Real_Lz = Lz + lz Real_Lx = Lx + 2 * lx if model['testing_parameters']['experiment_type'] == 'homogeneous': minimum_mesh_velocity = model['testing_parameters'][ 'minimum_mesh_velocity'] frequency = model["acquisition"]['frequency'] lbda = minimum_mesh_velocity / frequency Real_Lz = Lz + lz Real_Lx = Lx + 2 * lx edge_length = lbda / M bbox = (-Real_Lz, 0.0, -lx, Real_Lx - lx) rec = SeismicMesh.Rectangle(bbox) if comm.comm.rank == 0: # Creating rectangular mesh points, cells = SeismicMesh.generate_mesh(domain=rec, edge_length=edge_length, mesh_improvement=False, comm=comm.ensemble_comm, verbose=0) print('entering spatial rank 0 after mesh generation') points, cells = SeismicMesh.geometry.delete_boundary_entities( points, cells, min_qual=0.6) a = np.amin(SeismicMesh.geometry.simp_qual(points, cells)) meshio.write_points_cells("meshes/2Dhomogeneous" + str(G) + ".msh", points, [("triangle", cells)], file_format="gmsh22", binary=False) meshio.write_points_cells("meshes/2Dhomogeneous" + str(G) + ".vtk", points, [("triangle", cells)], file_format="vtk") if comm.comm.rank == 0: print('Finishing mesh generation', flush=True) elif model['testing_parameters']['experiment_type'] == 'heterogeneous': # Name of SEG-Y file containg velocity model. fname = "vel_z6.25m_x12.5m_exact.segy" # Bounding box describing domain extents (corner coordinates) bbox = (-12000.0, 0.0, 0.0, 67000.0) rectangle = SeismicMesh.Rectangle(bbox) # Desired minimum mesh size in domain frequency = model["acquisition"]['frequency'] hmin = 1429.0 / (M * frequency) # Construct mesh sizing object from velocity model ef = SeismicMesh.get_sizing_function_from_segy( fname, bbox, hmin=hmin, wl=M, freq=5.0, grade=0.15, domain_pad=model["BCs"]["lz"], pad_style="edge", ) points, cells = SeismicMesh.generate_mesh(domain=rectangle, edge_length=ef, verbose=0, mesh_improvement=False) meshio.write_points_cells("meshes/2Dheterogeneous" + str(G) + ".msh", points / 1000, [("triangle", cells)], file_format="gmsh22", binary=False) meshio.write_points_cells("meshes/2Dheterogeneous" + str(G) + ".vtk", points / 1000, [("triangle", cells)], file_format="vtk") comm.comm.barrier() if method == "CG" or method == "KMV": mesh = fire.Mesh( "meshes/2Dheterogeneous" + str(G) + ".msh", distribution_parameters={ "overlap_type": (fire.DistributedMeshOverlapType.NONE, 0) }, ) return model
import matplotlib.pyplot as plt # First, we need to export gmsh file to a vtk file (or stl maybe, not tested) # Convert the mesh type from gmsh vtk to xml for fenics # (XDMF not working not sure why) filename = 'test_gmsh_vtk' # filename = '2d_motor.vtk' # filename = 'boolean_cut.vtk' mesh = meshio.read(filename, file_format="vtk") points = mesh.points cells = mesh.cells meshio.write_points_cells( "fenics_mesh_l_bracket.xml", points, cells, ) # test if it work with fenics # by defining a traction boundary NUM_ELEMENTS_X = 80 NUM_ELEMENTS_Y = 40 LENGTH_X = 160. LENGTH_Y = 80. class TractionBoundary(df.SubDomain): def inside(self, x, on_boundary): return ((abs(x[1] - LENGTH_Y / 2) < LENGTH_Y / NUM_ELEMENTS_Y * 2.) and (abs(x[0] - LENGTH_X) < df.DOLFIN_EPS))
def test(mesh): with tempfile.TemporaryDirectory() as temp_dir: filepath = os.path.join(temp_dir, "out.svg") meshio.write_points_cells(filepath, mesh.points, mesh.cells) return
from helpers import compute_volume def test(): geom = pygmsh.built_in.Geometry() circle = geom.add_circle(x0=[0.5, 0.5, 0.0], radius=0.25, lcar=0.1, num_sections=4, make_surface=False) geom.add_rectangle(0.0, 1.0, 0.0, 1.0, 0.0, lcar=0.1, holes=[circle.line_loop]) ref = 0.8086582838174551 points, cells, _, _, _ = pygmsh.generate_mesh(geom, geo_filename="h.geo") assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells if __name__ == "__main__": import meshio meshio.write_points_cells("rectangle_with_hole.vtu", *test())
# -*- coding: utf-8 -*- import pygmsh from helpers import compute_volume def test(): geom = pygmsh.built_in.Geometry() geom.add_circle( [0.0, 0.0, 0.0], 1.0, lcar=0.1, num_sections=4, # If compound==False, the section borders have to be points of the # discretization. If using a compound circle, they don't; gmsh can # choose by itself where to point the circle points. compound=True, ) ref = 3.1363871677682247 points, cells, _, _, _ = pygmsh.generate_mesh(geom) assert abs(compute_volume(points, cells) - ref) < 1.0e-2 * ref return points, cells if __name__ == "__main__": import meshio meshio.write_points_cells("circle.vtk", *test())
def save_vtk(self, cont): p_data = {'Vm' : self.u[1:-1], 'g': self.gjnorm[0:-1], 'taug': self.taug[0:-1], 'gjnorm': self.g_ss[0:-1], 'r': self.r[1:-1,:]} io.write_points_cells(self.vtkpath + self.fname + '_%06i' % cont+".vtu", self.xyz, self.cells, point_data = p_data)
def convertSurfaces2VTK(points, cell_data, faceCounter, outputOption = 1, fileprefix='Surface', xy_origin=[0,0,0]): # Choose output option num3Dfaces=faceCounter print('The number of triangle elements (cells/faces) is: ' + str(num3Dfaces)) #apply origin transformation points[:, 0] = points[:, 0]+xy_origin[0] points[:, 1] = points[:, 1]+xy_origin[1] points[:, 2] = points[:, 2]+xy_origin[2] cell_data = pd.Series(cell_data.reshape((-1, ))) CatCodes = np.zeros((len(cell_data),)) filterB = (cell_data.str.contains('B')) filterS = (cell_data.str.contains('S')) CatCodes[filterB]= cell_data.loc[filterB].str[:-20].astype('category').cat.codes CatCodes[filterS]= -1*(cell_data.loc[filterS].str[:-12].astype('category').cat.codes+1) # print(np.unique(CatCodes[filterB])) # print(np.unique(CatCodes[filterS])) for i in range(1, len(CatCodes)): if(CatCodes[i]==0): CatCodes[i]=CatCodes[i-1] if(CatCodes[i-1]==0): CatCodes[i]=CatCodes[np.nonzero(CatCodes)[0][0]] # CatCodes[filterB]= 0 # CatCodes[filterS]= 1 UniqueCodes = np.unique(CatCodes) nSurfaces = len(UniqueCodes) # print(np.unique(CatCodes[filterB])) # print(np.unique(CatCodes[filterS])) # print(UniqueCodes) if (outputOption==2): ## if you would like a single vtk file cells = np.zeros((num3Dfaces, 3),dtype ='int') i=0 for f in range(num3Dfaces): cells[f,:]= [i, i+1, i+2] i=i+3 meshio.write_points_cells( "Model.vtk", points, cells={'triangle':cells}, cell_data= {'triangle': {'cat':CatCodes}} ) else: ## option 1: make a separate file for each surface for i in range(nSurfaces): filterPoints = CatCodes==UniqueCodes[i] nCells = np.sum(filterPoints) Cells_i = np.zeros((nCells, 3),dtype ='int') cntr = 0 for j in range(nCells): Cells_i[j]=[cntr, cntr+1, cntr+2] cntr=cntr+3 booleanFilter = np.repeat(filterPoints,3) meshio.write_points_cells( fileprefix+str(i)+".vtk", points[np.repeat(filterPoints,3), :], cells={'triangle':Cells_i} ) # print('surface ' +str(i) + ' code:'+str(UniqueCodes[i])) # print('Finished converting dxf to vtk') return nSurfaces, points, CatCodes
def save_meshio(filename, mesh, file_format=None, **kwargs): """Save mesh to file using meshio. Parameters ---------- mesh : pyvista.Common Any PyVista mesh/spatial data type. file_format : str File type for meshio to save. """ import meshio from meshio.vtk._vtk import vtk_to_meshio_type # Make sure relative paths will work filename = os.path.abspath(os.path.expanduser(str(filename))) # Cast to pyvista.UnstructuredGrid if not isinstance(mesh, pyvista.UnstructuredGrid): mesh = mesh.cast_to_unstructured_grid() # Copy useful arrays to avoid repeated calls to properties vtk_offset = mesh.offset vtk_cells = mesh.cells vtk_cell_type = mesh.celltypes # Check that meshio supports all cell types in input mesh pixel_voxel = {8, 11} # Handle pixels and voxels for cell_type in np.unique(vtk_cell_type): assert cell_type in vtk_to_meshio_type.keys( ) or cell_type in pixel_voxel, ( "meshio does not support VTK type {}.".format(cell_type)) # Get cells cells = {} mapper = {} # For cell data for i, (offset, cell_type) in enumerate(zip(vtk_offset, vtk_cell_type)): numnodes = vtk_cells[offset] cell = vtk_cells[offset + 1:offset + 1 + numnodes] cell = (cell if cell_type not in pixel_voxel else cell[[0, 1, 3, 2]] if cell_type == 8 else cell[[0, 1, 3, 2, 4, 5, 7, 6]]) cell_type = cell_type if cell_type not in pixel_voxel else cell_type + 1 cell_type = (vtk_to_meshio_type[cell_type] if cell_type != 7 else "polygon{}".format(numnodes)) if cell_type not in cells.keys(): cells[cell_type] = [cell] mapper[cell_type] = [i] else: cells[cell_type].append(cell) mapper[cell_type].append(i) cells = {k: np.vstack(v) for k, v in cells.items()} # Get point data point_data = {k.replace(" ", "_"): v for k, v in mesh.point_arrays.items()} # Get cell data vtk_cell_data = mesh.cell_arrays cell_data = { k: {kk.replace(" ", "_"): vv[v] for kk, vv in vtk_cell_data.items()} for k, v in mapper.items() } if vtk_cell_data else {} # Save using meshio meshio.write_points_cells(filename=filename, points=np.array(mesh.points), cells=cells, point_data=point_data, cell_data=cell_data, file_format=file_format, **kwargs)
diff1 = geom.boolean_difference([r1], [r2]) r22 = geom.add_rectangle([9.0, 10.0, 0.0], 11.0, 11.0) inter1 = geom.boolean_intersection([diff1, r22]) r3 = geom.add_rectangle([10.0, 19.5, 0.0], 21.0, 21.0, corner_radius=8.0) r4 = geom.add_rectangle([10.0, 20.5, 0.0], 20.0, 20.0, corner_radius=7.0) diff2 = geom.boolean_difference([r3], [r4]) r33 = geom.add_rectangle([20.0, 19.0, 0.0], 11.0, 11.0) inter2 = geom.boolean_intersection([diff2, r33]) geom.boolean_difference( [rect1, rect2], [disk1, disk2, rect3, rect4, inter1, inter2] ) mesh = pygmsh.generate_mesh(geom) ref = 1082.4470502181903 assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh if __name__ == "__main__": import optimesh mesh = test() points, cells = optimesh.lloyd(mesh.points, mesh.cells["triangle"], 1.0e-5, 10000) # # from helpers import plot # # plot("logo.png", points, {"triangle": cells}) import meshio meshio.write_points_cells("logo.svg", points, {"triangle": cells})
meshio.write_points_cells( f"resultados_{nombre_archivo}.vtk", points=xnod, cells={ "hexahedron20": LaG[:, np.array([ 3, 5, 7, 1, 15, 17, 19, 13, 4, 6, 8, 2, 16, 18, 20, 14, 10, 11, 12, 9 ]) - 1] }, point_data={ 'ex': ex, 'ey': ey, 'ez': ez, 'gxy': gxy, 'gxz': gxz, 'gyz': gyz, 'sx': sx, 'sy': sy, 'sz': sz, 'txy': txy, 'txz': txz, 'tyz': tyz, 's1': s1, 's2': s2, 's3': s3, 'tmax': tmax, 'sv': sv, 'uvw': a.reshape((nno, 3)), 'n1': n1, 'n2': n2, 'n3': n3 }, cell_data={"hexahedron20": { "material": mat }}, # field_data=field_data )
def _from_isa(isa, filename, target_format, extrude=0, layers=0, recombine=False): try: if not isa.FC_RADIUS: logger.warning("airgap radius is not set in source file") except AttributeError: isa.FC_RADIUS = 0 airgap_center_elements = [] for e in isa.elements: outside = [ np.sqrt(v.x**2 + v.y**2) > isa.FC_RADIUS for v in e.vertices ] if any(outside) and not all(outside): airgap_center_elements.append(e) airgap_center_vertices = [ v for e in airgap_center_elements for v in e.vertices ] airgap_inner_elements = [] airgap_outer_elements = [] for e in isa.elements: if e in airgap_center_elements: continue for v in e.vertices: if v not in airgap_center_vertices: continue if np.sqrt(v.x**2 + v.y**2) > isa.FC_RADIUS: airgap_outer_elements.append(e) break else: airgap_inner_elements.append(e) break airgap_outer_vertices = [ v for e in airgap_outer_elements for v in e.vertices ] airgap_lines = [] for e in airgap_center_elements: ev = e.vertices for i, v1 in enumerate(ev): v2 = ev[i - 1] if v1 in airgap_outer_vertices and \ v2 in airgap_outer_vertices: airgap_lines.append((v1, v2)) nodechain_links = defaultdict(list) for n in isa.nodechains: nodechain_links[n.node1].extend(n.nodes) nodechain_links[n.node2].extend(n.nodes) if n.nodemid is not None: nodechain_links[n.nodemid].extend(n.nodes) physical_lines = [ "v_potential_0", "v_potential_const", "periodic_+", "periodic_-", "infinite_boundary", "no_condition", "Airgap" ] physical_surfaces = sorted( set([sr.name for sr in isa.subregions] + [ "Winding_{}_{}".format(w.key, pol) for w in isa.windings for pol in ("+", "-") ] + [ "Air_Inner", "Air_Outer", "Airgap_Inner", "Airgap_Outer", "PM1", "PM2", "PM3", "PM4" ])) def physical_line(n1, n2): if (n1, n2) in airgap_lines or (n2, n1) in airgap_lines: return 7 # airgap if n1.bndcnd == n2.bndcnd: return boundary_condition(n1) if boundary_condition(n1) == 1: return boundary_condition(n2) return boundary_condition(n1) def boundary_condition(node): if node.bndcnd == 0: return 6 # no condition if node.bndcnd == 1: return 1 # vpot 0 if node.bndcnd == 2: return 2 # vpot const if node.bndcnd == 3 or node.bndcnd == 6: return 4 # periodic - if node.bndcnd == 4 or node.bndcnd == 5: return 3 # periodic + if node.bndcnd == 8 or node.bndcnd == 9: return 1 # vpot 0 def physical_surface(e): def surface_id(name): return physical_surfaces.index(name) + len(physical_lines) + 1 if any(e.mag): if e.mag[0] > 0: if e.mag[1] > 0: return surface_id("PM1") return surface_id("PM2") if e.mag[1] > 0: return surface_id("PM3") return surface_id("PM4") if e in airgap_inner_elements or e in airgap_center_elements: return surface_id("Airgap_Inner") if e in airgap_outer_elements: return surface_id("Airgap_Outer") sr_key = isa.superelements[e.se_key].sr_key if sr_key == -1: v = e.vertices[0] if np.sqrt(v.x**2 + v.y**2) > isa.FC_RADIUS: return surface_id("Air_Outer") return surface_id("Air_Inner") sr = isa.subregions[sr_key] if sr.wb_key != -1: wb = isa.subregions[sr.wb_key] if sr.curdir > 0: return surface_id("Winding_{}_-".format(wb.key)) return surface_id("Winding_{}_+".format(wb.key)) return surface_id(sr.name) def line_on_boundary(n1, n2): if n1.on_boundary() and n2.on_boundary(): if n1 in nodechain_links.keys(): return n2 in nodechain_links[n1] else: return False else: return (n1, n2) in airgap_lines or (n2, n1) in airgap_lines points = [[n.x, n.y, 0] for n in isa.nodes] vpot = [n.vpot[0] for n in isa.nodes] lines = [] line_ids = [] triangles = [] quads = [] physical_ids = dict(triangle=[], quad=[]) geometrical_ids = dict(triangle=[], quad=[]) b = dict(triangle=[], quad=[]) h = dict(triangle=[], quad=[]) perm = dict(triangle=[], quad=[]) iron_losses = dict(triangle=[], quad=[]) mag_losses = dict(triangle=[], quad=[]) wdg_losses = dict(triangle=[], quad=[]) for e in isa.elements: ev = e.vertices for i, v in enumerate(ev): v1, v2 = v, ev[i - 1] if line_on_boundary(v1, v2): lines.append([v1.key - 1, v2.key - 1]) line_ids.append(physical_line(v1, v2)) if len(ev) == 3: triangles.append([n.key - 1 for n in ev]) cell_type = "triangle" elif len(ev) == 4: quads.append([n.key - 1 for n in ev]) cell_type = "quad" try: magtemp = isa.MAGN_TEMPERATURE except AttributeError: magtemp = 20 physical_ids[cell_type].append(physical_surface(e)) geometrical_ids[cell_type].append(e.se_key) b[cell_type].append(e.flux_density()) h[cell_type].append(e.demagnetization(magtemp)) perm[cell_type].append(e.permeability()) iron_losses[cell_type].append(e.iron_loss_density()) mag_losses[cell_type].append(e.mag_loss_density()) wdg_losses[cell_type].append(e.wdg_loss_density()) if target_format == "msh": import meshio points = np.array(points) point_data = {"potential": np.array(vpot)} cells = [] cell_data = defaultdict(list) if lines: cells.append(("line", np.array(lines))) cell_data["gmsh:geometrical"].append(np.array(line_ids)) cell_data["gmsh:physical"].append(np.array(line_ids)) cell_data["b"].append(np.zeros((len(lines), 3))) cell_data["h"].append(np.zeros(len(lines))) cell_data["Rel. Permeability"].append(np.zeros(len(lines))) cell_data["Iron Loss Dens."].append(np.zeros(len(lines))) cell_data["Mag. Loss Dens."].append(np.zeros(len(lines))) cell_data["Wdg. Loss Dens."].append(np.zeros(len(lines))) if triangles: cells.append(("triangle", np.array(triangles))) cell_data["gmsh:geometrical"].append( np.array(geometrical_ids["triangle"])) cell_data["gmsh:physical"].append( np.array(physical_ids["triangle"])) cell_data["b"].append(np.array([i + (0, ) for i in b["triangle"]])) cell_data["h"].append(np.array(h["triangle"])) cell_data["Rel. Permeability"].append(np.array(perm["triangle"])) cell_data["Iron Loss Dens."].append( np.array(iron_losses["triangle"])) cell_data["Mag. Loss Dens."].append( np.array(mag_losses["triangle"])) cell_data["Wdg. Loss Dens."].append( np.array(wdg_losses["triangle"])) if quads: cells.append(("quad", np.array(quads))) cell_data["gmsh:geometrical"].append( np.array(geometrical_ids['quad'])) cell_data["gmsh:physical"].append(np.array(physical_ids['quad'])) cell_data["b"].append(np.array([i + (0, ) for i in b['quad']])) cell_data["h"].append(np.array(h['quad'])) cell_data["Rel. Permeability"].append(np.array(perm['quad'])) cell_data["Iron Loss Dens."].append(np.array(iron_losses['quad'])) cell_data["Mag. Loss Dens."].append(np.array(mag_losses['quad'])) cell_data["Wdg. Loss Dens."].append(np.array(wdg_losses['quad'])) field_data = {} for l in physical_lines: field_data[l] = np.array([physical_lines.index(l) + 1, 1]) for s in physical_surfaces: field_data[s] = np.array( [physical_surfaces.index(s) + 1 + len(physical_lines), 2]) meshio.write_points_cells(filename, points, cells, point_data, cell_data, field_data, file_format="gmsh22", binary=False) if target_format == "geo": import meshio geo = [] nc_nodes = set([n for c in isa.nodechains for n in c.nodes]) for n in isa.nodes: if n in nc_nodes: geo.append("Point({}) = {{{}, {}, {}}};".format( n.key, n.x, n.y, 0)) for c in isa.nodechains: geo.append("Line({}) = {{{}}};".format( c.key, ", ".join([str(n.key) for n in c.nodes]))) used = set() for c in isa.nodechains: n1, n2 = c.nodes[0], c.nodes[1] if line_on_boundary(n1, n2): id_ = physical_line(n1, n2) name = physical_lines[id_ - 1] if extrude: geo.append( "extrusion[] = Extrude {{0, 0, {}}} {{ Line{{{}}}; {}{}}};" .format( extrude, c.key, "Layers{{{}}}; ".format(layers) if layers else "", "Recombine; " if recombine else "")) geo.append( "Physical Surface('{}', {}) {} extrusion[1];".format( name, id_, "+=" if name in used else "=")) else: geo.append("Physical Line('{}', {}) {} {{{}}};".format( name, id_, "+=" if name in used else "=", c.key)) used.add(name) for se in isa.superelements: geo.append("Line Loop({}) = {{{}}};".format( se.key, ", ".join([str(c.key) for c in se.nodechains]))) geo.append("Plane Surface({0}) = {{{0}}};".format(se.key)) used = set() for se in isa.superelements: id_ = physical_surface(se.elements[0]) - len(physical_lines) name = physical_surfaces[id_ - 1] if extrude: geo.append( "extrusion[] = Extrude {{0, 0, {}}} {{ Surface{{{}}}; {}{}}};" .format(extrude, se.key, "Layers{{{}}}; ".format(layers) if layers else "", "Recombine; " if recombine else "")) geo.append("Physical Surface('base', {}) {} {{{}}};".format( len(physical_lines) + 1, "=" if se.key == 1 else "+=", se.key)) geo.append( "Physical Surface('top', {}) {} extrusion[0];".format( len(physical_lines) + 2, "=" if se.key == 1 else "+=")) geo.append("Physical Volume('{}', {}) {} extrusion[1];".format( name, id_, "+=" if name in used else "=")) else: geo.append("Physical Surface('{}', {}) {} {{{}}};".format( name, id_, "+=" if name in used else "=", se.key)) used.add(name) with open(filename, "w") as f: f.write("\n".join(geo)) if target_format == "vtu": import meshio assert len(points) == len(vpot) assert len(lines) == len(line_ids) assert len(triangles) == len(physical_ids['triangle']) == len( geometrical_ids['triangle']) == len(b['triangle']) == len( h['triangle']) == len(perm['triangle']) assert len(quads) == len(physical_ids['quad']) == len( geometrical_ids['quad']) == len(b['quad']) == len( h['quad']) == len(perm['quad']) points = np.array(points) point_data = {"potential": np.array(vpot)} cells = [] cell_data = defaultdict(list) if lines: cells.append(("line", np.array(lines))) cell_data["GeometryIds"].append(np.array(line_ids)) cell_data["PhysicalIds"].append(np.array(line_ids)) cell_data["b"].append(np.zeros((len(lines), 3))) cell_data["Demagnetization"].append(np.zeros(len(lines))) cell_data["Rel. Permeability"].append(np.zeros(len(lines))) cell_data["Iron Loss Dens."].append(np.zeros(len(lines))) cell_data["Mag. Loss Dens."].append(np.zeros(len(lines))) cell_data["Wdg. Loss Dens."].append(np.zeros(len(lines))) if triangles: cells.append(("triangle", np.array(triangles))) cell_data["GeometryIds"].append( np.array(geometrical_ids['triangle'])) cell_data["PhysicalIds"].append(np.array(physical_ids['triangle'])) cell_data["b"].append(np.array([i + (0, ) for i in b['triangle']])) cell_data["Demagnetization"].append(np.array(h['triangle'])) cell_data["Rel. Permeability"].append(np.array(perm['triangle'])) cell_data["Iron Loss Dens."].append( np.array(iron_losses['triangle'])) cell_data["Mag. Loss Dens."].append( np.array(mag_losses['triangle'])) cell_data["Wdg. Loss Dens."].append( np.array(wdg_losses['triangle'])) if quads: cells.append(("quad", np.array(quads))) cell_data["GeometryIds"].append(np.array(geometrical_ids['quad'])) cell_data["PhysicalIds"].append(np.array(physical_ids['quad'])) cell_data["b"].append(np.array([i + (0, ) for i in b['quad']])) cell_data["Demagnetization"].append(np.array(h['quad'])) cell_data["Rel. Permeability"].append(np.array(perm['quad'])) cell_data["Iron Loss Dens."].append(np.array(iron_losses['quad'])) cell_data["Mag. Loss Dens."].append(np.array(mag_losses['quad'])) cell_data["Wdg. Loss Dens."].append(np.array(wdg_losses['quad'])) field_data = {} for l in physical_lines: field_data[l] = np.array([physical_lines.index(l) + 1, 1]) for s in physical_surfaces: field_data[s] = np.array( [physical_surfaces.index(s) + 1 + len(physical_lines), 2]) meshio.write_points_cells(filename, points, cells, point_data=point_data, cell_data=cell_data, field_data=field_data, file_format="vtu", binary=True)
import meshio import numpy as np points = np.genfromtxt("CytoD_vertices.txt", delimiter=" ") faces = np.genfromtxt("CytoD_faces.txt", delimiter=" ") faces = faces.astype("int") faces = faces - 1 cells = [("triangle", faces)] meshio.write_points_cells( "cytod_uncentered_unpca_surface.xdmf", points, cells, )
def main(argv=None): parser = _get_parser() args = parser.parse_args(argv) if not (args.max_num_steps < math.inf or args.tolerance > 0.0): parser.error( "At least one of --max-num-steps or --tolerance required.") mesh = meshio.read(args.input_file) # Remove all points which do not belong to the highest-order simplex. Those would # lead to singular equations systems further down the line. mesh.cells = [ meshio.CellBlock("triangle", mesh.get_cells_type("triangle")) ] prune(mesh) if args.subdomain_field_name: field = mesh.cell_data["triangle"][args.subdomain_field_name] subdomain_idx = numpy.unique(field) cell_sets = [idx == field for idx in subdomain_idx] else: cell_sets = [ numpy.ones(mesh.get_cells_type("triangle").shape[0], dtype=bool) ] method = { "laplace": laplace.fixed_point, # "cpt-dp": cpt.linear_solve_density_preserving, "cpt-uniform-fp": cpt.fixed_point_uniform, "cpt-uniform-qn": cpt.quasi_newton_uniform, # "lloyd": cvt.quasi_newton_uniform_lloyd, "cvt-uniform-fp": cvt.quasi_newton_uniform_lloyd, "cvt-uniform-qnb": cvt.quasi_newton_uniform_blocks, "cvt-uniform-qnf": cvt.quasi_newton_uniform_full, # "odt-dp-fp": odt.fixed_point_density_preserving, "odt-uniform-fp": odt.fixed_point_uniform, "odt-uniform-bfgs": odt.nonlinear_optimization_uniform, }[args.method] cells = mesh.get_cells_type("triangle") for cell_idx in cell_sets: if args.method in ["odt-uniform-bfgs"]: # no relaxation parameter omega X, cls = method( mesh.points, cells[cell_idx], args.tolerance, args.max_num_steps, verbose=~args.quiet, step_filename_format=args.step_filename_format, ) else: X, cls = method( mesh.points, cells[cell_idx], args.tolerance, args.max_num_steps, omega=args.omega, verbose=~args.quiet, step_filename_format=args.step_filename_format, ) cells[cell_idx] = cls q = meshplex.MeshTri(X, cls).cell_quality meshio.write_points_cells( args.output_file, X, [("triangle", cells)], cell_data={"cell_quality": [q]}, )
with open(in_filename) as infile: total = infile.readline() nodes = [] lines = [] nodeid = 0 while True: line = infile.readline() if not line: break N = int(line) for i in range(N): v, x, y, z = infile.readline().split() if N > 2: nodes.append([float(x), float(y), float(z)]) if i < (N - 1): lines.append([nodeid, nodeid + 1]) nodeid += 1 points = np.array(nodes) cells = [("line", np.array(lines))] meshio.write_points_cells( out_filename, points, cells, )
geom.add_point([xmin + ball_radius, ball_y, z], lcar), geom.add_point([xmin, ball_y - ball_radius, z], lcar), ] lines = [ geom.add_line(points[0], points[1]), geom.add_line(points[1], points[2]), geom.add_line(points[2], points[3]), geom.add_line(points[3], points[4]), geom.add_circle_arc(points[4], points[5], points[6]), geom.add_circle_arc(points[6], points[5], points[7]), geom.add_line(points[7], points[0]), ] ll = geom.add_line_loop(lines) geom.add_plane_surface(ll) return geom def generate(): return pygmsh.generate_mesh(_define()) if __name__ == "__main__": import meshio points, cells, point_data, cell_data, _ = generate() meshio.write_points_cells( "ball-in-tube.vtu", points, cells, point_data=point_data, cell_data=cell_data )
def save_to_mesh(self, filename, **kwargs): points_count = self.geometry[0].shape[0] meshio.write_points_cells(filename, self.geometry[0].detach().cpu().numpy(), [('polygon'+str(points_count), torch.arange(points_count).view(1, -1).numpy())], **kwargs)
def save_to_file(self, filename): meshio.write_points_cells(filename, self.silent_module.manifold.gd.detach().cpu().numpy(), [('triangle', self.__triangles.cpu())])
'Displacements_true': U_true, "Forces": F } mesh.cell_data = { "stress_true": stress_true, "stress_fem": stress, "von_mises": von_mises } cells = {'triangle': mesh.elements} # Write the vtk file meshio.write_points_cells("./fileVtk/{}/".format( MaterialSets['piastra']['plane deformation'].replace(" ", "_")) + mesh_file + "_e{}.vtk".format(len(mesh.elements)), mesh.points, cells, mesh.point_data, mesh.cell_data, binary=False) #-------------------------------------------------------------------------------------------------- #Error norm computing E = 0 for e in range(len(mesh.elements)): v = (stress_true[e, :] - stress[e, :]).reshape(3, 1) # Integral - 2nd order Gaussian quadrature
diff1 = geom.boolean_difference([r1], [r2]) r22 = geom.add_rectangle([9.0, 10.0, 0.0], 11.0, 11.0) inter1 = geom.boolean_intersection([diff1, r22]) r3 = geom.add_rectangle([10.0, 19.5, 0.0], 21.0, 21.0, corner_radius=8.0) r4 = geom.add_rectangle([10.0, 20.5, 0.0], 20.0, 20.0, corner_radius=7.0) diff2 = geom.boolean_difference([r3], [r4]) r33 = geom.add_rectangle([20.0, 19.0, 0.0], 11.0, 11.0) inter2 = geom.boolean_intersection([diff2, r33]) geom.boolean_difference( [rect1, rect2], [disk1, disk2, rect3, rect4, inter1, inter2] ) mesh = pygmsh.generate_mesh(geom) ref = 1082.4470502181903 assert abs(compute_volume(mesh) - ref) < 1.0e-2 * ref return mesh if __name__ == "__main__": import optimesh mesh = test() points, cells = optimesh.lloyd(mesh.points, mesh.cells["triangle"], 1.0e-5, 10000) # # from helpers import plot # # plot("logo.png", points, {"triangle": cells}) import meshio meshio.write_points_cells("logo.svg", points, {"triangle": cells})
def save_meshio(filename, mesh, file_format=None, **kwargs): """Save mesh to file using meshio. Parameters ---------- mesh : pyvista.Common Any PyVista mesh/spatial data type. file_format : str File type for meshio to save. """ import meshio from meshio.vtk._vtk import vtk_to_meshio_type # Make sure relative paths will work filename = os.path.abspath(os.path.expanduser(str(filename))) # Cast to pyvista.UnstructuredGrid if not isinstance(mesh, pyvista.UnstructuredGrid): mesh = mesh.cast_to_unstructured_grid() # Copy useful arrays to avoid repeated calls to properties vtk_offset = mesh.offset vtk_cells = mesh.cells vtk_cell_type = mesh.celltypes # Get cells cells = {k: [] for k in np.unique(vtk_cell_type)} if 8 in cells.keys(): cells[9] = cells.pop(8) # Handle pixels if 11 in cells.keys(): cells[12] = cells.pop(11) # Handle voxels mapper = {k: [] for k in cells.keys()} # For cell data for i, (offset, cell_type) in enumerate(zip(vtk_offset, vtk_cell_type)): numnodes = vtk_cells[offset] cell = vtk_cells[offset + 1:offset + 1 + numnodes] cell = cell if cell_type not in {8, 11} \ else cell[[ 0, 1, 3, 2 ]] if cell_type == 8 \ else cell[[ 0, 1, 3, 2, 4, 5, 7, 6 ]] cell_type = cell_type if cell_type not in {8, 11} else cell_type + 1 cells[cell_type].append(cell) mapper[cell_type].append(i) cells = {vtk_to_meshio_type[k]: np.vstack(v) for k, v in cells.items()} mapper = {vtk_to_meshio_type[k]: v for k, v in mapper.items()} # Get point data point_data = {k.replace(" ", "_"): v for k, v in mesh.point_arrays.items()} # Get cell data vtk_cell_data = mesh.cell_arrays cell_data = { k: {kk.replace(" ", "_"): vv[v] for kk, vv in vtk_cell_data.items()} for k, v in mapper.items() } if vtk_cell_data else {} # Save using meshio meshio.write_points_cells(filename=filename, points=np.array(mesh.points), cells=cells, point_data=point_data, cell_data=cell_data, file_format=file_format, **kwargs)