编程细节
在每次IBM迭代过程中,force spreading后得到流体上的力,该力在这层迭代中,会被用到流体速度的更新。
这里我们可以先提取出速度的三个分量,按公式上所述更新该速度,此刻我们仅仅是得到速度数值。
接下来根据旧的速度和新的速度分别计算其平衡分布Feq,以D3Q19为例我们得到两份19个平衡分布。
最后是访问该格点的分布函数,该分布函数减去旧速度的Feq,然后加上新速度的Feq,即可实现速度的更新。(源码modifyJ的思路)
我试着跑了一下,结果看起来挺正常。
关于Palabos源码
Palabos源码中实现的Multi-direct forcing scheme IBM,从RBC那篇论文来看,应该是Shan & Chen approach来处理力的更新。
nextJ += tau*W*deltaG[iParticle];
不过Palabos并不是以我所叙述的方式来实现Multi-direct forcing scheme的,在Palabos的算例中,无论是RBC那个还是movingWall,都是额外定义了rhoBar和j来代入到计算中。
RBC源码为例,很明显是以latticeID_act4, rhoBarID_act4, jID_act4的形式,代入到ExternalRhoJcollideAndStream3D中,最后通过addInternalProcessors集成起来。
// 4. Collision and streaming.
plb::global::logfile("progress.log").flushEntry("Creating Actions 4 : Collide and Stream");
Actions3D actions4;
plint latticeID_act4 = actions4.addBlock(group.get("lattice"));
plint rhoBarID_act4 = actions4.addBlock(group.get("rhoBar"));
plint jID_act4 = actions4.addBlock(group.get("j"));
actions4.addProcessor(new ExternalRhoJcollideAndStream3D<T, DESCRIPTOR>(),
latticeID_act4, rhoBarID_act4, jID_act4, group.getBoundingBox());
plint level = 0;
actions4.addInternalProcessors(latticeID_act4, level); // Add the boundary conditions that were added to the lattices.
actions4.addCommunication(latticeID_act4, modif::staticVariables);
而movingWall是以rhoBarJarg的形式来储存rhoBar和j来实现IBM中的interpolation和spreading。
2020 Palabos Summer School的ppt
在ppt里,给出的公式如下
RBC那篇论文
RBC那篇论文公式如下
Note
公式和源码不对应的地方,不知道是不是我找错地方了,也可能是目前公开的Palabos内部仍然还是原先的Shan & Chen approach。