Collecting face elements from surfaces with gmsh (getFacesByFace)

About the development of the FEM module/workbench.

Moderator: bernd

Post Reply
marchirschvogel
Posts: 2
Joined: Wed Mar 25, 2020 10:15 am

Collecting face elements from surfaces with gmsh (getFacesByFace)

Post by marchirschvogel »

Dear community,

I've been using FreeCAD (freecad-daily) since a couple of weeks, so I'm pretty new to everything. My OS: Ubuntu 18.04. My machine: Dual 18 core Xeon Gold 6254 proc, 96 GB RAM.
I actually have an issue with a fairly I would say standard task. I have a solid body which is created via the Part workbench and now should be meshed by GMSH within FreeCAD. Let's call the body "Heart". My meshing code looks like this and works fine:

Code: Select all

# meshing
femmesh_obj_gmsh = ObjectsFem.makeMeshGmsh(doc, 'MyGMSHMeshObj')
femmesh_obj_gmsh.Part = doc.Heart
doc.recompute()

# mesh settings
#femmesh_obj_gmsh.Algorithm3D = 7 # not working... TODO: how to change element type?
femmesh_obj_gmsh.ElementOrder = 0
femmesh_obj_gmsh.CharacteristicLengthMax = max_edge_length
femmesh_obj_gmsh.CharacteristicLengthMin = min_edge_length

gmsh_mesh = femmesh.gmshtools.GmshTools(femmesh_obj_gmsh)
error = gmsh_mesh.create_mesh()
print(error)
doc.recompute()

# get FEM mesh
femmesh = doc.MyGMSHMeshObj.FemMesh

# some mesh info...
num_nodes = femmesh.NodeCount
nodedict = femmesh.Nodes
num_elements = femmesh.VolumeCount
elements = femmesh.Volumes
faceelements = femmesh.Faces
edgeelements = femmesh.Edges
# mesh info for output
nodes_per_el_vol = len(femmesh.getElementNodes(elements[0]))
nodes_per_el_surf = len(femmesh.getElementNodes(faceelements[0]))
nodes_per_el_line = len(femmesh.getElementNodes(edgeelements[0]))
However, now, of course, for export, I have to group certain face elements which belong to certain surfaces for my boundary conditions. Let's say I have a surface called

Code: Select all

 ff = doc.Heart.Shape.Faces[0] 
for example (a surface, not a finite element!).
To get the face elements of ff, I use

Code: Select all

fele = femmesh.getFacesByFace(ff)
which works... BUT: Having a very fine mesh (here I tried ~1.8M tet4 elements, which were ~350k nodes, ~210k faces), this command (getFacesByFace) takes AGES! I checked it and the meshing is done in let's say ~3 min, but looping over my seven surfaces calling getFacesByFace on everyone takes HOURS!
It perfectly works for a coarse mesh, but a very fine one - no way. :-/

Does anyone know an alternative command to this? One which can be called via script (without the GUI, so with freecadcmd-daily)? I want to hold my own Python array with a collection of these surface faces since I have my own writing routines for a FEM program.

Would be great if someone had some experience here!

Thanks!

Best,
Marc
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: Collecting face elements from surfaces with gmsh (getFacesByFace)

Post by Kunda1 »

Mod Edit: Moved to FEM subforum
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
joha2
Posts: 303
Joined: Tue Oct 11, 2016 9:48 pm

Re: Collecting face elements from surfaces with gmsh (getFacesByFace)

Post by joha2 »

marchirschvogel wrote: Wed Mar 25, 2020 10:39 am which works... BUT: Having a very fine mesh (here I tried ~1.8M tet4 elements, which were ~350k nodes, ~210k faces), this command (getFacesByFace) takes AGES! I checked it and the meshing is done in let's say ~3 min, but looping over my seven surfaces calling getFacesByFace on everyone takes HOURS!
It perfectly works for a coarse mesh, but a very fine one - no way. :-/
I wonder why this takes ages for a very fine mesh. In

https://github.com/FreeCAD/FreeCAD/blob ... p.cpp#L683

there is the definition of the Python API function, but first it is a C++ function and second the collection of the elements is in a for loop which is IMHO very fast. (Maybe with a slight overhead due to the iterators.)

Ok there is another call to FemMeshPtr in

https://github.com/FreeCAD/FreeCAD/blob ... h.cpp#L609

Maybe the intersection is a bottleneck, but first of all one has to find out where FreeCAD exactly breaks down.

Hope this helps as a starting point.

Best wishes
Johannes
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Collecting face elements from surfaces with gmsh (getFacesByFace)

Post by bernd »

I am on a mobile and thus can not test ATM.

What I would do is create mesh group objects in FreeCAD FEM. They are childs of the gmsh mesh object. With them the group geometry will passed to gmsh. Gmsh than returns the mesh with the groups included. This is not much slower than just meshing.

BTW. How many nodes and elements does the mesh has for which the search takes hours?
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Collecting face elements from surfaces with gmsh (getFacesByFace)

Post by bernd »

ahh 1.8 M which is a lot but it should not take hours but it can take long ... All the geometry mesh seach tools are not optimised on cost thus on huge meshes really take very long.
marchirschvogel
Posts: 2
Joined: Wed Mar 25, 2020 10:15 am

Re: Collecting face elements from surfaces with gmsh (getFacesByFace)

Post by marchirschvogel »

Hi all,

Thanks for your replies. Indeed collecting the face elements by MeshGroups is much much faster and the way to go! So now the whole stuff only takes about 5-6 min for this very fine mesh. And, additionally, getFacesByFace seems to skip face elements! So best to avoid this function and use the mesh group functionality!

Best,
Marc
Post Reply