예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="field"></param>
        /// <param name="result"></param>
        /// <param name="parallel"></param>
        public static void GetLaplacian(this GridField2d <double> field, double[] result, bool parallel = false)
        {
            if (parallel)
            {
                Parallel.ForEach(Partitioner.Create(0, field.CountXY), range => Body(range.Item1, range.Item2));
            }
            else
            {
                Body(0, field.CountXY);
            }

            void Body(int from, int to)
            {
                var vals = field.Values;

                (var nx, var ny) = field.Count;
                (var dx, var dy) = field.Scale;
                dx = 1.0 / (dx * dx);
                dy = 1.0 / (dy * dy);

                (int di, int dj) = field.GetBoundaryOffsets();
                (int i, int j)   = field.ToGridSpace(from);

                for (int index = from; index < to; index++, i++)
                {
                    if (i == nx)
                    {
                        j++; i = 0;
                    }

                    double tx0 = (i == 0) ? vals[index + di] : vals[index - 1];
                    double tx1 = (i == nx - 1) ? vals[index - di] : vals[index + 1];

                    double ty0 = (j == 0) ? vals[index + dj] : vals[index - nx];
                    double ty1 = (j == ny - 1) ? vals[index - dj] : vals[index + nx];

                    double t = vals[index] * 2.0;
                    result[index] = (tx0 + tx1 - t) * dx + (ty0 + ty1 - t) * dy;
                }
            }
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="field"></param>
        /// <param name="result"></param>
        /// <param name="parallel"></param>
        public static void GetCurl(this GridField2d <Vector2d> field, double[] result, bool parallel = false)
        {
            // implementation reference
            // http://www.math.harvard.edu/archive/21a_spring_09/PDF/13-05-curl-and-divergence.pdf

            if (parallel)
            {
                Parallel.ForEach(Partitioner.Create(0, field.CountXY), range => Body(range.Item1, range.Item2));
            }
            else
            {
                Body(0, field.CountXY);
            }

            void Body(int from, int to)
            {
                var vals = field.Values;

                (var nx, var ny) = field.Count;
                (var tx, var ty) = (0.5 / field.Scale);
                (int di, int dj) = field.GetBoundaryOffsets();
                (int i, int j)   = field.ToGridSpace(from);

                for (int index = from; index < to; index++, i++)
                {
                    if (i == nx)
                    {
                        j++; i = 0;
                    }

                    Vector2d tx0 = (i == 0) ? vals[index + di] : vals[index - 1];
                    Vector2d tx1 = (i == nx - 1) ? vals[index - di] : vals[index + 1];

                    Vector2d ty0 = (j == 0) ? vals[index + dj] : vals[index - nx];
                    Vector2d ty1 = (j == ny - 1) ? vals[index - dj] : vals[index + nx];

                    result[index] = (tx1.Y - tx0.Y) * tx - (ty1.X - ty0.X) * ty;
                }
            }
        }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="field"></param>
        /// <param name="result"></param>
        /// <param name="parallel"></param>
        public static void GetDivergence(this GridField2d <Vector2d> field, double[] result, bool parallel = false)
        {
            if (parallel)
            {
                Parallel.ForEach(Partitioner.Create(0, field.CountXY), range => Body(range.Item1, range.Item2));
            }
            else
            {
                Body(0, field.CountXY);
            }

            void Body(int from, int to)
            {
                var vals = field.Values;

                (var nx, var ny) = field.Count;
                (var dx, var dy) = (0.5 / field.Scale);
                (int di, int dj) = field.GetBoundaryOffsets();
                (int i, int j)   = field.ToGridSpace(from);

                for (int index = from; index < to; index++, i++)
                {
                    if (i == nx)
                    {
                        j++; i = 0;
                    }

                    Vector2d tx0 = (i == 0) ? vals[index + di] : vals[index - 1];
                    Vector2d tx1 = (i == nx - 1) ? vals[index - di] : vals[index + 1];

                    Vector2d ty0 = (j == 0) ? vals[index + dj] : vals[index - nx];
                    Vector2d ty1 = (j == ny - 1) ? vals[index - dj] : vals[index + nx];

                    result[index] = (tx1.X - tx0.X) * dx + (ty1.Y - ty0.Y) * dy;
                }
            }
        }