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/sles/ksp/kspimpl.h
 6:  #include petscsys.h

  8: /* Logging support */
  9: int KSP_COOKIE;
 10: int KSP_GMRESOrthogonalization;

 12: EXTERN int SLESInitializePackage(char *);

 14: PetscTruth KSPRegisterAllCalled = PETSC_FALSE;

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

 19:    Collective on KSP

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

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

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

 36:    Level: developer

 38: .keywords: KSP, view

 40: .seealso: PCView(), PetscViewerASCIIOpen()
 41: @*/
 42: int KSPView(KSP ksp,PetscViewer viewer)
 43: {
 44:   char        *type;
 45:   int         ierr;
 46:   PetscTruth  isascii;

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

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

 87: /*
 88:    Contains the list of registered KSP routines
 89: */
 90: PetscFList KSPList = 0;

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

 95:    Collective on KSP

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


111:    Options Database:
112: .   -ksp_norm_type <none,preconditioned,unpreconditioned,natural>

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

117:    Level: advanced

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

121: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged()                               
122: @*/
123: int KSPSetNormType(KSP ksp,KSPNormType normtype)
124: {

128:   ksp->normtype = normtype;
129:   if (normtype == KSP_NO_NORM) {
130:     PetscLogInfo(ksp,"KSPSetNormType:Warning seting KSPNormType to skip computing the normn
131:   make sure you set the KSP convergence test to KSPSkipConvergencen");
132:   }
133:   return(0);
134: }

136: static int KSPPublish_Petsc(PetscObject obj)
137: {
138: #if defined(PETSC_HAVE_AMS)
139:   KSP          v = (KSP) obj;
140:   int          ierr;
141: #endif


145: #if defined(PETSC_HAVE_AMS)
146:   /* if it is already published then return */
147:   if (v->amem >=0) return(0);

149:   PetscObjectPublishBaseBegin(obj);
150:   AMS_Memory_add_field((AMS_Memory)v->amem,"Iteration",&v->its,1,AMS_INT,AMS_READ,
151:                                 AMS_COMMON,AMS_REDUCT_UNDEF);
152:   AMS_Memory_add_field((AMS_Memory)v->amem,"Residual",&v->rnorm,1,AMS_DOUBLE,AMS_READ,
153:                                 AMS_COMMON,AMS_REDUCT_UNDEF);

155:   if (v->res_hist_max > 0) {
156:     AMS_Memory_add_field((AMS_Memory)v->amem,"ResidualNormsCount",&v->res_hist_len,1,AMS_INT,AMS_READ,
157:                                 AMS_COMMON,AMS_REDUCT_UNDEF);
158:     AMS_Memory_add_field((AMS_Memory)v->amem,"ResidualNormsCountMax",&v->res_hist_max,1,AMS_INT,AMS_READ,
159:                                 AMS_COMMON,AMS_REDUCT_UNDEF);
160:     AMS_Memory_add_field((AMS_Memory)v->amem,"ResidualNorms",v->res_hist,v->res_hist_max,AMS_DOUBLE,AMS_READ,
161:                                 AMS_COMMON,AMS_REDUCT_UNDEF);
162:   }

164:   PetscObjectPublishBaseEnd(obj);
165: #endif

167:   return(0);
168: }


171: /*@C
172:    KSPCreate - Creates the default KSP context.

174:    Collective on MPI_Comm

176:    Input Parameter:
177: .  comm - MPI communicator

179:    Output Parameter:
180: .  ksp - location to put the KSP context

182:    Notes:
183:    The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt
184:    orthogonalization.

186:    Level: developer

188: .keywords: KSP, create, context

190: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP
191: @*/
192: int KSPCreate(MPI_Comm comm,KSP *inksp)
193: {
194:   KSP ksp;

199:   *inksp = 0;
200: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
201:   SLESInitializePackage(PETSC_NULL);
202: #endif

204:   PetscHeaderCreate(ksp,_p_KSP,struct _KSPOps,KSP_COOKIE,-1,"KSP",comm,KSPDestroy,KSPView);
205:   PetscLogObjectCreate(ksp);
206:   *inksp             = ksp;
207:   ksp->bops->publish = KSPPublish_Petsc;

209:   ksp->type          = -1;
210:   ksp->max_it        = 10000;
211:   ksp->pc_side       = PC_LEFT;
212:   ksp->rtol          = 1.e-5;
213:   ksp->atol          = 1.e-50;
214:   ksp->divtol        = 1.e4;

216:   ksp->normtype            = KSP_PRECONDITIONED_NORM;
217:   ksp->rnorm               = 0.0;
218:   ksp->its                 = 0;
219:   ksp->guess_zero          = PETSC_TRUE;
220:   ksp->calc_sings          = PETSC_FALSE;
221:   ksp->res_hist            = PETSC_NULL;
222:   ksp->res_hist_len        = 0;
223:   ksp->res_hist_max        = 0;
224:   ksp->res_hist_reset      = PETSC_TRUE;
225:   ksp->numbermonitors      = 0;
226:   ksp->converged           = KSPDefaultConverged;
227:   ksp->ops->buildsolution  = KSPDefaultBuildSolution;
228:   ksp->ops->buildresidual  = KSPDefaultBuildResidual;

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

232:   ksp->vec_sol         = 0;
233:   ksp->vec_rhs         = 0;
234:   ksp->B               = 0;

236:   ksp->ops->solve      = 0;
237:   ksp->ops->setup      = 0;
238:   ksp->ops->destroy    = 0;

240:   ksp->data            = 0;
241:   ksp->nwork           = 0;
242:   ksp->work            = 0;

244:   ksp->cnvP            = 0;

246:   ksp->reason          = KSP_CONVERGED_ITERATING;

248:   ksp->setupcalled     = 0;
249:   PetscPublishAll(ksp);
250:   return(0);
251: }
252: 
253: /*@C
254:    KSPSetType - Builds KSP for a particular solver. 

256:    Collective on KSP

258:    Input Parameters:
259: +  ksp      - the Krylov space context
260: -  type - a known method

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

266:    Notes:  
267:    See "petsc/include/petscksp.h" for available methods (for instance,
268:    KSPCG or KSPGMRES).

270:   Normally, it is best to use the SLESSetFromOptions() command and
271:   then set the KSP type from the options database rather than by using
272:   this routine.  Using the options database provides the user with
273:   maximum flexibility in evaluating the many different Krylov methods.
274:   The KSPSetType() routine is provided for those situations where it
275:   is necessary to set the iterative solver independently of the command
276:   line or options database.  This might be the case, for example, when
277:   the choice of iterative solver changes during the execution of the
278:   program, and the user's application is taking responsibility for
279:   choosing the appropriate method.  In other words, this routine is
280:   not for beginners.

282:   Level: intermediate

284: .keywords: KSP, set, method

286: .seealso: PCSetType(), KSPType

288: @*/
289: int KSPSetType(KSP ksp,KSPType type)
290: {
291:   int        ierr,(*r)(KSP);
292:   PetscTruth match;


298:   PetscTypeCompare((PetscObject)ksp,type,&match);
299:   if (match) return(0);

301:   if (ksp->data) {
302:     /* destroy the old private KSP context */
303:     (*ksp->ops->destroy)(ksp);
304:     ksp->data = 0;
305:   }
306:   /* Get the function pointers for the iterative method requested */
307:   if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}

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

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

313:   ksp->setupcalled = 0;
314:   (*r)(ksp);

316:   PetscObjectChangeTypeName((PetscObject)ksp,type);
317:   return(0);
318: }

320: /*@C
321:    KSPRegisterDestroy - Frees the list of KSP methods that were
322:    registered by KSPRegisterDynamic().

324:    Not Collective

326:    Level: advanced

328: .keywords: KSP, register, destroy

330: .seealso: KSPRegisterDynamic(), KSPRegisterAll()
331: @*/
332: int KSPRegisterDestroy(void)
333: {

337:   if (KSPList) {
338:     PetscFListDestroy(&KSPList);
339:     KSPList = 0;
340:   }
341:   KSPRegisterAllCalled = PETSC_FALSE;
342:   return(0);
343: }

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

348:    Not Collective

350:    Input Parameter:
351: .  ksp - Krylov context 

353:    Output Parameter:
354: .  name - name of KSP method 

356:    Level: intermediate

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

360: .seealso: KSPSetType()
361: @*/
362: int KSPGetType(KSP ksp,KSPType *type)
363: {
366:   *type = ksp->type_name;
367:   return(0);
368: }

370: /*@
371:    KSPSetFromOptions - Sets KSP options from the options database.
372:    This routine must be called before KSPSetUp() if the user is to be 
373:    allowed to set the Krylov type. 

375:    Collective on KSP

377:    Input Parameters:
378: .  ksp - the Krylov space context

380:    Options Database Keys:
381: +   -ksp_max_it - maximum number of linear iterations
382: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
383:                 if residual norm decreases by this factor than convergence is declared
384: .   -ksp_atol atol - absolute tolerance used in default convergence test, i.e. if residual 
385:                 norm is less than this then convergence is declared
386: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
387: .   -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using 
388: $                       convergence test (say you always want to run with 5 iterations) to 
389: $                       save on communication overhead
390: $                    preconditioned - default for left preconditioning 
391: $                    unpreconditioned - see KSPSetNormType()
392: $                    natural - see KSPSetNormType()
393: .   -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
394: .   -ksp_cancelmonitors - cancel all previous convergene monitor routines set
395: .   -ksp_monitor - print residual norm at each iteration
396: .   -ksp_xmonitor - plot residual norm at each iteration
397: .   -ksp_vecmonitor - plot solution at each iteration
398: -   -ksp_singmonitor - monitor extremem singular values at each iteration

400:    Notes:  
401:    To see all options, run your program with the -help option
402:    or consult the users manual.

404:    Level: developer

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

408: .seealso: 
409: @*/
410: int KSPSetFromOptions(KSP ksp)
411: {
412:   int        ierr;
413:   char       type[256],*stype[] = {"none","preconditioned","unpreconditioned","natural"};
414:   PetscTruth flg;

418:   if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}
419:   PetscOptionsBegin(ksp->comm,ksp->prefix,"Krylov Method (KSP) Options","KSP");
420:     PetscOptionsList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(ksp->type_name?ksp->type_name:KSPGMRES),type,256,&flg);
421:     if (flg) {
422:       KSPSetType(ksp,type);
423:     }
424:     /*
425:       Set the type if it was never set.
426:     */
427:     if (!ksp->type_name) {
428:       KSPSetType(ksp,KSPGMRES);
429:     }

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

438:     PetscOptionsEList("-ksp_norm_type","KSP Norm type","KSPSetNormType",stype,4,"preconditioned",type,256,&flg);
439:     if (flg) {
440:       PetscTruth isnone,ispreconditioned,isunpreconditioned,isnatural;

442:       PetscStrcmp(type,stype[0],&isnone);
443:       PetscStrcmp(type,stype[1],&ispreconditioned);
444:       PetscStrcmp(type,stype[2],&isunpreconditioned);
445:       PetscStrcmp(type,stype[3],&isnatural);

447:       if (isnone) {
448:         KSPSetNormType(ksp,KSP_NO_NORM);
449:         KSPSetConvergenceTest(ksp,KSPSkipConverged,0);
450:       } else if (ispreconditioned) {
451:         KSPSetNormType(ksp,KSP_PRECONDITIONED_NORM);
452:       } else if (isunpreconditioned) {
453:         KSPSetNormType(ksp,KSP_UNPRECONDITIONED_NORM);
454:       } else if (isnatural) {
455:         KSPSetNormType(ksp,KSP_NATURAL_NORM);
456:       } else {
457:         SETERRQ1(1,"Unknown KSP normtype %s",type);
458:       }
459:     }

461:     PetscOptionsName("-ksp_cancelmonitors","Remove any hardwired monitor routines","KSPClearMonitor",&flg);
462:     /* -----------------------------------------------------------------------*/
463:     /*
464:       Cancels all monitors hardwired into code before call to KSPSetFromOptions()
465:     */
466:     if (flg) {
467:       KSPClearMonitor(ksp);
468:     }
469:     /*
470:       Prints preconditioned residual norm at each iteration
471:     */
472:     PetscOptionsName("-ksp_monitor","Monitor preconditioned residual norm","KSPSetMonitor",&flg);
473:     if (flg) {
474:       KSPSetMonitor(ksp,KSPDefaultMonitor,PETSC_NULL,PETSC_NULL);
475:     }
476:     /*
477:       Plots the vector solution 
478:     */
479:     PetscOptionsName("-ksp_vecmonitor","Monitor solution graphically","KSPSetMonitor",&flg);
480:     if (flg) {
481:       KSPSetMonitor(ksp,KSPVecViewMonitor,PETSC_NULL,PETSC_NULL);
482:     }
483:     /*
484:       Prints preconditioned and true residual norm at each iteration
485:     */
486:     PetscOptionsName("-ksp_truemonitor","Monitor true (unpreconditioned) residual norm","KSPSetMonitor",&flg);
487:     if (flg) {
488:       KSPSetMonitor(ksp,KSPTrueMonitor,PETSC_NULL,PETSC_NULL);
489:     }
490:     /*
491:       Prints extreme eigenvalue estimates at each iteration
492:     */
493:     PetscOptionsName("-ksp_singmonitor","Monitor singular values","KSPSetMonitor",&flg);
494:     if (flg) {
495:       KSPSetComputeSingularValues(ksp,PETSC_TRUE);
496:       KSPSetMonitor(ksp,KSPSingularValueMonitor,PETSC_NULL,PETSC_NULL);
497:     }
498:     /*
499:       Prints preconditioned residual norm with fewer digits
500:     */
501:     PetscOptionsName("-ksp_smonitor","Monitor preconditioned residual norm with fewer digitis","KSPSetMonitor",&flg);
502:     if (flg) {
503:       KSPSetMonitor(ksp,KSPDefaultSMonitor,PETSC_NULL,PETSC_NULL);
504:     }
505:     /*
506:       Graphically plots preconditioned residual norm
507:     */
508:     PetscOptionsName("-ksp_xmonitor","Monitor graphically preconditioned residual norm","KSPSetMonitor",&flg);
509:     if (flg) {
510:       KSPSetMonitor(ksp,KSPLGMonitor,PETSC_NULL,PETSC_NULL);
511:     }
512:     /*
513:       Graphically plots preconditioned and true residual norm
514:     */
515:     PetscOptionsName("-ksp_xtruemonitor","Monitor graphically true residual norm","KSPSetMonitor",&flg);
516:     if (flg){
517:       KSPSetMonitor(ksp,KSPLGTrueMonitor,PETSC_NULL,PETSC_NULL);
518:     }

520:     /* -----------------------------------------------------------------------*/

522:     PetscOptionsLogicalGroupBegin("-ksp_left_pc","Use left preconditioning","KSPSetPreconditionerSide",&flg);
523:     if (flg) { KSPSetPreconditionerSide(ksp,PC_LEFT); }
524:     PetscOptionsLogicalGroup("-ksp_right_pc","Use right preconditioning","KSPSetPreconditionerSide",&flg);
525:     if (flg) { KSPSetPreconditionerSide(ksp,PC_RIGHT);}
526:     PetscOptionsLogicalGroupEnd("-ksp_symmetric_pc","Use symmetric (factorized) preconditioning","KSPSetPreconditionerSide",&flg);
527:     if (flg) { KSPSetPreconditionerSide(ksp,PC_SYMMETRIC);}

529:     PetscOptionsName("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",&flg);
530:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
531:     PetscOptionsName("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",&flg);
532:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
533:     PetscOptionsName("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",&flg);
534:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }

536:     if (ksp->ops->setfromoptions) {
537:       (*ksp->ops->setfromoptions)(ksp);
538:     }
539:   PetscOptionsEnd();


542:   return(0);
543: }

545: /*MC
546:    KSPRegisterDynamic - Adds a method to the Krylov subspace solver package.

548:    Synopsis:
549:    int KSPRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(KSP))

551:    Not Collective

553:    Input Parameters:
554: +  name_solver - name of a new user-defined solver
555: .  path - path (either absolute or relative) the library containing this solver
556: .  name_create - name of routine to create method context
557: -  routine_create - routine to create method context

559:    Notes:
560:    KSPRegisterDynamic() may be called multiple times to add several user-defined solvers.

562:    If dynamic libraries are used, then the fourth input argument (routine_create)
563:    is ignored.

565:    Sample usage:
566: .vb
567:    KSPRegisterDynamic("my_solver",/home/username/my_lib/lib/libO/solaris/mylib.a,
568:                "MySolverCreate",MySolverCreate);
569: .ve

571:    Then, your solver can be chosen with the procedural interface via
572: $     KSPSetType(ksp,"my_solver")
573:    or at runtime via the option
574: $     -ksp_type my_solver

576:    Level: advanced

578:    Environmental variables such as ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, ${BOPT},
579:    and others of the form ${any_environmental_variable} occuring in pathname will be 
580:    replaced with appropriate values.

582: .keywords: KSP, register

584: .seealso: KSPRegisterAll(), KSPRegisterDestroy()

586: M*/

588: int KSPRegister(char *sname,char *path,char *name,int (*function)(KSP))
589: {
590:   int  ierr;
591:   char fullname[256];

594:   PetscFListConcat(path,name,fullname);
595:   PetscFListAdd(&KSPList,sname,fullname,(void (*)(void))function);
596:   return(0);
597: }