Actual source code: itcl.c

petsc-3.9.0 2018-04-07
Report Typos and Errors

  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: .keywords: KSP, set, options, prefix, database

 41: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
 42: @*/
 43: PetscErrorCode  KSPSetOptionsPrefix(KSP ksp,const char prefix[])
 44: {

 49:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
 50:   PCSetOptionsPrefix(ksp->pc,prefix);
 51:   PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
 52:   return(0);
 53: }

 55: /*@C
 56:    KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
 57:    KSP options in the database.

 59:    Logically Collective on KSP

 61:    Input Parameters:
 62: +  ksp - the Krylov context
 63: -  prefix - the prefix string to prepend to all KSP option requests

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

 69:    Level: advanced

 71: .keywords: KSP, append, options, prefix, database

 73: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
 74: @*/
 75: PetscErrorCode  KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
 76: {

 81:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
 82:   PCAppendOptionsPrefix(ksp->pc,prefix);
 83:   PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
 84:   return(0);
 85: }

 87: /*@
 88:    KSPGetTabLevel - Gets the number of tabs that ASCII output used by ksp.

 90:    Not Collective

 92:    Input Parameter:
 93: .  ksp - a KSP object.

 95:    Output Parameter:
 96: .   tab - the number of tabs

 98:    Level: developer

100:     Notes: this is used in conjunction with KSPSetTabLevel() to manage the output from the KSP and its PC coherently.


103: .seealso:  KSPSetTabLevel()

105: @*/
106: PetscErrorCode  KSPGetTabLevel(KSP ksp,PetscInt *tab)
107: {

112:   PetscObjectGetTabLevel((PetscObject)ksp, tab);
113:   return(0);
114: }

116: /*@
117:    KSPSetTabLevel - Sets the number of tabs that ASCII output for the ksp andn its pc will use.

119:    Not Collective

121:    Input Parameters:
122: +  ksp - a KSP object
123: -  tab - the number of tabs

125:    Level: developer

127:     Notes: this is used to manage the output from KSP and PC objects that are imbedded in other objects,
128:            for example, the KSP object inside a SNES object. By indenting each lower level further the heirarchy
129:            of objects is very clear.  By setting the KSP object's tab level with KSPSetTabLevel() its PC object
130:            automatically receives the same tab level, so that whatever objects the pc might create are tabbed
131:            appropriately, too.

133: .seealso:  KSPGetTabLevel()
134: @*/
135: PetscErrorCode  KSPSetTabLevel(KSP ksp, PetscInt tab)
136: {

141:   PetscObjectSetTabLevel((PetscObject)ksp, tab);
142:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
143:   /* Do we need a PCSetTabLevel()? */
144:   PetscObjectSetTabLevel((PetscObject)ksp->pc, tab);
145:   return(0);
146: }

148: /*@
149:    KSPSetUseFischerGuess - Use the Paul Fischer algorithm

151:    Logically Collective on KSP

153:    Input Parameters:
154: +  ksp - the Krylov context
155: .  model - use model 1, model 2 or any other number to turn it off
156: -  size - size of subspace used to generate initial guess

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

161:    Level: advanced

163: .keywords: KSP, set, options, prefix, database

165: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess(), KSPGetGuess()
166: @*/
167: PetscErrorCode  KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
168: {
169:   KSPGuess       guess;

176:   KSPGetGuess(ksp,&guess);
177:   KSPGuessSetType(guess,KSPGUESSFISCHER);
178:   KSPGuessFischerSetModel(guess,model,size);
179:   return(0);
180: }

182: /*@
183:    KSPSetGuess - Set the initial guess object

185:    Logically Collective on KSP

187:    Input Parameters:
188: +  ksp - the Krylov context
189: -  guess - the object created with KSPGuessCreate()

191:    Level: advanced

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

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

199: .keywords: KSP, set, options, prefix, database

201: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPGetGuess()
202: @*/
203: PetscErrorCode  KSPSetGuess(KSP ksp,KSPGuess guess)
204: {

210:   PetscObjectReference((PetscObject)guess);
211:   KSPGuessDestroy(&ksp->guess);
212:   ksp->guess = guess;
213:   ksp->guess->ksp = ksp;
214:   return(0);
215: }

217: /*@
218:    KSPGetGuess - Gets the initial guess generator for the KSP.

220:    Not Collective

222:    Input Parameters:
223: .  ksp - the Krylov context

225:    Output Parameters:
226: .   guess - the object

228:    Level: developer

230: .keywords: KSP, set, options, prefix, database

232: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess()
233: @*/
234: PetscErrorCode  KSPGetGuess(KSP ksp,KSPGuess *guess)
235: {

241:   if (!ksp->guess) {
242:     const char* prefix;

244:     KSPGuessCreate(PetscObjectComm((PetscObject)ksp),&ksp->guess);
245:     PetscObjectGetOptionsPrefix((PetscObject)ksp,&prefix);
246:     if (prefix) {
247:       PetscObjectSetOptionsPrefix((PetscObject)ksp->guess,prefix);
248:     }
249:     ksp->guess->ksp = ksp;
250:   }
251:   *guess = ksp->guess;
252:   return(0);
253: }

255: /*@C
256:    KSPGetOptionsPrefix - Gets the prefix used for searching for all
257:    KSP options in the database.

259:    Not Collective

261:    Input Parameters:
262: .  ksp - the Krylov context

264:    Output Parameters:
265: .  prefix - pointer to the prefix string used is returned

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

270:    Level: advanced

272: .keywords: KSP, set, options, prefix, database

274: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
275: @*/
276: PetscErrorCode  KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
277: {

282:   PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
283:   return(0);
284: }

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

289:    Collective on KSP

291:    Input Parameters:
292: +  ksp - KSP object you wish to monitor
293: .  name - the monitor type one is seeking
294: .  help - message indicating what monitoring is done
295: .  manual - manual page for the monitor
296: -  monitor - the monitor function, the context for this object is a PetscViewerAndFormat

298:    Level: developer

300: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
301:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
302:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
303:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
304:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
305:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
306:           PetscOptionsFList(), PetscOptionsEList()
307: @*/
308: PetscErrorCode  KSPMonitorSetFromOptions(KSP ksp,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,PetscViewerAndFormat*))
309: {
310:   PetscErrorCode       ierr;
311:   PetscBool            flg;
312:   PetscViewer          viewer;
313:   PetscViewerFormat    format;

316:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ksp),((PetscObject)ksp)->prefix,name,&viewer,&format,&flg);
317:   if (flg) {
318:     PetscViewerAndFormat *vf;
319:     PetscViewerAndFormatCreate(viewer,format,&vf);
320:     PetscObjectDereference((PetscObject)viewer);
321:     KSPMonitorSet(ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
322:   }
323:   return(0);
324: }

326: /*@
327:    KSPSetFromOptions - Sets KSP options from the options database.
328:    This routine must be called before KSPSetUp() if the user is to be
329:    allowed to set the Krylov type.

331:    Collective on KSP

333:    Input Parameters:
334: .  ksp - the Krylov space context

336:    Options Database Keys:
337: +   -ksp_max_it - maximum number of linear iterations
338: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
339:                 if residual norm decreases by this factor than convergence is declared
340: .   -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
341:                 norm is less than this then convergence is declared
342: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
343: .   -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm()
344: .   -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm()
345: .   -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
346:                        convergence test (say you always want to run with 5 iterations) to
347:                        save on communication overhead
348:                     preconditioned - default for left preconditioning
349:                     unpreconditioned - see KSPSetNormType()
350:                     natural - see KSPSetNormType()
351: .   -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
352:        works only for PCBCGS, PCIBCGS and and PCCG
353: .   -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
354:        the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
355:        This will require 1 more iteration of the solver than usual.
356: .   -ksp_guess_type - Type of initial guess generator for repeated linear solves
357: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
358: .   -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
359: .   -ksp_test_null_space - tests the null space set with MatSetNullSpace() to see if it truly is a null space
360: .   -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
361: .   -ksp_monitor_cancel - cancel all previous convergene monitor routines set
362: .   -ksp_monitor <optional filename> - print residual norm at each iteration
363: .   -ksp_monitor_lg_residualnorm - plot residual norm at each iteration
364: .   -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration
365: -   -ksp_monitor_singular_value - monitor extreme singular values at each iteration

367:    Notes:
368:    To see all options, run your program with the -help option
369:    or consult Users-Manual: Chapter 4 KSP: Linear System Solvers

371:    Level: beginner

373: .keywords: KSP, set, from, options, database

375: .seealso: KSPSetUseFischerGuess()

377: @*/
378: PetscErrorCode  KSPSetFromOptions(KSP ksp)
379: {
381:   PetscInt       indx;
382:   const char     *convtests[] = {"default","skip"};
383:   char           type[256], guesstype[256], monfilename[PETSC_MAX_PATH_LEN];
384:   PetscBool      flg,flag,reuse,set;
385:   PetscInt       model[2]={0,0},nmax;
386:   KSPNormType    normtype;
387:   PCSide         pcside;
388:   void           *ctx;

392:   if (!ksp->skippcsetfromoptions) {
393:     if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
394:     PCSetFromOptions(ksp->pc);
395:   }

397:   KSPRegisterAll();
398:   PetscObjectOptionsBegin((PetscObject)ksp);
399:   PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);
400:   if (flg) {
401:     KSPSetType(ksp,type);
402:   }
403:   /*
404:     Set the type if it was never set.
405:   */
406:   if (!((PetscObject)ksp)->type_name) {
407:     KSPSetType(ksp,KSPGMRES);
408:   }

410:   PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);
411:   if (flg) goto skipoptions;

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

418:   PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);
419:   if (set && flag) {KSPConvergedDefaultSetUIRNorm(ksp);}
420:   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);
421:   if (set && flag) {KSPConvergedDefaultSetUMIRNorm(ksp);}
422:   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);
423:   if (flg) {
424:     KSPSetInitialGuessNonzero(ksp,flag);
425:   }
426:   PCGetReusePreconditioner(ksp->pc,&reuse);
427:   PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);
428:   KSPSetReusePreconditioner(ksp,reuse);

430:   PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);
431:   PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
432:   PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);
433:   if (flg) {
434:     KSPGetGuess(ksp,&ksp->guess);
435:     KSPGuessSetType(ksp->guess,guesstype);
436:     KSPGuessSetFromOptions(ksp->guess);
437:   } else { /* old option for KSP */
438:     nmax = 2;
439:     PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
440:     if (flag) {
441:       if (nmax != 2) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
442:       KSPSetUseFischerGuess(ksp,model[0],model[1]);
443:     }
444:   }

446:   PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);
447:   if (flg) {
448:     switch (indx) {
449:     case 0:
450:       KSPConvergedDefaultCreate(&ctx);
451:       KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);
452:       break;
453:     case 1: KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);    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;

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

492:   PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);
493:   /* -----------------------------------------------------------------------*/
494:   /*
495:     Cancels all monitors hardwired into code before call to KSPSetFromOptions()
496:   */
497:   if (set && flg) {
498:     KSPMonitorCancel(ksp);
499:   }
500:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor","Monitor the (preconditioned) residual norm","KSPMonitorDefault",KSPMonitorDefault);
501:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_range","Monitor the percentage of large entries in the residual","KSPMonitorRange",KSPMonitorRange);
502:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_true_residual","Monitor the unprecondiitoned residual norm","KSPMOnitorTrueResidual",KSPMonitorTrueResidualNorm);
503:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_max","Monitor the maximum norm of the residual","KSPMonitorTrueResidualMaxNorm",KSPMonitorTrueResidualMaxNorm);
504:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorDefaultShort",KSPMonitorDefaultShort);
505:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_solution","Monitor the solution","KSPMonitorSolution",KSPMonitorSolution);
506:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSingularValue",KSPMonitorSingularValue);
507:   PetscOptionsHasName(NULL,((PetscObject)ksp)->prefix,"-ksp_monitor_singular_value",&flg);
508:   if (flg) {
509:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
510:   }
511:   PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);
512:   PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flag);

514:   if (flg || flag) {
515:     /* A hack for using dynamic tolerance in preconditioner */
516:     PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
517:     if (flg) {
518:       KSPDynTolCtx *scale;
519:       PetscMalloc1(1,&scale);
520:       scale->bnrm = -1.0;
521:       scale->coef = 1.0;
522:       PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);
523:       KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);
524:     }
525:   }
526: 

528:   /*
529:    Calls Python function
530:   */
531:   PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
532:   if (flg) {PetscPythonMonitorSet((PetscObject)ksp,monfilename);}
533:   /*
534:     Graphically plots preconditioned residual norm
535:   */
536:   PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
537:   if (set && flg) {
538:     PetscDrawLG ctx;

540:     KSPMonitorLGResidualNormCreate(PetscObjectComm((PetscObject)ksp),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
541:     KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
542:   }
543:   /*
544:     Graphically plots preconditioned and true residual norm
545:   */
546:   PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
547:   if (set && flg) {
548:     PetscDrawLG ctx;

550:     KSPMonitorLGTrueResidualNormCreate(PetscObjectComm((PetscObject)ksp),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
551:     KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
552:   }
553:   /*
554:     Graphically plots preconditioned residual norm and range of residual element values
555:   */
556:   PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
557:   if (set && flg) {
558:     PetscViewer ctx;

560:     PetscViewerDrawOpen(PetscObjectComm((PetscObject)ksp),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
561:     KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
562:   }

564: #if defined(PETSC_HAVE_SAWS)
565:   /*
566:     Publish convergence information using AMS
567:   */
568:   PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);
569:   if (set && flg) {
570:     void *ctx;
571:     KSPMonitorSAWsCreate(ksp,&ctx);
572:     KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);
573:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
574:   }
575: #endif

577:   /* -----------------------------------------------------------------------*/
578:   KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);
579:   PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
580:   if (flg) {KSPSetPCSide(ksp,pcside);}

582:   PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);
583:   if (set) { KSPSetComputeSingularValues(ksp,flg); }
584:   PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);
585:   if (set) { KSPSetComputeSingularValues(ksp,flg); }
586:   PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",PETSC_FALSE,&flg,&set);
587:   if (set) { KSPSetComputeSingularValues(ksp,flg); }

589: #if defined(PETSC_HAVE_SAWS)
590:   {
591:   PetscBool set;
592:   flg  = PETSC_FALSE;
593:   PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);
594:   if (set) {
595:     PetscObjectSAWsSetBlock((PetscObject)ksp,flg);
596:   }
597:   }
598: #endif

600:   if (ksp->ops->setfromoptions) {
601:     (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);
602:   }
603:   skipoptions:
604:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
605:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);
606:   PetscOptionsEnd();
607:   return(0);
608: }