A cfMesh workflow to speed up and improve your meshing
Here, I’ll cover the basic workflow that I implement when I am using cfMesh.
First, when do I use cfMesh? I love cfMesh. I find it robust, easy to use (with this workflow), and gives high quality hex-dominant meshes for use with OpenFOAM. But there are a few cases where I do not use cfMesh. These are when I am meshing multiple regions (such as rotating zones or conjugate heat transfer) and when I have decided (for some reason) that I am going to do a tet-dominant mesh. With that said, both of those can be accomplished with cfMesh, but I prefer snappyHexMesh for multi-region meshing, and I prefer the built-in Netgen, and gmsh modules of Salome if I am doing a tet-mesh.
What do you need to start?
- For this workflow using
cfMesh , you will obviously need a working installation ofcfMesh . Luckily it now comes preloaded as part of OFv18. Even if you prefer a differentopenfoam flavor, you can use the OFv18cfMesh to create the mesh, and the mesh will still work in the other flavors. - You will also need a working installation of Salome.
Geometry Preparation

Typically, I first start in a CAD program (it doesn’t matter which) and produce a 3D .step, .iges, or .brep representation of the fluid domain. This means that if you are doing an internal flow, you want a geometry file representing everywhere the fluid will go. For an external flow, you want a large open domain with your geometry subtracted from it. This is easily accomplished with
For an example, I’ll use the Glider geometry shown in the figure above. I downloaded this model from Grabcad, loaded it into Onshape, cleaned up some of the surfaces and subtracted the glider from a fluid domain:

FMS File Preparation
FMS is the recommended file format for using
For a very long time, I used
Selecting Patches
Back on topic: First load your STEP, IGES, or BREP file into geometry module of Salome. Now, we want to create and name our patches. To do this, use the menu New Entity -> Group -> Create Group. Make sure the geometry file is selected in the tree. A window will open where you can select points, edges, surfaces, or solids. We want surfaces.
Type the name of the patch you are going to select. Select the face in the viewer, and click add. Finally hit apply. Repeat this for each patch. In most cases, you will need to hide some surfaces to see the surfaces of the geometry. In those cases, just select the faces you aren’t currently selecting and then hit “Hide Selected”.

Extract Edges
Before we move on to creating our surface mesh, we should extract our edges for cfMesh. This is done by executing the “ExtractFeatureEdges.py” python script. Select your the geometry file in the
Generate Surface Mesh
It seems tedious to generate a mesh… before generating a mesh. But rest assured we are only creating a surface mesh. And it should run

After building the mesh (hitting the little gear button), we now just need to load our patches from the geometry module, and export to an FMS file.


Within the mesh module, select your mesh, and then go to Mesh->Create Groups from

Finally, we are ready to export to an FMS file. To do this, select your mesh on the tree.

Mesh Using cfMesh
From here on out, is basic cfMesh meshing. In your system/meshDict file you must select the FileName.fms that you created in the previous steps. I will not cover the meshDict options I used here, as the focus of this article was on the workflow described in the previous sections. But here are some images of the type of results you can expect from cfMesh:




As the general usage of cfMesh is covered in detail in the cfMesh manual, and in another post (the Ahmed Body) I will just give a couple tips and tricks here. A specific Tips and Tricks post may follow.
Use renameBoundary dict to simplify your case
In this workflow, I usually create surfaces for refinement within
Use the generateBoundaryLayers command
I have found that I get much better results if I first mesh without boundary layers, and then add them after using the generateBoundaryLayers command. This is for a
Use the crinkle-slice option in Paraview
When viewing your mesh, make sure to select the “crinkle-slice” option when viewing your mesh. If you just take a regular slice (a) you aren’t seeing the actual cells you are seeing a slice of them, and (b) the rendering puts some cross lines which don’t actually exist. You want to see the actual cells, and without extra non-existent lines.
Use the improveMeshQuality command
In some cases where I have had bad mesh quality, I have improved it by running the improveMeshQuality command. It basically runs through some of the improvement algorithms that are executed during the actual meshing, but runs through them again. I have had some success with it, but havent used it extensively. Try your best to have a good mesh quality right from the get-go (duh).
Use checkMesh
This sounds obvious… but checkMesh works. It gives you important statistics on the quality of your mesh. In my experience, take
Use .eMesh files for additional control
For some shapes, you may need extra refinement based on edges instead of faces. In this case, you can use the edgeMeshRefinement sub-dict and use an eMesh or
Good Luck!
If you are struggling with CFD, are interested in getting started, or are looking for consulting services, visit http://www.stfsol.com for information on CFD consulting services including training, development, private webinars and other simulation services.
Categories
Uncategorized
Hi,
many thanks for this article which clarifies a lot the methodology.
Would you have any advice about how to control a regular distribution on the domain outer faces, ideally with some extrusion scale factor?
whether it is tetra or poly meshes ?
Regards
Olivier
Hello,
I followed your workflow using Salome 8.5, but when I try to mesh using the generated .fms file, i get the following error:
” Expected a ‘)’ or a ‘}’ while reading FixedList, found on line 9674 the label 2650
file: C:/kws_work/case/bodyPatches/sprayMesh.fms at line 9674. ”
Any idea about the origin of this problem???
Kazu
kinda, If you open the fms files you should find a list of nodes/points followed by a list of triangles. If you use vim, you can use % to navigate between the parenthesis. This warning happens when the list of triangles is larger than 3. For some reason when you export the files it includes extra nodes in the triangles list.
I will troubleshoot this at some point. but my “workaround” was to go back to salome 8.5 (I was using 9.4 when I got this error), re-do my mesh, and use the original python scripts (I think the ones that came with openfoam 1812).
If I have some time I will go through the newer python 3 scripts
You can get a newer version of the script here https://www.cfd-online.com/Forums/openfoam-community-contributions/198872-general-workflow-create-flawless-mesh-cfmesh.html#post728586
Thanks for sharing this well explained workflow! But I met a problem.. After following the steps I found the mesh after cfMesh didn’t follow the face mesh generated by salome. It seems the face mesh didn’t affect the mesh procedure. Do I need to specify anything besides ‘surfaceFile “filename.fms” ‘ in meshDict?
In Salome 9.3 the Python macros now require Python 3 so the script doesn’t work. You should use an older version of Salome, 8.5 was used for this post
Hi,
Thanks for the article! Very helpful. I have questions I am wondering if you can help me:
I am using Salome 9.3 and OpenFOAM-v1906+ (also tried OpenFOAM-v1812+). When I tried to run the python script to extract the feature edges, I got errors (syntax errors). OS I am using is Linux Mint 19.1. Do I need to update the python script?
Thanks!
Pei-Ying
You can find updated scripts are comments #19 and #25 of this thead:
https://www.cfd-online.com/Forums/openfoam-community-contributions/198872-general-workflow-create-flawless-mesh-cfmesh.html