Dolfin:Problem importing a 3D mesh generated with gmsh

I have generated a simple 3D mesh with the following code:

import math as mth
import gmsh
import math as mt
import sys

#--- MESH GENERATION ---#
gmsh.initialize()
geo = gmsh.model.geo
Rr = 0.1
Ln = 0.10
res = 1/500	# resolution

phi = 0.6373 

c0 = geo.addPoint(0, -Rr*mt.sin(mt.pi/2-phi), 0, res, tag=1)
p1 = geo.addPoint(Rr*mt.cos(mt.pi/2 - phi), 0, 0, res, tag=(c0+1))
p2 = geo.addPoint(-Rr*mt.cos(mt.pi/2 - phi), 0, 0, res, tag=(p1+1))
cArc1 = geo.addCircleArc(p1, c0, p2, tag=1)
bioLine = geo.addLine(p2, p1, tag=(cArc1+1))

lineTot = geo.addCurveLoop([cArc1, bioLine], tag=(bioLine+1))
supTot = geo.addPlaneSurface([lineTot], tag=1)
tubo = geo.extrude([(2,supTot)], 0,0,0.5) 
geo.synchronize()

secInput = gmsh.model.addPhysicalGroup(2, [supTot], tag=1)
secInput = gmsh.model.addPhysicalGroup(2, [15], tag=2)
convection = gmsh.model.addPhysicalGroup(2, [14], tag=3)
conduction = gmsh.model.addPhysicalGroup(2, [10], tag=4)

#gmsh.option.setNumber("Mesh.Algorithm", 5)
gmsh.model.mesh.generate(3)
if '-nopopup' not in sys.argv:
	gmsh.fltk.run()
gmsh.write('dominio.msh')
gmsh.finalize()

My need is to convert the .msh in .xml file, mainteining the physical group IDs in order to define in a simple manner the Neumann conditions along the surfaces for a simple code written using Dolfin libraries.
I have read many other posts (.xdmf mixed type - problem with generating mesh - #2 by dokken , Transitioning from mesh.xml to mesh.xdmf, from dolfin-convert to meshio - #79 by dokken) but none of the proposed solutions seems to work for me.
In particular, if I use the solution proposed here: :Transitioning from mesh.xml to mesh.xdmf, from dolfin-convert to meshio - #79 by dokken, seems that the mesh does not have tetra cells but just triangular.
I worked with 2D geometries in the past and I have wrote a code that creates two files (one for physical region and one for facet region) and, unfortunately, this code does not work with 3D mesh.

Thank you for the support

You need to add physical groups for the volume as well.

It was easy. Thank you so much Dokken.
I try to ask another question not related to the title of the post:
Suppose to have a simple steady state 3D simulation solved in a cylinder, where the temperature profile is the solution. I would use the temperature profile obtained in the “outlet” section as a boudnary condition for the “inlet” section of another simulation. How can I do that (in dolfin)?
I’ve read some posts like https://fenicsproject.org/qa/11196/extract-solution-surface-boundary-discrete-function-assemble/ or https://fenicsproject.org/qa/11196/extract-solution-surface-boundary-discrete-function-assemble/ but i think that they solved a different problem repsect what I need.
Can you help me with this issue or even just link me to other posts discussing it?
thank you so much, and sorry

There are quite a few things to this new question that you haven’t covered. I would suggest making a separate post, Where you address the following questions

  1. what version of fenics are you using
  2. will the interface of the outlet align with the inlet of the other simulation? I.e. Will the triangles align?

Thank you. I’ll follow your suggestions.

Hello Dokken,
could you help me with the question?

Hi everyone,

I have a similar issue. I am trying to create the geometry for the hyperelasticity problem in tutorials to understand the creation of 3d geometries with gmsh. Although I have defined the Physical group for the curve, surface and volume. I created a surface and extruded it in the following way. (Without extrude command, it works fine). What am I doing wrong here? I have the same error regarding Physical groups using meshio in dolfinx. I am trying to create quad mesh using Mesh settings in gmsh as ‘Frontal-Delaunay for quads - 2d algorithm’ and ‘Frontal - 3d algorithm’.

//+
Point(1) = {0, 0, 0, 0.2};
//+
Point(2) = {20, 0, 0, 0.2};
//+
Point(3) = {20, 1, 0, 0.2};
//+
Point(4) = {0, 1, 0, 0.2};
//+
Line(1) = {1, 2};
//+
Line(2) = {2, 3};
//+
Line(3) = {3, 4};
//+
Line(4) = {4, 1};
//+
Curve Loop(1) = {4, 1, 2, 3};
//+
Plane Surface(1) = {1};
//+
Physical Curve(1) = {1, 2, 3, 4};
//+
Physical Surface("My surface") = {1};
//+
e() = Extrude {0, 0, 1}{ Surface{1}; Layers{10}; Recombine; };
//+
Physical Volume(1) = {e(1)};
//+
Coherence;
Mesh 3;
Coherence Mesh;

I am using the following code to read in the .msh file in dolfinx using another 3D mesh created without extrude option but I get an error given below. What could be the issue here?

proc = MPI.COMM_WORLD.rank

def create_mesh(mesh, cell_type, prune_z=False):
    cells = mesh.get_cells_type(cell_type)
    cell_data = mesh.get_cell_data("gmsh:physical", cell_type)
    points = mesh.points[:, :2] if prune_z else mesh.points
    out_mesh = meshio.Mesh(points=points, cells={cell_type: cells}, cell_data={"name_to_read": [cell_data.astype(np.int32)]})
    return out_mesh

if proc == 0:
    # Read in mesh
    msh = meshio.read(Path("geometry")/"hyper_3d_v1.msh")

    # Create and save one file for the mesh, and one file for the facets
    hex_mesh = create_mesh(msh, "hexahedron")
    quad_mesh = create_mesh(msh, "quad")
    meshio.write("mesh.xdmf", hex_mesh)
    meshio.write("mt.xdmf", quad_mesh)
MPI.COMM_WORLD.barrier()

with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "mesh.xdmf", "r") as xdmf:
    domain = xdmf.read_mesh(name="Grid") # cell tags
    ct = xdmf.read_meshtags(domain, name="Grid")
domain.topology.create_connectivity(domain.topology.dim, domain.topology.dim - 1)
with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "mt.xdmf", "r") as xdmf:
    facet_tag = xdmf.read_meshtags(domain, name="Grid") # facet tags

fdim = domain.topology.dim - 1
dim = domain.topology.dim    

Error

need at least one array to concatenate
  File "/home/igupta/studies/test/basic_tri_thrombus_v1.py", line 58, in create_mesh
    cell_data = mesh.get_cell_data("gmsh:physical", cell_type)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/igupta/studies/test/basic_tri_thrombus_v1.py", line 68, in <module>
    hex_mesh = create_mesh(msh, "hexahedron")
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: need at least one array to concatenate

Here is the .geo file with which this error exists

//+
Point(1) = {0, 0, 0, 0.2};
//+
Point(2) = {20, 0, 0, 0.2};
//+
Point(3) = {20, 1, 0, 0.2};
//+
Point(4) = {0, 1, 0, 0.2};
//+
Point(5) = {0, 0, 1, 0.2};
//+
Point(6) = {20, 0, 1, 0.2};
//+
Point(7) = {20, 1, 1, 0.2};
//+
Point(8) = {0, 1, 1, 0.2};
//+
Line(1) = {1, 2};
//+
Line(2) = {2, 3};
//+
Line(3) = {3, 4};
//+
Line(4) = {4, 1};
//+
Line(5) = {1, 5};
//+
Line(6) = {2, 6};
//+
Line(7) = {3, 7};
//+
Line(8) = {4, 8};
//+
Line(9) = {5, 6};
//+
Line(10) = {6, 7};
//+
Line(11) = {7, 8};
//+
Line(12) = {8, 5};
//+Top
Curve Loop(1) = {-8, -3, 7, 11};
//+Front
Curve Loop(2) = {4, 1, 2, 3};
//+Bottom
Curve Loop(3) = {-5, 1, 6, -9};
//+Back
Curve Loop(4) = {12, 9, 10, 11};
//+Right
Curve Loop(5) = {-2, 6, 10, -7};
//+Left
Curve Loop(6) = {4, 5, -12, -8};
//+
Plane Surface(1) = {1};
//+
Plane Surface(2) = {2};
//+
Plane Surface(3) = {3};
//+
Plane Surface(4) = {4};
//+
Plane Surface(5) = {5};
//+
Plane Surface(6) = {6};
//+
Physical Curve(1) = {1};
//+
Physical Curve(2) = {2};
//+
Physical Curve(3) = {3};
//+
Physical Curve(4) = {4};
//+
Physical Curve(5) = {5};
//+
Physical Curve(6) = {6};
//+
Physical Curve(7) = {7};
//+
Physical Curve(8) = {8};
//+
Physical Curve(9) = {9};
//+
Physical Curve(10) = {10};
//+
Physical Curve(11) = {11};
//+
Physical Curve(12) = {12};
//+
Physical Surface(1) = {1};
//+
Physical Surface(2) = {2};
//+
Physical Surface(3) = {3};
//+
Physical Surface(4) = {4};
//+
Physical Surface(5) = {5};
//+
Physical Surface(6) = {6};
//+
Surface Loop(11) = {1, 2, 3, 5, 4, 6};
//+
Volume(12) = {11};
Physical Volume("Volume", 1) = {12};
//+
Coherence;
Mesh 3;
Coherence Mesh;

Inspecting the generated mesh by calling print(msh) you observe that your mesh has no hexahedral cells:


<meshio mesh object>
  Number of points: 3411
  Number of cells:
    line: 100
    line: 5
    line: 100
    line: 5
    line: 5
    line: 5
    line: 5
    line: 5
    line: 100
    line: 5
    line: 100
    line: 5
    triangle: 1204
    triangle: 1204
    triangle: 1206
    triangle: 1204
    triangle: 66
    triangle: 68
    tetra: 12855
  Cell sets: Volume, gmsh:bounding_entities
  Point data: gmsh:dim_tags
  Cell data: gmsh:physical, gmsh:geometrical
  Field data: Volume

See for instance:

that uses re-combination algorithms to generate hexes.

Thank you for the comment @dokken. I added the following commands to the .geo file

Mesh 3;
//+
Mesh.RecombinationAlgorithm = 2;
//+
Mesh.RecombineAll = 2;
//+
Mesh.CharacteristicLengthFactor = 1;

And using GUI on gmsh and print(msh), I see now that it has quad, tetra and pyramid elements. Only the surface elements of the geometry are quad but inner elements are tetra and pyramid. Hence, the same error. What am I doing wrong here?

<meshio mesh object>
  Number of points: 3306
  Number of cells:
    quad: 24
    quad: 188
    quad: 24
    quad: 16
    tetra: 15187
    pyramid: 828
  Cell sets: gmsh:bounding_entities
  Point data: gmsh:dim_tags
  Cell data: gmsh:physical, gmsh:geometrical

It might be that you cannot make an unstructured hexahedral mesh (due to limitations in hexahedral meshing algorithms). This is more of a GMSH question, than a FEniCS question, and I would strongly suggest to interact with the developers there.