我最近遇到this fluid dynamics simulation,并一直在尝试阅读格子Boltzmann方法,以便更好地理解它。大部分代码都很透明,因此在阅读代码和阅读Wikipedia之间,我几乎已经知道了所有功能...除了核心``碰撞''函数中的运动学计算之外。
我已经弄清楚1 / 9、4 / 9和1/36的因子与沿着不同晶格方向连接细胞中心的向量的长度有关,我什至可以找到解释用于不同晶格类型的哪些不同因素(此代码中使用D2Q9晶格)。但是,我找不到任何能解释您如何从定义Lattice Boltzmann Algorithm的碰撞步骤的通用矢量方程到下面显示的特定9行实现算法的方法。特别是那些3、1.5和4.5的因子是哪里来的?
在链接的网页中使用的代码(进行少量编辑以删除自由变量并提高可读性)如下:
function collide(viscosity) { // kinematic viscosity coefficient in natural units
var omega = 1 / (3*viscosity + 0.5); // reciprocal of relaxation time
for (var y=1; y<ydim-1; y++) {
for (var x=1; x<xdim-1; x++) {
var i = x + y*xdim; // array index for this lattice site
var thisrho = n0[i]+nN[i]+nS[i]+nE[i]+nW[i]+nNW[i]+nNE[i]+nSW[i]+nSE[i];
// macroscopic horizontal velocity
var thisux = (nE[i]+nNE[i]+nSE[i]-nW[i]-nNW[i]-nSW[i])/thisrho;
// macroscopic vertical velocity
var thisuy = (nN[i]+nNE[i]+nNW[i]-nS[i]-nSE[i]-nSW[i])/thisrho;
var one9thrho = thisrho / 9;
var one36thrho = thisrho / 36;
var ux3 = 3 * thisux;
var uy3 = 3 * thisuy;
var ux2 = thisux * thisux;
var uy2 = thisuy * thisuy;
var uxuy2 = 2 * thisux * thisuy;
var u2 = ux2 + uy2;
var u215 = 1.5 * u2;
n0[i] += omega * (4/9*thisrho * (1 - u215) - n0[i]);
nE[i] += omega * ( one9thrho * (1 + ux3 + 4.5*ux2 - u215) - nE[i]);
nW[i] += omega * ( one9thrho * (1 - ux3 + 4.5*ux2 - u215) - nW[i]);
nN[i] += omega * ( one9thrho * (1 + uy3 + 4.5*uy2 - u215) - nN[i]);
nS[i] += omega * ( one9thrho * (1 - uy3 + 4.5*uy2 - u215) - nS[i]);
nNE[i] += omega * ( one36thrho * (1 + ux3 + uy3 + 4.5*(u2+uxuy2) - u215) - nNE[i]);
nSE[i] += omega * ( one36thrho * (1 + ux3 - uy3 + 4.5*(u2-uxuy2) - u215) - nSE[i]);
nNW[i] += omega * ( one36thrho * (1 - ux3 + uy3 + 4.5*(u2-uxuy2) - u215) - nNW[i]);
nSW[i] += omega * ( one36thrho * (1 - ux3 - uy3 + 4.5*(u2+uxuy2) - u215) - nSW[i]);
}
}
}
答案 0 :(得分:2)
var omega = 1 / (3*viscosity + 0.5);
for (var y=1; y<ydim-1; y++) {
for (var x=1; x<xdim-1; x++) {`
var i = x + y*xdim;
var thisrho = n0[i]+nN[i]+nS[i]+nE[i]+nW[i]+nNW[i]+nNE[i]+nSW[i]+nSE[i];
var thisux = (nE[i]+nNE[i]+nSE[i]-nW[i]-nNW[i]-nSW[i])/thisrho;
var thisuy = (nN[i]+nNE[i]+nNW[i]-nS[i]-nSE[i]-nSW[i])/thisrho;
var one9thrho = thisrho / 9;
var one36thrho = thisrho / 36;
var ux3 = 3 * thisux;
var uy3 = 3 * thisuy;
var ux2 = thisux * thisux;
var uy2 = thisuy * thisuy;
var uxuy2 = 2 * thisux * thisuy;
var u2 = ux2 + uy2;
var u215 = 1.5 * u2;
最后一步处理冲突 f_ \ alpha ^ t(其中t表示临时内容,因为它将随后进行流传输)= f_ \ alpha + \ omega *(f_ \ alpha ^ {eq}-f_ \ alpha)。每条线负责一个离散方向\ alpha,因此向量方程式只需输入一次。注意:
在这种情况下,f_ \ alpha ^ t再次存储在f_ \ alpha中,因此足以将 increment (+ =)f_ \ alpha(数组nNWSE)增加\ omega *(f_ \ alpha ^ {eq}-f_ \ alpha)。方括号中的第一项是均衡函数,而最后一项对应于当前的f_ \ alpha。
不可压缩的平衡函数由f_ \ alpha ^ {eq} = w_ \ alpha \ rho(1 + e_ {i \ alpha} u_i / c_s ^ 2 +(e_i \ alpha u_i)^ 2 /给出(2 c_s ^ 4)-u_i ^ 2 /(2 c_s ^ 2)),其中我们必须对包含索引i的所有项求和两次。声音c_s的晶格速度由1 / \ sqrt(3)* dx / dx给出,因此f_ \ alpha ^ {eq} = w_ \ alpha \ rho(1 + 3 e_ {i \ alpha} u_i + 4.5(e_i \ alpha u_i)^ 2-1.5 u_i ^ 2)。术语one9thrho和one36thrho对应于方括号之前的术语。 ux3和uy3的总和对应于括号3 e_ {i \ alpha}中的第二项。倒数第二个项4.5(e_i \ alpha u_i)^ 2对应于水平或垂直方向的4.5 u_x ^ 2或4.5 u_y ^ 2,并且对应于对角线方向的4.5(+ -u_x +-uy)^ 2作为两个分量存在,因此导致4.5(u_x ^ 2 + u_y ^ 2 +-u_x u_y)。当相减时,u215 = 1.5 * u2 = 1.5 *(ux + uy)对应于最后一项。您将必须考虑方向i上晶格速度\ vec e_ \ alpha的相应速度投影e_ {i \ alpha}是0还是+ -1。后迹象负责
n0[i] += omega * (4/9*thisrho * (1 - u215) - n0[i]);
nE[i] += omega * ( one9thrho * (1 + ux3 + 4.5*ux2 - u215) - nE[i]);
nW[i] += omega * ( one9thrho * (1 - ux3 + 4.5*ux2 - u215) - nW[i]);
nN[i] += omega * ( one9thrho * (1 + uy3 + 4.5*uy2 - u215) - nN[i]);
nS[i] += omega * ( one9thrho * (1 - uy3 + 4.5*uy2 - u215) - nS[i]);
nNE[i] += omega * ( one36thrho * (1 + ux3 + uy3 + 4.5*(u2+uxuy2) - u215) - nNE[i]);
nSE[i] += omega * ( one36thrho * (1 + ux3 - uy3 + 4.5*(u2-uxuy2) - u215) - nSE[i]);
nNW[i] += omega * ( one36thrho * (1 - ux3 + uy3 + 4.5*(u2-uxuy2) - u215) - nNW[i]);
nSW[i] += omega * ( one36thrho * (1 - ux3 - uy3 + 4.5*(u2+uxuy2) - u215) - nSW[i]);
像这样的代码不太可能非常有效。为了加快代码的速度,您应该对f_ \ alpha和f_ \ alpha ^ t使用两个数组,并一步一步地执行碰撞和流传输,而不是两步。另外,可以通过组合omega和oneXXthrho进一步重写平衡函数,以重新计算尽可能少的项,并进一步重写二次项。有关更好的书面代码,请参考code that accompanies "The Lattice Boltzmann Method: Principles and Practice"。这应该已经将性能至少提高了两倍。为了在您的机器上模拟3D,您将必须应用多个more difficult optimisations。此外,还有针对该主题的更好的论坛,例如Palabos(日内瓦大学)和OpenLB(卡尔斯鲁厄技术学院)。