Недавно я наткнулся на это моделирование гидродинамики и пытался прочитать метод решетчатого Больцмана, чтобы лучше понять его. Большая часть кода там довольно прозрачна, поэтому между чтением кода и чтением Википедии я в значительной степени понял, что все делает ... за исключением кинематических вычислений в базовой функции `` collide`.
Iудалось выяснить, что факторы 1/9, 4/9 и 1/36 связаны с длинами векторов, соединяющих центры клеток вдоль разных направлений решетки, и я даже могу найти ресурсы, которые объясняют, какие разные факторыиспользовать для различных типов решеток (с решеткой D2Q9, используемой в этом коде). Но я не смог найти ничего, что объясняло бы, как вы переходите от общего векторного уравнения, которое определяет шаг столкновения решеточного алгоритма Больцмана к конкретным девяти строкам арифметики реализации, показанным ниже. В частности, откуда взялись эти факторы 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]);
}
}
}