Actual source code: itcreate.c

  1: #define PETSCKSP_DLL

  3: /*
  4:      The basic KSP routines, Create, View etc. are here.
  5: */
 6:  #include src/ksp/ksp/kspimpl.h
 7:  #include petscsys.h

  9: /* Logging support */
 10: PetscCookie PETSCKSP_DLLEXPORT KSP_COOKIE = 0;
 11: PetscEvent  KSP_GMRESOrthogonalization = 0, KSP_SetUp = 0, KSP_Solve = 0;


 14: PetscTruth KSPRegisterAllCalled = PETSC_FALSE;

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

 21:    Collective on KSP

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

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

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

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

 41:    Level: beginner

 43: .keywords: KSP, view

 45: .seealso: PCView(), PetscViewerASCIIOpen()
 46: @*/
 47: PetscErrorCode PETSCKSP_DLLEXPORT KSPView(KSP ksp,PetscViewer viewer)
 48: {
 49:   const char     *type;
 51:   PetscTruth     iascii;

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

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

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

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

103:    Collective on KSP

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


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

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

125:    Level: advanced

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

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

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

147: static PetscErrorCode KSPPublish_Petsc(PetscObject obj)
148: {
150:   return(0);
151: }

155: /*@
156:    KSPSetOperators - Sets the matrix associated with the linear system
157:    and a (possibly) different one associated with the preconditioner. 

159:    Collective on KSP and Mat

161:    Input Parameters:
162: +  ksp - the KSP context
163: .  Amat - the matrix associated with the linear system
164: .  Pmat - the matrix to be used in constructing the preconditioner, usually the
165:           same as Amat. 
166: -  flag - flag indicating information about the preconditioner matrix structure
167:    during successive linear solves.  This flag is ignored the first time a
168:    linear system is solved, and thus is irrelevant when solving just one linear
169:    system.

171:    Notes: 
172:    The flag can be used to eliminate unnecessary work in the preconditioner 
173:    during the repeated solution of linear systems of the same size.  The
174:    available options are
175: $    SAME_PRECONDITIONER -
176: $      Pmat is identical during successive linear solves.
177: $      This option is intended for folks who are using
178: $      different Amat and Pmat matrices and want to reuse the
179: $      same preconditioner matrix.  For example, this option
180: $      saves work by not recomputing incomplete factorization
181: $      for ILU/ICC preconditioners.
182: $    SAME_NONZERO_PATTERN -
183: $      Pmat has the same nonzero structure during
184: $      successive linear solves. 
185: $    DIFFERENT_NONZERO_PATTERN -
186: $      Pmat does not have the same nonzero structure.

188:     Caution:
189:     If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
190:     and does not check the structure of the matrix.  If you erroneously
191:     claim that the structure is the same when it actually is not, the new
192:     preconditioner will not function correctly.  Thus, use this optimization
193:     feature carefully!

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

198:     Level: beginner

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

202: .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPGetOperators()
203: @*/
204: PetscErrorCode PETSCKSP_DLLEXPORT KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat,MatStructure flag)
205: {

212:   PCSetOperators(ksp->pc,Amat,Pmat,flag);
213:   if (ksp->setupcalled > 1) ksp->setupcalled = 1;  /* so that next solve call will call setup */
214:   return(0);
215: }

219: /*@
220:    KSPGetOperators - Gets the matrix associated with the linear system
221:    and a (possibly) different one associated with the preconditioner. 

223:    Collective on KSP and Mat

225:    Input Parameter:
226: .  ksp - the KSP context

228:    Output Parameters:
229: +  Amat - the matrix associated with the linear system
230: .  Pmat - the matrix to be used in constructing the preconditioner, usually the
231:           same as Amat. 
232: -  flag - flag indicating information about the preconditioner matrix structure
233:    during successive linear solves.  This flag is ignored the first time a
234:    linear system is solved, and thus is irrelevant when solving just one linear
235:    system.

237:     Level: intermediate

239: .keywords: KSP, set, get, operators, matrix, preconditioner, linear system

241: .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPSetOperators()
242: @*/
243: PetscErrorCode PETSCKSP_DLLEXPORT KSPGetOperators(KSP ksp,Mat *Amat,Mat *Pmat,MatStructure *flag)
244: {

249:   PCGetOperators(ksp->pc,Amat,Pmat,flag);
250:   return(0);
251: }

255: /*@C
256:    KSPCreate - Creates the default KSP context.

258:    Collective on MPI_Comm

260:    Input Parameter:
261: .  comm - MPI communicator

263:    Output Parameter:
264: .  ksp - location to put the KSP context

266:    Notes:
267:    The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt
268:    orthogonalization.

270:    Level: beginner

272: .keywords: KSP, create, context

274: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP
275: @*/
276: PetscErrorCode PETSCKSP_DLLEXPORT KSPCreate(MPI_Comm comm,KSP *inksp)
277: {
278:   KSP            ksp;

283:   *inksp = 0;
284: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
285:   KSPInitializePackage(PETSC_NULL);
286: #endif

288:   PetscHeaderCreate(ksp,_p_KSP,struct _KSPOps,KSP_COOKIE,-1,"KSP",comm,KSPDestroy,KSPView);
289:   *inksp             = ksp;
290:   ksp->bops->publish = KSPPublish_Petsc;

292:   ksp->type          = -1;
293:   ksp->max_it        = 10000;
294:   ksp->pc_side       = PC_LEFT;
295:   ksp->rtol          = 1.e-5;
296:   ksp->abstol          = 1.e-50;
297:   ksp->divtol        = 1.e4;

299:   ksp->normtype            = KSP_PRECONDITIONED_NORM;
300:   ksp->rnorm               = 0.0;
301:   ksp->its                 = 0;
302:   ksp->guess_zero          = PETSC_TRUE;
303:   ksp->calc_sings          = PETSC_FALSE;
304:   ksp->res_hist            = PETSC_NULL;
305:   ksp->res_hist_len        = 0;
306:   ksp->res_hist_max        = 0;
307:   ksp->res_hist_reset      = PETSC_TRUE;
308:   ksp->numbermonitors      = 0;
309:   ksp->converged           = KSPDefaultConverged;
310:   ksp->ops->buildsolution  = KSPDefaultBuildSolution;
311:   ksp->ops->buildresidual  = KSPDefaultBuildResidual;

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

315:   ksp->vec_sol         = 0;
316:   ksp->vec_rhs         = 0;
317:   ksp->pc              = 0;

319:   ksp->ops->solve      = 0;
320:   ksp->ops->setup      = 0;
321:   ksp->ops->destroy    = 0;

323:   ksp->data            = 0;
324:   ksp->nwork           = 0;
325:   ksp->work            = 0;

327:   ksp->cnvP            = 0;

329:   ksp->reason          = KSP_CONVERGED_ITERATING;

331:   ksp->setupcalled     = 0;
332:   PetscPublishAll(ksp);
333:   PCCreate(comm,&ksp->pc);
334:   return(0);
335: }
336: 
339: /*@C
340:    KSPSetType - Builds KSP for a particular solver. 

342:    Collective on KSP

344:    Input Parameters:
345: +  ksp      - the Krylov space context
346: -  type - a known method

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

352:    Notes:  
353:    See "petsc/include/petscksp.h" for available methods (for instance,
354:    KSPCG or KSPGMRES).

356:   Normally, it is best to use the KSPSetFromOptions() command and
357:   then set the KSP type from the options database rather than by using
358:   this routine.  Using the options database provides the user with
359:   maximum flexibility in evaluating the many different Krylov methods.
360:   The KSPSetType() routine is provided for those situations where it
361:   is necessary to set the iterative solver independently of the command
362:   line or options database.  This might be the case, for example, when
363:   the choice of iterative solver changes during the execution of the
364:   program, and the user's application is taking responsibility for
365:   choosing the appropriate method.  In other words, this routine is
366:   not for beginners.

368:   Level: intermediate

370: .keywords: KSP, set, method

372: .seealso: PCSetType(), KSPType

374: @*/
375: PetscErrorCode PETSCKSP_DLLEXPORT KSPSetType(KSP ksp, KSPType type)
376: {
377:   PetscErrorCode ierr,(*r)(KSP);
378:   PetscTruth     match;


384:   PetscTypeCompare((PetscObject)ksp,type,&match);
385:   if (match) return(0);

387:   if (ksp->data) {
388:     /* destroy the old private KSP context */
389:     (*ksp->ops->destroy)(ksp);
390:     ksp->data = 0;
391:   }
392:   /* Get the function pointers for the iterative method requested */
393:   if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}
394:    PetscFListFind(ksp->comm,KSPList,type,(void (**)(void)) &r);
395:   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown KSP type given: %s",type);
396:   ksp->setupcalled = 0;
397:   (*r)(ksp);
398:   PetscObjectChangeTypeName((PetscObject)ksp,type);
399:   return(0);
400: }

404: /*@C
405:    KSPRegisterDestroy - Frees the list of KSP methods that were
406:    registered by KSPRegisterDynamic().

408:    Not Collective

410:    Level: advanced

412: .keywords: KSP, register, destroy

414: .seealso: KSPRegisterDynamic(), KSPRegisterAll()
415: @*/
416: PetscErrorCode PETSCKSP_DLLEXPORT KSPRegisterDestroy(void)
417: {

421:   if (KSPList) {
422:     PetscFListDestroy(&KSPList);
423:     KSPList = 0;
424:   }
425:   KSPRegisterAllCalled = PETSC_FALSE;
426:   return(0);
427: }

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

434:    Not Collective

436:    Input Parameter:
437: .  ksp - Krylov context 

439:    Output Parameter:
440: .  name - name of KSP method 

442:    Level: intermediate

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

446: .seealso: KSPSetType()
447: @*/
448: PetscErrorCode PETSCKSP_DLLEXPORT KSPGetType(KSP ksp,KSPType *type)
449: {
453:   *type = ksp->type_name;
454:   return(0);
455: }

459: /*@
460:    KSPSetFromOptions - Sets KSP options from the options database.
461:    This routine must be called before KSPSetUp() if the user is to be 
462:    allowed to set the Krylov type. 

464:    Collective on KSP

466:    Input Parameters:
467: .  ksp - the Krylov space context

469:    Options Database Keys:
470: +   -ksp_max_it - maximum number of linear iterations
471: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
472:                 if residual norm decreases by this factor than convergence is declared
473: .   -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual 
474:                 norm is less than this then convergence is declared
475: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
476: .   -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using 
477: $                       convergence test (say you always want to run with 5 iterations) to 
478: $                       save on communication overhead
479: $                    preconditioned - default for left preconditioning 
480: $                    unpreconditioned - see KSPSetNormType()
481: $                    natural - see KSPSetNormType()
482: .    -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
483: .    -ksp_test_null_space - tests the null space set with KSPSetNullSpace() to see if it truly is a null space
484: .   -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
485: .   -ksp_cancelmonitors - cancel all previous convergene monitor routines set
486: .   -ksp_monitor - print residual norm at each iteration
487: .   -ksp_xmonitor - plot residual norm at each iteration
488: .   -ksp_vecmonitor - plot solution at each iteration
489: -   -ksp_singmonitor - monitor extremem singular values at each iteration

491:    Notes:  
492:    To see all options, run your program with the -help option
493:    or consult the users manual.

495:    Level: beginner

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

499: .seealso: 
500: @*/
501: PetscErrorCode PETSCKSP_DLLEXPORT KSPSetFromOptions(KSP ksp)
502: {
504:   PetscInt       indx;
505:   char           type[256];
506:   const char     *stype[] = {"none","preconditioned","unpreconditioned","natural"};
507:   PetscTruth     flg;

511:   PCSetFromOptions(ksp->pc);

513:   if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}
514:   PetscOptionsBegin(ksp->comm,ksp->prefix,"Krylov Method (KSP) Options","KSP");
515:     PetscOptionsList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(ksp->type_name?ksp->type_name:KSPGMRES),type,256,&flg);
516:     if (flg) {
517:       KSPSetType(ksp,type);
518:     }
519:     /*
520:       Set the type if it was never set.
521:     */
522:     if (!ksp->type_name) {
523:       KSPSetType(ksp,KSPGMRES);
524:     }

526:     PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,PETSC_NULL);
527:     PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,PETSC_NULL);
528:     PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,PETSC_NULL);
529:     PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,PETSC_NULL);
530:     PetscOptionsTruth("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,
531:                                   &ksp->guess_knoll,PETSC_NULL);

533:     PetscOptionsEList("-ksp_norm_type","KSP Norm type","KSPSetNormType",stype,4,"preconditioned",&indx,&flg);
534:     if (flg) {
535:       switch (indx) {
536:       case 0:
537:         KSPSetNormType(ksp,KSP_NO_NORM);
538:         KSPSetConvergenceTest(ksp,KSPSkipConverged,0);
539:         break;
540:       case 1:
541:         KSPSetNormType(ksp,KSP_PRECONDITIONED_NORM);
542:         break;
543:       case 2:
544:         KSPSetNormType(ksp,KSP_UNPRECONDITIONED_NORM);
545:         break;
546:       case 3:
547:         KSPSetNormType(ksp,KSP_NATURAL_NORM);
548:         break;
549:       }
550:     }

552:     PetscOptionsName("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",&flg);
553:     if (flg) {
554:       KSPSetDiagonalScale(ksp,PETSC_TRUE);
555:     }
556:     PetscOptionsName("-ksp_diagonal_scale_fix","Fix diagonaled scaled matrix after solve","KSPSetDiagonalScaleFix",&flg);
557:     if (flg) {
558:       KSPSetDiagonalScaleFix(ksp,PETSC_TRUE);
559:     }


562:     PetscOptionsName("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",&flg);
563:     if (flg) {
564:       MatNullSpace nsp;

566:       MatNullSpaceCreate(ksp->comm,PETSC_TRUE,0,0,&nsp);
567:       KSPSetNullSpace(ksp,nsp);
568:       MatNullSpaceDestroy(nsp);
569:     }

571:     /* option is actually checked in KSPSetUp() */
572:     if (ksp->nullsp) {
573:       PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);
574:     }

576:     /*
577:       Prints reason for convergence or divergence of each linear solve
578:     */
579:     PetscOptionsName("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",&flg);
580:     if (flg) {
581:       ksp->printreason = PETSC_TRUE;
582:     }

584:     PetscOptionsName("-ksp_cancelmonitors","Remove any hardwired monitor routines","KSPClearMonitor",&flg);
585:     /* -----------------------------------------------------------------------*/
586:     /*
587:       Cancels all monitors hardwired into code before call to KSPSetFromOptions()
588:     */
589:     if (flg) {
590:       KSPClearMonitor(ksp);
591:     }
592:     /*
593:       Prints preconditioned residual norm at each iteration
594:     */
595:     PetscOptionsName("-ksp_monitor","Monitor preconditioned residual norm","KSPSetMonitor",&flg);
596:     if (flg) {
597:       KSPSetMonitor(ksp,KSPDefaultMonitor,PETSC_NULL,PETSC_NULL);
598:     }
599:     /*
600:       Plots the vector solution 
601:     */
602:     PetscOptionsName("-ksp_vecmonitor","Monitor solution graphically","KSPSetMonitor",&flg);
603:     if (flg) {
604:       KSPSetMonitor(ksp,KSPVecViewMonitor,PETSC_NULL,PETSC_NULL);
605:     }
606:     /*
607:       Prints preconditioned and true residual norm at each iteration
608:     */
609:     PetscOptionsName("-ksp_truemonitor","Monitor true (unpreconditioned) residual norm","KSPSetMonitor",&flg);
610:     if (flg) {
611:       KSPSetMonitor(ksp,KSPTrueMonitor,PETSC_NULL,PETSC_NULL);
612:     }
613:     /*
614:       Prints extreme eigenvalue estimates at each iteration
615:     */
616:     PetscOptionsName("-ksp_singmonitor","Monitor singular values","KSPSetMonitor",&flg);
617:     if (flg) {
618:       KSPSetComputeSingularValues(ksp,PETSC_TRUE);
619:       KSPSetMonitor(ksp,KSPSingularValueMonitor,PETSC_NULL,PETSC_NULL);
620:     }
621:     /*
622:       Prints preconditioned residual norm with fewer digits
623:     */
624:     PetscOptionsName("-ksp_smonitor","Monitor preconditioned residual norm with fewer digitis","KSPSetMonitor",&flg);
625:     if (flg) {
626:       KSPSetMonitor(ksp,KSPDefaultSMonitor,PETSC_NULL,PETSC_NULL);
627:     }
628:     /*
629:       Graphically plots preconditioned residual norm
630:     */
631:     PetscOptionsName("-ksp_xmonitor","Monitor graphically preconditioned residual norm","KSPSetMonitor",&flg);
632:     if (flg) {
633:       KSPSetMonitor(ksp,KSPLGMonitor,PETSC_NULL,PETSC_NULL);
634:     }
635:     /*
636:       Graphically plots preconditioned and true residual norm
637:     */
638:     PetscOptionsName("-ksp_xtruemonitor","Monitor graphically true residual norm","KSPSetMonitor",&flg);
639:     if (flg){
640:       KSPSetMonitor(ksp,KSPLGTrueMonitor,PETSC_NULL,PETSC_NULL);
641:     }

643:     /* -----------------------------------------------------------------------*/

645:     PetscOptionsTruthGroupBegin("-ksp_left_pc","Use left preconditioning","KSPSetPreconditionerSide",&flg);
646:     if (flg) { KSPSetPreconditionerSide(ksp,PC_LEFT); }
647:     PetscOptionsTruthGroup("-ksp_right_pc","Use right preconditioning","KSPSetPreconditionerSide",&flg);
648:     if (flg) { KSPSetPreconditionerSide(ksp,PC_RIGHT);}
649:     PetscOptionsTruthGroupEnd("-ksp_symmetric_pc","Use symmetric (factorized) preconditioning","KSPSetPreconditionerSide",&flg);
650:     if (flg) { KSPSetPreconditionerSide(ksp,PC_SYMMETRIC);}

652:     PetscOptionsName("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",&flg);
653:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
654:     PetscOptionsName("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",&flg);
655:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
656:     PetscOptionsName("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",&flg);
657:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }

659:     if (ksp->ops->setfromoptions) {
660:       (*ksp->ops->setfromoptions)(ksp);
661:     }
662:     PetscOptionsName("-ksp_view","View linear solver parameters","KSPView",&flg);
663:   PetscOptionsEnd();
664:   return(0);
665: }

669: /*@C
670:   KSPRegister - See KSPRegisterDynamic()

672:   Level: advanced
673: @*/
674: PetscErrorCode PETSCKSP_DLLEXPORT KSPRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(KSP))
675: {
677:   char           fullname[PETSC_MAX_PATH_LEN];

680:   PetscFListConcat(path,name,fullname);
681:   PetscFListAdd(&KSPList,sname,fullname,(void (*)(void))function);
682:   return(0);
683: }

687: /*@C
688:   KSPSetNullSpace - Sets the null space of the operator

690:   Collective on KSP

692:   Input Parameters:
693: +  ksp - the Krylov space object
694: -  nullsp - the null space of the operator

696:   Level: advanced

698: .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPGetNullSpace()
699: @*/
700: PetscErrorCode PETSCKSP_DLLEXPORT KSPSetNullSpace(KSP ksp,MatNullSpace nullsp)
701: {

705:   if (ksp->nullsp) {
706:     MatNullSpaceDestroy(ksp->nullsp);
707:   }
708:   ksp->nullsp = nullsp;
709:   PetscObjectReference((PetscObject)ksp->nullsp);
710:   return(0);
711: }

715: /*@C
716:   KSPGetNullSpace - Gets the null space of the operator

718:   Collective on KSP

720:   Input Parameters:
721: +  ksp - the Krylov space object
722: -  nullsp - the null space of the operator

724:   Level: advanced

726: .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPSetNullSpace()
727: @*/
728: PetscErrorCode PETSCKSP_DLLEXPORT KSPGetNullSpace(KSP ksp,MatNullSpace *nullsp)
729: {
731:   *nullsp = ksp->nullsp;
732:   return(0);
733: }