さらに説明するコードを次に示します。
insideBoundは配列です (1 - 境界、0 - 空、流体は通過できます)
#define FOR_EACH_CELL for ( i=1 ; i<=N ; i++ ) { for ( j=1 ; j<=N ; j++ ) {
void set_bnd ( int N, int b, float * x, int * insideBound )
{
int i, j;
float sum;
int count;
for ( i=1 ; i<=N ; i++ ) {
x[IX(0 ,i)] = b==1 ? -x[IX(1,i)] : x[IX(1,i)];
x[IX(N+1,i)] = b==1 ? -x[IX(N,i)] : x[IX(N,i)];
x[IX(i,0 )] = b==2 ? -x[IX(i,1)] : x[IX(i,1)];
x[IX(i,N+1)] = b==2 ? -x[IX(i,N)] : x[IX(i,N)];
}
x[IX(0 ,0 )] = 0.5f*(x[IX(1,0 )]+x[IX(0 ,1)]);
x[IX(0 ,N+1)] = 0.5f*(x[IX(1,N+1)]+x[IX(0 ,N)]);
x[IX(N+1,0 )] = 0.5f*(x[IX(N,0 )]+x[IX(N+1,1)]);
x[IX(N+1,N+1)] = 0.5f*(x[IX(N,N+1)]+x[IX(N+1,N)]);
if (!b) return;
FOR_EACH_CELL
sum = 0.0f;
count = 0;
if (insideBound[IX(i,j)] == 1)
{
if (insideBound[IX(i-1,j)] != 1)
{
count++;
sum = sum + x[IX(i-1,j)];
}
if (insideBound[IX(i+1,j)] != 1)
{
count++;
sum = sum + x[IX(i+1,j)];
}
if (insideBound[IX(i,j-1)] != 1)
{
count++;
sum = sum + x[IX(i, j-1)];
}
if (insideBound[IX(i,j+1)] != 1)
{
count++;
sum = sum + x[IX(i, j+1)];
}
if (count > 0)
{
x[IX(i,j)] = -sum / count;
} else {
x[IX(i,j)] = 0;
}
}
END_FOR
}
ブックごと (作業中):
最初のループでは、上、右、下、左の境界セルが設定されます。それらには、バインドされていない隣接セルが1つしかないため、セルはその値を取得します。(なぜUが反対でVが同じ値なのかわかりません)
最初のループの後、角の境界値が設定されます。ここでは、隣接するセルから平均値を取得します(境界ではない隣接セルがないため、境界セルを使用していると思います)。
私の場合、正しく機能していません:
if (!b) return - 密度の計算を無視し、速度のみを更新します。
ループは、すべての境界セルの値を計算します (ここでも、境界自体ではない隣接セルからの平均値)。この方法でほぼ現実的な結果が得られますが、密度が大きく失われ、流体が完全に消えてしまう境界が大きすぎるというバグがいくつかあります。