void ApplyPreconditioner(Array2Df x, Array2Df y, Array2Df m) { //Maybe Incomplete Cholesky?? int i, j; float d; m.Reset(); // solve L*m=x for (j = 1; j < x.ny - 1; ++j) { for (i = 1; i < x.nx - 1; ++i) { if (marker[i, j] == FLUID) { d = x[i, j] - poisson[i - 1, j, 1] * preconditioner[i - 1, j] * m[i - 1, j] - poisson[i, j - 1, 2] * preconditioner[i, j - 1] * m[i, j - 1]; m[i, j] = preconditioner[i, j] * d; } } } // solve L'*y=m y.Reset(); for (j = x.ny - 2; j > 0; --j) { for (i = x.nx - 2; i > 0; --i) { if (marker[i, j] == FLUID) { d = m[i, j] - poisson[i, j, 1] * preconditioner[i, j] * y[i + 1, j] - poisson[i, j, 2] * preconditioner[i, j] * y[i, j + 1]; y[i, j] = preconditioner[i, j] * d; } } } }
public PICParticles(PICGrid grid, PICMain.SimType type) { this.grid = grid; this.type = type; np = 0; sum = new Array2Df(grid.pressure.nx + 1, grid.pressure.ny + 1); }
public PICGrid(float gravity, int nx, int ny, float domainSize) { this.gravity = gravity; domainx = domainSize; domainy = ny * domainx / nx; h = domainx / nx; invH = 1 / h; u = new Array2Df(nx + 1, ny); v = new Array2Df(nx, ny + 1); pressure = new Array2Df(nx, ny); marker = new Array2Di(nx, ny); phi = new Array2Df(nx, ny); du = new Array2Df(nx, ny); dv = new Array2Df(nx, ny); poisson = new Array2Dx3f(nx, ny); preconditioner = new Array2Df(nx, ny); m = new Array2Df(nx, ny); r = new Array2Df(nx, ny); z = new Array2Df(nx, ny); s = new Array2Df(nx, ny); rhsB = new Array2Df(nx, ny); }
public void SolveDistance(float p, float q, ref float r) { float d = Mathf.Min(p, q) + 1; if (d > Mathf.Max(p, q)) { d = (p + q + Mathf.Sqrt(2 - sqr(p - q))) / 2; } if (d < r) { r = d; } }
float GetPressureCoeff(Array2Df press, Array2Di marker, int u, int v) { u = Mathf.Max(0, u); v = Mathf.Max(0, v); u = Mathf.Min(this.pressure.nx - 1, u); v = Mathf.Min(this.pressure.ny - 1, v); if (marker[u, v] == SOLID) { return(1); } else { return(0); } }
float GetNeighborPressureCoeff(Array2Df press, Array2Di marker, int u, int v) { u = Mathf.Max(0, u); v = Mathf.Max(0, v); u = Mathf.Min(this.pressure.nx - 1, u); v = Mathf.Min(this.pressure.ny - 1, v); if (marker[u, v] == FLUID) { return(-press[u, v]); } else { return(0); } }
public void ApplyPoisson(Array2Df x, Array2Df y) { y.Reset(); for (int j = 1; j < poisson.ny - 1; ++j) { for (int i = 1; i < poisson.nx - 1; ++i) { if (marker[i, j] == FLUID) { y[i, j] = poisson[i, j, 0] * x[i, j] + poisson[i - 1, j, 1] * x[i - 1, j] + poisson[i, j, 1] * x[i + 1, j] + poisson[i, j - 1, 2] * x[i, j - 1] + poisson[i, j, 2] * x[i, j + 1]; } } } }
void accumulate(Array2Df accum, float q, int i, int j, float fx, float fy) { float weight; weight = (1 - fx) * (1 - fy); accum[i, j] += weight * q; sum[i, j] += weight; weight = fx * (1 - fy); accum[i + 1, j] += weight * q; sum[i + 1, j] += weight; weight = (1 - fx) * fy; accum[i, j + 1] += weight * q; sum[i, j + 1] += weight; weight = fx * fy; accum[i + 1, j + 1] += weight * q; sum[i + 1, j + 1] += weight; }
/* call this function to incorporate c[] when transfering particles to grid */ /* This function should take the c_pa^n values from c, and update them, with proper weighting, */ /* into the correct grid velocity values in accum */ void affineFix(Array2Df accum, Vector2 c, int i, int j, float fx, float fy) { var w00 = (1 - fx) * (1 - fy); var w10 = fx * (1 - fy); var w01 = (1 - fx) * fy; var w11 = fx * fy; var d00 = new Vector2(-fx, -fy); var d10 = new Vector2(1 - fx, -fy); var d01 = new Vector2(-fx, 1 - fy); var d11 = new Vector2(1 - fx, 1 - fy); accum[i, j] += Vector2.Dot(c, d00) * w00; accum[i + 1, j] += Vector2.Dot(c, d10) * w10; accum[i, j + 1] += Vector2.Dot(c, d01) * w01; accum[i + 1, j + 1] += Vector2.Dot(c, d11) * w11; }
/* this function computes c from the gradient of w and the velocity field from the grid. */ Vector2 computeC(Array2Df ufield, int i, int j, float fx, float fy) { var f00 = ufield[i, j]; var f10 = ufield[i + 1, j]; var f01 = ufield[i, j + 1]; var f11 = ufield[i + 1, j + 1]; var w00 = new Vector2((1 - fx), (1 - fy)); var w10 = new Vector2(fx, (1 - fy)); var w01 = new Vector2((1 - fx), fy); var w11 = new Vector2(fx, fy); var gw00 = new Vector2(-(1 - fy), -(1 - fx)); var gw10 = new Vector2(1 - fy, -fx); var gw01 = new Vector2(-fy, 1 - fx); var gw11 = new Vector2(fy, fx); return(gw00 * f00 + gw10 * f10 + gw01 * f01 + gw11 * f11); }