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