Actual source code: itcl.c

  1: /*
  2:     Code for setting KSP options from the options database.
  3: */

  5: #include <petsc/private/kspimpl.h>
  6: #include <petscdraw.h>

  8: /*@
  9:   KSPSetOptionsPrefix - Sets the prefix used for searching for all
 10:   `KSP` options in the database.

 12:   Logically Collective

 14:   Input Parameters:
 15: + ksp    - the Krylov context
 16: - prefix - the prefix string to prepend to all `KSP` option requests

 18:   Level: intermediate

 20:   Notes:
 21:   A hyphen (-) must NOT be given at the beginning of the prefix name.
 22:   The first character of all runtime options is AUTOMATICALLY the
 23:   hyphen.

 25:   For example, to distinguish between the runtime options for two
 26:   different `KSP` contexts, one could call
 27: .vb
 28:       KSPSetOptionsPrefix(ksp1,"sys1_")
 29:       KSPSetOptionsPrefix(ksp2,"sys2_")
 30: .ve

 32:   This would enable use of different options for each system, such as
 33: .vb
 34:       -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
 35:       -sys2_ksp_type bcgs  -sys2_ksp_rtol 1.e-4
 36: .ve

 38: .seealso: [](ch_ksp), `KSP`, `KSPAppendOptionsPrefix()`, `KSPGetOptionsPrefix()`, `KSPSetFromOptions()`
 39: @*/
 40: PetscErrorCode KSPSetOptionsPrefix(KSP ksp, const char prefix[])
 41: {
 42:   PetscBool ispcmpi;

 44:   PetscFunctionBegin;
 46:   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
 47:   PetscCall(PetscObjectTypeCompare((PetscObject)ksp->pc, PCMPI, &ispcmpi));
 48:   if (ispcmpi) {
 49:     size_t     len;
 50:     const char suffix[] = "mpi_linear_solver_server_";
 51:     char      *newprefix;

 53:     PetscCall(PetscStrlen(prefix, &len));
 54:     PetscCall(PetscMalloc1(len + sizeof(suffix) + 1, &newprefix));
 55:     PetscCall(PetscStrncpy(newprefix, prefix, len + sizeof(suffix)));
 56:     PetscCall(PetscStrlcat(newprefix, suffix, len + sizeof(suffix)));
 57:     PetscCall(PCSetOptionsPrefix(ksp->pc, newprefix));
 58:     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ksp, newprefix));
 59:     PetscCall(PetscFree(newprefix));
 60:   } else {
 61:     PetscCall(PCSetOptionsPrefix(ksp->pc, prefix));
 62:     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ksp, prefix));
 63:   }
 64:   PetscFunctionReturn(PETSC_SUCCESS);
 65: }

 67: /*@
 68:   KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
 69:   `KSP` options in the database.

 71:   Logically Collective

 73:   Input Parameters:
 74: + ksp    - the Krylov context
 75: - prefix - the prefix string to prepend to all `KSP` option requests

 77:   Level: intermediate

 79:   Note:
 80:   A hyphen (-) must NOT be given at the beginning of the prefix name.
 81:   The first character of all runtime options is AUTOMATICALLY the hyphen.

 83: .seealso: [](ch_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPGetOptionsPrefix()`, `KSPSetFromOptions()`
 84: @*/
 85: PetscErrorCode KSPAppendOptionsPrefix(KSP ksp, const char prefix[])
 86: {
 87:   PetscFunctionBegin;
 89:   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
 90:   PetscCall(PCAppendOptionsPrefix(ksp->pc, prefix));
 91:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)ksp, prefix));
 92:   PetscFunctionReturn(PETSC_SUCCESS);
 93: }

 95: /*@
 96:   KSPSetUseFischerGuess - Use the Paul Fischer algorithm or its variants to compute initial guesses for a set of solves with related right-hand sides

 98:   Logically Collective

100:   Input Parameters:
101: + ksp   - the Krylov context
102: . model - use model 1, model 2, model 3, or any other number to turn it off
103: - size  - size of subspace used to generate initial guess

105:   Options Database Key:
106: . -ksp_fischer_guess model,size - uses the Fischer initial guess generator for repeated linear solves

108:   Level: advanced

110: .seealso: [](ch_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetGuess()`, `KSPGetGuess()`, `KSPGuess`
111: @*/
112: PetscErrorCode KSPSetUseFischerGuess(KSP ksp, PetscInt model, PetscInt size)
113: {
114:   KSPGuess guess;

116:   PetscFunctionBegin;
120:   PetscCall(KSPGetGuess(ksp, &guess));
121:   PetscCall(KSPGuessSetType(guess, KSPGUESSFISCHER));
122:   PetscCall(KSPGuessFischerSetModel(guess, model, size));
123:   PetscFunctionReturn(PETSC_SUCCESS);
124: }

126: /*@
127:   KSPSetGuess - Set the initial guess object `KSPGuess` to be used by the `KSP` object to generate initial guesses

129:   Logically Collective

131:   Input Parameters:
132: + ksp   - the Krylov context
133: - guess - the object created with `KSPGuessCreate()`

135:   Level: advanced

137:   Notes:
138:   this allows a single `KSP` to be used with several different initial guess generators (likely for different linear
139:   solvers, see `KSPSetPC()`).

141:   This increases the reference count of the guess object, you must destroy the object with `KSPGuessDestroy()`
142:   before the end of the program.

144: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetUseFischerGuess()`, `KSPGetGuess()`
145: @*/
146: PetscErrorCode KSPSetGuess(KSP ksp, KSPGuess guess)
147: {
148:   PetscFunctionBegin;
151:   PetscCall(PetscObjectReference((PetscObject)guess));
152:   PetscCall(KSPGuessDestroy(&ksp->guess));
153:   ksp->guess      = guess;
154:   ksp->guess->ksp = ksp;
155:   PetscFunctionReturn(PETSC_SUCCESS);
156: }

158: /*@
159:   KSPGetGuess - Gets the initial guess generator for the `KSP`.

161:   Not Collective

163:   Input Parameter:
164: . ksp - the Krylov context

166:   Output Parameter:
167: . guess - the object

169:   Level: developer

171: .seealso: [](ch_ksp), `KSPGuess`, `KSP`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetUseFischerGuess()`, `KSPSetGuess()`
172: @*/
173: PetscErrorCode KSPGetGuess(KSP ksp, KSPGuess *guess)
174: {
175:   PetscFunctionBegin;
177:   PetscAssertPointer(guess, 2);
178:   if (!ksp->guess) {
179:     const char *prefix;

181:     PetscCall(KSPGuessCreate(PetscObjectComm((PetscObject)ksp), &ksp->guess));
182:     PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
183:     if (prefix) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ksp->guess, prefix));
184:     ksp->guess->ksp = ksp;
185:   }
186:   *guess = ksp->guess;
187:   PetscFunctionReturn(PETSC_SUCCESS);
188: }

190: /*@
191:   KSPGetOptionsPrefix - Gets the prefix used for searching for all
192:   `KSP` options in the database.

194:   Not Collective

196:   Input Parameter:
197: . ksp - the Krylov context

199:   Output Parameter:
200: . prefix - pointer to the prefix string used is returned

202:   Level: advanced

204: .seealso: [](ch_ksp), `KSP`, `KSPSetFromOptions()`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`
205: @*/
206: PetscErrorCode KSPGetOptionsPrefix(KSP ksp, const char *prefix[])
207: {
208:   PetscFunctionBegin;
210:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, prefix));
211:   PetscFunctionReturn(PETSC_SUCCESS);
212: }

214: static PetscErrorCode PetscViewerAndFormatCreate_Internal(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
215: {
216:   PetscFunctionBegin;
217:   PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
218:   (*vf)->data = ctx;
219:   PetscFunctionReturn(PETSC_SUCCESS);
220: }

222: /*@
223:   KSPMonitorSetFromOptions - Sets a monitor function, viewer, and viewer format based on the viewer specification in the options database

225:   Collective

227:   Input Parameters:
228: + ksp  - `KSP` object you wish to monitor
229: . opt  - the command line option for this monitor, for example `-ksp_monitor`
230: . name - the monitor type one is seeking, for example, `"preconditioned_residual"`
231: - ctx  - An optional application context for the monitor, or `NULL`

233:   Level: developer

235:   Note:
236:   See `PetscOptionsCreateViewer()` for details on the viewer specification, for example, `-ksp_monitor ascii:myfile::append`

238: .seealso: [](ch_ksp), `KSPMonitorRegister()`, `KSPMonitorSet()`, `PetscOptionsCreateViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
239:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`,
240:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
241:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
242:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
243:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
244:           `PetscOptionsFList()`, `PetscOptionsEList()`
245: @*/
246: PetscErrorCode KSPMonitorSetFromOptions(KSP ksp, const char opt[], const char name[], PetscCtx ctx)
247: {
248:   PetscErrorCode (*mfunc)(KSP, PetscInt, PetscReal, void *);
249:   PetscErrorCode (*cfunc)(PetscViewer, PetscViewerFormat, void *, PetscViewerAndFormat **);
250:   PetscErrorCode (*dfunc)(PetscViewerAndFormat **);
251:   PetscViewerAndFormat *vf;
252:   PetscViewer           viewer;
253:   PetscViewerFormat     format;
254:   PetscViewerType       vtype;
255:   char                  key[PETSC_MAX_PATH_LEN];
256:   PetscBool             all, flg;
257:   const char           *prefix = NULL;

259:   PetscFunctionBegin;
260:   PetscCall(PetscStrcmp(opt, "-all_ksp_monitor", &all));
261:   if (!all) PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
262:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)ksp), ((PetscObject)ksp)->options, prefix, opt, &viewer, &format, &flg));
263:   if (!flg) PetscFunctionReturn(PETSC_SUCCESS);

265:   PetscCall(PetscViewerGetType(viewer, &vtype));
266:   PetscCall(KSPMonitorMakeKey_Internal(name, vtype, format, key));
267:   PetscCall(PetscFunctionListFind(KSPMonitorList, key, &mfunc));
268:   PetscCall(PetscFunctionListFind(KSPMonitorCreateList, key, &cfunc));
269:   PetscCall(PetscFunctionListFind(KSPMonitorDestroyList, key, &dfunc));
270:   if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
271:   if (!dfunc) dfunc = PetscViewerAndFormatDestroy;

273:   PetscCall((*cfunc)(viewer, format, ctx, &vf));
274:   PetscCall(PetscViewerDestroy(&viewer));
275:   PetscCall(KSPMonitorSet(ksp, mfunc, vf, (PetscCtxDestroyFn *)dfunc));
276:   PetscFunctionReturn(PETSC_SUCCESS);
277: }

279: PETSC_INTERN PetscErrorCode KSPCheckPCMPI(KSP);

281: /*@
282:   KSPSetFromOptions - Sets `KSP` options from the options database.
283:   This routine must be called before `KSPSetUp()` if the user is to be
284:   allowed to set the Krylov type.

286:   Collective

288:   Input Parameter:
289: . ksp - the Krylov space context

291:   Options Database Keys:
292: + -ksp_rtol rtol                                                                          - relative tolerance used in default determination of convergence, i.e.
293:                                                                                             if residual norm decreases by this factor than convergence is declared
294: . -ksp_atol abstol                                                                        - absolute tolerance used in default convergence test, i.e. if residual
295:                                                                                             norm is less than this then convergence is declared
296: . -ksp_divtol tol                                                                         - if residual norm increases by this factor than divergence is declared
297: . -ksp_max_it maxits                                                                      - maximum number of linear iterations
298: . -ksp_min_it minits                                                                      - minimum number of linear iterations to use, defaults to zero
299: . -ksp_reuse_preconditioner (true|false)                                                  - reuse the previously computed preconditioner
300: . -ksp_converged_use_initial_residual_norm (true|false)                                   - see `KSPConvergedDefaultSetUIRNorm()`
301: . -ksp_converged_use_min_initial_residual_norm (true|false)                               - see `KSPConvergedDefaultSetUMIRNorm()`
302: . -ksp_converged_maxits (true|false)                                                      - see `KSPConvergedDefaultSetConvergedMaxits()`
303: . -ksp_norm_type (none|preconditioned|unpreconditioned|natural)                           - see `KSPSetNormType()`
304: . -ksp_check_norm_iteration it                                                            - do not compute residual norm until iteration number it (does compute at 0th iteration)
305:                                                                                             works only for `KSPBCGS`, `KSPIBCGS`, and `KSPCG`
306: . -ksp_lag_norm (true|false)                                                              - compute the norm of the residual for the ith iteration on the i+1 iteration;
307:                                                                                             this means that one can use the norm of the residual for convergence test WITHOUT
308:                                                                                             an extra `MPI_Allreduce()` limiting global synchronizations.
309:                                                                                             This will require 1 more iteration of the solver than usual.
310: . -ksp_guess_type (fischer|pod)                                                           - type of initial guess generator for repeated linear solves,
311:                                                                                             see `KSPGuessSetFromOptions()` for additional options to control initial guess generation
312: . -ksp_fischer_guess model,size                                                           - uses the Fischer initial guess generator for repeated linear solves
313: . -ksp_constant_null_space (true|false)                                                   - assume the operator (matrix) has the constant vector in its null space
314: . -ksp_test_null_space (true|false)                                                       - tests if the null space associated with the linear system operator of the `KSP` is actually a null space of the operator
315: . -ksp_knoll (true|false)                                                                 - compute initial guess by applying the preconditioner to the right-hand side
316: . -ksp_orthogonalization (cgs|mgs)                                                        - use either classical (default) or modified Gram-Schmidt to orthogonalize
317:                                                                                             the Krylov space basis vectors
318: . -ksp_orthogonalization_cgs_refinement_type (refine_never|refine_ifneeded|refine_always) - determine if iterative refinement is used to increase the stability of the
319:                                                                                             classical Gram-Schmidt orthogonalization
320: . -ksp_use_explicittranspose (true|false)                                                 - transpose the system explicitly in `KSPSolveTranspose()`
321: . -ksp_error_if_not_converged (true|false)                                                - stop the program as soon as an error is detected in `KSPSolve()`,
322:                                                                                             `KSP_DIVERGED_ITS` is not treated as an error on inner solves
323: . -ksp_monitor_cancel (true|false)                                                        - cancel all previous convergence monitor routines set
324: . -ksp_monitor viewer_specification                                                       - monitor the (preconditioned) residual norm
325: . -ksp_monitor_true_residual viewer_specification                                         - monitor the true l2 residual norm, see `KSPMonitorTrueResidual()`
326: . -ksp_monitor_solution viewer_specification                                              - monitor the solution
327: . -ksp_monitor_singular_value viewer_specification                                        - monitor the extreme singular values
328: . -ksp_monitor_range viewer_specification                                                 - monitor the range of values in the (preconditioned) residual
329: . -ksp_monitor_max viewer_specification                                                   - monitor the maximum value in the true residual
330: . -ksp_monitor_error viewer_specification                                                 - monitor the error or its l2 norm, see `KSPMonitorError()`, `KSPMonitorErrorDraw()`, and `KSPMonitorErrorDrawLG()`
331: . -ksp_monitor_pause_final (true|false)                                                   - pauses all draw monitors at the final iterate
332: . -all_ksp_monitor viewer_specification                                                   - monitor the (preconditioned) residual norm for all `KSP` solves, regardless of their prefix. This is
333:                                                                                             useful for `PCFIELDSPLIT`, `PCMG`, etc that have inner solvers and
334:                                                                                             you wish to track the convergence of all the solvers.
335: . -ksp_view_pre viewer_specification                                                      - view the `KSP` object before each `KSPSolve()`
336: . -ksp_view viewer_specification                                                          - view the `KSP` object after each `KSPSolve()`
337: . -ksp_converged_reason viewer_specification                                              - view the convergence state at the end of the solve
338: . -ksp_converged_rate viewer_specification                                                - view the computed convergence rate of the iterative solver
339: . -ksp_view_mat viewer_specification                                                      - view the matrix defining the linear system
340: . -ksp_view_pmat viewer_specification                                                     - view the matrix from which the preconditioner is constructed
341: . -ksp_view_rhs viewer_specification                                                      - view the right hand side of the linear system
342: . -ksp_view_solution viewer_specification                                                 - view the computed solution
343: . -ksp_view_mat_explicit viewer_specification                                             - view the matrix computed explicitly via `MatComputeOperator()`, useful when the operator is provided matrix-free
344: . -ksp_view_eigenvalues viewer_specification                                              - view the approximate eigenvalues of the preconditioned operator computed via `KSPComputeEigenvalues()`
345: . -ksp_view_singularvalues viewer_specification                                           - view the approximate singular values of the preconditioned operator computed via `KSPComputeExtremeSingularValues()`
346: . -ksp_view_eigenvalues_explicit viewer_specification                                     - view the approximate eigenvalues of the preconditioned operator computed with LAPACK
347: . -ksp_view_preconditioned_operator_explicit viewer_specification                         - view the preconditioned operator computed via `KSPComputeOperator()`
348: . -ksp_view_final_residual viewer_specification                                           - view the final true residual norm
349: - -ksp_view_final_residual_vec viewer_specification                                       - view the final true residual vector, must also use `-ksp_view_final_residual ascii:`

351:   Level: beginner

353:   Notes:
354:   See `PetscOptionsCreateViewer()` for the values of `viewer_specification`.

356:   The monitors are called at every iteration.

358:   Except for `-ksp_view_pre` all the `-ksp_view` viewers are called at the end of `KSPSolve()`.

360:   To see all options, run your program with the `-help` option or consult [](ch_ksp).

362: .seealso: [](ch_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPResetFromOptions()`, `KSPSetUseFischerGuess()`
363: @*/
364: PetscErrorCode KSPSetFromOptions(KSP ksp)
365: {
366:   const char *convtests[] = {"default", "skip", "lsqr"}, *orthogs[] = {"cgs", "mgs"}, *prefix;
367:   char        type[256], monfilename[PETSC_MAX_PATH_LEN];
368:   PetscBool   flg, flag, reuse, set;
369:   PetscInt    indx, model[2] = {0, 0}, nmax, max_it;
370:   KSPNormType normtype;
371:   PCSide      pcside;
372:   void       *ctx;
373:   MPI_Comm    comm;
374:   PetscReal   rtol, abstol, divtol;

376:   PetscFunctionBegin;

379:   PetscCall(PetscObjectGetComm((PetscObject)ksp, &comm));
380:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));

382:   PetscCall(KSPRegisterAll());
383:   PetscObjectOptionsBegin((PetscObject)ksp);
384:   PetscCall(PetscOptionsFList("-ksp_type", "Krylov method", "KSPSetType", KSPList, (char *)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES), type, sizeof(type), &flg));
385:   if (flg) PetscCall(KSPSetType(ksp, type));
386:   /*
387:     Set the type if it was never set.
388:   */
389:   if (!((PetscObject)ksp)->type_name) PetscCall(KSPSetType(ksp, KSPGMRES));

391:   PetscCall(KSPResetViewers(ksp));

393:   /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */
394:   PetscCall(PetscOptionsBool("-ksp_monitor_cancel", "Remove any hardwired monitor routines", "KSPMonitorCancel", PETSC_FALSE, &flg, &set));
395:   if (set && flg) PetscCall(KSPMonitorCancel(ksp));
396:   PetscCall(PetscOptionsDeprecated("-ksp_monitor_short", "-ksp_monitor", "3.26", NULL));
397:   PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor", "preconditioned_residual", NULL));
398:   PetscCall(KSPMonitorSetFromOptions(ksp, "-all_ksp_monitor", "preconditioned_residual", NULL));
399:   PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_range", "preconditioned_residual_range", NULL));
400:   PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_true_residual", "true_residual", NULL));
401:   PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_max", "true_residual_max", NULL));
402:   PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_solution", "solution", NULL));
403:   PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_singular_value", "singular_value", ksp));
404:   PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_error", "error", ksp));
405:   PetscCall(PetscOptionsBool("-ksp_monitor_pause_final", "Pauses all draw monitors at the final iterate", "KSPMonitorPauseFinal_Internal", PETSC_FALSE, &ksp->pauseFinal, NULL));
406:   PetscCall(PetscOptionsBool("-ksp_initial_guess_nonzero", "Use the contents of the solution vector for initial guess", "KSPSetInitialNonzero", ksp->guess_zero ? PETSC_FALSE : PETSC_TRUE, &flag, &flg));
407:   if (flg) PetscCall(KSPSetInitialGuessNonzero(ksp, flag));

409:   PetscCall(KSPGetReusePreconditioner(ksp, &reuse));
410:   PetscCall(PetscOptionsBool("-ksp_reuse_preconditioner", "Use initial preconditioner and don't ever compute a new one", "KSPReusePreconditioner", reuse, &reuse, NULL));
411:   PetscCall(KSPSetReusePreconditioner(ksp, reuse));
412:   PetscCall(PetscOptionsBool("-ksp_error_if_not_converged", "Generate error if solver does not converge", "KSPSetErrorIfNotConverged", ksp->errorifnotconverged, &ksp->errorifnotconverged, &set));
413:   if (set) PetscCall(KSPSetErrorIfNotConverged(ksp, ksp->errorifnotconverged));
414:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view", &ksp->viewer, &ksp->format, &ksp->view));
415:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_pre", &ksp->viewerPre, &ksp->formatPre, &ksp->viewPre));
416:   PetscCall(PetscViewerDestroy(&ksp->convergedreasonviewer));
417:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, ((PetscObject)ksp)->prefix, "-ksp_converged_reason", &ksp->convergedreasonviewer, &ksp->convergedreasonformat, NULL));
418:   flg = PETSC_FALSE;
419:   PetscCall(PetscOptionsBool("-ksp_converged_reason_view_cancel", "Cancel all the converged reason view functions set using KSPConvergedReasonViewSet", "KSPConvergedReasonViewCancel", PETSC_FALSE, &flg, &set));
420:   if (set && flg) PetscCall(KSPConvergedReasonViewCancel(ksp));
421:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat));
422:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat));
423:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs));
424:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol));
425:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp));
426:   PetscCall(PetscOptionsDeprecated("-ksp_final_residual", "-ksp_view_final_residual", "3.9", NULL));
427:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_final_residual", &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes));
428:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_preconditioned_operator_explicit", &ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp));
429:   nmax = ksp->nmax;
430:   PetscCall(PetscOptionsDeprecated("-ksp_matsolve_block_size", "-ksp_matsolve_batch_size", "3.15", NULL));
431:   PetscCall(PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg));
432:   if (flg) PetscCall(KSPSetMatSolveBatchSize(ksp, nmax));
433:   PetscCall(PetscObjectTypeCompare((PetscObject)ksp, KSPPREONLY, &flg));
434:   if (flg) goto skipoptions;

436:   rtol   = ksp->rtol;
437:   abstol = ksp->abstol;
438:   divtol = ksp->divtol;
439:   max_it = ksp->max_it;
440:   PetscCall(PetscOptionsReal("-ksp_rtol", "Relative decrease in residual norm", "KSPSetTolerances", ksp->rtol, &rtol, NULL));
441:   PetscCall(PetscOptionsReal("-ksp_atol", "Absolute value of residual norm", "KSPSetTolerances", ksp->abstol, &abstol, NULL));
442:   PetscCall(PetscOptionsReal("-ksp_divtol", "Residual norm increase cause divergence", "KSPSetTolerances", ksp->divtol, &divtol, NULL));
443:   PetscCall(PetscOptionsInt("-ksp_max_it", "Maximum number of iterations", "KSPSetTolerances", ksp->max_it, &max_it, &flg));
444:   PetscCall(KSPSetTolerances(ksp, rtol, abstol, divtol, max_it));
445:   PetscCall(PetscOptionsRangeInt("-ksp_min_it", "Minimum number of iterations", "KSPSetMinimumIterations", ksp->min_it, &ksp->min_it, NULL, 0, ksp->max_it));

447:   PetscCall(PetscOptionsBool("-ksp_converged_use_initial_residual_norm", "Use initial residual norm for computing relative convergence", "KSPConvergedDefaultSetUIRNorm", PETSC_FALSE, &flag, &set));
448:   if (set && flag) PetscCall(KSPConvergedDefaultSetUIRNorm(ksp));
449:   PetscCall(PetscOptionsBool("-ksp_converged_use_min_initial_residual_norm", "Use minimum of initial residual norm and b for computing relative convergence", "KSPConvergedDefaultSetUMIRNorm", PETSC_FALSE, &flag, &set));
450:   if (set && flag) PetscCall(KSPConvergedDefaultSetUMIRNorm(ksp));
451:   PetscCall(PetscOptionsBool("-ksp_converged_maxits", "Declare convergence if the maximum number of iterations is reached", "KSPConvergedDefaultSetConvergedMaxits", PETSC_FALSE, &flag, &set));
452:   if (set) PetscCall(KSPConvergedDefaultSetConvergedMaxits(ksp, flag));
453:   PetscCall(KSPGetConvergedNegativeCurvature(ksp, &flag));
454:   PetscCall(PetscOptionsBool("-ksp_converged_neg_curve", "Declare convergence if negative curvature is detected", "KSPConvergedNegativeCurvature", flag, &flag, &set));
455:   if (set) PetscCall(KSPSetConvergedNegativeCurvature(ksp, flag));

457:   PetscCall(PetscOptionsBool("-ksp_knoll", "Use preconditioner applied to b for initial guess", "KSPSetInitialGuessKnoll", ksp->guess_knoll, &ksp->guess_knoll, NULL));
458:   PetscCall(PetscOptionsFList("-ksp_guess_type", "Initial guess in Krylov method", NULL, KSPGuessList, NULL, type, sizeof(type), &flg));
459:   if (flg) {
460:     PetscCall(KSPGetGuess(ksp, &ksp->guess));
461:     PetscCall(KSPGuessSetType(ksp->guess, type));
462:     PetscCall(KSPGuessSetFromOptions(ksp->guess));
463:   } else { /* old option for KSP */
464:     nmax = 2;
465:     PetscCall(PetscOptionsIntArray("-ksp_fischer_guess", "Use Paul Fischer's algorithm or its variants for initial guess", "KSPSetUseFischerGuess", model, &nmax, &flag));
466:     if (flag) {
467:       PetscCheck(nmax == 2, comm, PETSC_ERR_ARG_OUTOFRANGE, "Must pass in model,size as arguments");
468:       PetscCall(KSPSetUseFischerGuess(ksp, model[0], model[1]));
469:     }
470:   }

472:   PetscCall(PetscOptionsEList("-ksp_convergence_test", "Convergence test", "KSPSetConvergenceTest", convtests, 3, "default", &indx, &flg));
473:   if (flg) {
474:     switch (indx) {
475:     case 0:
476:       PetscCall(KSPConvergedDefaultCreate(&ctx));
477:       PetscCall(KSPSetConvergenceTest(ksp, KSPConvergedDefault, ctx, KSPConvergedDefaultDestroy));
478:       break;
479:     case 1:
480:       PetscCall(KSPSetConvergenceTest(ksp, KSPConvergedSkip, NULL, NULL));
481:       break;
482:     case 2:
483:       PetscCall(KSPConvergedDefaultCreate(&ctx));
484:       PetscCall(KSPSetConvergenceTest(ksp, KSPLSQRConvergedDefault, ctx, KSPConvergedDefaultDestroy));
485:       break;
486:     }
487:   }

489:   PetscCall(KSPSetUpNorms_Private(ksp, PETSC_FALSE, &normtype, NULL));
490:   PetscCall(PetscOptionsEnum("-ksp_norm_type", "KSP Norm type", "KSPSetNormType", KSPNormTypes, (PetscEnum)normtype, (PetscEnum *)&normtype, &flg));
491:   if (flg) PetscCall(KSPSetNormType(ksp, normtype));

493:   PetscCall(PetscOptionsInt("-ksp_check_norm_iteration", "First iteration to compute residual norm", "KSPSetCheckNormIteration", ksp->chknorm, &ksp->chknorm, NULL));

495:   PetscCall(PetscOptionsBool("-ksp_lag_norm", "Lag the calculation of the residual norm", "KSPSetLagNorm", ksp->lagnorm, &flag, &flg));
496:   if (flg) PetscCall(KSPSetLagNorm(ksp, flag));

498:   PetscCall(PetscOptionsBool("-ksp_constant_null_space", "Add constant null space to Krylov solver matrix", "MatSetNullSpace", PETSC_FALSE, &flg, &set));
499:   if (set && flg) {
500:     MatNullSpace nsp;
501:     Mat          Amat = NULL;

503:     PetscCall(MatNullSpaceCreate(comm, PETSC_TRUE, 0, NULL, &nsp));
504:     if (ksp->pc) PetscCall(PCGetOperators(ksp->pc, &Amat, NULL));
505:     PetscCheck(Amat, comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot set nullspace, matrix has not yet been provided");
506:     PetscCall(MatSetNullSpace(Amat, nsp));
507:     PetscCall(MatNullSpaceDestroy(&nsp));
508:   }

510:   PetscCall(PetscOptionsDeprecated("-ksp_gmres_classicalgramschmidt", NULL, "3.26", "Use -ksp_orthogonalization cgs"));
511:   PetscCall(PetscOptionsDeprecated("-ksp_gmres_modifiedgramschmidt", NULL, "3.26", "Use -ksp_orthogonalization mgs"));
512:   PetscCall(PetscOptionsGetBool(((PetscObject)ksp)->options, prefix, "-ksp_gmres_classicalgramschmidt", &flg, &set));
513:   if (set && flg) PetscCall(KSPOrthogonalizationSet(ksp, KSPOrthogonalizationClassicalGramSchmidt));
514:   PetscCall(PetscOptionsGetBool(((PetscObject)ksp)->options, prefix, "-ksp_gmres_modifiedgramschmidt", &flg, &set));
515:   if (set && flg) PetscCall(KSPOrthogonalizationSet(ksp, KSPOrthogonalizationModifiedGramSchmidt));
516:   PetscCall(PetscOptionsEList("-ksp_orthogonalization", "Orthogonalization method", "KSPOrthogonalizationSet", orthogs, 2, "cgs", &indx, &flg));
517:   if (flg) {
518:     switch (indx) {
519:     case 0:
520:       PetscCall(KSPOrthogonalizationSet(ksp, KSPOrthogonalizationClassicalGramSchmidt));
521:       break;
522:     case 1:
523:       PetscCall(KSPOrthogonalizationSet(ksp, KSPOrthogonalizationModifiedGramSchmidt));
524:       break;
525:     }
526:   }
527:   PetscCall(PetscOptionsDeprecated("-ksp_gmres_cgs_refinement_type", "-ksp_orthogonalization_cgs_refinement_type", "3.26", NULL));
528:   PetscCall(PetscOptionsEnum("-ksp_orthogonalization_cgs_refinement_type", "Type of iterative refinement for classical (unmodified) Gram-Schmidt", "KSPOrthogonalizationSetCGSRefinementType", KSPOrthogonalizationCGSRefinementTypes, (PetscEnum)ksp->cgstype,
529:                              (PetscEnum *)&ksp->cgstype, &flg));

531:   flg = PETSC_FALSE;
532:   if (ksp->pc) {
533:     PetscCall(PetscObjectTypeCompare((PetscObject)ksp->pc, PCKSP, &flg));
534:     if (!flg) PetscCall(PetscObjectTypeCompare((PetscObject)ksp->pc, PCBJACOBI, &flg));
535:     if (!flg) PetscCall(PetscObjectTypeCompare((PetscObject)ksp->pc, PCDEFLATION, &flg));
536:   }

538:   if (flg) {
539:     /* Using dynamic tolerance in preconditioner */
540:     PetscCall(PetscOptionsString("-sub_ksp_dynamic_tolerance", "Use dynamic tolerance for inner PC", "KSPMonitorDynamicTolerance", "stdout", monfilename, sizeof(monfilename), &flg));
541:     if (flg) {
542:       void     *scale;
543:       PetscReal coeff = 1.0;

545:       PetscCall(KSPMonitorDynamicToleranceCreate(&scale));
546:       PetscCall(PetscOptionsReal("-sub_ksp_dynamic_tolerance", "Coefficient of dynamic tolerance for inner PC", "KSPMonitorDynamicTolerance", coeff, &coeff, &flg));
547:       if (flg) PetscCall(KSPMonitorDynamicToleranceSetCoefficient(scale, coeff));
548:       PetscCall(KSPMonitorSet(ksp, KSPMonitorDynamicTolerance, scale, KSPMonitorDynamicToleranceDestroy));
549:     }
550:   }

552:   /*
553:    Calls Python function
554:   */
555:   PetscCall(PetscOptionsString("-ksp_monitor_python", "Use Python function", "KSPMonitorSet", NULL, monfilename, sizeof(monfilename), &flg));
556:   if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)ksp, monfilename));
557:   /*
558:     Graphically plots preconditioned residual norm and range of residual element values
559:   */
560:   PetscCall(PetscOptionsBool("-ksp_monitor_lg_range", "Monitor graphically range of preconditioned residual norm", "KSPMonitorSet", PETSC_FALSE, &flg, &set));
561:   if (set && flg) {
562:     PetscViewer ctx;

564:     PetscCall(PetscViewerDrawOpen(comm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx));
565:     PetscCall(KSPMonitorSet(ksp, KSPMonitorLGRange, ctx, (PetscCtxDestroyFn *)PetscViewerDestroy));
566:   }
567:   /* TODO Do these show up in help? */
568:   PetscCall(PetscOptionsHasName(((PetscObject)ksp)->options, prefix, "-ksp_converged_rate", &flg));
569:   if (flg) {
570:     const char *RateTypes[] = {"default", "residual", "error", "PetscRateType", "RATE_", NULL};
571:     PetscEnum   rtype       = (PetscEnum)1;

573:     PetscCall(PetscOptionsGetEnum(((PetscObject)ksp)->options, prefix, "-ksp_converged_rate_type", RateTypes, &rtype, &flg));
574:     if (rtype == (PetscEnum)0 || rtype == (PetscEnum)1) PetscCall(KSPSetResidualHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE));
575:     if (rtype == (PetscEnum)0 || rtype == (PetscEnum)2) PetscCall(KSPSetErrorHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE));
576:   }

578:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_converged_rate", &ksp->viewerRate, &ksp->formatRate, &ksp->viewRate));
579:   PetscCall(PetscOptionsDeprecated("-ksp_compute_eigenvalues", "-ksp_view_eigenvalues", "3.9", NULL));
580:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_eigenvalues", &ksp->viewerEV, &ksp->formatEV, &ksp->viewEV));
581:   PetscCall(PetscOptionsDeprecated("-ksp_compute_singularvalues", "-ksp_view_singularvalues", "3.9", NULL));
582:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_singularvalues", &ksp->viewerSV, &ksp->formatSV, &ksp->viewSV));
583:   PetscCall(PetscOptionsDeprecated("-ksp_compute_eigenvalues_explicitly", "-ksp_view_eigenvalues_explicit", "3.9", NULL));
584:   PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_eigenvalues_explicit", &ksp->viewerEVExp, &ksp->formatEVExp, &ksp->viewEVExp));

586: #if PetscDefined(HAVE_SAWS)
587:   /*
588:     Publish convergence information using AMS
589:   */
590:   PetscCall(PetscOptionsBool("-ksp_monitor_saws", "Publish KSP progress using SAWs", "KSPMonitorSet", PETSC_FALSE, &flg, &set));
591:   if (set && flg) {
592:     PetscCtx ctx;
593:     PetscCall(KSPMonitorSAWsCreate(ksp, &ctx));
594:     PetscCall(KSPMonitorSet(ksp, KSPMonitorSAWs, ctx, KSPMonitorSAWsDestroy));
595:     PetscCall(KSPSetComputeSingularValues(ksp, PETSC_TRUE));
596:   }
597: #endif

599:   PetscCall(KSPSetUpNorms_Private(ksp, PETSC_FALSE, NULL, &pcside));
600:   PetscCall(PetscOptionsEnum("-ksp_pc_side", "KSP preconditioner side", "KSPSetPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg));
601:   if (flg) PetscCall(KSPSetPCSide(ksp, pcside));

603:   if (ksp->viewSV || ksp->viewEV) PetscCall(KSPSetComputeSingularValues(ksp, PETSC_TRUE));

605: #if PetscDefined(HAVE_SAWS)
606:   {
607:     PetscBool set;
608:     flg = PETSC_FALSE;
609:     PetscCall(PetscOptionsBool("-ksp_saws_block", "Block for SAWs at end of KSPSolve", "PetscObjectSAWsBlock", ((PetscObject)ksp)->amspublishblock, &flg, &set));
610:     if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)ksp, flg));
611:   }
612: #endif

614:   flg = PETSC_FALSE;
615:   PetscCall(PetscOptionsBool("-ksp_use_explicittranspose", "Explicitly transpose the system in KSPSolveTranspose() and KSPMatSolveTranspose()", "KSPSetUseExplicitTranspose", ksp->transpose.use_explicittranspose, &flg, &set));
616:   if (set) PetscCall(KSPSetUseExplicitTranspose(ksp, flg));

618:   PetscTryTypeMethod(ksp, setfromoptions, PetscOptionsObject);
619: skipoptions:
620:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
621:   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)ksp, PetscOptionsObject));
622:   PetscOptionsEnd();
623:   ksp->setfromoptionscalled++;

625:   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
626:   if (!ksp->skippcsetfromoptions) PetscCall(PCSetFromOptions(ksp->pc));
627:   PetscFunctionReturn(PETSC_SUCCESS);
628: }

630: /*@
631:   KSPResetFromOptions - Sets `KSP` parameters from user options ONLY if the `KSP` was previously set from options

633:   Collective

635:   Input Parameter:
636: . ksp - the `KSP` context

638:   Level: advanced

640: .seealso: [](ch_ksp), `KSPSetFromOptions()`, `KSPSetOptionsPrefix()`
641: @*/
642: PetscErrorCode KSPResetFromOptions(KSP ksp)
643: {
644:   PetscFunctionBegin;
645:   if (ksp->setfromoptionscalled) PetscCall(KSPSetFromOptions(ksp));
646:   PetscFunctionReturn(PETSC_SUCCESS);
647: }