Hello,
I have run into a problem when trying to import a mesh with the function dolfinx.io.gmshio.model_to_mesh. I obtain the following error:
malloc(): mismatching next->prev_size (unsorted)
I was using a similar mesh up to now without any problems. I also output the mesh to a file and check it with the GMSH GUI, and it seems okay.
I would appreciate any help or suggestion what could have gone wrong.
The full error message is:
malloc(): mismatching next->prev_size (unsorted)
[DESKTOP-UNNANJK:02638] *** Process received signal ***
[DESKTOP-UNNANJK:02638] Signal: Aborted (6)
[DESKTOP-UNNANJK:02638] Signal code: (-6)
[DESKTOP-UNNANJK:02638] [ 0] /lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7f4ded922520]
[DESKTOP-UNNANJK:02638] [ 1] /lib/x86_64-linux-gnu/libc.so.6(pthread_kill+0x12c)[0x7f4ded976a7c]
[DESKTOP-UNNANJK:02638] [ 2] /lib/x86_64-linux-gnu/libc.so.6(raise+0x16)[0x7f4ded922476]
[DESKTOP-UNNANJK:02638] [ 3] /lib/x86_64-linux-gnu/libc.so.6(abort+0xd3)[0x7f4ded9087f3]
[DESKTOP-UNNANJK:02638] [ 4] /lib/x86_64-linux-gnu/libc.so.6(+0x896f6)[0x7f4ded9696f6]
[DESKTOP-UNNANJK:02638] [ 5] /lib/x86_64-linux-gnu/libc.so.6(+0xa0d7c)[0x7f4ded980d7c]
[DESKTOP-UNNANJK:02638] [ 6] /lib/x86_64-linux-gnu/libc.so.6(+0xa43fc)[0x7f4ded9843fc]
[DESKTOP-UNNANJK:02638] [ 7] /lib/x86_64-linux-gnu/libc.so.6(malloc+0x99)[0x7f4ded9851b9]
[DESKTOP-UNNANJK:02638] [ 8] /home/przemo/mambaforge/lib/../lib/libstdc++.so.6(_Znwm+0x1c)[0x7f4de76aab48]
[DESKTOP-UNNANJK:02638] [ 9] /home/przemo/mambaforge/lib/python3.10/site-packages/dolfinx/../../../libdolfinx.so.0.6(+0x1413b7)[0x7f4daef553b7]
[DESKTOP-UNNANJK:02638] [10] /home/przemo/mambaforge/lib/python3.10/site-packages/dolfinx/../../../libdolfinx.so.0.6(_ZN7dolfinx4mesh11create_meshEP19ompi_communicator_tRKNS_5graph13AdjacencyListIlEERKNS_3fem17CoordinateElementESt4spanIKdLm18446744073709551615EESt5arrayImLm2EERKSt8functionIFNS4_IiEES2_iiS7_EE+0x3a9)[0x7f4daef55a09]
[DESKTOP-UNNANJK:02638] [11] /home/przemo/mambaforge/lib/python3.10/site-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0x1d4f1d)[0x7f4daf1d7f1d]
[DESKTOP-UNNANJK:02638] [12] /home/przemo/mambaforge/lib/python3.10/site-packages/dolfinx/cpp.cpython-310-x86_64-linux-gnu.so(+0x77ce0)[0x7f4daf07ace0]
[DESKTOP-UNNANJK:02638] [13] /home/przemo/mambaforge/bin/python(+0x1406b7)[0x7f4deddc56b7]
[DESKTOP-UNNANJK:02638] [14] /home/przemo/mambaforge/bin/python(_PyObject_MakeTpCall+0x26b)[0x7f4deddbecdb]
[DESKTOP-UNNANJK:02638] [15] /home/przemo/mambaforge/bin/python(_PyEval_EvalFrameDefault+0x559e)[0x7f4deddbaace]
[DESKTOP-UNNANJK:02638] [16] /home/przemo/mambaforge/bin/python(_PyFunction_Vectorcall+0x6f)[0x7f4deddc5b1f]
[DESKTOP-UNNANJK:02638] [17] /home/przemo/mambaforge/bin/python(_PyEval_EvalFrameDefault+0x332)[0x7f4deddb5862]
[DESKTOP-UNNANJK:02638] [18] /home/przemo/mambaforge/bin/python(_PyFunction_Vectorcall+0x6f)[0x7f4deddc5b1f]
[DESKTOP-UNNANJK:02638] [19] /home/przemo/mambaforge/bin/python(_PyEval_EvalFrameDefault+0x13d0)[0x7f4deddb6900]
[DESKTOP-UNNANJK:02638] [20] /home/przemo/mambaforge/bin/python(+0x1db6a2)[0x7f4dede606a2]
[DESKTOP-UNNANJK:02638] [21] /home/przemo/mambaforge/bin/python(PyEval_EvalCode+0x87)[0x7f4dede605e7]
[DESKTOP-UNNANJK:02638] [22] /home/przemo/mambaforge/bin/python(+0x20e3fc)[0x7f4dede933fc]
[DESKTOP-UNNANJK:02638] [23] /home/przemo/mambaforge/bin/python(+0x2092d4)[0x7f4dede8e2d4]
[DESKTOP-UNNANJK:02638] [24] /home/przemo/mambaforge/bin/python(+0x9758d)[0x7f4dedd1c58d]
[DESKTOP-UNNANJK:02638] [25] /home/przemo/mambaforge/bin/python(_PyRun_SimpleFileObject+0x1b5)[0x7f4dede884f5]
[DESKTOP-UNNANJK:02638] [26] /home/przemo/mambaforge/bin/python(_PyRun_AnyFileObject+0x43)[0x7f4dede880a3]
[DESKTOP-UNNANJK:02638] [27] /home/przemo/mambaforge/bin/python(Py_RunMain+0x399)[0x7f4dede85279]
[DESKTOP-UNNANJK:02638] [28] /home/przemo/mambaforge/bin/python(Py_BytesMain+0x39)[0x7f4dede52dc9]
[DESKTOP-UNNANJK:02638] [29] /lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7f4ded909d90]
[DESKTOP-UNNANJK:02638] *** End of error message ***
Aborted (core dumped)
The code that I have up to the point:
def _shift_points_2d(p, dx=0, dy=0): return [(x[0]+dx, x[1]+dy) for x in p]
def _shift_points_3d(p, dx=0, dy=0, dz=0): return [(x[0]+dx, x[1]+dy, x[2]+dz) for x in p]
def _mirror_along_x(p, x0=0): return [ (x[0], -x[1]) for x in p]
def _mirror_along_y(p, y0=0): return [ (-x[0], x[1]) for x in p]
def set_remove_list(s, c):
t = s.copy()
t.difference_update(c)
return t
def tags_filter_2d(t):
tags = []
for tag in t:
if tag[0]==2:
tags.append(tag[1])
return tags
def tags_filter_3d(t):
tags = []
for tag in t:
if tag[0]==3:
tags.append(tag[1])
return tags
def extrude_from_points_list(_gmsh, p, dz, z0=0):
# a list of tags of all the points that will be created
p_tags = [gmsh.model.occ.addPoint(x[0], x[1], z0 ) for x in p]
# a list of tags of all the lines connecting the points
lines = [gmsh.model.occ.addLine(p_tags[i], p_tags[i+1]) for i in range(len(p_tags)-1)]
lines.append(gmsh.model.occ.addLine(p_tags[-1], p_tags[0]))
# now it is a loop
loop = gmsh.model.occ.addCurveLoop(lines)
# create a surface out of the wires loop
face = gmsh.model.occ.addPlaneSurface([loop])
# extrude the surface so a volume is obtained
objs = gmsh.model.occ.extrude([(2,face)], 0,0, dz)
volumes = tags_filter_3d(objs)
walls = tags_filter_2d(objs)
return volumes, walls
mesh_filename = '02_mesh.msh'
resolution = 1 # Normal resolution
resolution_hq = 0.1 # High Quality resolution
# Pick some tags for the elements
SUBS_VOLUME_TAG = 1
AIR_VOLUME_TAG = 2
METAL_WALLS_TAG = 1
MICROSTRIP1_WALLS_TAG = 2
MICROSTRIP2_WALLS_TAG = 3
SUBS_AIR_WALLS_TAG = 4
PBC_WALLS_TAG = 5
# The microstrip thickness and coordinates of the points (x, y)
L = 2
metal_th = 0.025
metal_gap = 0.5
tw1 = 0.4
tw2 = 0.4
th1 = 0.9
th2 = 0.9
line1_w = 0.7
line2_w = 0.7
assert(th1+th2<L)
assert( max([tw1, tw2])<metal_gap)
metal1_points = [(0, -line1_w), (L, -line1_w), (L, 0.0), ((L+th1)/2, 0.0), ((L+th1)/2, 0.0+tw1), ((L-th1)/2, 0.0+tw1), ((L-th1)/2, 0.0), (0, 0.0)]
metal2_points = [(0, -0.0-tw2), (th2/2, -0.0-tw2), (th2/2, -0.0), (L-th2/2, -0.0), (L-th2/2, -0.0-tw2), (L, -0.0-tw2), (L, line2_w), (0.0, line2_w)]
metal1_points = _shift_points_2d(metal1_points, dy=-metal_gap/2)
metal2_points = _shift_points_2d(metal2_points, dy=metal_gap/2)
# The substrate width, length and thickness
subs_w, subs_h, subs_th = L, 10, 0.254
# The substrate dielectic constant
subs_er = 2.33
# The air box above width, length and height
air_w, air_h, air_th = subs_w, subs_h, 5
import gmsh
gmsh.initialize()
gmsh.option.setNumber("General.Terminal", 0) # disable console output
#%% The first part - prepare the model
# Create a new (and only model)
gmsh.model.add("dut")
# Preapre the substrate and the air volumes
substrate = gmsh.model.occ.addBox(0, -subs_h/2, -subs_th, subs_w, subs_h, subs_th)
air = gmsh.model.occ.addBox(0, -air_h/2, 0, air_w, air_h, air_th)
# Create the metal volume
metal1_volumes, metal1_walls = extrude_from_points_list(gmsh, metal1_points, dz=metal_th)
metal2_volumes, metal2_walls = extrude_from_points_list(gmsh, metal2_points, dz=metal_th)
# Remove the metal volume from the air volume
# We want to first remove the metal form the air, and then from the substrate, so in the first occ.cut there is removeTool=False
# Unfortunately it seems that in the current version cut_map can't help us yet
cut_result, cut_map = gmsh.model.occ.cut([(3, air)], [(3, metal1_volumes[0]), (3, metal2_volumes[0])], removeTool=False)
air = cut_result[0][1]
cut_result, cut_map = gmsh.model.occ.cut([(3, substrate)], [(3, metal1_volumes[0]), (3, metal2_volumes[0])])
substrate = cut_result[0][1]
# The most important thing, do the boolean fragment - then the mesh is conformal
gmsh.model.occ.fragment([(3, air), (3, substrate)], [ ])
#%% The second part - assign tags
gmsh.model.occ.synchronize()
# there are no 4d objects available
_, substrate_adj_surfaces = gmsh.model.getAdjacencies(3, substrate)
_, air_adj_surfaces = gmsh.model.getAdjacencies(3, air)
# let's change the lists to sets, surface tags are unique afterall
substrate_adj_surfaces = set(substrate_adj_surfaces)
air_adj_surfaces = set(air_adj_surfaces)
common_surfaces = substrate_adj_surfaces & air_adj_surfaces
substrate_unique_surfaces = set_remove_list(substrate_adj_surfaces, common_surfaces)
air_unique_surfaces = set_remove_list(air_adj_surfaces, common_surfaces)
all_surfaces = substrate_adj_surfaces | air_adj_surfaces
# Periodic Boundary Condition walls
pbc_walls = []
# Metal Box walls
metal_walls = []
# Microstrip walls
microstrip1_walls = []
microstrip2_walls = []
# The air-substrate interface
subs_air_interface = list(common_surfaces.copy())
for tag in all_surfaces:
comx, comy, comz = gmsh.model.occ.getCenterOfMass(2, tag)
xmin, ymin, zmin, xmax, ymax, zmax = gmsh.model.occ.getBoundingBox(2, tag) # return xmin ymin zmin xmax ymax zmax
if tag in air_unique_surfaces and (zmax>2*metal_th) and (xmax-xmin>L/2):
metal_walls.append(tag)
elif tag in air_unique_surfaces and (zmax>2*metal_th) and (xmax-xmin<L/2):
pbc_walls.append(tag)
elif tag in substrate_unique_surfaces and (zmin<-subs_th/2) and (xmax-xmin>L/2):
metal_walls.append(tag)
elif tag in substrate_unique_surfaces and (zmin<-subs_th/2) and (xmax-xmin<L/2):
pbc_walls.append(tag)
elif tag in substrate_unique_surfaces and not tag in common_surfaces and comy<0:
microstrip1_walls.append(tag)
elif tag in substrate_unique_surfaces and not tag in common_surfaces and comy>0:
microstrip2_walls.append(tag)
# The remaining tags belong to microstrip1 and microstrip2, let's try to get them in another way
def _find_adj_walls(mtl_tag, cond=True):
_, mtl_adj_points = gmsh.model.getAdjacencies(2, mtl_tag)
mtl_walls = set([])
for p in mtl_adj_points:
p_adj_surfaces, _= gmsh.model.getAdjacencies(1, p)
for s in p_adj_surfaces:
comx, comy, comz = gmsh.model.occ.getCenterOfMass(2, s)
if (cond and comz>metal_th/4 and comz<3/4*metal_th) or not cond:
mtl_walls.add(s)
return mtl_walls
def _find_shared_walls(mtl_tags):
shared_walls = None
for tag in mtl_tags:
walls = _find_adj_walls(tag, cond=False)
if shared_walls is None:
shared_walls = set(walls)
else:
shared_walls = shared_walls & walls
return shared_walls
# The strategy is: we easily managed to identified the microstrip 1 and 2 on the interface between the substrate and air, because
# it is just one surface each with distinct COM
# The rest we identify by finding the walls adjecent to this distinct surfaces that have z-comp. of the COM in the microstrip
# The final "roof" surface is found as the shared wall among the ones from the previous step
mtl1_adj_walls = _find_adj_walls(microstrip1_walls[0])
mtl2_adj_walls = _find_adj_walls(microstrip2_walls[0])
mtl1_shared_walls = _find_shared_walls(mtl1_adj_walls)
mtl2_shared_walls = _find_shared_walls(mtl2_adj_walls)
mtl1_adj_walls.update(mtl1_shared_walls)
mtl2_adj_walls.update(mtl2_shared_walls)
microstrip1_walls.extend(mtl1_adj_walls)
microstrip2_walls.extend(mtl2_adj_walls)
gmsh.model.addPhysicalGroup(2, pbc_walls, PBC_WALLS_TAG)
gmsh.model.setPhysicalName(2, PBC_WALLS_TAG, "Periodic BC")
gmsh.model.addPhysicalGroup(2, metal_walls, METAL_WALLS_TAG)
gmsh.model.setPhysicalName(2, METAL_WALLS_TAG, "PEC Box")
gmsh.model.addPhysicalGroup(2, microstrip1_walls, MICROSTRIP1_WALLS_TAG)
gmsh.model.setPhysicalName(2, MICROSTRIP1_WALLS_TAG, "PEC Microstrip 1")
gmsh.model.addPhysicalGroup(2, microstrip2_walls, MICROSTRIP2_WALLS_TAG)
gmsh.model.setPhysicalName(2, MICROSTRIP2_WALLS_TAG, "PEC Microstrip 2")
gmsh.model.addPhysicalGroup(2, subs_air_interface, SUBS_AIR_WALLS_TAG)
gmsh.model.setPhysicalName(2, SUBS_AIR_WALLS_TAG, "Substrate-Air Interface")
#%% Now let's set the meshing
# First we define from which object the distance matters (from the microstrip)
distance = gmsh.model.mesh.field.add("Distance")
microstrip_walls = (microstrip1_walls.copy())
microstrip_walls.extend(microstrip2_walls) # a list of all microstrip wall surfaces
gmsh.model.mesh.field.setNumbers(distance, "FacesList", microstrip_walls)
# So the finest mesh will be up to half of metal_w and then gradually change
# to the regular mesh at the distance of 2x metal_w
threshold = gmsh.model.mesh.field.add("Threshold")
gmsh.model.mesh.field.setNumber(threshold, "IField", distance)
gmsh.model.mesh.field.setNumber(threshold, "LcMin", resolution_hq)
gmsh.model.mesh.field.setNumber(threshold, "LcMax", resolution)
gmsh.model.mesh.field.setNumber(threshold, "DistMin", resolution_hq*3)
gmsh.model.mesh.field.setNumber(threshold, "DistMax", resolution_hq*10)
# Set the mesh
gmsh.model.mesh.field.setAsBackgroundMesh(threshold)
#%% Generate the mesh and save it
gmsh.model.occ.synchronize()
gmsh.model.mesh.generate(3)
gmsh.write(mesh_filename)
#%% Load the mesh to DOLFINx
from dolfinx.io.gmshio import model_to_mesh
from mpi4py import MPI
import numpy as np
model_rank = 0
mesh, cell_tags, facet_tags = model_to_mesh(gmsh.model, MPI.COMM_WORLD, model_rank, gdim=3)