在markPatchesAsHole函数之后是markDonors函数。可以先看到解析文档的介绍:
翻译一遍就是:这是一个用来确定所有目标体元的贡献单元的函数。寻址通过waveMethod计算得到。变量tgtToScrAddr由目标子网格和源子网格创建。创建了覆盖所有目标单元的循环映射。变量srcCelli等于带有与目标单元相关的索引的寻址。如果这个变量不等于-1,且它的类型也不是HOLE,那么就会找到贡献单元。然后检查是否有更好的贡献单元,最后确定。
markDonors调用和定义参数分别如下左右图:
最后输出的,应该是allStencil和allDonorID,此变量labelList allDonorID(mesh_.nCells(), -1);大小为网格量大小,初始化为-1。处理网格与网格之间对应关系的寻址用到waveMethod,输出tgtToSrcAddr存储了Src和Tgt之间的对应关系。
waveMethod::calculate(tgtMesh, srcMesh, tgtToSrcAddr);
这一函数分了两种情况进行考虑:
// 1. do processor-local src/tgt overlap
// 2. Send over tgtMesh bits that overlap src and do calculation on srcMesh.
第一个是处理单个处理器内部的不同zone下的重叠情况。第二个是处理各处理器之间(并行)的不同zone下的重叠情况。第二部分因为涉及到并行的算法,所以会比较复杂。下面是单个处理器下的处理方法。
可以看到最后有一个if下判据是betterDonor(),这个bool类型函数判断当下的srcI是否作为donor更好?如果是的话,那么allDonor就会用这个zone的体元来担当贡献单元。反之则是由其他更好的zone来做。注意到allDonor[celli]中的celli是来自tgt的体元,也就是说,目标层的体元的贡献单元可能会来自不同的zone(srcI),这个由betterDonor来判断。这样,allDonor这一个labelList(下标列表)就记录了各体元的贡献单元所在的zone。因而markDonors并非只是记录个体元的贡献单元,而是这些贡献单元所在的zone,因为在多层网格重叠的情况下,系统必须判断要用哪一层的单元来作贡献插值。
各体元的贡献单元记录在allStencil里:
label globalDonor = globalCells.toGlobal(srcCellMap[srcCelli]);
allStencil[celli].setSize(1);
allStencil[celli][0] = globalDonor;
可以看到,allStencil每次只存一个单元的映射。那么重叠网格多个donors又是如何实现的呢?需要继续看update()后面的代码。
暂无评论内容