Why Gmsh create more surfaces than expected when I use "gmhs.model.occ.cut()" command?

546 Views Asked by At

I am trying to create a volume in Gmsh (using Python API) by cutting some small cylinders from a bigger one.

When I do that, I expect to have one surface for each cutted region, instead, I get the result in the figure. I have highlighted in red the surfaces that give me the problem (some cutted regions behave as expected), as you can see, instead of one surface I get two, that sometimes aren't even equal.

gmsh creates more surfaces than expected:

gmsh creates more surfaces than expected

So, my questions are:

Why gmsh behaves like that? How can I fix this as I need predictable behavior?

Below is the code I used to generate the geometry. The code to work requires some parameters such as core_height, core_inner_radius and core_outer_radius, the number of small cylinders and their radius.

gmsh.initialize(sys.argv)
#gmsh.initialize()

gmsh.clear()

    
gmsh.model.add("circle_extrusion")
inner_cyl_tag = 1
outer_cyl_tag = 2

inner_cyl = gmsh.model.occ.addCylinder(0,0,0, 0, 0, core_height, core_inner_radius, tag = inner_cyl_tag)
outer_cyl = gmsh.model.occ.addCylinder(0,0,0, 0, 0, core_height, core_outer_radius, tag = outer_cyl_tag)
    
core_tag = 3
cut1 = gmsh.model.occ.cut([(3,outer_cyl)],[(3,inner_cyl)], tag = core_tag)
    
    
#create a set of filled cylinders 
#set position
    
angle_vector = np.linspace(0,2*np.pi,number_of_hp+1)
pos_x = hp_radial_position*np.cos(angle_vector)
pos_y = hp_radial_position*np.sin(angle_vector)
pos_z = 0.0
    
    
#cut one cylinder at the time and assign the new core tag   
for ii in range(0,len(angle_vector)):
    old_core_tag = core_tag
    heat_pipe = gmsh.model.occ.addCylinder(pos_x[ii], pos_y[ii], pos_z, 0, 0, core_height,hp_outer_radius, tag =-1)
    core_tag = heat_pipe+1
    core = gmsh.model.occ.cut([(3,old_core_tag)],[(3,heat_pipe)], tag = core_tag)  
        

gmsh.model.occ.synchronize()


#get volume entities and assign physical groups
volumes = gmsh.model.getEntities(dim=3)
solid_marker = 1
gmsh.model.addPhysicalGroup(volumes[0][0], [volumes[0][1]],solid_marker)
gmsh.model.setPhysicalName(volumes[0][0],solid_marker, "solid_volume")
    
#get surfaces entities and apply physical groups
    
surfaces = gmsh.model.getEntities(dim=2)
surface_markers= np.arange(1,len(surfaces)+1,1)
for ii in range(0,len(surfaces)):
    gmsh.model.addPhysicalGroup(2,[surfaces[ii][1]],tag = surface_markers[ii])
    

#We finally generate and save the mesh:
gmsh.model.mesh.generate(3)
gmsh.model.mesh.refine()
gmsh.model.mesh.refine()
gmsh.option.setNumber("Mesh.MshFileVersion", 2.2) #save in ASCII 2 format
gmsh.write(mesh_name+".msh")


# Launch the GUI to see the results:
#if '-nopopup' not in sys.argv:
#    gmsh.fltk.run()

gmsh.finalize()
1

There are 1 best solutions below

3
On

I do not think that you have additional surfaces in the sense of gmsh.model.occ surfaces. To me this looks like your volume mesh is sticking out of your surface mesh, i.e. volume and surface mesh do not fit together.

Here is what I did to check your case:

First I added the following lines at the beginning of our code to get a minimum working example:

import gmsh
import sys
import numpy as np

inner_cyl_tag = 1
outer_cyl_tag = 2

core_height = 1
core_inner_radius = 0.1
core_outer_radius = 0.2

number_of_hp  = 5
hp_radial_position = 0.1
hp_outer_radius = 0.05

What I get with this code is the following:

enter image description here

To visualize it like this go to "Tools"-->"Options"-->"Mesh" and check "2D element faces", "3D element edges" and "3D element faces".

You can see that there are some purple triangles sticking out of the green/yellowish surfaces triangles of the inner surfaces.

You could try to visualize your case the same way and check <--> uncheck the "3D element faces" a few times.

So here is the solution for this behaviour, I did not know that gmsh behaves like this myself. It seems that when you create your mesh and refine it the refinement will be applied on the 2D surface mesh and the 3D volume mesh seperately, which means that those two meshes are not connected after the refinement anymore. What I did next was to try what happens if you create the 2D mesh only, refine it, and then create the 3D mesh, i.e.:

replace:

gmsh.model.mesh.generate(3)
gmsh.model.mesh.refine()
gmsh.model.mesh.refine()

by:

gmsh.model.mesh.generate(2)
gmsh.model.mesh.refine()
gmsh.model.mesh.refine()
gmsh.model.mesh.generate(3)

The result then looks like this:

enter image description here

I hope that this was actually your problem. But in future it would be good if you could provide us a minimum working example of code that we can copy-paste and get the same visualization you showed us in your image.