Overset, inverseDistance and wall contact, possible fix
cellTypes isn't calculated correctly when walls are close or overlaps. This is a known issue. I'm proposing a fix below for inverseDistance.
Steps to reproduce
Run the attached testcase with inverseDistance. Any other tutorial is also fine just move overset meshes outside the domain.
I’m attaching a small test case with two zones. The second zone is object that slides along the wall of the background mesh. This case works with my proposed fixes to inverseDistance. It also works with cellVolumeWeight but one has to copy cellTypes from a fixed inverseDistanceStencil to the first time step.
What is the current bug behaviour?
What is the expected correct behavior?
Something like the attached animation =) proof.avi
Due to the coarseness of the mesh of the attached case a rather large part of where the walls intersect is cut out. I think this could be improved by a better selection of nDivs. Currently we select the number of divisions bases on sqrt(nCells) (2D). nCells is based on the entire mesh. A better choice would be sqrt(nCells) for each zone. Still this would not guarantee the same size of the voxels across processors. However for this type of case refining the mesh near the wall should be enough or manually setting nDivs.
OpenFOAM version : v1912 Operating system : any Hardware info : Intel Xeon Compiler : gcc
A first step to allowing wall contact is to make sure the cellCellStencils calculate cellTypes correctly. This is a proposed fix: inverseDistanceCellCellStencil.C
There are three changes needed to inverseDistance in order for it to work and two more which I find convenient when debugging. I’m attaching a version with all five fixes.
- In markDonors we exclude primary donors that are HOLE. It’s better to include them. See attached figure of “allStencil_hole”. The near wall cells are considered HOLE. This will create a gap for walkFront to spill out from. When walkFront “spills out” we kill the entire background mesh.
There are two checks in markDonors;
if (srcCelli != -1 && allCellTypes[srcCellMap[srcCelli]] != HOLE)That should be changed to
if (srcCelli != -1)
- In createStencil, HOLE cells are excluded. Meaning if the primary donor is a HOLE we don’t even try to find suitable donors among its neighbours. We have two options here that both work,
Try to find donors and keep them even if they are all holes. It seems like nonsense but it will work. This is what’s done in cellVolumeWeight. In order to accomplish this just keep isValidDonor true for all cells. I.e. skip the loop right after it’s created.
The other option is to set the amount of interpolation to zero, i.e. set cellInterpolationWeight to zero. For this to work, we still need to have isValidDonor true otherwise the cell will be removed by globalCellCells and set to HOLE. After createStencil we need to set the “amount of interpolation to zero”. This option is what is included in the attaced file.
In update(), right after allCellType_patch is written a check with cellTypes from the previous time step is performed. If cells have changed from HOLE to calculated they are set to interpolated. This check is no longer necessary for inverseDistance (but is what makes cellVolumeWeight work). In fact the check should be removed. The check can cause additional layers of interpolation cells which aren’t need nor wanted. This will happen for mesh courant numbers above one. To illustrate, imagine a cylinder which in one time step move say half its diameter. Half the cells where the cylinder was the prevous time step but isn’t now would be interpolated. Wolfdynamics has a nice illustration of this here: https://youtu.be/kVMA7_1YvH0?list=PLoI86R1JVvv_rDlODjff5LUWD4WX9G9vc&t=1218
The fourth change isn’t necessary but makes debugging easier. The stencil is written out as an wavefront file. I would prefer if one file is written per region.
I also find it use full to create a field with the size of the final stencil.
These patches just make inverseDistance behave with some sort of decency if walls between meshes are close. It’s not a guarantee that it will work. Mass won’t be preserved at all if there is a large change in volume. Change the movement to y direction instead in the test case. But I still think these patches should be included. There are many cases were only a moderate change in volume takes place when walls interact.
Secondly another solution is required for where walls intersect. The currently solution doesn’t crash and should be stable but an additional error will be introduced. For the cases I’ve tried this error is still smaller than the general mass preservation problem already present. I’ve been looking in to that with little success. At the moment I take note that overset in foam-extend is exact in terms of mass balance. For the same case (where no wall-to-wall interaction occurs) v1912 might have 5% error in mass while extend has an error in the order of the tolerance in the pressure equation. If there is interest I could file a different bug with my findings but I have no fix only indications to where the problem is.