removePhysicalName suspected in bugged state after OCC removeAllDuplicates
I may have encountered a suspected bug in gmsh.model.removePhysicalName
of the Python API, whereby in certain conditions, it does not remove the specified name from the model. I believe it occurs when removePhysicalName(name)
is called after some OCC entities in the model have changed; but not necessarily those within the physical group with name name
. This means subsequent calling of setPhysicalName()
with the same name
will "collide" and do nothing.
Consider the below straightforward convenience functions:
import gmsh
gmsh.initialize()
_FACTORY = gmsh.model.occ
def add_simple_polygon_to_mesh(xy, z, mesh_size):
if xy[-1] != xy[0]:
xy.append(xy[0])
point_tags = [_FACTORY.add_point(x,y,z, mesh_size) for x,y in xy]
line_tags = [_FACTORY.add_line(point_tags[i], point_tags[i+1]) for i in range(len(point_tags)-1)]
face_tag = _FACTORY.add_plane_surface([_FACTORY.add_curve_loop(line_tags)])
return face_tag
def extrude_simple_polygon(xy, z0, z1, mesh_size):
face_tag = add_simple_polygon_to_mesh(xy, z0, mesh_size)
object_tags = _FACTORY.extrude([(2,face_tag)], 0,0, z1-z0)
volume_tags = [obj for obj in object_tags if obj[0]==3]
_FACTORY.synchronize()
return volume_tags[0]
def make_group(tags, name):
group_tag = gmsh.model.addPhysicalGroup(3, [t[1] for t in tags])
gmsh.model.setPhysicalName(3, group_tag, name)
_FACTORY.synchronize()
def clear_groups():
print('[clearing groups]')
for dim, tag in gmsh.model.getPhysicalGroups():
name = gmsh.model.getPhysicalName(dim, tag)
gmsh.model.removePhysicalName(name)
gmsh.model.removePhysicalGroups()
def remake_groups(name_tag_map):
clear_groups()
print('[making groups]')
for name, tags in name_tag_map.items():
make_group(tags, name)
def print_all_entities_and_groups():
print("all volume entities:")
print('\t', [e for e in _FACTORY.getEntities() if e[0]==3])
print("all surface entities")
print('\t', [e for e in _FACTORY.getEntities() if e[0]==2])
print("known groups:")
groups = gmsh.model.getPhysicalGroups()
if len(groups) == 0:
print('\t(none)')
else:
for dim_tag in groups:
name = gmsh.model.getPhysicalName(*dim_tag)
print(dim_tag, f"name: '{name}'")
print('')
def make_conformal():
print("[removing duplicates]\n")
_FACTORY.removeAllDuplicates()
_FACTORY.synchronize()
As an example, we make four cuboids which overlap along their surfaces:
v1 = extrude_simple_polygon([(0,0), (0,1), (1,1), (1,0)], 0, 1, .1)
v2 = extrude_simple_polygon([(2,0), (2,1), (3,1), (3,0)], 0, 1, .1)
v3 = extrude_simple_polygon([(0,1), (0,2), (1,2), (1,1)], 0, 1, .1)
v4 = extrude_simple_polygon([(2,1), (2,2), (3,2), (3,1)], 0, 1, .1)
Consider the below verbatim code, which does not demonstrate the bug, because the scene does not change between invocations of remake_groups
:
remake_groups({'a':[v1, v2], 'b':[v3, v4]})
print_all_entities_and_groups()
# if below is uncommented...
# - subsequent group name clearing will fail(?)
# - ergo the above names will persist in the model
# - ergo the remade groups will name-collide and default to ''
# make_conformal()
remake_groups({'a':[v1, v2], 'b':[v3, v4]})
print_all_entities_and_groups()
Running the above prints:
[clearing groups]
[making groups]
all volume entities:
[(3, 1), (3, 2), (3, 3), (3, 4)]
all surface entities
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
known groups:
(3, 1) name: 'a'
(3, 2) name: 'b'
[clearing groups]
[making groups]
all volume entities:
[(3, 1), (3, 2), (3, 3), (3, 4)]
all surface entities
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
known groups:
(3, 3) name: 'a'
(3, 4) name: 'b'
However, we now uncomment make_conformal()
in the above code and re-run. This invokes gmsh.model.occ.removeAllDuplicates()
which deletes the overlapping shared surfaces of v1
,v2
,v3
,v4
, but should not change or remove the volume entities. Indeed, their tags are not changed. The code now outputs:
[clearing groups]
[making groups]
all volume entities:
[(3, 1), (3, 2), (3, 3), (3, 4)]
all surface entities
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
known groups:
(3, 1) name: 'a'
(3, 2) name: 'b'
[removing duplicates]
[clearing groups]
[making groups]
all volume entities:
[(3, 1), (3, 2), (3, 3), (3, 4)]
all surface entities
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
known groups:
(3, 3) name: ''
(3, 4) name: ''
We see the physical groups (3,3)
and (3,4)
have lost their names, erroneously.
The invocation of removeAllDuplicates()
has meant that the subsequent calling of setPhysicalName()
with names a
and b
(previously known to the model) has failed - and the remade groups have defaulted to names ''
. I suspect this is due to the removePhysicalName
invocation preceding it failing.
This occurs with gmsh 4.11.0
in python 3.8.13
on Windows 11.