Actual source code: ex1.c


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

  4: #include <petscksp.h>

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

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

 30:   PetscFunctionBeginUser;
 31:   PetscCall(PetscInitialize(&argc, &args, (char *)0, help));

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

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

 50:   PetscCall(VecAssemblyBegin(b));
 51:   PetscCall(VecAssemblyEnd(b));

 53:   /* solve linear system */
 54:   PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
 55:   PetscCall(KSPSetOperators(ksp, C, C));
 56:   PetscCall(KSPSetFromOptions(ksp));
 57:   PetscCall(KSPSolve(ksp, b, u));

 59:   /* test proper handling of convergence test by KSPLSQR */
 60:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_lsqr", &flg, NULL));
 61:   if (flg) {
 62:     char     *type;
 63:     char      convtestname[16];
 64:     PetscBool islsqr;
 65:     PetscErrorCode (*converged)(KSP, PetscInt, PetscReal, KSPConvergedReason *, void *);
 66:     PetscErrorCode (*converged1)(KSP, PetscInt, PetscReal, KSPConvergedReason *, void *);
 67:     PetscErrorCode (*destroy)(void *), (*destroy1)(void *);
 68:     void *ctx, *ctx1;

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

102:   PetscCall(MatMult(C, u, x));
103:   PetscCall(VecAXPY(x, -1.0, b));
104:   PetscCall(VecNorm(x, NORM_2, &norm));

106:   PetscCall(KSPDestroy(&ksp));
107:   PetscCall(VecDestroy(&u));
108:   PetscCall(VecDestroy(&x));
109:   PetscCall(VecDestroy(&b));
110:   PetscCall(MatDestroy(&C));
111:   PetscCall(PetscFinalize());
112:   return 0;
113: }

115: /*TEST

117:     test:
118:       args:  -pc_type jacobi -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always

120:     test:
121:       suffix: 2
122:       nsize: 2
123:       args: -pc_type jacobi -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always

125:     test:
126:       suffix: 3
127:       args: -pc_type sor -pc_sor_symmetric -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always

129:     test:
130:       suffix: 5
131:       args: -pc_type eisenstat -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always

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

146: TEST*/