Exemplo n.º 1
0
 public FluidSimulationFrame(IntSize3 leveSetSizeStokesSize, int numParticles, IntSize3 navierStokesSize, float navierStokesCellSize)
 {
     LeveSetSizeStokesSize = leveSetSizeStokesSize;
     Particles             = new Vector3[numParticles];
     Phi              = new double[leveSetSizeStokesSize.Volume()];
     ParticleMask     = new bool[leveSetSizeStokesSize.Volume()];
     NavierStokesGrid = new NavierStokesGrid(navierStokesSize, navierStokesCellSize);
 }
Exemplo n.º 2
0
        public LevelSet(IntSize3 size, float cellSize, INavierStokesGrid grid)
        {
            Size         = size;
            CellSize     = cellSize;
            phi          = new double[size.Volume()];
            backPhi      = new double[size.Volume()];
            mass         = new float[size.Volume()];
            backMass     = new float[size.Volume()];
            states       = new NavierStokesCellState[size.Volume()];
            particleMass = new float[size.Volume()];
            particleMask = new bool[size.Volume()];

            for (int j = 0; j < Size.Height - 1; j++)
            {
                for (int i = 0; i < Size.Width - 1; i++)
                {
                    var point = new Vector3(i, j, 0) * CellSize;
                    State(i, j) = grid.StateAtPoint(point);
                }
            }
        }
Exemplo n.º 3
0
        public void TransferPhi(float deltaT, INavierStokesGrid grid)
        {
            /*
             * Parallel.For(0, Size.Volume(), index =>
             * {
             *  var j = index / Size.Width;
             *  var i = index - j * Size.Width;
             *
             *  if (i < 1 || i >= Size.Width - 1 || j < 1 || j >= Size.Height - 1)
             *      return;
             *
             *  var dpdx = (Phi(i + 1, j) - Phi(i - 1, j)) / (2 * CellSize);
             *  var dpdy = (Phi(i, j + 1) - Phi(i, j - 1)) / (2 * CellSize);
             *  var point = CellSize * (new Vector3(i, j, 0) + new Vector3(0.5f, 0.5f, 0.5f));
             *  var u = grid.GetVelocityAt(point) * deltaT;
             *  var deltaPhi = -u.X * dpdx - u.Y * dpdy;
             *  BackPhi(i, j) = Phi(i, j) + deltaPhi;
             * });*/

            /*
             * for (int j = 1; j < Size.Height - 1; j++)
             * for (int i = 1; i < Size.Width - 1; i++)
             * {
             *  var dpdx = (Phi(i + 1, j) - Phi(i - 1, j)) / (2 * CellSize);
             *  var dpdy = (Phi(i, j + 1) - Phi(i, j - 1)) / (2 * CellSize);
             *  var point = CellSize * (new Vector3(i, j, 0) + new Vector3(0.5f, 0.5f, 0.5f));
             *  var u = grid.GetVelocityAt(point) * deltaT;
             *  var deltaPhi = -u.X * dpdx - u.Y * dpdy;
             *  BackPhi(i, j) = Phi(i, j) + deltaPhi;
             * }*/


            Array.Clear(backPhi, 0, backPhi.Length);
            var halfVector   = new Vector3(0.5f, 0.5f, 0.5f);
            var cornerOffset = CellSize * halfVector;

            Parallel.For(0, Size.Volume(), index =>
            {
                var j = index / Size.Width;
                var i = index - j * Size.Width;

                if (i < 1 || i >= Size.Width - 1 || j < 1 || j >= Size.Height - 1)
                {
                    return;
                }

                var remainingDeltaT = deltaT;
                var point           = CellSize * (new Vector3(i, j, 0) + halfVector);

                while (remainingDeltaT > 0)
                {
                    var v                   = grid.GetVelocityAt(point);
                    var vlen                = v.Length();
                    var localDeltaT         = vlen * remainingDeltaT > CellSize ? CellSize / vlen : remainingDeltaT;
                    var potentialPoint      = point + v * localDeltaT;
                    var potentialCorner     = potentialPoint - cornerOffset;
                    var normPotentialCorner = potentialCorner / CellSize;
                    var npci                = (int)normPotentialCorner.X;
                    var npcj                = (int)normPotentialCorner.Y;
                    if (State(npci, npcj) == NavierStokesCellState.Object)
                    {
                        break;
                    }
                    point            = potentialPoint;
                    remainingDeltaT -= localDeltaT;
                }

                var corner = point - cornerOffset;
                //var centerPoint = new Vector3(Size.Width, Size.Height, 0) * CellSize / 2;
                //while (grid.StateAtPoint(corner) == NavierStokesCellState.Object)
                //{
                //    corner = Vector3.Lerp(corner, centerPoint, 0.05f);
                //}

                var ti        = (int)(corner.X / CellSize);
                var tj        = (int)(corner.Y / CellSize);
                var intCorner = new Vector3(ti, tj, 0) * CellSize;

                var rightVolume = (corner.X - intCorner.X) / CellSize;
                var upVolume    = (corner.Y - intCorner.Y) / CellSize;
                var leftVolume  = 1 - rightVolume;
                var downVolume  = 1 - upVolume;

                var originalMass = Phi(i, j);
                var a00          = originalMass * leftVolume * downVolume;
                var a01          = originalMass * leftVolume * upVolume;
                var a10          = originalMass * rightVolume * downVolume;
                var a11          = originalMass * rightVolume * upVolume;

                lock (backWriteLock)
                {
                    BackPhi(ti, tj)         += a00;
                    BackPhi(ti + 1, tj)     += a10;
                    BackPhi(ti, tj + 1)     += a01;
                    BackPhi(ti + 1, tj + 1) += a11;
                }
            });

            CodingHelper.Swap(ref phi, ref backPhi);
        }