# Generate a mesh on each rank with the gmsh API, and create a DOLFIN-X mesh # on each rank. :: gmsh.initialize() gmsh.option.setNumber("General.Terminal", 0) model = gmsh.model() model.add("Sphere") model.setCurrent("Sphere") model.occ.addSphere(0, 0, 0, 1, tag=1) # Generate mesh model.occ.synchronize() model.mesh.generate(3) # Sort mesh nodes according to their index in gmsh (Starts at 1) x = extract_gmsh_geometry(model, model_name="Sphere") # Extract cells from gmsh (Only interested in tetrahedrons) element_types, element_tags, node_tags = model.mesh.getElements(dim=3) assert len(element_types) == 1 name, dim, order, num_nodes, local_coords, num_first_order_nodes = model.mesh.getElementProperties( element_types[0]) cells = node_tags[0].reshape(-1, num_nodes) - 1 mesh = create_mesh(MPI.COMM_SELF, cells, x, ufl_mesh_from_gmsh(element_types[0], x.shape[1])) with XDMFFile(MPI.COMM_SELF, "mesh_rank_{}.xdmf".format(MPI.COMM_WORLD.rank), "w") as file: file.write_mesh(mesh)
def gmsh_model_to_mesh(model, cell_data=False, facet_data=False, gdim=None, exportMesh=False, fileName="mesh.msh"): """ Given a GMSH model, create a DOLFIN-X mesh and MeshTags. Can theoretically export to msh file model: The GMSH model cell_data: Boolean, True of a mesh tag for cell data should be returned (Default: False) facet_data: Boolean, True if a mesh tag for facet data should be returned (Default: False) gdim: Geometrical dimension of problem (Default: 3) """ if gdim is None: gdim = 3 if MPI.COMM_WORLD.rank == 0: # Get mesh geometry x = extract_gmsh_geometry(model) # Get mesh topology for each element topologies = extract_gmsh_topology_and_markers(model) # Get information about each cell type from the msh files num_cell_types = len(topologies.keys()) cell_information = {} cell_dimensions = numpy.zeros(num_cell_types, dtype=numpy.int32) for i, element in enumerate(topologies.keys()): properties = model.mesh.getElementProperties(element) name, dim, order, num_nodes, local_coords, _ = properties cell_information[i] = { "id": element, "dim": dim, "num_nodes": num_nodes } cell_dimensions[i] = dim # Sort elements by ascending dimension perm_sort = numpy.argsort(cell_dimensions) # Broadcast cell type data and geometric dimension cell_id = cell_information[perm_sort[-1]]["id"] tdim = cell_information[perm_sort[-1]]["dim"] num_nodes = cell_information[perm_sort[-1]]["num_nodes"] cell_id, num_nodes = MPI.COMM_WORLD.bcast([cell_id, num_nodes], root=0) # Check for facet data and broadcast if found if facet_data: if tdim - 1 in cell_dimensions: num_facet_nodes = MPI.COMM_WORLD.bcast( cell_information[perm_sort[-2]]["num_nodes"], root=0) gmsh_facet_id = cell_information[perm_sort[-2]]["id"] marked_facets = numpy.asarray( topologies[gmsh_facet_id]["topology"], dtype=numpy.int64) facet_values = numpy.asarray( topologies[gmsh_facet_id]["cell_data"], dtype=numpy.int32) else: raise ValueError("No facet data found in file.") cells = numpy.asarray(topologies[cell_id]["topology"], dtype=numpy.int64) cell_values = numpy.asarray(topologies[cell_id]["cell_data"], dtype=numpy.int32) else: cell_id, num_nodes = MPI.COMM_WORLD.bcast([None, None], root=0) cells, x = numpy.empty([0, num_nodes], dtype=numpy.int32), numpy.empty([0, gdim]) cell_values = numpy.empty((0, ), dtype=numpy.int32) if facet_data: num_facet_nodes = MPI.COMM_WORLD.bcast(None, root=0) marked_facets = numpy.empty((0, num_facet_nodes), dtype=numpy.int32) facet_values = numpy.empty((0, ), dtype=numpy.int32) # Create distributed mesh ufl_domain = ufl_mesh_from_gmsh(cell_id, gdim) gmsh_cell_perm = perm_gmsh(to_type(str(ufl_domain.ufl_cell())), num_nodes) cells = cells[:, gmsh_cell_perm] mesh = create_mesh(MPI.COMM_WORLD, cells, x[:, :gdim], ufl_domain) # Create MeshTags for cells if cell_data: local_entities, local_values = distribute_entity_data( mesh, mesh.topology.dim, cells, cell_values) mesh.topology.create_connectivity(mesh.topology.dim, 0) adj = AdjacencyList_int32(local_entities) ct = create_meshtags(mesh, mesh.topology.dim, adj, numpy.int32(local_values)) ct.name = "cells" # Create MeshTags for facets if facet_data: # Permute facets from MSH to Dolfin-X ordering # FIXME: This does not work for prism meshes facet_type = cell_entity_type(to_type(str(ufl_domain.ufl_cell())), mesh.topology.dim - 1, 0) gmsh_facet_perm = perm_gmsh(facet_type, num_facet_nodes) marked_facets = marked_facets[:, gmsh_facet_perm] local_entities, local_values = distribute_entity_data( mesh, mesh.topology.dim - 1, marked_facets, facet_values) mesh.topology.create_connectivity(mesh.topology.dim - 1, mesh.topology.dim) adj = AdjacencyList_int32(local_entities) ft = create_meshtags(mesh, mesh.topology.dim - 1, adj, numpy.int32(local_values)) ft.name = "facets" if exportMesh: gmsh.write(fileName) if cell_data and facet_data: return mesh, ct, ft elif cell_data and not facet_data: return mesh, ct elif not cell_data and facet_data: return mesh, ft else: return mesh
gmsh.model.addPhysicalGroup(volumes[0][0], [volumes[0][1]], fluid_marker) gmsh.model.setPhysicalName(volumes[0][0], fluid_marker, "Fluid") obstacle_marker = 1 surfaces = gmsh.model.getEntities(dim=gdim-1) gmsh.model.addPhysicalGroup(surfaces[0][0], [surfaces[0][1]], obstacle_marker) gmsh.model.setPhysicalName(surfaces[0][0], obstacle_marker, "Obstacle") gmsh.model.mesh.setSize(gmsh.model.getEntities(0), h_elem) gmsh.model.occ.synchronize() gmsh.model.mesh.generate(3) gmsh.model.mesh.setOrder(2) # Command required for quadratic elements # Create dolfinx mesh on process 0 x = extract_gmsh_geometry(gmsh.model) gmsh_cell_id = MPI.COMM_WORLD.bcast( gmsh.model.mesh.getElementType("triangle", 2), root=0) topologies = extract_gmsh_topology_and_markers(gmsh.model) cells = topologies[gmsh_cell_id]["topology"] cell_data = topologies[gmsh_cell_id]["cell_data"] num_nodes = MPI.COMM_WORLD.bcast(cells.shape[1], root=0) gmsh_facet_id = gmsh.model.mesh.getElementType("line", 2) marked_facets = topologies[gmsh_facet_id]["topology"].astype(np.int64) facet_values = topologies[gmsh_facet_id]["cell_data"].astype(np.int32) else: # Create dolfinx mesh on other processes gmsh_cell_id = MPI.COMM_WORLD.bcast(None, root=0) num_nodes = MPI.COMM_WORLD.bcast(None, root=0) cells, x = np.empty([0, num_nodes]), np.empty([0, 3]) marked_facets = np.empty((0, 3), dtype=np.int64)
def build_piston(n, length, radius, write_file=False, fname=""): """ Build a hex cylinder mesh using gmsh """ gmsh.initialize() gmsh.option.setNumber("General.Terminal", 0) model = gmsh.model() if MPI.COMM_WORLD.rank == 0: model.add("Piston") model.setCurrent("Piston") h = length / n gmsh.option.setNumber("Mesh.RecombineAll", 2) gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 2) gmsh.option.setNumber("Mesh.CharacteristicLengthMin", 0.98 * h) gmsh.option.setNumber("Mesh.CharacteristicLengthMax", 1.02 * h) circle = model.occ.addDisk(0, 0, 0, radius, radius) model.occ.rotate([(2, circle)], 0., 0., 0., 0., 1., 0., np.pi / 2) model.occ.extrude([(2, circle)], length, 0, 0, numElements=[n], recombine=True) model.occ.synchronize() model.mesh.generate(3) # sort mesh according to their index in gmsh x = extract_gmsh_geometry(model, model.getCurrent()) # extract cells from gmsh element_types, element_tags, node_tags = model.mesh.getElements(dim=3) name, dim, order, num_nodes, local_coords, num_first_order_nodes = \ model.mesh.getElementProperties(element_types[0]) # broadcast cell type data and geometric dimension gmsh_cell_id = MPI.COMM_WORLD.bcast(element_types[0], root=0) # get mesh data for dim (0, tdim) cells = node_tags[0].reshape(-1, num_nodes) - 1 num_nodes = MPI.COMM_WORLD.bcast(cells.shape[1], root=0) gmsh.finalize() else: gmsh_cell_id = MPI.COMM_WORLD.bcast(None, root=0) num_nodes = MPI.COMM_WORLD.bcast(None, root=0) cells, x = np.empty([0, num_nodes]), np.empty([0, 3]) # permute the mesh topology from GMSH ordering to DOLFIN-X ordering domain = ufl_mesh_from_gmsh(gmsh_cell_id, 3) gmsh_hex = perm_gmsh(cpp.mesh.CellType.hexahedron, 8) cells = cells[:, gmsh_hex] mesh = create_mesh(MPI.COMM_WORLD, cells, x, domain) mesh.name = "piston_hex" if write_file: with XDMFFile(MPI.COMM_WORLD, "{}.xdmf".format(fname), "w") as file: file.write_mesh(mesh) return mesh
def gmsh_model_to_mesh(model, gdim): """ Given a GMSH model, create a DOLFINx mesh and MeshTags. Parameters ---------- model : gmsh.model The GMSH model. gdim: int Geometrical dimension of problem. Author ---------- J. S. Dokken, http://jsdokken.com/converted_files/tutorial_gmsh.html """ assert MPI.COMM_WORLD.size == 1, "This function has been simplified to the case of serial computations" # Get mesh geometry x = extract_gmsh_geometry(model) # Get mesh topology for each element topologies = extract_gmsh_topology_and_markers(model) # Get information about each cell type from the msh files num_cell_types = len(topologies.keys()) cell_information = {} cell_dimensions = np.zeros(num_cell_types, dtype=np.int32) for i, element in enumerate(topologies.keys()): properties = model.mesh.getElementProperties(element) name, dim, order, num_nodes, coords, _ = properties cell_information[i] = { "id": element, "dim": dim, "num_nodes": num_nodes } cell_dimensions[i] = dim # Sort elements by ascending dimension perm_sort = np.argsort(cell_dimensions) # Get cell type data and geometric dimension cell_id = cell_information[perm_sort[-1]]["id"] tdim = cell_information[perm_sort[-1]]["dim"] num_nodes = cell_information[perm_sort[-1]]["num_nodes"] cells = np.asarray(topologies[cell_id]["topology"], dtype=np.int64) cell_values = np.asarray(topologies[cell_id]["cell_data"], dtype=np.int32) # Look up facet data assert tdim - 1 in cell_dimensions num_facet_nodes = cell_information[perm_sort[-2]]["num_nodes"] gmsh_facet_id = cell_information[perm_sort[-2]]["id"] marked_facets = np.asarray(topologies[gmsh_facet_id]["topology"], dtype=np.int64) facet_values = np.asarray(topologies[gmsh_facet_id]["cell_data"], dtype=np.int32) # Create distributed mesh ufl_domain = ufl_mesh_from_gmsh(cell_id, gdim) gmsh_cell_perm = perm_gmsh(to_type(str(ufl_domain.ufl_cell())), num_nodes) cells = cells[:, gmsh_cell_perm] mesh = create_mesh(MPI.COMM_WORLD, cells, x[:, :gdim], ufl_domain) # Create MeshTags for cells entities, values = distribute_entity_data(mesh, mesh.topology.dim, cells, cell_values) mesh.topology.create_connectivity(mesh.topology.dim, 0) adj = AdjacencyList_int32(entities) ct = meshtags_from_entities(mesh, mesh.topology.dim, adj, np.int32(values)) ct.name = "Cell tags" # Create MeshTags for facets facet_type = cell_entity_type(to_type(str(ufl_domain.ufl_cell())), mesh.topology.dim - 1, 0) gmsh_facet_perm = perm_gmsh(facet_type, num_facet_nodes) marked_facets = marked_facets[:, gmsh_facet_perm] entities, values = distribute_entity_data(mesh, mesh.topology.dim - 1, marked_facets, facet_values) mesh.topology.create_connectivity(mesh.topology.dim - 1, mesh.topology.dim) adj = AdjacencyList_int32(entities) ft = meshtags_from_entities(mesh, mesh.topology.dim - 1, adj, np.int32(values)) ft.name = "Facet tags" return mesh, ct, ft