The behaviour of airflow around an object is extremely complex. Phenomena such as turbulence, flow separation and eddy currents can be present and significantly affect aerodynamic performance. To accurately model the intricacies of this flow, CFD simulations need to run with finer meshes in these areas of interest.
In CFD, the volume around an object is divided into miniature 3D blocks called cells. Similar to pixels in a digital photograph, the smaller the cells, the more detail you can capture. However, a higher number of cells requires more processing power. Therefore, to balance this demand for detail with efficient run times, aerodynamicists refine the mesh in areas of complex flow behaviour, using a low resolution for the rest of the mesh.
Adaptive mesh refinement
However, it is impossible for even the most experienced aerodynamicists to accurately predict where the flow will be the most complicated, after all that’s why they’re using CFD. To help solve this problem, adaptive mesh refinement was invented.
This technique runs an initial simulation with a coarse mesh, determines where higher resolutions are required and then automatically refines the mesh in these areas. This process is repeated until the desired accuracy and run time are satisfied. It is also used to refine/unrefine a mesh dynamically during transient simulations, as in this Karman vortex street simulation.
At the core of AirShaper is an open source CFD software called OpenFOAM. It utilises adaptive mesh refinement but only refines the cells in the volume around an object and not on the object’s surface itself. AirShaper can work with any given 3D model, even if the geometry is not completely watertight, so having the capability to use adaptive mesh refinement for such a wide variety of 3D shapes is essential. Not being able to refine the surface detail of the model could lead to unrepresentative results.
To ensure that adaptive mesh refinement could be used for both the volume around an object and for the object’s surface in AirShaper, we developed our own code. Using the default mesher snappyHexMesh in OpenFOAM, we’re excited to announce that we have now made this part of the code open source.
Open source repository
The AirShaper adaptive mesh refinement repository works in a series of steps, as highlighted in the diagram below.
The process for a regular snappyHexMesh is as follows:
The blockMesh is refined based on edge, surface and region refinement settings. These are manual refinement settings, which are different from adaptive mesh refinement. Also, any mesh inside an object is removed.
Snapping phase: Here, the cut cells are snapped to the surface of the object.
For our adaptive mesh refinement solution, we wanted to keep the castellated mesh and store it separately before it is cut out and snapped. Therefore, the castellated phase and snapping phase are executed separately, with the following modifications:
To avoid the inner mesh being cut away, the patches are set to baffle type. This will leave the entire castellated mesh intact. A copy of this mesh is then stored in the “primal refinement” folder.
Snapping phase This picks up the castellated mesh generated in the first step, cuts out the inside cells, and then snaps them to the object, just like it would normally.
This “original mesh” is now ready for a CFD simulation with the results stored in the “primal run” folder.
To adaptively refine the mesh based on the flow field, the results from the first CFD simulation are mapped onto the castellated mesh that was stored in the “primal refinement” folder. Then, a refinement parameter called “refVal” is calculated (the repository provides methods for both gradient of pressure and vorticity) using those fields and the castellated mesh. It’s important to do this on the castellated mesh, as refinement in snappyHexMesh cannot be done on a snapped mesh.
Once the refVal field has been created, the castellated mesh is refined by running pimpleFoam, which uses the refVal field. The user can play with the threshold values of refVal to select more or less cells for refinement in the dynamicMeshDict file.
Once this castellated mesh has been refined, it is sent back to the “primal run” folder. There, the snapping phase is executed again, but now starting from this refined mesh. In this way, all the cells on the surface will be refined and snapped to the object. Once this snapping phase is complete, a second CFD run is then executed with the newly refined mesh.
What experts say
We’ve had the honour of receiving feedback from a number of leading OpenFOAM experts. Here’s what they had to say about the repository:
Jozsef Nagy (Fouder of eulerion-solutions / OpenFOAM YouTube Channel / OpenFOAM Wiki): "This is a great addition to the community contributions of OpenFOAM. Mesh refinement is an important topic in order to intelligently find the balance between grid resolution and simulation runtime. Try it out!"
Jozsef even created a dedicated AirShaper wiki page for this repository
Joel Guerrero (Co-founder of Wolf Dynamics):
Bruno Santos (Co-founder of FS Dynamics):
Robin Knowles (Founder of CFD Engine): "This is exactly the kind of thing that makes me smile about OpenFOAM - taking the standard "building blocks" & doing something really clever with them. The repo's not just useful for those looking to do this kind of refinement, but it's also a practical demonstration of "OpenFOAM thinking" & problem solving. Well worth digging into 🙏"
We’ve created an open-source repository to provide the OpenFOAM community with access to a part of our adaptive mesh refinement code. We are excited to be part of this open-source community and look forward to future contributions from the OpenFoam community.
Interesting links:Github repository