No groups from mesh being recognised after importing .h5 file

,

I have produced a mesh by converting the .msh and .med files to a .h5 file which also spits out the .xml files too. The mesh is of a simple cylinder but I have grouped the surfaces and volumes seperately as I wish to use this to model a surface energy source. The .msh and .xml files each recognise that different groups are present. I want to just do a sanity check to see if the .h5 file is importing the files correctly by asking it to tell me the area of one of the surfaces.

However, this consistently gives me an answer of zero, even though it should be non-zero. My minimal working example is here:

from __future__ import print_function
import numpy as np
from dolfin import *
import ufl
import math
from mpi4py import MPI

parameters["allow_extrapolation"] = True
parameters["form_compiler"]["cpp_optimize"] = True
parameters["form_compiler"]["optimize"] = True
set_log_level(50)


#--Import the required mesh files produced in Salome and gmsh-----
mesh_file = 'Mesh_convergence/'
filename = 'mesh_3mm_9'

data = mesh_file+filename

mesh = Mesh()
hdf = HDF5File(mesh.mpi_comm(), data+'.h5', 'r')
hdf.read(mesh, '/mesh', False)
cells_f = MeshFunction('size_t', mesh, 3)
hdf.read(cells_f, '/cells')
facets_f = MeshFunction('size_t', mesh, 2)
hdf.read(facets_f, '/facets')

#-----------------------------------------------
# Mark the tags for 'top' and 'surface' groups
#-----------------------------------------------
tag_s = 2  #Tags for 'surface' group in .msh file
tag_t = 3  # Tag for 'top' group in .msh file

i,j,k = ufl.indices(3)

x = SpatialCoordinate(mesh)

#------------------------------------------------
da = Measure('ds', domain=mesh, subdomain_data = facets_f, metadata = {'quadrature_degree': 2})  #area element

#-------------------------------------------

print(assemble(1*da(tag_t)))

The files for “mesh_3mm_9” can be found here: Med2h5 conversion - Google Drive

I am wondering if there is an issue with my installation of dolfin that I am running through a conda environment as the function HDF5File comes from dolfin. Does anyone have any recommendations?

Could you reduce this to the following:

from dolfin import *


mesh_file = 'Mesh_convergence/'
filename = 'mesh_3mm_9'

data = mesh_file+filename

mesh = Mesh()
hdf = HDF5File(mesh.mpi_comm(), data+'.h5', 'r')
hdf.read(mesh, '/mesh', False)
cells_f = MeshFunction('size_t', mesh, 3)
hdf.read(cells_f, '/cells')
facets_f = MeshFunction('size_t', mesh, 2)
hdf.read(facets_f, '/facets')
print(facets_f.array())
print(cells_f.array())

and also check the data in your h5 file with h5dump ?
https://manpages.debian.org/jessie/hdf5-tools/h5dump.1.en.html

It seems like you have written your own medtoh5 converter (or have you gotten it from someone?). If you have written it yourself. are you sure that the data is added to the h5 file?

If you haven’t written it yourself, what is the original source of the file?

I would also prefer that such a script is embedded on the forum with

```python
# add code here

```

rather than in a google drive, that might disappear in the future.

Thank you for your reply. What package do I need to install/use in order to test the h5dump command that you recommended? For the converter, this was provided by a colleague. This converter has been very successful in the past and has previously worked well with prior meshes produced by Salome. The script itself is very long (around 800 lines) so embedding this all into the forum may not be that practical, hence the Google Drive.

It should be provided with any hdf5 installation, as far as I am aware, ref: hdf5 - How do I download h5dump? (h5dump: command not found) - Stack Overflow

The problem is that it is likely the converter not working, which means that it one would have to dive into this code.

You could start by just calling

as suggested above to see if you actually read in any facet or cell values.

Ok, I will try the h5dump as you suggested. In addition, I have run the code provided by yourself and detected facet and cell values:

(base) [jsmith@ifcluster Fenics]$ python3 mesh_import_check.py
[2 2 2 ... 0 0 0]
[1 1 1 ... 1 1 1]
(base) [jsmith@ifcluster Fenics]$

The h5dump gives the following:

<?xml version="1.0" encoding="UTF-8"?>
<hdf5:HDF5-File xmlns:hdf5="http://hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdfgroup.org/HDF5/XML/schema/HDF5-File http://www.hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd">
<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/">
   <hdf5:Group Name="cells" OBJ-XID="xid_28016" H5Path="/cells" Parents="xid_96" H5ParentPaths="/" >
      <hdf5:Dataset Name="cell_indices" OBJ-XID="xid_367152" H5Path= "/cells/cell_indices" Parents="xid_28016" H5ParentPaths="/cells">
         <hdf5:StorageLayout>
            <hdf5:ContiguousLayout/>
         </hdf5:StorageLayout>
         <hdf5:FillValueInfo FillTime="FillIfSet" AllocationTime="Late">
            <hdf5:FillValue>
               <hdf5:NoFill/>
            </hdf5:FillValue>
         </hdf5:FillValueInfo>
         <hdf5:Dataspace>
            <hdf5:SimpleDataspace Ndims="1">
               <hdf5:Dimension  DimSize="7812" MaxDimSize="7812"/>
            </hdf5:SimpleDataspace>
         </hdf5:Dataspace>
         <hdf5:DataType>
            <hdf5:AtomicType>
               <hdf5:IntegerType ByteOrder="LE" Sign="true" Size="8" />
            </hdf5:AtomicType>
         </hdf5:DataType>
         <hdf5:Data>
            <hdf5:DataFromFile>

The raw data then follows this. No facets are seemingly detected here, unless I am misinterpreting the header.

So at least it seems to read in some values that are marked with two.
The next would be to check if these facets are exterior:

marked_facets = facets_f.where_equal(2)
mesh.init(mesh.topology().dim()-1, mesh.topology().dim())
for facet in marked_facets:
     print(dolfin.Facet(mesh, facet).entities(mesh.topology().dim())

Yes, some exterior facets are detected:

[1856 1857]
[1856 1857]
[3474 3475]
[3514 3515]
[638 639]
[18 19]
[484 485]
[2116 2117]
[3848 3849]
[1520 1521]
[1520 1521]
[1496 1497]
[1516 1517]
[1834 1835]
[1834 1835]
[2086 2087]
[492 493]
[492 493]
[3422 3423]
[270 271]
[3442 3443]
[3442 3443]
[1342 1343]
[1604 1605]
[2056 2057]
[2056 2057]
[1396 1397]
[1846 1847]
[1846 1847]
[1364 1365]
[1368 1369]
[518 519]
[518 519]
[528 529]
[1510 1511]
[1610 1611]
[1610 1611]
[2210 2211]
[736 737]
[246 247]
[722 723]
[328 329]
[3750 3751]
[3750 3751]
[3160 3161]
[354 355]
[354 355]
[954 955]
[344 345]
[2786 2787]
[2786 2787]
[1544 1545]
[1800 1801]
[776 777]
[2446 2447]
[2420 2421]
[3460 3461]
[3460 3461]
[2406 2407]
[262 263]
[3504 3505]
[3504 3505]
[268 269]
[3770 3771]
[3770 3771]
[3606 3607]
[2102 2103]
[3524 3525]
[14 15]
[1498 1499]
[3568 3569]
[100 101]
[3610 3611]
[1904 1905]
[912 913]
[1874 1875]
[1466 1467]
[2596 2597]
[1288 1289]
[400 401]
[1166 1167]
[972 973]
[3182 3183]
[620 621]
[3494 3495]
[3334 3335]
[3824 3825]
[2602 2603]
[3480 3481]
[408 409]
[3354 3355]
.
.
.

Neither of those facets are exterior, as they are connected to two cells.

Thus, these are interior, and you should use the dS measure, rather than ds (which is for facets connected to a single cell).

What energy flux calculations?

The only ds integral I see in your code is:

Are these, which I do not believe should cause any issues as all variables are continuous across internal facets.

So I guess you have another calculation somewhere, where you would like to compute dot(grad(T),n) across one of these interior facets.
Then you need to restrict the integral to be from a given side, as grad(T) is discontinuous across the facet.

Ok, I think this is more of an issue with how the mesh was originally constructed as all the other meshes I have produced give something like this:

[25273]
[219139]
[219132]
[182735]
[62803]
[82921]
[109436]
[60814]
[147820]
[171232]
[145664]
[182732]
[171229]
[73885]
[13912]
[81081]
[147469]
[98526]
[105754]
[98432]
[145665]
[100509]
[109437]
[72013]
[219129]
[143780]
[44801]
[219126]
[219131]
[100355]
[73888]
[35277]
[36240]
[73857]
[44107]
.
.
.

Whereas the current mesh is connected to two cells, like you mentioned. Which would cause the calculation to not compute correctly. So perhaps there is an issue with either how the original .med/.msh file is being output or how the file is being converted to .h5

For reference, I am also running this code with the following dolfin version:

Client:
 Version:           27.2.0
 API version:       1.47
 Go version:        go1.21.13
 Git commit:        3ab4256
 Built:             Tue Aug 27 14:17:17 2024
 OS/Arch:           windows/amd64
 Context:           desktop-linux

Server: Docker Desktop 4.34.2 (167172)
 Engine:
  Version:          27.2.0
  API version:      1.47 (minimum version 1.24)
  Go version:       go1.21.13
  Git commit:       3ab5c7d
  Built:            Tue Aug 27 14:15:15 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.20
  GitCommit:        8fc6bcff51318944179630522a095cc9dbf9f353
 runc:
  Version:          1.1.13
  GitCommit:        v1.1.13-0-g58aa920
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

It is likely the original file that has an internal interface where you expect an external one.

Hmm I see. I made the mesh via Salome (output as the .med file in the Google Drive) and then converted it to a .msh file via gmsh (again, this is in the Google Drive). You may attempt to convert this yourself into a h5 file to see if the issue lies with the converter or how the mesh was produced in Salome.

That is unfortunately not something I have the bandwidth to do.
As I’ve shown above, you seem to have meshed elements on both sides of the interface in Salome.
That is not something that I can easily circumvent in a meshing conversion script, as the elements are already present in the mesh.

I see. Do you have any other recommendations for programs that can produce such a cylindrical mesh, whilst being able to create surface groups?

I guess you can use GMSH for it? https://gmsh.info/

Can gmsh natively do .xml or .h5 files?

So you are aware, I have mostly solved the issue now. The problem was arising form my Fenics installation in docker, in that whenever I restarted the container, the packages did not fully carry over. Now when the code you provided runs, I obtain the following:

root@bff41e02d6ca:/home/fenics/shared# python3 mesh_import_check.py
mesh_3mm_9
[183]
[541]
[167]
[419]
[325]
[423]
[95]
[92]
[446]
[96]
[191]
[15]
[237]
[90]
[244]
[155]
[358]
[511]
[1179]
[1537]
[1163]
[1415]
[1321]
[1419]
[1091]
[1088]
[1442]
[1092]
[1187]
[1011]
[1233]
[1086]
[1240]
[1151]
[1354]
[1507]
[2358 2359]
[3074 3075]
[2326 2327]
[2830 2831]
[2642 2643]
[2838 2839]
[2182 2183]
[2176 2177]
[2884 2885]
[2184 2185]
[2374 2375]
[2022 2023]
[2466 2467]
[2172 2173]
[2480 2481]
[2302 2303]
[2708 2709]
[3014 3015]
[4350 4351]
[5066 5067]
[4318 4319]
[4822 4823]
[4634 4635]
[4830 4831]
[4174 4175]
[4168 4169]
[4876 4877]
[4176 4177]
[4366 4367]
[4014 4015]
[4458 4459]
[4164 4165]
[4472 4473]
[4294 4295]
[4700 4701]
[5006 5007]
[451]
[553]
[303]
[170]
[242]
[104]
[1447]
[1549]
[1299]
[1166]
[1238]
[1100]
[2894 2895]
[3098 3099]
[2598 2599]
[2332 2333]
[2476 2477]
[2200 2201]
[4886 4887]
[5090 5091]
[4590 4591]
[4324 4325]
[4468 4469]
[4192 4193]
Calling FFC just-in-time (JIT) compiler, this may take some time.
Calling FFC just-in-time (JIT) compiler, this may take some time.
Calling FFC just-in-time (JIT) compiler, this may take some time.
Calling FFC just-in-time (JIT) compiler, this may take some time.
1.3497798380737298e-05

Thus some external facets are now being detected.

This seems to be an issue with either:

  1. How you define your mesh in salome
  2. How the long export script you got from your collaborator does the conversion.

Without some effort put into identifying which of these are the issue (and what section of your collaborators code causes the issue), I do not have the bandwidth to give further guidance.

That being said, this is an open source forum, and maybe someone else has the time an expertise to dig into this further.

gmsh writes out msh files, which you can convert to xml or xdmf for DOLFINx with meshio.
There are many tutorials on this on the forum (search for “DOLFIN meshio”)