public static void UpdateBondaries(TArray Z) { Z[R.El(0), R.All] = Z[R.El(1), R.All]; Z[R.El(-1), R.All] = Z[R.El(-2), R.All]; Z[R.All, R.El(0)] = Z[R.All, R.El(1)]; Z[R.All, R.El(-1)] = Z[R.All, R.El(-2)]; }
private static TArray Laplacian(TArray Z, TData dx) { var Ztop = Z[R.R(0, -2), R.R(1, -1)]; var Zleft = Z[R.R(1, -1), R.R(0, -2)]; var Zbottom = Z[R.R(2, 0), R.R(1, -1)]; var Zright = Z[R.R(1, -1), R.R(2, 0)]; var Zcenter = Z[R.R(1, -1), R.R(1, -1)]; return((Ztop + Zleft + Zbottom + Zright - 4 * Zcenter) / (TData)Math.Pow(dx, 2)); }
public static NdArray Create(long width, long height) { var res = Generate.Zeroes(height + 2, width + 2); res[R.All, R.El(0)] = -273.5f; res[R.All, R.El(-1)] = -273.5f; res[R.El(0), R.All] = 40f; res[R.El(-1), R.All] = -273.5f; return(res); }
public static TArray Solve(Data data, long iterations, bool image_output) { var a = (TData)2.8e-4; var b = (TData)5e-3; var tau = (TData)(0.1); var k = (TData)(-0.005); var dx = (TData)(2.0 / data.Size); var T = (TData)10.0; // Total time var dt = (TData)(.9 * Math.Pow(dx, 2) / 2); // time step var n = (long)(T / dt); var U = data.U; var V = data.V; for (var step = 0L; step < iterations; step++) { if (image_output) { Plot(data, step, iterations); } // We compute the Laplacian of u and v. var deltaU = Laplacian(U, dx); var deltaV = Laplacian(V, dx); // We take the values of u and v inside the grid. var Uc = U[R.R(1, -1), R.R(1, -1)]; var Vc = V[R.R(1, -1), R.R(1, -1)]; // We update the variables. U[R.R(1, -1), R.R(1, -1)] = Uc + dt * (a * deltaU + Uc - Uc.Pow(3) - Vc + k); V[R.R(1, -1), R.R(1, -1)] = Vc + dt * (b * deltaV + Uc - Vc) / tau; // Neumann conditions: derivatives at the edges are null. UpdateBondaries(U); UpdateBondaries(V); } if (image_output) { Plot(data, iterations, iterations); } return(U); }
public static Tuple <int, NdArray> Solve(NdArray full, long?fixedIterations = null) { var center = full[R.Slice(1, -1), R.Slice(1, -1)]; var north = full[R.Slice(1, -1), R.Slice(0, -2)]; var east = full[R.Slice(0, -2), R.Slice(1, -1)]; var west = full[R.Slice(2, 0), R.Slice(1, -1)]; var south = full[R.Slice(1, -1), R.Slice(2, 0)]; if (fixedIterations != null) { for (var i = 0; i < fixedIterations.Value; i++) { center[R.All] = 0.2f * (center + north + east + west + south); } return(new Tuple <int, NdArray>((int)fixedIterations.Value, full)); } else { T epsilon = 0.005f; T delta = epsilon + 1; int iteration = 0; while (epsilon < delta) { iteration++; var work = 0.2f * (center + north + east + west + south); delta = (work - center).Abs().Sum(); center[R.All] = work; } return(new Tuple <int, NdArray>(iteration, full)); } }