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: }