Creating a mesh by cutting several meshes using GMSH

I would like to create a circular domain with two holes in it. I used this code

import gmsh
from mpi4py import MPI
from dolfinx.io import gmshio

gmsh.initialize()
gmsh.clear()

markerId = 1
disk = gmsh.model.occ.addDisk(0, 0, 0, 5, 5)
hole1 = gmsh.model.occ.addDisk(0, 0, 0, 1, 1)
membrane1 = gmsh.model.occ.cut([(2, disk)], [(2, hole1)])
hole2 = gmsh.model.occ.addDisk(2, 2, 0, 1, 1)
membrane = gmsh.model.occ.cut([(2, membrane1)], [(2, hole2)])

gmsh.model.occ.synchronize()

volumes = gmsh.model.getEntities(dim=2)
assert(volumes == membrane[0])
membrane_marker = 11

gdim = 2
gmsh.model.addPhysicalGroup(volumes[0][0], [volumes[0][1]], membrane_marker)

meshSize = 1
gmsh.option.setNumber("Mesh.CharacteristicLengthMin",meshSize)
gmsh.option.setNumber("Mesh.CharacteristicLengthMax",meshSize)
gmsh.model.mesh.generate(gdim)

gmsh_model_rank = 0
mesh_comm = MPI.COMM_WORLD
domain, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model, mesh_comm, gmsh_model_rank, gdim=gdim)
gmsh.finalize()

but got the following error:

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 2 dimensions. The detected shape was (1, 2) + inhomogeneous part.

When I use the same code for only one hole everything works just fine. What did I do wrong?

Make sure your model is valid, e.g.

...
gmsh.model.occ.synchronize()
gmsh.fltk.run()

See the gmsh tutorial: Gmsh 4.11.1.

Consider contacting the gmsh community for help with gmsh.

Hello,
I’ve the same problem : I want to cut several elements in a mesh (rectangles for example).

With a similar code that the one of oszachter, I’ve the same error.

import gmsh
from mpi4py import MPI
gmsh.initialize()
proc = MPI.COMM_WORLD.rank
if proc == 0:
rectangle_big=gmsh.model.occ.addRectangle(0, 0, 0, 2, 1, tag=1)
rectangle_small_1=gmsh.model.occ.addRectangle(0.1, 0, 0, 0.5, 0.5, tag=2)
rectangle_small_2=gmsh.model.occ.addRectangle(1, 0, 0, 0.5, 0.5, tag=3)

fluid1 = gmsh.model.occ.cut([(2, rectangle_big)], [(2, rectangle_small_1)])
fluid2 = gmsh.model.occ.cut([(2, fluid1)], [(2, rectangle_small_2)])
gmsh.model.occ.synchronize()

The error is :

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 2 dimensions. The detected shape was (1, 2) + inhomogeneous part.

Thansk a lot for your help

Please note that this is a pure GMSH question and should better be asked on their communication platforms/issue tracker.

First, I would suggest you inspect the return type of fluid1, as this is:

([(2, 1)], [[(2, 1)], []])

If you then in turn read the docs of gmsh.model.occ.cut it states:

  Compute the boolean difference between the entities `objectDimTags' and
            `toolDimTags' (given as vectors of (dim, tag) pairs) in the OpenCASCADE CAD
            representation. Return the resulting entities in `outDimTags'. If `tag' is
            positive, try to set the tag explicitly (only valid if the boolean
            operation results in a single entity). Remove the object if `removeObject'
            is set. Remove the tool if `removeTool' is set.

            Return `outDimTags', `outDimTagsMap'.

            Types:
            - `objectDimTags': vector of pairs of integers
            - `toolDimTags': vector of pairs of integers
            - `outDimTags': vector of pairs of integers
            - `outDimTagsMap': vector of vectors of pairs of integers
            - `tag': integer
            - `removeObject': boolean
            - `removeTool': boolean

i.e.
you would like

    fluid2 = gmsh.model.occ.cut(fluid1[0], [(2, rectangle_small_2)])

which in turn would give you:

import gmsh
from mpi4py import MPI
gmsh.initialize()
proc = MPI.COMM_WORLD.rank
if proc == 0:
    rectangle_big=gmsh.model.occ.addRectangle(0, 0, 0, 2, 1, tag=1)
    rectangle_small_1=gmsh.model.occ.addRectangle(0.1, 0, 0, 0.5, 0.5, tag=2)
    rectangle_small_2=gmsh.model.occ.addRectangle(1, 0, 0, 0.5, 0.5, tag=3)
    fluid1 = gmsh.model.occ.cut([(2, rectangle_big)], [(2, rectangle_small_1)])
    fluid2 = gmsh.model.occ.cut(fluid1[0], [(2, rectangle_small_2)])

    gmsh.model.occ.synchronize()
    surfaces = gmsh.model.getEntities(2)
    for s in surfaces:
        gmsh.model.addPhysicalGroup(2, [s[1]], s[1])
    gmsh.model.mesh.generate(2)
    gmsh.write("mwe.msh")
gmsh.finalize()

and the mesh

1 Like

Perfect!
Thanks a lot for the solution and the explanation! :slight_smile: