private static void test02() //****************************************************************************80 // // Purpose: // // TEST02 tests CG_RC with the Wathen matrix. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 13 January 2013 // // Author: // // John Burkardt // { int i; double rnrm2; Console.WriteLine(""); Console.WriteLine("TEST02"); Console.WriteLine(" Use CG_RC to solve a linear system"); Console.WriteLine(" involving the Wathen matrix."); const int nx = 5; const int ny = 4; Console.WriteLine(""); Console.WriteLine(" NX = " + nx + ""); Console.WriteLine(" NY = " + ny + ""); int n = WathenMatrix.wathen_order(nx, ny); Console.WriteLine(" N = " + n + ""); double[] a = WathenMatrix.wathen(nx, ny, n); int seed = 123456789; double[] x_exact = UniformRNG.r8vec_uniform_01_new(n, ref seed); double[] b = new double[n]; typeMethods.r8mat_mv(n, n, a, x_exact, ref b); // // Here is the initial guess for the solution. // double[] x = new double[n]; for (i = 0; i < n; i++) { x[i] = 0.0; } double[] ax = new double[n]; // // Parameters for the stopping test. // int it = 0; const int it_max = 30; const double tol = 1.0E-05; double bnrm2 = 0.0; for (i = 0; i < n; i++) { bnrm2 += b[i] * b[i]; } bnrm2 = Math.Sqrt(bnrm2); // // Set parameters for the CG_RC code. // double[] r = new double[n]; double[] z = new double[n]; double[] p = new double[n]; double[] q = new double[n]; int job = 1; // // Repeatedly call the CG_RC code, and on return, do what JOB tells you. // ConjugateGradientData data = new(); for (;;) { job = ConjugateGradientRC.cg_rc(ref data, n, b, ref x, ref r, ref z, ref p, ref q, ref job); // // Compute q = A * p. // if (job == 1) { typeMethods.r8mat_mv(n, n, a, p, ref q); } // // Solve M * z = r. // else if (job == 2) { for (i = 0; i < n; i++) { z[i] = r[i] / a[i + i * n]; } } // // Compute r = r - A * x. // else if (job == 3) { typeMethods.r8mat_mv(n, n, a, x, ref ax); for (i = 0; i < n; i++) { r[i] -= ax[i]; } } // // Stopping test. // else if (job == 4) { rnrm2 = 0.0; for (i = 0; i < n; i++) { rnrm2 += r[i] * r[i]; } rnrm2 = Math.Sqrt(rnrm2); if (bnrm2 == 0.0) { if (rnrm2 <= tol) { break; } } else { if (rnrm2 <= tol * bnrm2) { break; } } it += 1; if (it_max <= it) { Console.WriteLine(""); Console.WriteLine(" Iteration limit exceeded."); Console.WriteLine(" Terminating early."); break; } } job = 2; } Console.WriteLine(""); Console.WriteLine(" Number of iterations was " + it + ""); Console.WriteLine(" Estimated error is " + rnrm2 + ""); double err = 0.0; for (i = 0; i < n; i++) { double t = Math.Abs(x_exact[i] - x[i]); if (err < t) { err = t; } } Console.WriteLine(" Loo error is " + err + ""); Console.WriteLine(""); Console.WriteLine(" I X(I) X_EXACT(I) B(I)"); Console.WriteLine(""); for (i = 0; i < n; i++) { Console.WriteLine(" " + i.ToString(CultureInfo.InvariantCulture).PadLeft(4) + " " + x[i].ToString(CultureInfo.InvariantCulture).PadLeft(14) + " " + x_exact[i].ToString(CultureInfo.InvariantCulture).PadLeft(14) + " " + b[i].ToString(CultureInfo.InvariantCulture).PadLeft(14) + ""); } }
private static void test03() //****************************************************************************80 // // Purpose: // // TEST03 carries out test case #3. // // Discussion: // // Use A3, C3, F3, EXACT3, EXACT_UX3, EXACT_UX3. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 07 July 2014 // // Author: // // John Burkardt // { int i; int j; const int nx = 5; const int ny = 5; Console.WriteLine(""); Console.WriteLine("TEST03"); Console.WriteLine(" Solve - del ( A del U ) + C U = F "); Console.WriteLine(" on the unit square with zero boundary conditions."); Console.WriteLine(" A1(X,Y) = 0.0"); Console.WriteLine(" C1(X,Y) = 1.0"); Console.WriteLine(" F1(X,Y) = X * ( 1 - X ) * Y * ( 1 - Y )"); Console.WriteLine(" U1(X,Y) = X * ( 1 - X ) * Y * ( 1 - Y )"); Console.WriteLine(""); Console.WriteLine(" This example is contrived so that the system matrix"); Console.WriteLine(" is the WATHEN matrix."); Console.WriteLine(""); Console.WriteLine(" Number of X grid values NX = " + nx + ""); Console.WriteLine(" Number of Y grid values NY = " + ny + ""); // // Geometry definitions. // const double x_first = 0.0; const double x_last = 1.0; double[] x = typeMethods.r8vec_linspace_new(nx, x_first, x_last); const double y_first = 0.0; const double y_last = 1.0; double[] y = typeMethods.r8vec_linspace_new(ny, y_first, y_last); double[] u = FEM_2D_BVP_Serene.fem2d_bvp_serene(nx, ny, a3, c3, f3, x, y, true); switch (nx * ny) { case <= 25: { Console.WriteLine(""); Console.WriteLine(" I J X Y U Uexact Error"); Console.WriteLine(""); int k = 0; for (j = 0; j < ny; j++) { int inc = (j % 2) switch { 0 => 1, _ => 2 }; for (i = 0; i < nx; i += inc) { double uexact = exact3(x[i], y[j]); Console.WriteLine(i.ToString(CultureInfo.InvariantCulture).PadLeft(4) + " " + j.ToString(CultureInfo.InvariantCulture).PadLeft(4) + " " + x[i].ToString(CultureInfo.InvariantCulture).PadLeft(8) + " " + y[j].ToString(CultureInfo.InvariantCulture).PadLeft(8) + " " + u[k].ToString(CultureInfo.InvariantCulture).PadLeft(14) + " " + uexact.ToString(CultureInfo.InvariantCulture).PadLeft(14) + " " + Math.Abs(u[k] - uexact).ToString(CultureInfo.InvariantCulture).PadLeft(14) + ""); k += 1; } } break; } } double e1 = FEM_2D_BVP_Serene.fem2d_l1_error_serene(nx, ny, x, y, u, exact3); double e2 = FEM_2D_BVP_Serene.fem2d_l2_error_serene(nx, ny, x, y, u, exact3); double h1s = FEM_2D_BVP_Serene.fem2d_h1s_error_serene(nx, ny, x, y, u, exact_ux3, exact_uy3); Console.WriteLine(""); Console.WriteLine(" l1 norm of error = " + e1 + ""); Console.WriteLine(" L2 norm of error = " + e2 + ""); Console.WriteLine(" Seminorm of error = " + h1s + ""); // // Pull out the Wathen matrix from MATLAB. // It will have been multiplied by a random scale factor. // While my numbering scheme is // 3 2 1 // 4 8 // 5 6 7 // the numbering scheme used here is // 1 2 3 // 4 5 // 6 7 8 // double[] amat = WathenMatrix.wathen(1, 1, 8); double scale = 0.5 * amat[0 + 2 * 8]; for (j = 0; j < 8; j++) { for (i = 0; i < 8; i++) { amat[i + j * 8] /= scale; } } typeMethods.r8mat_print(8, 8, amat, " Wathen matrix:"); }