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 on ksp

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

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

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

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

 37:    Level: advanced

 39: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
 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 on ksp

 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: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
 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

 80:    Logically Collective on ksp

 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:
 88: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves

 90:    Level: advanced

 92: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess(), KSPGetGuess()
 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 on ksp

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: 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: 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) {
163:       PetscObjectSetOptionsPrefix((PetscObject)ksp->guess,prefix);
164:     }
165:     ksp->guess->ksp = ksp;
166:   }
167:   *guess = ksp->guess;
168:   return 0;
169: }

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

175:    Not Collective

177:    Input Parameters:
178: .  ksp - the Krylov context

180:    Output Parameters:
181: .  prefix - pointer to the prefix string used is returned

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

187:    Level: advanced

189: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
190: @*/
191: PetscErrorCode  KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
192: {
194:   PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
195:   return 0;
196: }

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

205: /*@C
206:    KSPMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user

208:    Collective on ksp

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

216:    Level: developer

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

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

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

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

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

263:    Collective on ksp

265:    Input Parameter:
266: .  ksp - the Krylov space context

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

307:    Notes:
308:    To see all options, run your program with the -help option
309:    or consult Users-Manual: ch_ksp

311:    Level: beginner

313: .seealso: KSPSetOptionsPrefix(), KSPResetFromOptions(), KSPSetUseFischerGuess()

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

329:   PetscObjectGetComm((PetscObject) ksp, &comm);
330:   PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
331:   if (!ksp->skippcsetfromoptions) {
332:     if (!ksp->pc) KSPGetPC(ksp,&ksp->pc);
333:     PCSetFromOptions(ksp->pc);
334:   }

336:   KSPRegisterAll();
337:   PetscObjectOptionsBegin((PetscObject)ksp);
338:   PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);
339:   if (flg) {
340:     KSPSetType(ksp,type);
341:   }
342:   /*
343:     Set the type if it was never set.
344:   */
345:   if (!((PetscObject)ksp)->type_name) {
346:     KSPSetType(ksp,KSPGMRES);
347:   }

349:   KSPResetViewers(ksp);

351:   /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */
352:   PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);
353:   if (set && flg) KSPMonitorCancel(ksp);
354:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor", "preconditioned_residual", NULL);
355:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_short", "preconditioned_residual_short", NULL);
356:   KSPMonitorSetFromOptions(ksp, "-all_ksp_monitor", "preconditioned_residual", NULL);
357:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_range", "preconditioned_residual_range", NULL);
358:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_true_residual", "true_residual", NULL);
359:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_max", "true_residual_max", NULL);
360:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_solution", "solution", NULL);
361:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_singular_value", "singular_value", ksp);
362:   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_error", "error", ksp);
363:   PetscOptionsBool("-ksp_monitor_pause_final", "Pauses all draw monitors at the final iterate", "KSPMonitorPauseFinal_Internal", PETSC_FALSE, &ksp->pauseFinal, NULL);
364:   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);
365:   if (flg) {
366:     KSPSetInitialGuessNonzero(ksp,flag);
367:   }

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

390:     KSPGetDiagonalScale(ksp,&flag);
391:     PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
392:     if (flg) {
393:       KSPSetDiagonalScale(ksp,flag);
394:     }
395:     KSPGetDiagonalScaleFix(ksp,&flag);
396:     PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
397:     if (flg) {
398:       KSPSetDiagonalScaleFix(ksp,flag);
399:     }
400:     nmax = ksp->nmax;
401:     PetscOptionsDeprecated("-ksp_matsolve_block_size","-ksp_matsolve_batch_size","3.15",NULL);
402:     PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg);
403:     if (flg) {
404:       KSPSetMatSolveBatchSize(ksp, nmax);
405:     }
406:     goto skipoptions;
407:   }

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

414:   PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);
415:   if (set && flag) KSPConvergedDefaultSetUIRNorm(ksp);
416:   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);
417:   if (set && flag) KSPConvergedDefaultSetUMIRNorm(ksp);
418:   PetscOptionsBool("-ksp_converged_maxits","Declare convergence if the maximum number of iterations is reached","KSPConvergedDefaultSetConvergedMaxits",PETSC_FALSE,&flag,&set);
419:   if (set) KSPConvergedDefaultSetConvergedMaxits(ksp,flag);
420:   KSPGetReusePreconditioner(ksp,&reuse);
421:   PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);
422:   KSPSetReusePreconditioner(ksp,reuse);

424:   PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);
425:   PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
426:   PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);
427:   if (flg) {
428:     KSPGetGuess(ksp,&ksp->guess);
429:     KSPGuessSetType(ksp->guess,guesstype);
430:     KSPGuessSetFromOptions(ksp->guess);
431:   } else { /* old option for KSP */
432:     nmax = 2;
433:     PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm or its variants for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
434:     if (flag) {
436:       KSPSetUseFischerGuess(ksp,model[0],model[1]);
437:     }
438:   }

440:   PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,3,"default",&indx,&flg);
441:   if (flg) {
442:     switch (indx) {
443:     case 0:
444:       KSPConvergedDefaultCreate(&ctx);
445:       KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);
446:       break;
447:     case 1:
448:       KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);
449:       break;
450:     case 2:
451:       KSPConvergedDefaultCreate(&ctx);
452:       KSPSetConvergenceTest(ksp,KSPLSQRConvergedDefault,ctx,KSPConvergedDefaultDestroy);
453:       break;
454:     }
455:   }

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

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

463:   PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);
464:   if (flg) {
465:     KSPSetLagNorm(ksp,flag);
466:   }

468:   KSPGetDiagonalScale(ksp,&flag);
469:   PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
470:   if (flg) {
471:     KSPSetDiagonalScale(ksp,flag);
472:   }
473:   KSPGetDiagonalScaleFix(ksp,&flag);
474:   PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
475:   if (flg) {
476:     KSPSetDiagonalScaleFix(ksp,flag);
477:   }

479:   PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);
480:   if (set && flg) {
481:     MatNullSpace nsp;
482:     Mat          Amat = NULL;

484:     MatNullSpaceCreate(comm,PETSC_TRUE,0,NULL,&nsp);
485:     if (ksp->pc) PCGetOperators(ksp->pc,&Amat,NULL);
486:     if (Amat) {
487:       MatSetNullSpace(Amat,nsp);
488:       MatNullSpaceDestroy(&nsp);
489:     } else SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided");
490:   }

492:   flg = PETSC_FALSE;
493:   if (ksp->pc) {
494:     PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);
495:     if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flg);
496:     if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc,PCDEFLATION,&flg);
497:   }

499:   if (flg) {
500:     /* A hack for using dynamic tolerance in preconditioner */
501:     PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,sizeof(monfilename),&flg);
502:     if (flg) {
503:       KSPDynTolCtx *scale;
504:       PetscMalloc1(1,&scale);
505:       scale->bnrm = -1.0;
506:       scale->coef = 1.0;
507:       PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);
508:       KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);
509:     }
510:   }

512:   /*
513:    Calls Python function
514:   */
515:   PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);
516:   if (flg) PetscPythonMonitorSet((PetscObject)ksp,monfilename);
517:   /*
518:     Graphically plots preconditioned residual norm and range of residual element values
519:   */
520:   PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
521:   if (set && flg) {
522:     PetscViewer ctx;

524:     PetscViewerDrawOpen(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
525:     KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
526:   }
527:   /* TODO Do these show up in help? */
528:   PetscOptionsHasName(((PetscObject) ksp)->options, prefix, "-ksp_converged_rate", &flg);
529:   if (flg) {
530:     const char *RateTypes[] = {"default", "residual", "error", "PetscRateType", "RATE_", NULL};
531:     PetscEnum rtype = (PetscEnum) 1;

533:     PetscOptionsGetEnum(((PetscObject) ksp)->options, prefix, "-ksp_converged_rate_type", RateTypes, &rtype, &flg);
534:     if (rtype == (PetscEnum) 0 || rtype == (PetscEnum) 1) KSPSetResidualHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE);
535:     if (rtype == (PetscEnum) 0 || rtype == (PetscEnum) 2) KSPSetErrorHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE);
536:   }
537:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer,&ksp->format,&ksp->view);
538:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pre",&ksp->viewerPre,&ksp->formatPre,&ksp->viewPre);

540:   flg = PETSC_FALSE;
541:   PetscOptionsBool("-ksp_converged_reason_view_cancel","Cancel all the converged reason view functions set using KSPConvergedReasonViewSet","KSPConvergedReasonViewCancel",PETSC_FALSE,&flg,&set);
542:   if (set && flg) {
543:     KSPConvergedReasonViewCancel(ksp);
544:   }
545:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_rate",&ksp->viewerRate,&ksp->formatRate,&ksp->viewRate);
546:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);
547:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);
548:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);
549:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);
550:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);
551:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);
552:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);
553:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues_explicit",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);
554:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
555:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);
556:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);

558:   /* Deprecated options */
559:   if (!ksp->viewEV) {
560:     PetscOptionsDeprecated("-ksp_compute_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues");
561:     PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);
562:   }
563:   if (!ksp->viewEV) {
564:     PetscOptionsDeprecated("-ksp_plot_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues draw");
565:     PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);
566:     if (ksp->viewEV) {
567:       ksp->formatEV = PETSC_VIEWER_DEFAULT;
568:       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
569:       PetscObjectReference((PetscObject) ksp->viewerEV);
570:     }
571:   }
572:   if (!ksp->viewEV) {
573:     PetscOptionsDeprecated("-ksp_plot_eigencontours",NULL,"3.9","Use -ksp_view_eigenvalues draw::draw_contour");
574:     PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);
575:     if (ksp->viewEV) {
576:       ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR;
577:       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
578:       PetscObjectReference((PetscObject) ksp->viewerEV);
579:     }
580:   }
581:   if (!ksp->viewEVExp) {
582:     PetscOptionsDeprecated("-ksp_compute_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit");
583:     PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues_explicitly",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);
584:   }
585:   if (!ksp->viewEVExp) {
586:     PetscOptionsDeprecated("-ksp_plot_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit draw");
587:     PetscOptionsName("-ksp_plot_eigenvalues_explicitly","[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]","KSPView",&ksp->viewEVExp);
588:     if (ksp->viewEVExp) {
589:       ksp->formatEVExp = PETSC_VIEWER_DEFAULT;
590:       ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm);
591:       PetscObjectReference((PetscObject) ksp->viewerEVExp);
592:     }
593:   }
594:   if (!ksp->viewSV) {
595:     PetscOptionsDeprecated("-ksp_compute_singularvalues",NULL,"3.9","Use -ksp_view_singularvalues");
596:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_compute_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);
597:   }
598:   if (!ksp->viewFinalRes) {
599:     PetscOptionsDeprecated("-ksp_final_residual",NULL,"3.9","Use -ksp_view_final_residual");
600:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
601:   }

603: #if defined(PETSC_HAVE_SAWS)
604:   /*
605:     Publish convergence information using AMS
606:   */
607:   PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);
608:   if (set && flg) {
609:     void *ctx;
610:     KSPMonitorSAWsCreate(ksp,&ctx);
611:     KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);
612:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
613:   }
614: #endif

616:   /* -----------------------------------------------------------------------*/
617:   KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);
618:   PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
619:   if (flg) KSPSetPCSide(ksp,pcside);

621:   if (ksp->viewSV || ksp->viewEV) {
622:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
623:   }

625: #if defined(PETSC_HAVE_SAWS)
626:   {
627:     PetscBool set;
628:     flg  = PETSC_FALSE;
629:     PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);
630:     if (set) {
631:       PetscObjectSAWsSetBlock((PetscObject)ksp,flg);
632:     }
633:   }
634: #endif

636:   nmax = ksp->nmax;
637:   PetscOptionsDeprecated("-ksp_matsolve_block_size","-ksp_matsolve_batch_size","3.15",NULL);
638:   PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg);
639:   if (flg) {
640:     KSPSetMatSolveBatchSize(ksp, nmax);
641:   }

643:   flg  = PETSC_FALSE;
644:   PetscOptionsBool("-ksp_use_explicittranspose","Explicitly transpose the system in KSPSolveTranspose","KSPSetUseExplicitTranspose",ksp->transpose.use_explicittranspose,&flg,&set);
645:   if (set) {
646:     KSPSetUseExplicitTranspose(ksp,flg);
647:   }

649:   if (ksp->ops->setfromoptions) {
650:     (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);
651:   }
652:   skipoptions:
653:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
654:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);
655:   PetscOptionsEnd();
656:   ksp->setfromoptionscalled++;
657:   return 0;
658: }

660: /*@
661:    KSPResetFromOptions - Sets various KSP parameters from user options ONLY if the KSP was previously set from options

663:    Collective on ksp

665:    Input Parameter:
666: .  ksp - the KSP context

668:    Level: beginner

670: .seealso: KSPSetFromOptions(), KSPSetOptionsPrefix()
671: @*/
672: PetscErrorCode KSPResetFromOptions(KSP ksp)
673: {
674:   if (ksp->setfromoptionscalled) KSPSetFromOptions(ksp);
675:   return 0;
676: }