前言
使用OpenFOAM-v2006版本的重叠网格时,其挖洞只能挖出壁面以及壁面附近区域的网格,而离重叠区边缘(fringe)还有一定距离,如下图所示:
经研究,其和挖洞策略有关系,修改需要动源代码,十分费工夫。foam-extend-4.1版本有比较好的重叠网格功能,挖洞也很完善,能挖到边缘,是比较标准的,但extend比较大杂烩,也没有其他一些我需要的功能,所以只好作罢。我只好以extend版本为参考,修改2006版本的挖洞相关的代码来修正这一问题。这个过程需要深入地读取源码,特此记录。
OpenFOAM-v2006重叠网格原理简述
这里以overPimpleDyMFoam为例。我们知道,OpenFOAM是基于有限体积方法的,计算时每一个体元(cell)对应一组NS方程。通过simple或piso算法,对隐式的方程组进行迭代使其收敛。重叠网格的实现原理是在重叠的区域对体元的流场量乘上一个系数,使其传递两套甚至更多套网格之间的信息。具体可看overPimpleDyMFoam.C, pEqn.H, UEqn.H等文件。这一系数与重叠网格的插值格式有关,OpenFOAM的2006版本提供了四种插值格式:cellVolumeWeight,inverseDistance,leastSquares和trackingInverseDistance。不同插值格式可能有不一样的结果,这里不予深究,我用的是inverseDistance格式。
OpenFOAM将重叠网格的功能整合到动网格的一个库里(dynamicOversetFvMesh),通过类进行信息和指令的传递,所以其他的计算步骤等都相对比较独立。当需要网格运动时,mesh.update()就会被激活,这个函数在大类里是虚函数,只有到实际用上它的类那里才会被具体定义。找到文件inverseDistanceCellCellStencil.C,在最后有update()的定义:
这一函数有600多行,囊括了重叠网格的所有步骤,总的来说就是挖洞以及网格装配。挖洞就是前言所说,把不需要进行计算的网格进行识别,并在计算时不予考虑。一般来说,两层网格之间的重叠区域不宜太大,仅在边缘有两到三层即可,因为这样才能体现出重叠网格相比于浸入边界的优势:运动网格,满足大变形运动,并且在近壁面也能保持比较好的网格质量(y+,模拟湍流)。不知为何OpenFOAM连最基本的这一功能都无法保证!只好自己改代码了。网格装配就是在挖洞之后,把需要进行信息传递的网格之间用一定的格式连接起来。这里有两个角色:donor贡献者和acceptor接受者,通过一定的插值格式来完成信息的传递。网格如何装配会影响最后的精度以及计算效果,但不是本次主要的研究对象,不细说了。
在第1932行找到Mark holes的步骤段。前面两百多行似乎是一些准备工作,如定义一些临时的数组,定义搜索范围等。我们看到这一段,里面有markPatchesAsHoles的函数,字面意思就是把patch标记为hole,就是挖洞对应的函数。
这一函数在第314行开始,在333行开始,进行挖洞的步骤,可以看到有allCellTypes[celli]=HOLE的指令,在这一行的上方有一个if判据,里面是overlaps的函数。从这不难看出,overlaps将是决定改体元在此刻会不会被当成洞来挖掉的函数,也就是本次研究的主要目标。
下图是overlaps的代码段,可以看到,当vals[i1]==patchCellType::PATCH为真时,返回true,回到markPatchesAsHole上就会把当前的体元标记成hole。
为了深入理解这一判据的含义,以便进行修改完善,这里提出三个问题:
1. PATCH指的是哪一类patch?
2. vals是什么?
3. il是什么?它遍历的对象是什么?
接下来的博文,会逐步理解这些问题。