/// <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; } } }
/// <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; } } }
/// <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; } } }