Exemple #1
0
        protected void DrawPhi()
        {
            if (this.phi == null)
            {
                return;
            }

            var norm = FluidHelper.Infnorm(this.phi);
            var old  = Gizmos.color;

            this.phi?.ForEachData((ref float value, int[] list) =>
            {
                var dataOrg = this.phi.DataOrigin;
                var c       = Color.white;
                if (value < 0)
                {
                    c = Color.black;
                }
                c           *= Mathf.Abs(value);
                c.a          = 0.5f;
                Gizmos.color = c;
                Gizmos.DrawCube(new Vector3(list[0], list[1], 0) + new Vector3(dataOrg.x, dataOrg.y, 0), new Vector3(cellSpace, cellSpace, 0.1f) * 0.9f);
            });
            Gizmos.color = old;
        }
Exemple #2
0
        protected void DrawVelocity()
        {
            if (this.velocity == null)
            {
                return;
            }

            var norm  = FluidHelper.Infnorm(this.velocity);
            var scale = Vector2.one / norm * 0.4f * new Vector2(cellSpace, cellSpace);

            var old = Gizmos.color;

            this.velocity?.ForEachuData((ref float value, int i, int j) =>
            {
                var dataOrg = this.velocity.uDataOrigin;
                var from    = new Vector3(i, j, 0) + new Vector3(dataOrg.x, dataOrg.y, 0);
                var to      = from + new Vector3(value, 0, 0) * scale.x;

                Gizmos.DrawLine(from, to);
            });

            this.velocity?.ForEachvData((ref float value, int i, int j) =>
            {
                var dataOrg = this.velocity.vDataOrigin;
                var from    = new Vector3(i, j, 0) + new Vector3(dataOrg.x, dataOrg.y, 0);
                var to      = from + new Vector3(0, value, 0) * scale.y;

                Gizmos.DrawLine(from, to);
            });
            Gizmos.color = old;
        }
Exemple #3
0
        protected override int AbsoluteDataIndex(params int[] list)
        {
            Assert.IsTrue(list.Length == 2);
            Assert.IsTrue(0 <= list[0] && list[0] < this.DataSize.x);
            Assert.IsTrue(0 <= list[1] && list[1] < this.DataSize.y);
            Vector2Int index = FluidHelper.ClampIndex(new Vector2Int(list[0], list[1]), Vector2Int.zero, this.DataSize);

            return(index.x + (this.DataSize.x * index.y));
        }
Exemple #4
0
        public override float BiLerp(int i, int j, float fx, float fy)
        {
            var f00 = this[i, j];
            var f10 = this[i + 1, j];
            var f01 = this[i, j + 1];
            var f11 = this[i + 1, j + 1];

            return(FluidHelper.BiLerp(f00, f10, f01, f11, fx, fy));
        }
Exemple #5
0
        protected float GetCFL()
        {
            var   h     = cellSpace;
            var   norm  = FluidHelper.Infnorm(this.velocity);
            float maxv2 = Mathf.Max(h * Gravaty, sqr(norm.x) + sqr(norm.y));

            if (maxv2 < 1e-16)
            {
                maxv2 = 1e-16f;
            }
            return(h / Mathf.Sqrt(maxv2));
        }
Exemple #6
0
        public void AccumulatePoint(Vector2 pos, Vector2 value)
        {
            Vector2Int[] index;
            Vector2[]    weights;

            var cellSpace = this.CellSize;

            var org = this.uDataOrigin;
            //and first - Vector2Int.one is for data index [0, size-1]
            var indexSize = this.uDataSize - Vector2Int.one;

            //note index max should be size-1, clamp did this check
            FluidHelper.GetIndexAndWeight(pos, org, cellSpace,
                                          Vector2Int.zero, indexSize,
                                          out index, out weights);

            for (var i = 0; i < index.Length; ++i)
            {
                var type   = DataType.U;
                var id     = this.AbsoluteIndex(type, index[i]);
                var weight = weights[i].x * weights[i].y;
                this.data[type][id] += value.x * weight;
                this.uWeightSum[index[i].x, index[i].y] += weight;
            }

            org = this.vDataOrigin;
            //and first - Vector2Int.one is for data index [0, size-1]
            indexSize = this.vDataSize - Vector2Int.one;

            //note index max should be size-1, clamp did this check
            FluidHelper.GetIndexAndWeight(pos, org, cellSpace,
                                          Vector2Int.zero, indexSize,
                                          out index, out weights);

            for (var i = 0; i < index.Length; ++i)
            {
                var type   = DataType.V;
                var id     = this.AbsoluteIndex(type, index[i]);
                var weight = weights[i].x * weights[i].y;
                this.data[type][id] += value.y * weight;
                this.vWeightSum[index[i].x, index[i].y] += weight;
            }
        }
Exemple #7
0
        public override Vector2 GetDataFromIndex(params int[] list)
        {
            Assert.IsTrue(list.Length == 4);

            var ret = new Vector2();

            Assert.IsTrue(0 <= list[0] && list[0] < this.uDataSize.x);
            Assert.IsTrue(0 <= list[1] && list[1] < this.uDataSize.y);
            Vector2Int index = FluidHelper.ClampIndex(new Vector2Int(list[0], list[1]), Vector2Int.zero, this.uDataSize);

            ret.x = this.data[DataType.U][this.AbsoluteIndex(DataType.U, index)];

            Assert.IsTrue(0 <= list[2] && list[2] < this.vDataSize.x);
            Assert.IsTrue(0 <= list[3] && list[3] < this.vDataSize.y);
            index = FluidHelper.ClampIndex(new Vector2Int(list[2], list[3]), Vector2Int.zero, this.vDataSize);
            ret.y = this.data[DataType.V][this.AbsoluteIndex(DataType.V, index)];

            return(ret);
        }
Exemple #8
0
        void SolvePressure(int maxits, float tolerance)
        {
            int   its;
            float rNorm = FluidHelper.Infnorm(this.r);
            float tol   = tolerance * rNorm;

            pressure.Reset();
            if (rNorm == 0)
            {
                return;
            }
            ApplyPreconditioner(r, z, mField);
            z.CopyTo(s);
            float rho = FluidHelper.Dot(z, r);

            if (rho == 0)
            {
                return;
            }
            for (its = 0; its < maxits; ++its)
            {
                ApplyPoisson(s, z);
                float alpha = rho / FluidHelper.Dot(s, z);
                FluidHelper.Increment(pressure, s, alpha);
                FluidHelper.Increment(r, z, -alpha);
                if (FluidHelper.Infnorm(this.r) <= tol)
                {
                    Debug.LogFormat("pressure converged to {0} in {1} iterations\n", FluidHelper.Infnorm(this.r), its);
                    return;
                }
                ApplyPreconditioner(r, z, mField);
                float rhonew = FluidHelper.Dot(z, r);
                float beta   = rhonew / rho;
                FluidHelper.ScaleAndIncrement(s, z, beta);
                rho = rhonew;
            }
            Debug.LogFormat("Didn't converge in pressure solve (its={0}, tol={1}, |r|={2})\n", its, tol, FluidHelper.Infnorm(this.r));
        }
Exemple #9
0
        protected void ParticleToGrid()
        {
            this.velocity.ResetValueAndWeight();
            this.marker.Reset(AIR);
            foreach (var p in this.CPUData)
            {
                if (p.active == false)
                {
                    continue;
                }

                var pos = p.position;
                var vel = p.velocity;

                this.velocity.AccumulatePoint(pos, vel);

                Vector2Int posIndex;
                Vector2    posFrac;
                FluidHelper.GetIndexAndFraction(pos, this.marker.Origin, this.marker.CellSize, Vector2Int.zero, this.marker.DataSize, out posIndex, out posFrac);
                this.marker[posIndex.x, posIndex.y] = FLUID;
            }

            this.velocity.NormalizeWeight();
        }