Actual source code: ex1.c

  1: static char help[] = "Tests solving linear system on 0 by 0 matrix, and KSPLSQR convergence test handling.\n\n";

  3: #include <petscksp.h>

  5: static PetscErrorCode GetConvergenceTestName(KSPConvergenceTestFn *converged, char name[], size_t n)
  6: {
  7:   PetscFunctionBegin;
  8:   if (converged == KSPConvergedDefault) {
  9:     PetscCall(PetscStrncpy(name, "default", n));
 10:   } else if (converged == KSPConvergedSkip) {
 11:     PetscCall(PetscStrncpy(name, "skip", n));
 12:   } else if (converged == KSPLSQRConvergedDefault) {
 13:     PetscCall(PetscStrncpy(name, "lsqr", n));
 14:   } else {
 15:     PetscCall(PetscStrncpy(name, "other", n));
 16:   }
 17:   PetscFunctionReturn(PETSC_SUCCESS);
 18: }

 20: int main(int argc, char **args)
 21: {
 22:   Mat       C;
 23:   PetscInt  N = 0;
 24:   Vec       u, b, x;
 25:   KSP       ksp;
 26:   PetscReal norm;
 27:   PetscBool flg = PETSC_FALSE;

 29:   PetscFunctionBeginUser;
 30:   PetscCall(PetscInitialize(&argc, &args, NULL, help));

 32:   /* create stiffness matrix */
 33:   PetscCall(MatCreate(PETSC_COMM_WORLD, &C));
 34:   PetscCall(MatSetSizes(C, PETSC_DECIDE, PETSC_DECIDE, N, N));
 35:   PetscCall(MatSetFromOptions(C));
 36:   PetscCall(MatSetUp(C));
 37:   PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
 38:   PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));

 40:   /* create right-hand side and solution */
 41:   PetscCall(VecCreate(PETSC_COMM_WORLD, &u));
 42:   PetscCall(VecSetSizes(u, PETSC_DECIDE, N));
 43:   PetscCall(VecSetFromOptions(u));
 44:   PetscCall(VecDuplicate(u, &b));
 45:   PetscCall(VecDuplicate(u, &x));

 47:   PetscCall(VecAssemblyBegin(b));
 48:   PetscCall(VecAssemblyEnd(b));

 50:   /* solve linear system */
 51:   PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
 52:   PetscCall(KSPSetOperators(ksp, C, C));
 53:   PetscCall(KSPSetFromOptions(ksp));
 54:   PetscCall(KSPSolve(ksp, b, u));

 56:   /* test proper handling of convergence test by KSPLSQR */
 57:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_lsqr", &flg, NULL));
 58:   if (flg) {
 59:     char                 *type;
 60:     char                  convtestname[16];
 61:     PetscBool             islsqr;
 62:     KSPConvergenceTestFn *converged, *converged1;
 63:     PetscCtxDestroyFn    *destroy, *destroy1;
 64:     void                 *ctx, *ctx1;

 66:     {
 67:       const char *typeP;
 68:       PetscCall(KSPGetType(ksp, &typeP));
 69:       PetscCall(PetscStrallocpy(typeP, &type));
 70:     }
 71:     PetscCall(PetscStrcmp(type, KSPLSQR, &islsqr));
 72:     PetscCall(KSPGetConvergenceTest(ksp, &converged, &ctx, &destroy));
 73:     PetscCall(GetConvergenceTestName(converged, convtestname, 16));
 74:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
 75:     PetscCall(KSPSetType(ksp, KSPLSQR));
 76:     PetscCall(KSPGetConvergenceTest(ksp, &converged1, &ctx1, &destroy1));
 77:     PetscCheck(converged1 == KSPLSQRConvergedDefault, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test should be KSPLSQRConvergedDefault");
 78:     PetscCheck(destroy1 == KSPConvergedDefaultDestroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function should be KSPConvergedDefaultDestroy");
 79:     if (islsqr) {
 80:       PetscCheck(converged1 == converged, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test should be kept");
 81:       PetscCheck(destroy1 == destroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function should be kept");
 82:       PetscCheck(ctx1 == ctx, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test context should be kept");
 83:     }
 84:     PetscCall(GetConvergenceTestName(converged1, convtestname, 16));
 85:     PetscCall(KSPViewFromOptions(ksp, NULL, "-ksp1_view"));
 86:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
 87:     PetscCall(KSPSetType(ksp, type));
 88:     PetscCall(KSPGetConvergenceTest(ksp, &converged1, &ctx1, &destroy1));
 89:     PetscCheck(converged1 == converged, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test not reverted properly");
 90:     PetscCheck(destroy1 == destroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function not reverted properly");
 91:     PetscCheck(ctx1 == ctx, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test context not reverted properly");
 92:     PetscCall(GetConvergenceTestName(converged1, convtestname, 16));
 93:     PetscCall(KSPViewFromOptions(ksp, NULL, "-ksp2_view"));
 94:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
 95:     PetscCall(PetscFree(type));
 96:   }

 98:   PetscCall(MatMult(C, u, x));
 99:   PetscCall(VecAXPY(x, -1.0, b));
100:   PetscCall(VecNorm(x, NORM_2, &norm));

102:   PetscCall(KSPDestroy(&ksp));
103:   PetscCall(VecDestroy(&u));
104:   PetscCall(VecDestroy(&x));
105:   PetscCall(VecDestroy(&b));
106:   PetscCall(MatDestroy(&C));
107:   PetscCall(PetscFinalize());
108:   return 0;
109: }

111: /*TEST

113:     test:
114:       args: -pc_type jacobi -ksp_monitor -ksp_orthogonalization_cgs_refinement_type refine_always

116:     test:
117:       suffix: 2
118:       nsize: 2
119:       args: -pc_type jacobi -ksp_monitor -ksp_orthogonalization_cgs_refinement_type refine_always

121:     test:
122:       suffix: 3
123:       args: -pc_type sor -pc_sor_symmetric -ksp_monitor -ksp_orthogonalization_cgs_refinement_type refine_always

125:     test:
126:       suffix: 5
127:       args: -pc_type eisenstat -ksp_monitor -ksp_orthogonalization_cgs_refinement_type refine_always

129:     testset:
130:       args: -test_lsqr -ksp{,1,2}_view -pc_type jacobi
131:       filter: grep -E "(^  type:|preconditioning|norm type|convergence test:)"
132:       test:
133:         suffix: lsqr_0
134:         args: -ksp_convergence_test {{default skip}separate output}
135:       test:
136:         suffix: lsqr_1
137:         args: -ksp_type cg -ksp_convergence_test {{default skip}separate output}
138:       test:
139:         suffix: lsqr_2
140:         args: -ksp_type lsqr

142: TEST*/