private static void SetBoundary(uint N, BoundaryCollisionType b, float[] x) { for (uint i = 1; i <= N; i++) { x[GetIndex(N, 0, i)] = b == BoundaryCollisionType.XDirection ? -x[GetIndex(N, 1, i)] : x[GetIndex(N, 1, i)]; x[GetIndex(N, N + 1, i)] = b == BoundaryCollisionType.XDirection ? -x[GetIndex(N, N, i)] : x[GetIndex(N, N, i)]; x[GetIndex(N, i, 0)] = b == BoundaryCollisionType.YDirection ? -x[GetIndex(N, i, 1)] : x[GetIndex(N, i, 1)]; x[GetIndex(N, i, N + 1)] = b == BoundaryCollisionType.YDirection ? -x[GetIndex(N, i, N)] : x[GetIndex(N, i, N)]; } x[GetIndex(N, 0, 0)] = 0.5f * (x[GetIndex(N, 1, 0)] + x[GetIndex(N, 0, 1)]); x[GetIndex(N, 0, N + 1)] = 0.5f * (x[GetIndex(N, 1, N + 1)] + x[GetIndex(N, 0, N)]); x[GetIndex(N, N + 1, 0)] = 0.5f * (x[GetIndex(N, N, 0)] + x[GetIndex(N, N + 1, 1)]); x[GetIndex(N, N + 1, N + 1)] = 0.5f * (x[GetIndex(N, N, N + 1)] + x[GetIndex(N, N + 1, N)]); }
private static void Advect(uint N, float dt, float[] dest, float[] destPre, float[] u, float[] v, BoundaryCollisionType b) { float a = dt * N; for (uint i = 1; i <= N; ++i) { for (uint j = 1; j <= N; ++j) { uint centerIndex = GetIndex(N, i, j); float x = i - a * u[centerIndex]; float y = j - a * v[centerIndex]; if (x < 0.5f) { x = 0.5f; } if (x > N + 0.5f) { x = N + 0.5f; } uint i0 = (uint)x; uint i1 = i0 + 1; if (y < 0.5f) { y = 0.5f; } if (y > N + 0.5f) { y = N + 0.5f; } uint j0 = (uint)y; uint j1 = j0 + 1; float s1 = x - i0; float s0 = 1 - s1; float t1 = y - j0; float t0 = 1 - t1; dest[centerIndex] = s0 * ( t0 * destPre[GetIndex(N, i0, j0)] + t1 * destPre[GetIndex(N, i0, j1)] ) + s1 * ( t0 * destPre[GetIndex(N, i1, j0)] + t1 * destPre[GetIndex(N, i1, j1)] ); } } SetBoundary(N, b, dest); }
private static void Diffuse(uint N, float[] cur, float[] pre, float dt, float diffusionVelocity, BoundaryCollisionType b) { float a = diffusionVelocity * dt * N * N; for (uint k = 0; k < 20; ++k) { for (uint i = 1; i <= N; ++i) { for (uint j = 1; j <= N; ++j) { uint centerIndex = GetIndex(N, i, j); cur[centerIndex] = ( pre[centerIndex] + a * ( cur[GetIndex(N, i + 1, j)] + cur[GetIndex(N, i, j + 1)] + cur[GetIndex(N, i - 1, j)] + cur[GetIndex(N, i, j - 1)] ) ) / (1 + 4 * a); } } SetBoundary(N, b, cur); } }