Actual source code: ex89.c

  1: static char help[] = "Test interface functions of KSPIDR with a nonsymmetric matrix.\n\n";

  3: #include <petscksp.h>

  5: int main(int argc, char **args)
  6: {
  7:   Vec         x, b, xe; /* approx solution, RHS, exact solution */
  8:   Mat         A;        /* linear system matrix */
  9:   KSP         ksp;      /* linear solver context */
 10:   PC          pc;       /* preconditioner */
 11:   PetscInt    i, Istart, Iend, n = 40, s = 0;
 12:   PetscReal   nrm;
 13:   PetscRandom rctx;

 15:   PetscFunctionBeginUser;
 16:   PetscCall(PetscInitialize(&argc, &args, NULL, help));
 17:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL));

 19:   /* Create bidiagonal matrix */
 20:   PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
 21:   PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n));
 22:   PetscCall(MatSetFromOptions(A));
 23:   PetscCall(MatSetUp(A));
 24:   PetscCall(MatGetOwnershipRange(A, &Istart, &Iend));

 26:   for (i = Istart; i < Iend; i++) {
 27:     PetscCall(MatSetValue(A, i, i, 2.0, INSERT_VALUES));
 28:     if (i < n - 1) PetscCall(MatSetValue(A, i, i + 1, 1.0 / (i + 1), INSERT_VALUES));
 29:   }

 31:   PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
 32:   PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));

 34:   PetscCall(MatCreateVecs(A, &x, &b));
 35:   PetscCall(VecDuplicate(x, &xe));
 36:   PetscCall(VecSet(xe, 1.0));
 37:   PetscCall(MatMult(A, xe, b));

 39:   /* Create linear solver context */
 40:   PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
 41:   PetscCall(KSPSetOperators(ksp, A, A));
 42:   PetscCall(KSPSetType(ksp, KSPIDR));
 43:   PetscCall(KSPGetPC(ksp, &pc));
 44:   PetscCall(PCSetType(pc, PCNONE));

 46:   /* Pass specific IDR options, including user-provided PetscRandom */
 47:   PetscCall(KSPIDRSetS(ksp, 6));
 48:   PetscCall(KSPIDRSetCosine(ksp, 0.8));
 49:   PetscCall(PetscRandomCreate(PETSC_COMM_WORLD, &rctx));
 50:   PetscCall(PetscRandomSetFromOptions(rctx));
 51:   PetscCall(KSPIDRSetRandom(ksp, rctx));
 52:   PetscCall(PetscRandomDestroy(&rctx));
 53:   PetscCall(KSPSetFromOptions(ksp));

 55:   PetscCall(KSPSolve(ksp, b, x));

 57:   PetscCall(VecAXPY(x, -1.0, xe));
 58:   PetscCall(VecNorm(x, NORM_2, &nrm));
 59:   PetscCall(KSPIDRGetS(ksp, &s));
 60:   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Absolute error (s=%" PetscInt_FMT ") = %1.6f\n", s, (double)nrm));

 62:   /* Solve again with different s */
 63:   PetscCall(KSPIDRSetS(ksp, 4));
 64:   PetscCall(KSPSolve(ksp, b, x));

 66:   PetscCall(VecAXPY(x, -1.0, xe));
 67:   PetscCall(VecNorm(x, NORM_2, &nrm));
 68:   PetscCall(KSPIDRGetS(ksp, &s));
 69:   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Absolute error (s=%" PetscInt_FMT ") = %1.6f\n", s, (double)nrm));

 71:   /* Free work space */
 72:   PetscCall(KSPDestroy(&ksp));
 73:   PetscCall(VecDestroy(&x));
 74:   PetscCall(VecDestroy(&xe));
 75:   PetscCall(VecDestroy(&b));
 76:   PetscCall(MatDestroy(&A));

 78:   PetscCall(PetscFinalize());
 79:   return 0;
 80: }

 82: /*TEST

 84:    test:
 85:       suffix: 1

 87:    test:
 88:       args: -pc_type jacobi -ksp_pc_side right
 89:       suffix: 2

 91: TEST*/