11 std::string
const& petsc_options)
13#if PETSC_VERSION_LT(3, 7, 0)
14 PetscOptionsInsertString(petsc_options.c_str());
16 PetscOptionsInsertString(
nullptr, petsc_options.c_str());
19 PetscCallAbort(PETSC_COMM_WORLD, KSPCreate(PETSC_COMM_WORLD, &
solver_));
21 PetscCallAbort(PETSC_COMM_WORLD, KSPGetPC(
solver_, &
pc_));
25 PetscCallAbort(PETSC_COMM_WORLD,
26 KSPSetOptionsPrefix(
solver_, prefix.c_str()));
29 PetscCallAbort(PETSC_COMM_WORLD,
30 KSPSetInitialGuessNonzero(
solver_, PETSC_TRUE));
31 PetscCallAbort(PETSC_COMM_WORLD,
35 PetscCallAbort(PETSC_COMM_WORLD, KSPGetType(
solver_, &ksp_type));
46 PetscLogDouble mem1, mem2;
47 PetscMemoryGetCurrentUsage(&mem1);
50 KSPNormType norm_type;
51 PetscCallAbort(PETSC_COMM_WORLD, KSPGetNormType(
solver_, &norm_type));
54 PetscCallAbort(PETSC_COMM_WORLD, KSPGetType(
solver_, &ksp_type));
55 PetscCallAbort(PETSC_COMM_WORLD, PCGetType(
pc_, &pc_type));
57 PetscPrintf(PETSC_COMM_WORLD,
58 "\n================================================");
59 PetscPrintf(PETSC_COMM_WORLD,
60 "\nLinear solver %s with %s preconditioner using %s", ksp_type,
61 pc_type, KSPNormTypes[norm_type]);
66 PetscCallAbort(PETSC_COMM_WORLD,
69 KSPConvergedReason reason;
70 PetscCallAbort(PETSC_COMM_WORLD, KSPGetConvergedReason(
solver_, &reason));
72 bool converged =
true;
76 PetscCallAbort(PETSC_COMM_WORLD, KSPGetIterationNumber(
solver_, &its));
77 PetscPrintf(PETSC_COMM_WORLD,
"\nconverged in %d iterations", its);
80 case KSP_CONVERGED_RTOL:
81 PetscPrintf(PETSC_COMM_WORLD,
82 " (relative convergence criterion fulfilled).");
84 case KSP_CONVERGED_ATOL:
85 PetscPrintf(PETSC_COMM_WORLD,
86 " (absolute convergence criterion fulfilled).");
89 PetscPrintf(PETSC_COMM_WORLD,
".");
92 PetscPrintf(PETSC_COMM_WORLD,
93 "\n================================================\n");
95 else if (reason == KSP_DIVERGED_ITS)
97 PetscPrintf(PETSC_COMM_WORLD,
98 "\nWarning: maximum number of iterations reached.\n");
103 if (reason == KSP_DIVERGED_INDEFINITE_PC)
105 PetscPrintf(PETSC_COMM_WORLD,
106 "\nDivergence because of indefinite preconditioner,");
107 PetscPrintf(PETSC_COMM_WORLD,
108 "\nTry to run again with "
109 "-pc_factor_shift_positive_definite option.\n");
111 else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
113 PetscPrintf(PETSC_COMM_WORLD,
114 "\nKSPBICG method was detected so the method could not "
115 "continue to enlarge the Krylov space.");
116 PetscPrintf(PETSC_COMM_WORLD,
117 "\nTry to run again with another solver.\n");
119 else if (reason == KSP_DIVERGED_NONSYMMETRIC)
121 PetscPrintf(PETSC_COMM_WORLD,
122 "\nMatrix or preconditioner is unsymmetric but KSP "
123 "requires symmetric.\n");
127 PetscPrintf(PETSC_COMM_WORLD,
128 "\nDivergence detected, use command option "
129 "-ksp_monitor or -log_summary to check the details.\n");
134 PetscMemoryGetCurrentUsage(&mem2);
137 "###Memory usage by solver. Before: %f After: %f Increase: %d\n", mem1,
138 mem2, (
int)(mem2 - mem1));