Exemple #1
0
# 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)
Exemple #2
0
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
Exemple #5
0
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