/// <summary> /// Interpolated velocity components, pressure and divergence field to cell centred grid. /// </summary> /// <param name="u_interp">interpolated x component of velocity</param> /// <param name="v_interp">interpolated y component of velocity</param> /// <param name="w_interp">interpolated z component of velocity</param> /// <param name="p_interp">interpolated pressure</param> /// <param name="div_interp">interpolated divergence</param> private void interpolate_to_cell_centre_grid(out double[, ,] u_interp, out double[, ,] v_interp, out double[, ,] w_interp, out double[, ,] p_interp, out double[, ,] div_interp) { int Nx = omega.Nx - 2; int Ny = omega.Ny - 2; int Nz = omega.Nz - 2; u_interp = new double[Nx, Ny, Nz]; v_interp = new double[Nx, Ny, Nz]; w_interp = new double[Nx, Ny, Nz]; p_interp = new double[Nx, Ny, Nz]; div_interp = new double[Nx, Ny, Nz]; for (int i = 1; i < Nx + 1; i++) { for (int j = 1; j < Ny + 1; j++) { for (int k = 1; k < Nz + 1; k++) { //if (omega.obstacle_cells[i, j, k] == 0) { double[] velocity_interp = de.get_velocity((i - 0.5) * omega.hx, (j - 0.5) * omega.hy, (k - 0.5) * omega.hz); u_interp[i - 1, j - 1, k - 1] = velocity_interp[0]; v_interp[i - 1, j - 1, k - 1] = velocity_interp[1]; w_interp[i - 1, j - 1, k - 1] = velocity_interp[2]; p_interp[i - 1, j - 1, k - 1] = de.get_pressure((i - 0.5) * omega.hx, (j - 0.5) * omega.hy, (k - 0.5) * omega.hz); div_interp[i - 1, j - 1, k - 1] = (fs.u[i, j, k] - fs.u[i - 1, j, k]) / omega.hx + (fs.v[i, j, k] - fs.v[i, j - 1, k]) / omega.hy + (fs.w[i, j, k] - fs.w[i, j, k - 1]) / omega.hz; } } } } }
/// <summary> /// Computes L2 and L-infinity error between FFD approximation and exact solution. /// </summary> /// <param name="fs">FluidSolver containing FFD solution at time t</param> /// <pram name="omega">Domain on which exact solution is given</pram> /// <param name="err_l2">Normalized pointwise L2 error</param> /// <param name="err_inf">Pointwise L-infinity error</param> /// <param name="t">Time</param> /// <param name="component">Component to evaluate</param> /// <remarks>The component to evaluate must be one of: /// 1 for pressure /// 2 for x component of velocity /// 3 for y component of velocity /// 4 for z component of velocity</remarks> public static void calculate_errors(FluidSolver fs, Domain omega, out double err_l2, out double err_inf, double t, int component) { DataExtractor de = new DataExtractor(omega, fs); double nu = fs.nu; int Nx = omega.Nx - 1; int Ny = omega.Ny - 1; int Nz = omega.Nz - 1; double[, ,] err_array = new double[Nx, Ny, Nz]; double[, ,] comp_interp = new double[Nx, Ny, Nz]; double[, ,] zeros = new double[Nx, Ny, Nz]; for (int i = 0; i < Nx; i++) { for (int j = 0; j < Ny; j++) { for (int k = 0; k < Nz; k++) { double x = i * omega.hx; double y = j * omega.hy; double z = k * omega.hz; double[] coordinate = new double[] { x, y, z }; double[] velocity_interp = de.get_velocity(x, y, z); double u_exact, v_exact, w_exact, p_exact; omega.exact_solution(coordinate, nu, t, out u_exact, out v_exact, out w_exact, out p_exact); switch (component) { case 1: comp_interp[i, j, k] = de.get_pressure(x, y, z); err_array[i, j, k] = Math.Abs(de.get_pressure(x, y, z) - p_exact); break; case 2: comp_interp[i, j, k] = velocity_interp[0]; err_array[i, j, k] = Math.Abs(velocity_interp[0] - u_exact); break; case 3: comp_interp[i, j, k] = velocity_interp[1]; err_array[i, j, k] = Math.Abs(velocity_interp[1] - v_exact); break; case 4: comp_interp[i, j, k] = velocity_interp[2]; err_array[i, j, k] = Math.Abs(velocity_interp[2] - w_exact); break; } } } } err_l2 = Utilities.compute_L2_difference(err_array, zeros); //L2 norm of errors err_inf = err_array.Cast <double>().Max(); }