Actual source code: itcl.c


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

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

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

 13:    Logically Collective

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

 19:    Level: advanced

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

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

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

 39: .seealso: [](chapter_ksp), `KSP`, `KSPAppendOptionsPrefix()`, `KSPGetOptionsPrefix()`, `KSPSetFromOptions()`
 40: @*/
 41: PetscErrorCode KSPSetOptionsPrefix(KSP ksp, const char prefix[])
 42: {
 44:   if (!ksp->pc) KSPGetPC(ksp, &ksp->pc);
 45:   PCSetOptionsPrefix(ksp->pc, prefix);
 46:   PetscObjectSetOptionsPrefix((PetscObject)ksp, prefix);
 47:   return 0;
 48: }

 50: /*@C
 51:    KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
 52:    `KSP` options in the database.

 54:    Logically Collective

 56:    Input Parameters:
 57: +  ksp - the Krylov context
 58: -  prefix - the prefix string to prepend to all `KSP` option requests

 60:    Notes:
 61:    A hyphen (-) must NOT be given at the beginning of the prefix name.
 62:    The first character of all runtime options is AUTOMATICALLY the hyphen.

 64:    Level: advanced

 66: .seealso: [](chapter_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPGetOptionsPrefix()`, `KSPSetFromOptions()`
 67: @*/
 68: PetscErrorCode KSPAppendOptionsPrefix(KSP ksp, const char prefix[])
 69: {
 71:   if (!ksp->pc) KSPGetPC(ksp, &ksp->pc);
 72:   PCAppendOptionsPrefix(ksp->pc, prefix);
 73:   PetscObjectAppendOptionsPrefix((PetscObject)ksp, prefix);
 74:   return 0;
 75: }

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

 80:    Logically Collective

 82:    Input Parameters:
 83: +  ksp - the Krylov context
 84: .  model - use model 1, model 2, model 3, or any other number to turn it off
 85: -  size - size of subspace used to generate initial guess

 87:     Options Database Key:
 88: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves

 90:    Level: advanced

 92: .seealso: [](chapter_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetUseFischerGuess()`, `KSPSetGuess()`, `KSPGetGuess()`, `KSPGuess`
 93: @*/
 94: PetscErrorCode KSPSetUseFischerGuess(KSP ksp, PetscInt model, PetscInt size)
 95: {
 96:   KSPGuess guess;

101:   KSPGetGuess(ksp, &guess);
102:   KSPGuessSetType(guess, KSPGUESSFISCHER);
103:   KSPGuessFischerSetModel(guess, model, size);
104:   return 0;
105: }

107: /*@
108:    KSPSetGuess - Set the initial guess object

110:    Logically Collective

112:    Input Parameters:
113: +  ksp - the Krylov context
114: -  guess - the object created with `KSPGuessCreate()`

116:    Level: advanced

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

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

125: .seealso: [](chapter_ksp), `KSP`, `KSPGuess`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetUseFischerGuess()`, `KSPGetGuess()`
126: @*/
127: PetscErrorCode KSPSetGuess(KSP ksp, KSPGuess guess)
128: {
131:   PetscObjectReference((PetscObject)guess);
132:   KSPGuessDestroy(&ksp->guess);
133:   ksp->guess      = guess;
134:   ksp->guess->ksp = ksp;
135:   return 0;
136: }

138: /*@
139:    KSPGetGuess - Gets the initial guess generator for the `KSP`.

141:    Not Collective

143:    Input Parameters:
144: .  ksp - the Krylov context

146:    Output Parameters:
147: .   guess - the object

149:    Level: developer

151: .seealso: [](chapter_ksp), `KSPGuess`, `KSP`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetUseFischerGuess()`, `KSPSetGuess()`
152: @*/
153: PetscErrorCode KSPGetGuess(KSP ksp, KSPGuess *guess)
154: {
157:   if (!ksp->guess) {
158:     const char *prefix;

160:     KSPGuessCreate(PetscObjectComm((PetscObject)ksp), &ksp->guess);
161:     PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
162:     if (prefix) PetscObjectSetOptionsPrefix((PetscObject)ksp->guess, prefix);
163:     ksp->guess->ksp = ksp;
164:   }
165:   *guess = ksp->guess;
166:   return 0;
167: }

169: /*@C
170:    KSPGetOptionsPrefix - Gets the prefix used for searching for all
171:    `KSP` options in the database.

173:    Not Collective

175:    Input Parameters:
176: .  ksp - the Krylov context

178:    Output Parameters:
179: .  prefix - pointer to the prefix string used is returned

181:    Notes:
182:     On the fortran side, the user should pass in a string 'prefix' of
183:    sufficient length to hold the prefix.

185:    Level: advanced

187: .seealso: [](chapter_ksp), `KSP`, `KSPSetFromOptions()`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`
188: @*/
189: PetscErrorCode KSPGetOptionsPrefix(KSP ksp, const char *prefix[])
190: {
192:   PetscObjectGetOptionsPrefix((PetscObject)ksp, prefix);
193:   return 0;
194: }

196: static PetscErrorCode PetscViewerAndFormatCreate_Internal(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
197: {
198:   PetscViewerAndFormatCreate(viewer, format, vf);
199:   (*vf)->data = ctx;
200:   return 0;
201: }

203: /*@C
204:    KSPMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user in the options database

206:    Collective

208:    Input Parameters:
209: +  ksp  - `KSP` object you wish to monitor
210: .  opt  - the command line option for this monitor
211: .  name - the monitor type one is seeking
212: -  ctx  - An optional user context for the monitor, or NULL

214:    Level: developer

216: .seealso: [](chapter_ksp), `KSPMonitorRegister()`, `KSPMonitorSet()`, `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
217:           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
218:           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
219:           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
220:           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
221:           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
222:           `PetscOptionsFList()`, `PetscOptionsEList()`
223: @*/
224: PetscErrorCode KSPMonitorSetFromOptions(KSP ksp, const char opt[], const char name[], void *ctx)
225: {
226:   PetscErrorCode (*mfunc)(KSP, PetscInt, PetscReal, void *);
227:   PetscErrorCode (*cfunc)(PetscViewer, PetscViewerFormat, void *, PetscViewerAndFormat **);
228:   PetscErrorCode (*dfunc)(PetscViewerAndFormat **);
229:   PetscViewerAndFormat *vf;
230:   PetscViewer           viewer;
231:   PetscViewerFormat     format;
232:   PetscViewerType       vtype;
233:   char                  key[PETSC_MAX_PATH_LEN];
234:   PetscBool             all, flg;
235:   const char           *prefix = NULL;

237:   PetscStrcmp(opt, "-all_ksp_monitor", &all);
238:   if (!all) PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
239:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ksp), ((PetscObject)ksp)->options, prefix, opt, &viewer, &format, &flg);
240:   if (!flg) return 0;

242:   PetscViewerGetType(viewer, &vtype);
243:   KSPMonitorMakeKey_Internal(name, vtype, format, key);
244:   PetscFunctionListFind(KSPMonitorList, key, &mfunc);
245:   PetscFunctionListFind(KSPMonitorCreateList, key, &cfunc);
246:   PetscFunctionListFind(KSPMonitorDestroyList, key, &dfunc);
247:   if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
248:   if (!dfunc) dfunc = PetscViewerAndFormatDestroy;

250:   (*cfunc)(viewer, format, ctx, &vf);
251:   PetscObjectDereference((PetscObject)viewer);
252:   KSPMonitorSet(ksp, mfunc, vf, (PetscErrorCode(*)(void **))dfunc);
253:   return 0;
254: }

256: /*@
257:    KSPSetFromOptions - Sets `KSP` options from the options database.
258:    This routine must be called before `KSPSetUp()` if the user is to be
259:    allowed to set the Krylov type.

261:    Collective

263:    Input Parameter:
264: .  ksp - the Krylov space context

266:    Options Database Keys:
267: +   -ksp_max_it - maximum number of linear iterations
268: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
269:                 if residual norm decreases by this factor than convergence is declared
270: .   -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
271:                 norm is less than this then convergence is declared
272: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
273: .   -ksp_converged_use_initial_residual_norm - see `KSPConvergedDefaultSetUIRNorm()`
274: .   -ksp_converged_use_min_initial_residual_norm - see `KSPConvergedDefaultSetUMIRNorm()`
275: .   -ksp_converged_maxits - see `KSPConvergedDefaultSetConvergedMaxits()`
276: .   -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
277:                        convergence test (say you always want to run with 5 iterations) to
278:                        save on communication overhead
279:                     preconditioned - default for left preconditioning
280:                     unpreconditioned - see `KSPSetNormType()`
281:                     natural - see `KSPSetNormType()`
282: .   -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
283:        works only for `KSPBCGS`, `KSPIBCGS` and and `KSPCG`
284: .   -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
285:        the norm of the residual for convergence test WITHOUT an extra `MPI_Allreduce()` limiting global synchronizations.
286:        This will require 1 more iteration of the solver than usual.
287: .   -ksp_guess_type - Type of initial guess generator for repeated linear solves
288: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
289: .   -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
290: .   -ksp_test_null_space - tests the null space set with `MatSetNullSpace()` to see if it truly is a null space
291: .   -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
292: .   -ksp_monitor_cancel - cancel all previous convergene monitor routines set
293: .   -ksp_monitor - print residual norm at each iteration
294: .   -ksp_monitor draw::draw_lg - plot residual norm at each iteration
295: .   -ksp_monitor_true_residual - print true residual norm at each iteration
296: .   -all_ksp_monitor <optional filename> - print residual norm at each iteration for ALL KSP solves, regardless of their prefix. This is
297:                                            useful for `PCFIELDSPLIT`, `PCMG`, etc that have inner solvers and you wish to track the convergence of all the solvers
298: .   -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration
299: .   -ksp_monitor_singular_value - monitor extreme singular values at each iteration
300: .   -ksp_converged_reason - view the convergence state at the end of the solve
301: .   -ksp_use_explicittranspose - transpose the system explicitly in KSPSolveTranspose
302: .   -ksp_error_if_not_converged - stop the program as soon as an error is detected in a `KSPSolve()`, `KSP_DIVERGED_ITS` is not treated as an error on inner solves
303: -   -ksp_converged_rate - view the convergence rate at the end of the solve

305:    Notes:
306:    To see all options, run your program with the -help option
307:    or consult [](chapter_ksp)

309:    Level: beginner

311: .seealso: [](chapter_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPResetFromOptions()`, `KSPSetUseFischerGuess()`
312: @*/
313: PetscErrorCode KSPSetFromOptions(KSP ksp)
314: {
315:   const char *convtests[] = {"default", "skip", "lsqr"}, *prefix;
316:   char        type[256], guesstype[256], monfilename[PETSC_MAX_PATH_LEN];
317:   PetscBool   flg, flag, reuse, set;
318:   PetscInt    indx, model[2] = {0, 0}, nmax;
319:   KSPNormType normtype;
320:   PCSide      pcside;
321:   void       *ctx;
322:   MPI_Comm    comm;

325:   PetscObjectGetComm((PetscObject)ksp, &comm);
326:   PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix);
327:   if (!ksp->skippcsetfromoptions) {
328:     if (!ksp->pc) KSPGetPC(ksp, &ksp->pc);
329:     PCSetFromOptions(ksp->pc);
330:   }

332:   KSPRegisterAll();
333:   PetscObjectOptionsBegin((PetscObject)ksp);
334:   PetscOptionsFList("-ksp_type", "Krylov method", "KSPSetType", KSPList, (char *)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES), type, 256, &flg);
335:   if (flg) KSPSetType(ksp, type);
336:   /*
337:     Set the type if it was never set.
338:   */
339:   if (!((PetscObject)ksp)->type_name) KSPSetType(ksp, KSPGMRES);

341:   KSPResetViewers(ksp);

343:   /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */
344:   PetscOptionsBool("-ksp_monitor_cancel", "Remove any hardwired monitor routines", "KSPMonitorCancel", PETSC_FALSE, &flg, &set);
345:   if (set && flg) KSPMonitorCancel(ksp);
346:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor", "preconditioned_residual", NULL);
347:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_short", "preconditioned_residual_short", NULL);
348:   KSPMonitorSetFromOptions(ksp, "-all_ksp_monitor", "preconditioned_residual", NULL);
349:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_range", "preconditioned_residual_range", NULL);
350:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_true_residual", "true_residual", NULL);
351:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_max", "true_residual_max", NULL);
352:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_solution", "solution", NULL);
353:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_singular_value", "singular_value", ksp);
354:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_error", "error", ksp);
355:   PetscOptionsBool("-ksp_monitor_pause_final", "Pauses all draw monitors at the final iterate", "KSPMonitorPauseFinal_Internal", PETSC_FALSE, &ksp->pauseFinal, NULL);
356:   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);
357:   if (flg) KSPSetInitialGuessNonzero(ksp, flag);

359:   PetscObjectTypeCompare((PetscObject)ksp, KSPPREONLY, &flg);
360:   if (flg) {
361:     KSPGetReusePreconditioner(ksp, &reuse);
362:     PetscOptionsBool("-ksp_reuse_preconditioner", "Use initial preconditioner and don't ever compute a new one", "KSPReusePreconditioner", reuse, &reuse, NULL);
363:     KSPSetReusePreconditioner(ksp, reuse);
364:     PetscOptionsBool("-ksp_error_if_not_converged", "Generate error if solver does not converge", "KSPSetErrorIfNotConverged", ksp->errorifnotconverged, &ksp->errorifnotconverged, NULL);
365:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view", &ksp->viewer, &ksp->format, &ksp->view);
366:     flg = PETSC_FALSE;
367:     PetscOptionsBool("-ksp_converged_reason_view_cancel", "Cancel all the converged reason view functions set using KSPConvergedReasonViewSet", "KSPConvergedReasonViewCancel", PETSC_FALSE, &flg, &set);
368:     if (set && flg) KSPConvergedReasonViewCancel(ksp);
369:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat);
370:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat);
371:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs);
372:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol);
373:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp);
374:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_final_residual", &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes);
375:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_preconditioned_operator_explicit", &ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp);
376:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_diagonal_scale", &ksp->viewerDScale, &ksp->formatDScale, &ksp->viewDScale);

378:     KSPGetDiagonalScale(ksp, &flag);
379:     PetscOptionsBool("-ksp_diagonal_scale", "Diagonal scale matrix before building preconditioner", "KSPSetDiagonalScale", flag, &flag, &flg);
380:     if (flg) KSPSetDiagonalScale(ksp, flag);
381:     KSPGetDiagonalScaleFix(ksp, &flag);
382:     PetscOptionsBool("-ksp_diagonal_scale_fix", "Fix diagonally scaled matrix after solve", "KSPSetDiagonalScaleFix", flag, &flag, &flg);
383:     if (flg) KSPSetDiagonalScaleFix(ksp, flag);
384:     nmax = ksp->nmax;
385:     PetscOptionsDeprecated("-ksp_matsolve_block_size", "-ksp_matsolve_batch_size", "3.15", NULL);
386:     PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg);
387:     if (flg) KSPSetMatSolveBatchSize(ksp, nmax);
388:     goto skipoptions;
389:   }

391:   PetscOptionsInt("-ksp_max_it", "Maximum number of iterations", "KSPSetTolerances", ksp->max_it, &ksp->max_it, NULL);
392:   PetscOptionsReal("-ksp_rtol", "Relative decrease in residual norm", "KSPSetTolerances", ksp->rtol, &ksp->rtol, NULL);
393:   PetscOptionsReal("-ksp_atol", "Absolute value of residual norm", "KSPSetTolerances", ksp->abstol, &ksp->abstol, NULL);
394:   PetscOptionsReal("-ksp_divtol", "Residual norm increase cause divergence", "KSPSetTolerances", ksp->divtol, &ksp->divtol, NULL);

396:   PetscOptionsBool("-ksp_converged_use_initial_residual_norm", "Use initial residual norm for computing relative convergence", "KSPConvergedDefaultSetUIRNorm", PETSC_FALSE, &flag, &set);
397:   if (set && flag) KSPConvergedDefaultSetUIRNorm(ksp);
398:   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);
399:   if (set && flag) KSPConvergedDefaultSetUMIRNorm(ksp);
400:   PetscOptionsBool("-ksp_converged_maxits", "Declare convergence if the maximum number of iterations is reached", "KSPConvergedDefaultSetConvergedMaxits", PETSC_FALSE, &flag, &set);
401:   if (set) KSPConvergedDefaultSetConvergedMaxits(ksp, flag);
402:   KSPGetReusePreconditioner(ksp, &reuse);
403:   PetscOptionsBool("-ksp_reuse_preconditioner", "Use initial preconditioner and don't ever compute a new one", "KSPReusePreconditioner", reuse, &reuse, NULL);
404:   KSPSetReusePreconditioner(ksp, reuse);

406:   PetscOptionsBool("-ksp_knoll", "Use preconditioner applied to b for initial guess", "KSPSetInitialGuessKnoll", ksp->guess_knoll, &ksp->guess_knoll, NULL);
407:   PetscOptionsBool("-ksp_error_if_not_converged", "Generate error if solver does not converge", "KSPSetErrorIfNotConverged", ksp->errorifnotconverged, &ksp->errorifnotconverged, NULL);
408:   PetscOptionsFList("-ksp_guess_type", "Initial guess in Krylov method", NULL, KSPGuessList, NULL, guesstype, 256, &flg);
409:   if (flg) {
410:     KSPGetGuess(ksp, &ksp->guess);
411:     KSPGuessSetType(ksp->guess, guesstype);
412:     KSPGuessSetFromOptions(ksp->guess);
413:   } else { /* old option for KSP */
414:     nmax = 2;
415:     PetscOptionsIntArray("-ksp_fischer_guess", "Use Paul Fischer's algorithm or its variants for initial guess", "KSPSetUseFischerGuess", model, &nmax, &flag);
416:     if (flag) {
418:       KSPSetUseFischerGuess(ksp, model[0], model[1]);
419:     }
420:   }

422:   PetscOptionsEList("-ksp_convergence_test", "Convergence test", "KSPSetConvergenceTest", convtests, 3, "default", &indx, &flg);
423:   if (flg) {
424:     switch (indx) {
425:     case 0:
426:       KSPConvergedDefaultCreate(&ctx);
427:       KSPSetConvergenceTest(ksp, KSPConvergedDefault, ctx, KSPConvergedDefaultDestroy);
428:       break;
429:     case 1:
430:       KSPSetConvergenceTest(ksp, KSPConvergedSkip, NULL, NULL);
431:       break;
432:     case 2:
433:       KSPConvergedDefaultCreate(&ctx);
434:       KSPSetConvergenceTest(ksp, KSPLSQRConvergedDefault, ctx, KSPConvergedDefaultDestroy);
435:       break;
436:     }
437:   }

439:   KSPSetUpNorms_Private(ksp, PETSC_FALSE, &normtype, NULL);
440:   PetscOptionsEnum("-ksp_norm_type", "KSP Norm type", "KSPSetNormType", KSPNormTypes, (PetscEnum)normtype, (PetscEnum *)&normtype, &flg);
441:   if (flg) KSPSetNormType(ksp, normtype);

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

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

448:   KSPGetDiagonalScale(ksp, &flag);
449:   PetscOptionsBool("-ksp_diagonal_scale", "Diagonal scale matrix before building preconditioner", "KSPSetDiagonalScale", flag, &flag, &flg);
450:   if (flg) KSPSetDiagonalScale(ksp, flag);
451:   KSPGetDiagonalScaleFix(ksp, &flag);
452:   PetscOptionsBool("-ksp_diagonal_scale_fix", "Fix diagonally scaled matrix after solve", "KSPSetDiagonalScaleFix", flag, &flag, &flg);
453:   if (flg) KSPSetDiagonalScaleFix(ksp, flag);

455:   PetscOptionsBool("-ksp_constant_null_space", "Add constant null space to Krylov solver matrix", "MatSetNullSpace", PETSC_FALSE, &flg, &set);
456:   if (set && flg) {
457:     MatNullSpace nsp;
458:     Mat          Amat = NULL;

460:     MatNullSpaceCreate(comm, PETSC_TRUE, 0, NULL, &nsp);
461:     if (ksp->pc) PCGetOperators(ksp->pc, &Amat, NULL);
462:     if (Amat) {
463:       MatSetNullSpace(Amat, nsp);
464:       MatNullSpaceDestroy(&nsp);
465:     } else SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot set nullspace, matrix has not yet been provided");
466:   }

468:   flg = PETSC_FALSE;
469:   if (ksp->pc) {
470:     PetscObjectTypeCompare((PetscObject)ksp->pc, PCKSP, &flg);
471:     if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc, PCBJACOBI, &flg);
472:     if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc, PCDEFLATION, &flg);
473:   }

475:   if (flg) {
476:     /* A hack for using dynamic tolerance in preconditioner */
477:     PetscOptionsString("-sub_ksp_dynamic_tolerance", "Use dynamic tolerance for PC if PC is a KSP", "KSPMonitorDynamicTolerance", "stdout", monfilename, sizeof(monfilename), &flg);
478:     if (flg) {
479:       KSPDynTolCtx *scale;
480:       PetscMalloc1(1, &scale);
481:       scale->bnrm = -1.0;
482:       scale->coef = 1.0;
483:       PetscOptionsReal("-sub_ksp_dynamic_tolerance_param", "Parameter of dynamic tolerance for inner PCKSP", "KSPMonitorDynamicToleranceParam", scale->coef, &scale->coef, &flg);
484:       KSPMonitorSet(ksp, KSPMonitorDynamicTolerance, scale, KSPMonitorDynamicToleranceDestroy);
485:     }
486:   }

488:   /*
489:    Calls Python function
490:   */
491:   PetscOptionsString("-ksp_monitor_python", "Use Python function", "KSPMonitorSet", NULL, monfilename, sizeof(monfilename), &flg);
492:   if (flg) PetscPythonMonitorSet((PetscObject)ksp, monfilename);
493:   /*
494:     Graphically plots preconditioned residual norm and range of residual element values
495:   */
496:   PetscOptionsBool("-ksp_monitor_lg_range", "Monitor graphically range of preconditioned residual norm", "KSPMonitorSet", PETSC_FALSE, &flg, &set);
497:   if (set && flg) {
498:     PetscViewer ctx;

500:     PetscViewerDrawOpen(comm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx);
501:     KSPMonitorSet(ksp, KSPMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy);
502:   }
503:   /* TODO Do these show up in help? */
504:   PetscOptionsHasName(((PetscObject)ksp)->options, prefix, "-ksp_converged_rate", &flg);
505:   if (flg) {
506:     const char *RateTypes[] = {"default", "residual", "error", "PetscRateType", "RATE_", NULL};
507:     PetscEnum   rtype       = (PetscEnum)1;

509:     PetscOptionsGetEnum(((PetscObject)ksp)->options, prefix, "-ksp_converged_rate_type", RateTypes, &rtype, &flg);
510:     if (rtype == (PetscEnum)0 || rtype == (PetscEnum)1) KSPSetResidualHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE);
511:     if (rtype == (PetscEnum)0 || rtype == (PetscEnum)2) KSPSetErrorHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE);
512:   }
513:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view", &ksp->viewer, &ksp->format, &ksp->view);
514:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_pre", &ksp->viewerPre, &ksp->formatPre, &ksp->viewPre);

516:   flg = PETSC_FALSE;
517:   PetscOptionsBool("-ksp_converged_reason_view_cancel", "Cancel all the converged reason view functions set using KSPConvergedReasonViewSet", "KSPConvergedReasonViewCancel", PETSC_FALSE, &flg, &set);
518:   if (set && flg) KSPConvergedReasonViewCancel(ksp);
519:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_converged_rate", &ksp->viewerRate, &ksp->formatRate, &ksp->viewRate);
520:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat);
521:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat);
522:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs);
523:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol);
524:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp);
525:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_eigenvalues", &ksp->viewerEV, &ksp->formatEV, &ksp->viewEV);
526:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_singularvalues", &ksp->viewerSV, &ksp->formatSV, &ksp->viewSV);
527:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_eigenvalues_explicit", &ksp->viewerEVExp, &ksp->formatEVExp, &ksp->viewEVExp);
528:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_final_residual", &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes);
529:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_preconditioned_operator_explicit", &ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp);
530:   PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_diagonal_scale", &ksp->viewerDScale, &ksp->formatDScale, &ksp->viewDScale);

532:   /* Deprecated options */
533:   if (!ksp->viewEV) {
534:     PetscOptionsDeprecated("-ksp_compute_eigenvalues", NULL, "3.9", "Use -ksp_view_eigenvalues");
535:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_compute_eigenvalues", &ksp->viewerEV, &ksp->formatEV, &ksp->viewEV);
536:   }
537:   if (!ksp->viewEV) {
538:     PetscOptionsDeprecated("-ksp_plot_eigenvalues", NULL, "3.9", "Use -ksp_view_eigenvalues draw");
539:     PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);
540:     if (ksp->viewEV) {
541:       ksp->formatEV = PETSC_VIEWER_DEFAULT;
542:       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
543:       PetscObjectReference((PetscObject)ksp->viewerEV);
544:     }
545:   }
546:   if (!ksp->viewEV) {
547:     PetscOptionsDeprecated("-ksp_plot_eigencontours", NULL, "3.9", "Use -ksp_view_eigenvalues draw::draw_contour");
548:     PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);
549:     if (ksp->viewEV) {
550:       ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR;
551:       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
552:       PetscObjectReference((PetscObject)ksp->viewerEV);
553:     }
554:   }
555:   if (!ksp->viewEVExp) {
556:     PetscOptionsDeprecated("-ksp_compute_eigenvalues_explicitly", NULL, "3.9", "Use -ksp_view_eigenvalues_explicit");
557:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_compute_eigenvalues_explicitly", &ksp->viewerEVExp, &ksp->formatEVExp, &ksp->viewEVExp);
558:   }
559:   if (!ksp->viewEVExp) {
560:     PetscOptionsDeprecated("-ksp_plot_eigenvalues_explicitly", NULL, "3.9", "Use -ksp_view_eigenvalues_explicit draw");
561:     PetscOptionsName("-ksp_plot_eigenvalues_explicitly", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]", "KSPView", &ksp->viewEVExp);
562:     if (ksp->viewEVExp) {
563:       ksp->formatEVExp = PETSC_VIEWER_DEFAULT;
564:       ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm);
565:       PetscObjectReference((PetscObject)ksp->viewerEVExp);
566:     }
567:   }
568:   if (!ksp->viewSV) {
569:     PetscOptionsDeprecated("-ksp_compute_singularvalues", NULL, "3.9", "Use -ksp_view_singularvalues");
570:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_compute_singularvalues", &ksp->viewerSV, &ksp->formatSV, &ksp->viewSV);
571:   }
572:   if (!ksp->viewFinalRes) {
573:     PetscOptionsDeprecated("-ksp_final_residual", NULL, "3.9", "Use -ksp_view_final_residual");
574:     PetscOptionsGetViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_final_residual", &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes);
575:   }

577: #if defined(PETSC_HAVE_SAWS)
578:   /*
579:     Publish convergence information using AMS
580:   */
581:   PetscOptionsBool("-ksp_monitor_saws", "Publish KSP progress using SAWs", "KSPMonitorSet", PETSC_FALSE, &flg, &set);
582:   if (set && flg) {
583:     void *ctx;
584:     KSPMonitorSAWsCreate(ksp, &ctx);
585:     KSPMonitorSet(ksp, KSPMonitorSAWs, ctx, KSPMonitorSAWsDestroy);
586:     KSPSetComputeSingularValues(ksp, PETSC_TRUE);
587:   }
588: #endif

590:   /* -----------------------------------------------------------------------*/
591:   KSPSetUpNorms_Private(ksp, PETSC_FALSE, NULL, &pcside);
592:   PetscOptionsEnum("-ksp_pc_side", "KSP preconditioner side", "KSPSetPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg);
593:   if (flg) KSPSetPCSide(ksp, pcside);

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

597: #if defined(PETSC_HAVE_SAWS)
598:   {
599:     PetscBool set;
600:     flg = PETSC_FALSE;
601:     PetscOptionsBool("-ksp_saws_block", "Block for SAWs at end of KSPSolve", "PetscObjectSAWsBlock", ((PetscObject)ksp)->amspublishblock, &flg, &set);
602:     if (set) PetscObjectSAWsSetBlock((PetscObject)ksp, flg);
603:   }
604: #endif

606:   nmax = ksp->nmax;
607:   PetscOptionsDeprecated("-ksp_matsolve_block_size", "-ksp_matsolve_batch_size", "3.15", NULL);
608:   PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg);
609:   if (flg) KSPSetMatSolveBatchSize(ksp, nmax);

611:   flg = PETSC_FALSE;
612:   PetscOptionsBool("-ksp_use_explicittranspose", "Explicitly transpose the system in KSPSolveTranspose", "KSPSetUseExplicitTranspose", ksp->transpose.use_explicittranspose, &flg, &set);
613:   if (set) KSPSetUseExplicitTranspose(ksp, flg);

615:   PetscTryTypeMethod(ksp, setfromoptions, PetscOptionsObject);
616: skipoptions:
617:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
618:   PetscObjectProcessOptionsHandlers((PetscObject)ksp, PetscOptionsObject);
619:   PetscOptionsEnd();
620:   ksp->setfromoptionscalled++;
621:   return 0;
622: }

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

627:    Collective

629:    Input Parameter:
630: .  ksp - the `KSP` context

632:    Level: advanced

634: .seealso: [](chapter_ksp), `KSPSetFromOptions()`, `KSPSetOptionsPrefix()`
635: @*/
636: PetscErrorCode KSPResetFromOptions(KSP ksp)
637: {
638:   if (ksp->setfromoptionscalled) KSPSetFromOptions(ksp);
639:   return 0;
640: }