Ejemplo n.º 1
0
        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;
                    }
                }
            }
        }
Ejemplo n.º 2
0
 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);
 }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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;
            }
        }
Ejemplo n.º 5
0
        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);
            }
        }
Ejemplo n.º 6
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);
            }
        }
Ejemplo n.º 7
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];
             }
         }
     }
 }
Ejemplo n.º 8
0
        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;
        }
Ejemplo n.º 9
0
        /* 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;
        }
Ejemplo n.º 10
0
        /* 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);
        }