Actual source code: itcreate.c
1: #define PETSCKSP_DLL
3: /*
4: The basic KSP routines, Create, View etc. are here.
5: */
6: #include private/kspimpl.h
8: /* Logging support */
9: PetscCookie KSP_COOKIE;
10: PetscLogEvent KSP_GMRESOrthogonalization, KSP_SetUp, KSP_Solve;
12: /*
13: Contains the list of registered KSP routines
14: */
15: PetscFList KSPList = 0;
16: PetscTruth KSPRegisterAllCalled = PETSC_FALSE;
20: /*@C
21: KSPView - Prints the KSP data structure.
23: Collective on KSP
25: Input Parameters:
26: + ksp - the Krylov space context
27: - viewer - visualization context
29: Options Database Keys:
30: . -ksp_view - print the ksp data structure at the end of a KSPSolve call
32: Note:
33: The available visualization contexts include
34: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
35: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
36: output where only the first processor opens
37: the file. All other processors send their
38: data to the first processor to print.
40: The user can open an alternative visualization context with
41: PetscViewerASCIIOpen() - output to a specified file.
43: Level: beginner
45: .keywords: KSP, view
47: .seealso: PCView(), PetscViewerASCIIOpen()
48: @*/
49: PetscErrorCode KSPView(KSP ksp,PetscViewer viewer)
50: {
51: const KSPType type;
53: PetscTruth iascii;
57: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(((PetscObject)ksp)->comm);
61: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
62: if (iascii) {
63: KSPGetType(ksp,&type);
64: if (((PetscObject)ksp)->prefix) {
65: PetscViewerASCIIPrintf(viewer,"KSP Object:(%s)\n",((PetscObject)ksp)->prefix);
66: } else {
67: PetscViewerASCIIPrintf(viewer,"KSP Object:\n");
68: }
69: if (type) {
70: PetscViewerASCIIPrintf(viewer," type: %s\n",type);
71: } else {
72: PetscViewerASCIIPrintf(viewer," type: not yet set\n");
73: }
74: if (ksp->ops->view) {
75: PetscViewerASCIIPushTab(viewer);
76: (*ksp->ops->view)(ksp,viewer);
77: PetscViewerASCIIPopTab(viewer);
78: }
79: if (ksp->guess_zero) {PetscViewerASCIIPrintf(viewer," maximum iterations=%D, initial guess is zero\n",ksp->max_it);}
80: else {PetscViewerASCIIPrintf(viewer," maximum iterations=%D\n", ksp->max_it);}
81: if (ksp->guess_knoll) {PetscViewerASCIIPrintf(viewer," using preconditioner applied to right hand side for initial guess\n");}
82: PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, divergence=%G\n",ksp->rtol,ksp->abstol,ksp->divtol);
83: if (ksp->pc_side == PC_RIGHT) {PetscViewerASCIIPrintf(viewer," right preconditioning\n");}
84: else if (ksp->pc_side == PC_SYMMETRIC) {PetscViewerASCIIPrintf(viewer," symmetric preconditioning\n");}
85: else {PetscViewerASCIIPrintf(viewer," left preconditioning\n");}
86: if (ksp->guess) {PetscViewerASCIIPrintf(viewer," using Fischers initial guess method %D with size %D\n",ksp->guess->method,ksp->guess->maxl);}
87: if (ksp->dscale) {PetscViewerASCIIPrintf(viewer," diagonally scaled system\n");}
88: if (ksp->nullsp) {PetscViewerASCIIPrintf(viewer," has attached null space\n");}
89: if (!ksp->guess_zero) {PetscViewerASCIIPrintf(viewer," using nonzero initial guess\n");}
90: PetscViewerASCIIPrintf(viewer," using %s norm type for convergence test\n",KSPNormTypes[ksp->normtype]);
91: } else {
92: if (ksp->ops->view) {
93: (*ksp->ops->view)(ksp,viewer);
94: }
95: }
96: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
97: PCView(ksp->pc,viewer);
98: return(0);
99: }
104: /*@
105: KSPSetNormType - Sets the norm that is used for convergence testing.
107: Collective on KSP
109: Input Parameter:
110: + ksp - Krylov solver context
111: - normtype - one of
112: $ KSP_NORM_NO - skips computing the norm, this should only be used if you are using
113: $ the Krylov method as a smoother with a fixed small number of iterations.
114: $ Implicitly sets KSPSkipConverged as KSP convergence test.
115: $ Supported only by CG, Richardson, Bi-CG-stab, CR, and CGS methods.
116: $ KSP_NORM_PRECONDITIONED - the default for left preconditioned solves, uses the l2 norm
117: $ of the preconditioned residual
118: $ KSP_NORM_UNPRECONDITIONED - uses the l2 norm of the true b - Ax residual, supported only by
119: $ CG, CHEBYCHEV, and RICHARDSON, automatically true for right (see KSPSetPreconditioningSide())
120: $ preconditioning..
121: $ KSP_NORM_NATURAL - supported by KSPCG, KSPCR, KSPCGNE, KSPCGS
124: Options Database Key:
125: . -ksp_norm_type <none,preconditioned,unpreconditioned,natural>
127: Notes:
128: Currently only works with the CG, Richardson, Bi-CG-stab, CR, and CGS methods.
130: Level: advanced
132: .keywords: KSP, create, context, norms
134: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged()
135: @*/
136: PetscErrorCode KSPSetNormType(KSP ksp,KSPNormType normtype)
137: {
142: ksp->normtype = normtype;
143: if (normtype == KSP_NORM_NO) {
144: KSPSetConvergenceTest(ksp,KSPSkipConverged,0,0);
145: PetscInfo(ksp,"Warning: setting KSPNormType to skip computing the norm\n\
146: KSP convergence test is implicitly set to KSPSkipConverged\n");
147: }
148: return(0);
149: }
153: /*@
154: KSPSetCheckNormIteration - Sets the first iteration at which the norm of the residual will be
155: computed and used in the convergence test.
157: Collective on KSP
159: Input Parameter:
160: + ksp - Krylov solver context
161: - it - use -1 to check at all iterations
163: Notes:
164: Currently only works with KSPCG, KSPBCGS and KSPIBCGS
166: Use KSPSetNormType(ksp,KSP_NORM_NO) to never check the norm
168: On steps where the norm is not computed, the previous norm is still in the variable, so if you run with, for example,
169: -ksp_monitor the residual norm will appear to be unchanged for several iterations (though it is not really unchanged).
170: Level: advanced
172: .keywords: KSP, create, context, norms
174: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged(), KSPSetNormType()
175: @*/
176: PetscErrorCode KSPSetCheckNormIteration(KSP ksp,PetscInt it)
177: {
180: ksp->chknorm = it;
181: return(0);
182: }
186: /*@
187: KSPSetLagNorm - Lags the residual norm calculation so that it is computed as part of the MPI_Allreduce() for
188: computing the inner products for the next iteration. This can reduce communication costs at the expense of doing
189: one additional iteration.
192: Collective on KSP
194: Input Parameter:
195: + ksp - Krylov solver context
196: - flg - PETSC_TRUE or PETSC_FALSE
198: Options Database Keys:
199: . -ksp_lag_norm - lag the calculated residual norm
201: Notes:
202: Currently only works with KSPIBCGS.
204: Use KSPSetNormType(ksp,KSP_NORM_NO) to never check the norm
206: If you lag the norm and run with, for example, -ksp_monitor, the residual norm reported will be the lagged one.
207: Level: advanced
209: .keywords: KSP, create, context, norms
211: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged(), KSPSetNormType()
212: @*/
213: PetscErrorCode KSPSetLagNorm(KSP ksp,PetscTruth flg)
214: {
217: ksp->lagnorm = flg;
218: return(0);
219: }
223: /*@
224: KSPGetNormType - Sets the norm that is used for convergence testing.
226: Not Collective
228: Input Parameter:
229: . ksp - Krylov solver context
231: Output Parameter:
232: . normtype - norm that is used for convergence testing
234: Level: advanced
236: .keywords: KSP, create, context, norms
238: .seealso: KSPNormType, KSPSetNormType(), KSPSkipConverged()
239: @*/
240: PetscErrorCode KSPGetNormType(KSP ksp, KSPNormType *normtype) {
244: *normtype = ksp->normtype;
245: return(0);
246: }
248: #if 0
251: static PetscErrorCode KSPPublish_Petsc(PetscObject obj)
252: {
254: return(0);
255: }
256: #endif
260: /*@
261: KSPSetOperators - Sets the matrix associated with the linear system
262: and a (possibly) different one associated with the preconditioner.
264: Collective on KSP and Mat
266: Input Parameters:
267: + ksp - the KSP context
268: . Amat - the matrix associated with the linear system
269: . Pmat - the matrix to be used in constructing the preconditioner, usually the
270: same as Amat.
271: - flag - flag indicating information about the preconditioner matrix structure
272: during successive linear solves. This flag is ignored the first time a
273: linear system is solved, and thus is irrelevant when solving just one linear
274: system.
276: Notes:
277: The flag can be used to eliminate unnecessary work in the preconditioner
278: during the repeated solution of linear systems of the same size. The
279: available options are
280: $ SAME_PRECONDITIONER -
281: $ Pmat is identical during successive linear solves.
282: $ This option is intended for folks who are using
283: $ different Amat and Pmat matrices and want to reuse the
284: $ same preconditioner matrix. For example, this option
285: $ saves work by not recomputing incomplete factorization
286: $ for ILU/ICC preconditioners.
287: $ SAME_NONZERO_PATTERN -
288: $ Pmat has the same nonzero structure during
289: $ successive linear solves.
290: $ DIFFERENT_NONZERO_PATTERN -
291: $ Pmat does not have the same nonzero structure.
293: Passing a PETSC_NULL for Amat or Pmat removes the matrix that is currently used.
295: If you wish to replace either Amat or Pmat but leave the other one untouched then
296: first call KSPGetOperators() to get the one you wish to keep, call PetscObjectReference()
297: on it and then pass it back in in your call to KSPSetOperators().
299: Caution:
300: If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
301: and does not check the structure of the matrix. If you erroneously
302: claim that the structure is the same when it actually is not, the new
303: preconditioner will not function correctly. Thus, use this optimization
304: feature carefully!
306: If in doubt about whether your preconditioner matrix has changed
307: structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
309: Level: beginner
311: Alternative usage: If the operators have NOT been set with KSP/PCSetOperators() then the operators
312: are created in PC and returned to the user. In this case, if both operators
313: mat and pmat are requested, two DIFFERENT operators will be returned. If
314: only one is requested both operators in the PC will be the same (i.e. as
315: if one had called KSP/PCSetOperators() with the same argument for both Mats).
316: The user must set the sizes of the returned matrices and their type etc just
317: as if the user created them with MatCreate(). For example,
319: $ KSP/PCGetOperators(ksp/pc,&mat,PETSC_NULL,PETSC_NULL); is equivalent to
320: $ set size, type, etc of mat
322: $ MatCreate(comm,&mat);
323: $ KSP/PCSetOperators(ksp/pc,mat,mat,SAME_NONZERO_PATTERN);
324: $ PetscObjectDereference((PetscObject)mat);
325: $ set size, type, etc of mat
327: and
329: $ KSP/PCGetOperators(ksp/pc,&mat,&pmat,PETSC_NULL); is equivalent to
330: $ set size, type, etc of mat and pmat
332: $ MatCreate(comm,&mat);
333: $ MatCreate(comm,&pmat);
334: $ KSP/PCSetOperators(ksp/pc,mat,pmat,SAME_NONZERO_PATTERN);
335: $ PetscObjectDereference((PetscObject)mat);
336: $ PetscObjectDereference((PetscObject)pmat);
337: $ set size, type, etc of mat and pmat
339: The rational for this support is so that when creating a TS, SNES, or KSP the hierarchy
340: of underlying objects (i.e. SNES, KSP, PC, Mat) and their livespans can be completely
341: managed by the top most level object (i.e. the TS, SNES, or KSP). Another way to look
342: at this is when you create a SNES you do not NEED to create a KSP and attach it to
343: the SNES object (the SNES object manages it for you). Similarly when you create a KSP
344: you do not need to attach a PC to it (the KSP object manages the PC object for you).
345: Thus, why should YOU have to create the Mat and attach it to the SNES/KSP/PC, when
346: it can be created for you?
348: .keywords: KSP, set, operators, matrix, preconditioner, linear system
350: .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPGetOperators()
351: @*/
352: PetscErrorCode KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat,MatStructure flag)
353: {
362: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
363: PCSetOperators(ksp->pc,Amat,Pmat,flag);
364: if (ksp->setupcalled > 1) ksp->setupcalled = 1; /* so that next solve call will call setup */
365: if (ksp->guess) {
366: KSPFischerGuessReset(ksp->guess);
367: }
368: return(0);
369: }
373: /*@
374: KSPGetOperators - Gets the matrix associated with the linear system
375: and a (possibly) different one associated with the preconditioner.
377: Collective on KSP and Mat
379: Input Parameter:
380: . ksp - the KSP context
382: Output Parameters:
383: + Amat - the matrix associated with the linear system
384: . Pmat - the matrix to be used in constructing the preconditioner, usually the
385: same as Amat.
386: - flag - flag indicating information about the preconditioner matrix structure
387: during successive linear solves. This flag is ignored the first time a
388: linear system is solved, and thus is irrelevant when solving just one linear
389: system.
391: Level: intermediate
393: .keywords: KSP, set, get, operators, matrix, preconditioner, linear system
395: .seealso: KSPSolve(), KSPGetPC(), PCGetOperators(), PCSetOperators(), KSPSetOperators(), KSPGetOperatorsSet()
396: @*/
397: PetscErrorCode KSPGetOperators(KSP ksp,Mat *Amat,Mat *Pmat,MatStructure *flag)
398: {
403: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
404: PCGetOperators(ksp->pc,Amat,Pmat,flag);
405: return(0);
406: }
410: /*@C
411: KSPGetOperatorsSet - Determines if the matrix associated with the linear system and
412: possibly a different one associated with the preconditioner have been set in the KSP.
414: Not collective, though the results on all processes should be the same
416: Input Parameter:
417: . pc - the preconditioner context
419: Output Parameters:
420: + mat - the matrix associated with the linear system was set
421: - pmat - matrix associated with the preconditioner was set, usually the same
423: Level: intermediate
425: .keywords: KSP, get, operators, matrix, linear system
427: .seealso: PCSetOperators(), KSPGetOperators(), KSPSetOperators(), PCGetOperators(), PCGetOperatorsSet()
428: @*/
429: PetscErrorCode KSPGetOperatorsSet(KSP ksp,PetscTruth *mat,PetscTruth *pmat)
430: {
435: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
436: PCGetOperatorsSet(ksp->pc,mat,pmat);
437: return(0);
438: }
442: /*@
443: KSPCreate - Creates the default KSP context.
445: Collective on MPI_Comm
447: Input Parameter:
448: . comm - MPI communicator
450: Output Parameter:
451: . ksp - location to put the KSP context
453: Notes:
454: The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt
455: orthogonalization.
457: Level: beginner
459: .keywords: KSP, create, context
461: .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP
462: @*/
463: PetscErrorCode KSPCreate(MPI_Comm comm,KSP *inksp)
464: {
465: KSP ksp;
467: void *ctx;
471: *inksp = 0;
472: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
473: KSPInitializePackage(PETSC_NULL);
474: #endif
476: PetscHeaderCreate(ksp,_p_KSP,struct _KSPOps,KSP_COOKIE,-1,"KSP",comm,KSPDestroy,KSPView);
478: ksp->max_it = 10000;
479: ksp->pc_side = PC_LEFT;
480: ksp->rtol = 1.e-5;
481: ksp->abstol = 1.e-50;
482: ksp->divtol = 1.e4;
483:
484: ksp->chknorm = -1;
485: ksp->normtype = KSP_NORM_PRECONDITIONED;
486: ksp->rnorm = 0.0;
487: ksp->its = 0;
488: ksp->guess_zero = PETSC_TRUE;
489: ksp->calc_sings = PETSC_FALSE;
490: ksp->res_hist = PETSC_NULL;
491: ksp->res_hist_alloc = PETSC_NULL;
492: ksp->res_hist_len = 0;
493: ksp->res_hist_max = 0;
494: ksp->res_hist_reset = PETSC_TRUE;
495: ksp->numbermonitors = 0;
497: KSPDefaultConvergedCreate(&ctx);
498: KSPSetConvergenceTest(ksp,KSPDefaultConverged,ctx,KSPDefaultConvergedDestroy);
499: ksp->ops->buildsolution = KSPDefaultBuildSolution;
500: ksp->ops->buildresidual = KSPDefaultBuildResidual;
502: ksp->vec_sol = 0;
503: ksp->vec_rhs = 0;
504: ksp->pc = 0;
505: ksp->data = 0;
506: ksp->nwork = 0;
507: ksp->work = 0;
508: ksp->reason = KSP_CONVERGED_ITERATING;
509: ksp->setupcalled = 0;
511: PetscPublishAll(ksp);
512: *inksp = ksp;
513: return(0);
514: }
515:
518: /*@C
519: KSPSetType - Builds KSP for a particular solver.
521: Collective on KSP
523: Input Parameters:
524: + ksp - the Krylov space context
525: - type - a known method
527: Options Database Key:
528: . -ksp_type <method> - Sets the method; use -help for a list
529: of available methods (for instance, cg or gmres)
531: Notes:
532: See "petsc/include/petscksp.h" for available methods (for instance,
533: KSPCG or KSPGMRES).
535: Normally, it is best to use the KSPSetFromOptions() command and
536: then set the KSP type from the options database rather than by using
537: this routine. Using the options database provides the user with
538: maximum flexibility in evaluating the many different Krylov methods.
539: The KSPSetType() routine is provided for those situations where it
540: is necessary to set the iterative solver independently of the command
541: line or options database. This might be the case, for example, when
542: the choice of iterative solver changes during the execution of the
543: program, and the user's application is taking responsibility for
544: choosing the appropriate method. In other words, this routine is
545: not for beginners.
547: Level: intermediate
549: .keywords: KSP, set, method
551: .seealso: PCSetType(), KSPType
553: @*/
554: PetscErrorCode KSPSetType(KSP ksp, const KSPType type)
555: {
556: PetscErrorCode ierr,(*r)(KSP);
557: PetscTruth match;
563: PetscTypeCompare((PetscObject)ksp,type,&match);
564: if (match) return(0);
566: PetscFListFind(KSPList,((PetscObject)ksp)->comm,type,(void (**)(void)) &r);
567: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested KSP type %s",type);
568: /* Destroy the previous private KSP context */
569: if (ksp->ops->destroy) { (*ksp->ops->destroy)(ksp); }
570: /* Reinitialize function pointers in KSPOps structure */
571: PetscMemzero(ksp->ops,sizeof(struct _KSPOps));
572: ksp->ops->buildsolution = KSPDefaultBuildSolution;
573: ksp->ops->buildresidual = KSPDefaultBuildResidual;
574: /* Call the KSPCreate_XXX routine for this particular Krylov solver */
575: ksp->setupcalled = 0;
576: (*r)(ksp);
577: PetscObjectChangeTypeName((PetscObject)ksp,type);
578: return(0);
579: }
583: /*@
584: KSPRegisterDestroy - Frees the list of KSP methods that were
585: registered by KSPRegisterDynamic().
587: Not Collective
589: Level: advanced
591: .keywords: KSP, register, destroy
593: .seealso: KSPRegisterDynamic(), KSPRegisterAll()
594: @*/
595: PetscErrorCode KSPRegisterDestroy(void)
596: {
600: PetscFListDestroy(&KSPList);
601: KSPRegisterAllCalled = PETSC_FALSE;
602: return(0);
603: }
607: /*@C
608: KSPGetType - Gets the KSP type as a string from the KSP object.
610: Not Collective
612: Input Parameter:
613: . ksp - Krylov context
615: Output Parameter:
616: . name - name of KSP method
618: Level: intermediate
620: .keywords: KSP, get, method, name
622: .seealso: KSPSetType()
623: @*/
624: PetscErrorCode KSPGetType(KSP ksp,const KSPType *type)
625: {
629: *type = ((PetscObject)ksp)->type_name;
630: return(0);
631: }
635: /*@C
636: KSPRegister - See KSPRegisterDynamic()
638: Level: advanced
639: @*/
640: PetscErrorCode KSPRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(KSP))
641: {
643: char fullname[PETSC_MAX_PATH_LEN];
646: PetscFListConcat(path,name,fullname);
647: PetscFListAdd(&KSPList,sname,fullname,(void (*)(void))function);
648: return(0);
649: }
653: /*@
654: KSPSetNullSpace - Sets the null space of the operator
656: Collective on KSP
658: Input Parameters:
659: + ksp - the Krylov space object
660: - nullsp - the null space of the operator
662: Level: advanced
664: .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPGetNullSpace()
665: @*/
666: PetscErrorCode KSPSetNullSpace(KSP ksp,MatNullSpace nullsp)
667: {
673: PetscObjectReference((PetscObject)nullsp);
674: if (ksp->nullsp) { MatNullSpaceDestroy(ksp->nullsp); }
675: ksp->nullsp = nullsp;
676: return(0);
677: }
681: /*@
682: KSPGetNullSpace - Gets the null space of the operator
684: Collective on KSP
686: Input Parameters:
687: + ksp - the Krylov space object
688: - nullsp - the null space of the operator
690: Level: advanced
692: .seealso: KSPSetOperators(), MatNullSpaceCreate(), KSPSetNullSpace()
693: @*/
694: PetscErrorCode KSPGetNullSpace(KSP ksp,MatNullSpace *nullsp)
695: {
699: *nullsp = ksp->nullsp;
700: return(0);
701: }