Actual source code: itcreate.c

  1: /*$Id: itcreate.c,v 1.206 2001/08/06 21:16:38 bsmith Exp $*/
  2: /*
  3:      The basic KSP routines, Create, View etc. are here.
  4: */
 5:  #include src/ksp/ksp/kspimpl.h
 6:  #include petscsys.h

  8: /* Logging support */
  9: int KSP_COOKIE = 0;
 10: int KSP_GMRESOrthogonalization = 0, KSP_SetUp = 0, KSP_Solve = 0;


 13: PetscTruth KSPRegisterAllCalled = PETSC_FALSE;

 17: /*@C 
 18:    KSPView - Prints the KSP data structure.

 20:    Collective on KSP

 22:    Input Parameters:
 23: +  ksp - the Krylov space context
 24: -  viewer - visualization context

 26:    Options Database Keys:
 27: .  -ksp_view - print the ksp data structure at the end of a KSPSolve call

 29:    Note:
 30:    The available visualization contexts include
 31: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
 32: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
 33:          output where only the first processor opens
 34:          the file.  All other processors send their 
 35:          data to the first processor to print. 

 37:    The user can open an alternative visualization context with
 38:    PetscViewerASCIIOpen() - output to a specified file.

 40:    Level: developer

 42: .keywords: KSP, view

 44: .seealso: PCView(), PetscViewerASCIIOpen()
 45: @*/
 46: int KSPView(KSP ksp,PetscViewer viewer)
 47: {
 48:   char        *type;
 49:   int         ierr;
 50:   PetscTruth  isascii;

 54:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(ksp->comm);

 58:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
 59:   if (isascii) {
 60:     KSPGetType(ksp,&type);
 61:     if (ksp->prefix) {
 62:       PetscViewerASCIIPrintf(viewer,"KSP Object:(%s)\n",ksp->prefix);
 63:     } else {
 64:       PetscViewerASCIIPrintf(viewer,"KSP Object:\n");
 65:     }
 66:     if (type) {
 67:       PetscViewerASCIIPrintf(viewer,"  type: %s\n",type);
 68:     } else {
 69:       PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");
 70:     }
 71:     if (ksp->ops->view) {
 72:       PetscViewerASCIIPushTab(viewer);
 73:       (*ksp->ops->view)(ksp,viewer);
 74:       PetscViewerASCIIPopTab(viewer);
 75:     }
 76:     if (ksp->guess_zero) {PetscViewerASCIIPrintf(viewer,"  maximum iterations=%d, initial guess is zero\n",ksp->max_it);}
 77:     else                 {PetscViewerASCIIPrintf(viewer,"  maximum iterations=%d\n", ksp->max_it);}
 78:     if (ksp->guess_knoll) {PetscViewerASCIIPrintf(viewer,"  using preconditioner applied to right hand side for initial guess\n");}
 79:     PetscViewerASCIIPrintf(viewer,"  tolerances:  relative=%g, absolute=%g, divergence=%g\n",ksp->rtol,ksp->atol,ksp->divtol);
 80:     if (ksp->pc_side == PC_RIGHT)          {PetscViewerASCIIPrintf(viewer,"  right preconditioning\n");}
 81:     else if (ksp->pc_side == PC_SYMMETRIC) {PetscViewerASCIIPrintf(viewer,"  symmetric preconditioning\n");}
 82:     else                                   {PetscViewerASCIIPrintf(viewer,"  left preconditioning\n");}
 83:   } else {
 84:     if (ksp->ops->view) {
 85:       (*ksp->ops->view)(ksp,viewer);
 86:     }
 87:   }
 88:   PCView(ksp->B,viewer);
 89:   return(0);
 90: }

 92: /*
 93:    Contains the list of registered KSP routines
 94: */
 95: PetscFList KSPList = 0;

 99: /*@C
100:    KSPSetNormType - Sets the norm that is used for convergence testing.

102:    Collective on KSP

104:    Input Parameter:
105: +  ksp - Krylov solver context
106: -  normtype - one of 
107: $   KSP_NO_NORM - skips computing the norm, this should only be used if you are using
108: $                 the Krylov method as a smoother with a fixed small number of iterations.
109: $                 You must also call KSPSetConvergenceTest(ksp,KSPSkipConverged,PETSC_NULL);
110: $                 supported only by CG, Richardson, Bi-CG-stab, CR, and CGS methods.
111: $   KSP_PRECONDITIONED_NORM - the default for left preconditioned solves, uses the l2 norm
112: $                 of the preconditioned residual
113: $   KSP_UNPRECONDITIONED_NORM - uses the l2 norm of the true b - Ax residual, supported only by
114: $                 CG, CHEBYCHEV, and RICHARDSON  
115: $   KSP_NATURAL_NORM - supported  by cg, cr, and cgs 


118:    Options Database Key:
119: .   -ksp_norm_type <none,preconditioned,unpreconditioned,natural>

121:    Notes: 
122:    Currently only works with the CG, Richardson, Bi-CG-stab, CR, and CGS methods.

124:    Level: advanced

126: .keywords: KSP, create, context, norms

128: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged()                               
129: @*/
130: int KSPSetNormType(KSP ksp,KSPNormType normtype)
131: {

135:   ksp->normtype = normtype;
136:   if (normtype == KSP_NO_NORM) {
137:     PetscLogInfo(ksp,"KSPSetNormType:Warning seting KSPNormType to skip computing the norm\n\
138:   make sure you set the KSP convergence test to KSPSkipConvergence\n");
139:   }
140:   return(0);
141: }

145: static int KSPPublish_Petsc(PetscObject obj)
146: {
147: #if defined(PETSC_HAVE_AMS)
148:   KSP          v = (KSP) obj;
149:   int          ierr;
150: #endif


154: #if defined(PETSC_HAVE_AMS)
155:   /* if it is already published then return */
156:   if (v->amem >=0) return(0);

158:   PetscObjectPublishBaseBegin(obj);
159:   AMS_Memory_add_field((AMS_Memory)v->amem,"Iteration",&v->its,1,AMS_INT,AMS_READ,
160:                                 AMS_COMMON,AMS_REDUCT_UNDEF);
161:   AMS_Memory_add_field((AMS_Memory)v->amem,"Residual",&v->rnorm,1,AMS_DOUBLE,AMS_READ,
162:                                 AMS_COMMON,AMS_REDUCT_UNDEF);

164:   if (v->res_hist_max > 0) {
165:     AMS_Memory_add_field((AMS_Memory)v->amem,"ResidualNormsCount",&v->res_hist_len,1,AMS_INT,AMS_READ,
166:                                 AMS_COMMON,AMS_REDUCT_UNDEF);
167:     AMS_Memory_add_field((AMS_Memory)v->amem,"ResidualNormsCountMax",&v->res_hist_max,1,AMS_INT,AMS_READ,
168:                                 AMS_COMMON,AMS_REDUCT_UNDEF);
169:     AMS_Memory_add_field((AMS_Memory)v->amem,"ResidualNorms",v->res_hist,v->res_hist_max,AMS_DOUBLE,AMS_READ,
170:                                 AMS_COMMON,AMS_REDUCT_UNDEF);
171:   }

173:   PetscObjectPublishBaseEnd(obj);
174: #endif
175:   return(0);
176: }

180: /*@
181:    KSPSetOperators - Sets the matrix associated with the linear system
182:    and a (possibly) different one associated with the preconditioner. 

184:    Collective on KSP and Mat

186:    Input Parameters:
187: +  ksp - the KSP context
188: .  Amat - the matrix associated with the linear system
189: .  Pmat - the matrix to be used in constructing the preconditioner, usually the
190:           same as Amat. 
191: -  flag - flag indicating information about the preconditioner matrix structure
192:    during successive linear solves.  This flag is ignored the first time a
193:    linear system is solved, and thus is irrelevant when solving just one linear
194:    system.

196:    Notes: 
197:    The flag can be used to eliminate unnecessary work in the preconditioner 
198:    during the repeated solution of linear systems of the same size.  The
199:    available options are
200: $    SAME_PRECONDITIONER -
201: $      Pmat is identical during successive linear solves.
202: $      This option is intended for folks who are using
203: $      different Amat and Pmat matrices and want to reuse the
204: $      same preconditioner matrix.  For example, this option
205: $      saves work by not recomputing incomplete factorization
206: $      for ILU/ICC preconditioners.
207: $    SAME_NONZERO_PATTERN -
208: $      Pmat has the same nonzero structure during
209: $      successive linear solves. 
210: $    DIFFERENT_NONZERO_PATTERN -
211: $      Pmat does not have the same nonzero structure.

213:     Caution:
214:     If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
215:     and does not check the structure of the matrix.  If you erroneously
216:     claim that the structure is the same when it actually is not, the new
217:     preconditioner will not function correctly.  Thus, use this optimization
218:     feature carefully!

220:     If in doubt about whether your preconditioner matrix has changed
221:     structure or not, use the flag DIFFERENT_NONZERO_PATTERN.

223:     Level: beginner

225: .keywords: KSP, set, operators, matrix, preconditioner, linear system

227: .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators()
228: @*/
229: int KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat,MatStructure flag)
230: {
235:   PCSetOperators(ksp->B,Amat,Pmat,flag);
236:   if (ksp->setupcalled > 1) ksp->setupcalled = 1;  /* so that next solve call will call setup */
237:   return(0);
238: }

242: /*@C
243:    KSPCreate - Creates the default KSP context.

245:    Collective on MPI_Comm

247:    Input Parameter:
248: .  comm - MPI communicator

250:    Output Parameter:
251: .  ksp - location to put the KSP context

253:    Notes:
254:    The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt
255:    orthogonalization.

257:    Level: developer

259: .keywords: KSP, create, context

261: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP
262: @*/
263: int KSPCreate(MPI_Comm comm,KSP *inksp)
264: {
265:   KSP ksp;

270:   *inksp = 0;
271: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
272:   KSPInitializePackage(PETSC_NULL);
273: #endif

275:   PetscHeaderCreate(ksp,_p_KSP,struct _KSPOps,KSP_COOKIE,-1,"KSP",comm,KSPDestroy,KSPView);
276:   PetscLogObjectCreate(ksp);
277:   *inksp             = ksp;
278:   ksp->bops->publish = KSPPublish_Petsc;

280:   ksp->type          = -1;
281:   ksp->max_it        = 10000;
282:   ksp->pc_side       = PC_LEFT;
283:   ksp->rtol          = 1.e-5;
284:   ksp->atol          = 1.e-50;
285:   ksp->divtol        = 1.e4;

287:   ksp->normtype            = KSP_PRECONDITIONED_NORM;
288:   ksp->rnorm               = 0.0;
289:   ksp->its                 = 0;
290:   ksp->guess_zero          = PETSC_TRUE;
291:   ksp->calc_sings          = PETSC_FALSE;
292:   ksp->res_hist            = PETSC_NULL;
293:   ksp->res_hist_len        = 0;
294:   ksp->res_hist_max        = 0;
295:   ksp->res_hist_reset      = PETSC_TRUE;
296:   ksp->numbermonitors      = 0;
297:   ksp->converged           = KSPDefaultConverged;
298:   ksp->ops->buildsolution  = KSPDefaultBuildSolution;
299:   ksp->ops->buildresidual  = KSPDefaultBuildResidual;

301:   ksp->ops->setfromoptions = 0;

303:   ksp->vec_sol         = 0;
304:   ksp->vec_rhs         = 0;
305:   ksp->B               = 0;

307:   ksp->ops->solve      = 0;
308:   ksp->ops->setup      = 0;
309:   ksp->ops->destroy    = 0;

311:   ksp->data            = 0;
312:   ksp->nwork           = 0;
313:   ksp->work            = 0;

315:   ksp->cnvP            = 0;

317:   ksp->reason          = KSP_CONVERGED_ITERATING;

319:   ksp->setupcalled     = 0;
320:   PetscPublishAll(ksp);
321:   PCCreate(comm,&ksp->B);
322:   return(0);
323: }
324: 
327: /*@C
328:    KSPSetType - Builds KSP for a particular solver. 

330:    Collective on KSP

332:    Input Parameters:
333: +  ksp      - the Krylov space context
334: -  type - a known method

336:    Options Database Key:
337: .  -ksp_type  <method> - Sets the method; use -help for a list 
338:     of available methods (for instance, cg or gmres)

340:    Notes:  
341:    See "petsc/include/petscksp.h" for available methods (for instance,
342:    KSPCG or KSPGMRES).

344:   Normally, it is best to use the KSPSetFromOptions() command and
345:   then set the KSP type from the options database rather than by using
346:   this routine.  Using the options database provides the user with
347:   maximum flexibility in evaluating the many different Krylov methods.
348:   The KSPSetType() routine is provided for those situations where it
349:   is necessary to set the iterative solver independently of the command
350:   line or options database.  This might be the case, for example, when
351:   the choice of iterative solver changes during the execution of the
352:   program, and the user's application is taking responsibility for
353:   choosing the appropriate method.  In other words, this routine is
354:   not for beginners.

356:   Level: intermediate

358: .keywords: KSP, set, method

360: .seealso: PCSetType(), KSPType

362: @*/
363: int KSPSetType(KSP ksp,const KSPType type)
364: {
365:   int        ierr,(*r)(KSP);
366:   PetscTruth match;


372:   PetscTypeCompare((PetscObject)ksp,type,&match);
373:   if (match) return(0);

375:   if (ksp->data) {
376:     /* destroy the old private KSP context */
377:     (*ksp->ops->destroy)(ksp);
378:     ksp->data = 0;
379:   }
380:   /* Get the function pointers for the iterative method requested */
381:   if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}

383:    PetscFListFind(ksp->comm,KSPList,type,(void (**)(void)) &r);

385:   if (!r) SETERRQ1(1,"Unknown KSP type given: %s",type);

387:   ksp->setupcalled = 0;
388:   (*r)(ksp);

390:   PetscObjectChangeTypeName((PetscObject)ksp,type);
391:   return(0);
392: }

396: /*@C
397:    KSPRegisterDestroy - Frees the list of KSP methods that were
398:    registered by KSPRegisterDynamic().

400:    Not Collective

402:    Level: advanced

404: .keywords: KSP, register, destroy

406: .seealso: KSPRegisterDynamic(), KSPRegisterAll()
407: @*/
408: int KSPRegisterDestroy(void)
409: {

413:   if (KSPList) {
414:     PetscFListDestroy(&KSPList);
415:     KSPList = 0;
416:   }
417:   KSPRegisterAllCalled = PETSC_FALSE;
418:   return(0);
419: }

423: /*@C
424:    KSPGetType - Gets the KSP type as a string from the KSP object.

426:    Not Collective

428:    Input Parameter:
429: .  ksp - Krylov context 

431:    Output Parameter:
432: .  name - name of KSP method 

434:    Level: intermediate

436: .keywords: KSP, get, method, name

438: .seealso: KSPSetType()
439: @*/
440: int KSPGetType(KSP ksp,KSPType *type)
441: {
445:   *type = ksp->type_name;
446:   return(0);
447: }

451: /*@
452:    KSPSetFromOptions - Sets KSP options from the options database.
453:    This routine must be called before KSPSetUp() if the user is to be 
454:    allowed to set the Krylov type. 

456:    Collective on KSP

458:    Input Parameters:
459: .  ksp - the Krylov space context

461:    Options Database Keys:
462: +   -ksp_max_it - maximum number of linear iterations
463: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
464:                 if residual norm decreases by this factor than convergence is declared
465: .   -ksp_atol atol - absolute tolerance used in default convergence test, i.e. if residual 
466:                 norm is less than this then convergence is declared
467: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
468: .   -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using 
469: $                       convergence test (say you always want to run with 5 iterations) to 
470: $                       save on communication overhead
471: $                    preconditioned - default for left preconditioning 
472: $                    unpreconditioned - see KSPSetNormType()
473: $                    natural - see KSPSetNormType()
474: .   -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
475: .   -ksp_cancelmonitors - cancel all previous convergene monitor routines set
476: .   -ksp_monitor - print residual norm at each iteration
477: .   -ksp_xmonitor - plot residual norm at each iteration
478: .   -ksp_vecmonitor - plot solution at each iteration
479: -   -ksp_singmonitor - monitor extremem singular values at each iteration

481:    Notes:  
482:    To see all options, run your program with the -help option
483:    or consult the users manual.

485:    Level: developer

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

489: .seealso: 
490: @*/
491: int KSPSetFromOptions(KSP ksp)
492: {
493:   int        ierr,indx;
494:   char       type[256];
495:   const char *stype[] = {"none","preconditioned","unpreconditioned","natural"};
496:   PetscTruth flg;

500:   PCSetFromOptions(ksp->B);

502:   if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}
503:   PetscOptionsBegin(ksp->comm,ksp->prefix,"Krylov Method (KSP) Options","KSP");
504:     PetscOptionsList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(ksp->type_name?ksp->type_name:KSPGMRES),type,256,&flg);
505:     if (flg) {
506:       KSPSetType(ksp,type);
507:     }
508:     /*
509:       Set the type if it was never set.
510:     */
511:     if (!ksp->type_name) {
512:       KSPSetType(ksp,KSPGMRES);
513:     }

515:     PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,PETSC_NULL);
516:     PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,PETSC_NULL);
517:     PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->atol,&ksp->atol,PETSC_NULL);
518:     PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,PETSC_NULL);
519:     PetscOptionsLogical("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,
520:                                   &ksp->guess_knoll,PETSC_NULL);

522:     PetscOptionsEList("-ksp_norm_type","KSP Norm type","KSPSetNormType",stype,4,"preconditioned",&indx,&flg);
523:     if (flg) {
524:       switch (indx) {
525:       case 0:
526:         KSPSetNormType(ksp,KSP_NO_NORM);
527:         KSPSetConvergenceTest(ksp,KSPSkipConverged,0);
528:         break;
529:       case 1:
530:         KSPSetNormType(ksp,KSP_PRECONDITIONED_NORM);
531:         break;
532:       case 2:
533:         KSPSetNormType(ksp,KSP_UNPRECONDITIONED_NORM);
534:         break;
535:       case 3:
536:         KSPSetNormType(ksp,KSP_NATURAL_NORM);
537:         break;
538:       }
539:     }

541:     PetscOptionsName("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",&flg);
542:     if (flg) {
543:       KSPSetDiagonalScale(ksp,PETSC_TRUE);
544:     }
545:     PetscOptionsName("-ksp_diagonal_scale_fix","Fix diagonaled scaled matrix after solve","KSPSetDiagonalScaleFix",&flg);
546:     if (flg) {
547:       KSPSetDiagonalScaleFix(ksp,PETSC_TRUE);
548:     }

550:     /*
551:       Prints reason for convergence or divergence of each linear solve
552:     */
553:     PetscOptionsName("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",&flg);
554:     if (flg) {
555:       ksp->printreason = PETSC_TRUE;
556:     }

558:     PetscOptionsName("-ksp_cancelmonitors","Remove any hardwired monitor routines","KSPClearMonitor",&flg);
559:     /* -----------------------------------------------------------------------*/
560:     /*
561:       Cancels all monitors hardwired into code before call to KSPSetFromOptions()
562:     */
563:     if (flg) {
564:       KSPClearMonitor(ksp);
565:     }
566:     /*
567:       Prints preconditioned residual norm at each iteration
568:     */
569:     PetscOptionsName("-ksp_monitor","Monitor preconditioned residual norm","KSPSetMonitor",&flg);
570:     if (flg) {
571:       KSPSetMonitor(ksp,KSPDefaultMonitor,PETSC_NULL,PETSC_NULL);
572:     }
573:     /*
574:       Plots the vector solution 
575:     */
576:     PetscOptionsName("-ksp_vecmonitor","Monitor solution graphically","KSPSetMonitor",&flg);
577:     if (flg) {
578:       KSPSetMonitor(ksp,KSPVecViewMonitor,PETSC_NULL,PETSC_NULL);
579:     }
580:     /*
581:       Prints preconditioned and true residual norm at each iteration
582:     */
583:     PetscOptionsName("-ksp_truemonitor","Monitor true (unpreconditioned) residual norm","KSPSetMonitor",&flg);
584:     if (flg) {
585:       KSPSetMonitor(ksp,KSPTrueMonitor,PETSC_NULL,PETSC_NULL);
586:     }
587:     /*
588:       Prints extreme eigenvalue estimates at each iteration
589:     */
590:     PetscOptionsName("-ksp_singmonitor","Monitor singular values","KSPSetMonitor",&flg);
591:     if (flg) {
592:       KSPSetComputeSingularValues(ksp,PETSC_TRUE);
593:       KSPSetMonitor(ksp,KSPSingularValueMonitor,PETSC_NULL,PETSC_NULL);
594:     }
595:     /*
596:       Prints preconditioned residual norm with fewer digits
597:     */
598:     PetscOptionsName("-ksp_smonitor","Monitor preconditioned residual norm with fewer digitis","KSPSetMonitor",&flg);
599:     if (flg) {
600:       KSPSetMonitor(ksp,KSPDefaultSMonitor,PETSC_NULL,PETSC_NULL);
601:     }
602:     /*
603:       Graphically plots preconditioned residual norm
604:     */
605:     PetscOptionsName("-ksp_xmonitor","Monitor graphically preconditioned residual norm","KSPSetMonitor",&flg);
606:     if (flg) {
607:       KSPSetMonitor(ksp,KSPLGMonitor,PETSC_NULL,PETSC_NULL);
608:     }
609:     /*
610:       Graphically plots preconditioned and true residual norm
611:     */
612:     PetscOptionsName("-ksp_xtruemonitor","Monitor graphically true residual norm","KSPSetMonitor",&flg);
613:     if (flg){
614:       KSPSetMonitor(ksp,KSPLGTrueMonitor,PETSC_NULL,PETSC_NULL);
615:     }

617:     /* -----------------------------------------------------------------------*/

619:     PetscOptionsLogicalGroupBegin("-ksp_left_pc","Use left preconditioning","KSPSetPreconditionerSide",&flg);
620:     if (flg) { KSPSetPreconditionerSide(ksp,PC_LEFT); }
621:     PetscOptionsLogicalGroup("-ksp_right_pc","Use right preconditioning","KSPSetPreconditionerSide",&flg);
622:     if (flg) { KSPSetPreconditionerSide(ksp,PC_RIGHT);}
623:     PetscOptionsLogicalGroupEnd("-ksp_symmetric_pc","Use symmetric (factorized) preconditioning","KSPSetPreconditionerSide",&flg);
624:     if (flg) { KSPSetPreconditionerSide(ksp,PC_SYMMETRIC);}

626:     PetscOptionsName("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",&flg);
627:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
628:     PetscOptionsName("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",&flg);
629:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
630:     PetscOptionsName("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",&flg);
631:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }

633:     if (ksp->ops->setfromoptions) {
634:       (*ksp->ops->setfromoptions)(ksp);
635:     }
636:     PetscOptionsName("-ksp_view","View linear solver parameters","KSPView",&flg);
637:   PetscOptionsEnd();
638:   return(0);
639: }


644: /*@C
645:   KSPRegister - See KSPRegisterDynamic()

647:   Level: advanced
648: @*/
649: int KSPRegister(const char sname[],const char path[],const char name[],int (*function)(KSP))
650: {
651:   int  ierr;
652:   char fullname[256];

655:   PetscFListConcat(path,name,fullname);
656:   PetscFListAdd(&KSPList,sname,fullname,(void (*)(void))function);
657:   return(0);
658: }