My application deals with many shapes processed with gmsh's Python API, but I have reduced my problem to a MWE of two polygons which lie in separate planes. Their coordinates are:
# polygon spans (x, y, zs[0])
xy1 = [(0.0, 504.0), (247.0, 504.0), (247.0, 496.0), (0.0, 496.0), (0.0, 504.0)]
zs1 = [0, 50]
xy2 = [(0.0, 396.0), (0.0, 496.0), (0.0, 504.0), (247.0, 504.0), (285.0, 504.0), (285.0, 496.0), (285.0, 396.0), (285.0, 388.0), (247.0, 388.0), (0.0, 388.0), (0.0, 396.0)]
zs2 = [50, 100]
My first step is to project these coordinates onto a finite grid so gmsh doesn't complain about node duplication. I do this by merging proximate points, although this isn't necessary for the example above so I simplify it here for clarity:
coord_labels = {}
def get_coord_label(xyz):
if xyz not in coord_labels:
coord_labels[xyz] = gmsh.model.geo.add_point(*xyz)
return coord_labels[xyz]
pts1 = [get_coord_label((x,y,zs1[0])) for (x,y) in xy1]
pts2 = [get_coord_label((x,y,zs2[0])) for (x,y) in xy2]
This produces unique gmsh point labels:
pts1
>>> [1, 2, 3, 4, 1]
pts2
>>> [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 5]
My task now is to extrude these polygons into polyhedra which span zs[0]
to zs[1]
. Since the polygons are specified in the z = zs[0]
plane, I extrude them along vector (0,0,1)
by a distance zs[1]-zs[0]
like so:
def extrude(pts, dz):
lines = [gmsh.model.geo.add_line(pts[i], pts[i+1]) for i in range(len(pts)-1)]
face = gmsh.model.geo.add_plane_surface([gmsh.model.geo.add_curve_loop(lines, reorient=True)])
objs = gmsh.model.geo.extrude([(2,face)], 0,0, dz)
extrude(pts1, zs1[1] - zs1[0])
extrude(pts2, zs2[1] - zs2[0])
The resulting polyhedra look fine to me when I run
gmsh.model.geo.synchronize()
gmsh.fltk.run()
Above, we see the two volumes; the lower bottom-right one is formed by xy1
and shares its top-surface at z=50
with a sub-bottom-surface of xy2
's extrusion.
Alas, this geometry cannot be meshed. Calling
gmsh.model.mesh.generate()
raises exception
No elements in volume 1
If I had to guess, the problem is that gmsh's extrusion
function (of xy1
) is creating new points within surface z = zs1[1]
, and are not automatically recognised co-planar with z = zs2[0]
. But this is my speculation, and I am not sure why it causes this issue nor how to workaround it.
The entire process (e.g. having to myself group proximate coordinates before extrusion) seems unreasonably difficult for such a simple exercise of extruding polygons! What am I doing wrong? Note in my application, some abutting volumes like this should be merged into a single volume in the mesh, while others should be treated separately (and ergo have an explicit separating surface).