Actual source code: itfunc.c
1: /*$Id: itfunc.c,v 1.159 2001/08/07 03:03:45 balay Exp $*/
2: /*
3: Interface KSP routines that the user calls.
4: */
6: #include src/ksp/ksp/kspimpl.h
10: /*@
11: KSPComputeExtremeSingularValues - Computes the extreme singular values
12: for the preconditioned operator. Called after or during KSPSolve().
14: Not Collective
16: Input Parameter:
17: . ksp - iterative context obtained from KSPCreate()
19: Output Parameters:
20: . emin, emax - extreme singular values
22: Notes:
23: One must call KSPSetComputeSingularValues() before calling KSPSetUp()
24: (or use the option -ksp_compute_eigenvalues) in order for this routine to work correctly.
26: Many users may just want to use the monitoring routine
27: KSPSingularValueMonitor() (which can be set with option -ksp_singmonitor)
28: to print the extreme singular values at each iteration of the linear solve.
30: Level: advanced
32: .keywords: KSP, compute, extreme, singular, values
34: .seealso: KSPSetComputeSingularValues(), KSPSingularValueMonitor(), KSPComputeEigenvalues()
35: @*/
36: int KSPComputeExtremeSingularValues(KSP ksp,PetscReal *emax,PetscReal *emin)
37: {
44: if (!ksp->calc_sings) {
45: SETERRQ(4,"Singular values not requested before KSPSetUp()");
46: }
48: if (ksp->ops->computeextremesingularvalues) {
49: (*ksp->ops->computeextremesingularvalues)(ksp,emax,emin);
50: } else {
51: *emin = -1.0;
52: *emax = -1.0;
53: }
54: return(0);
55: }
59: /*@
60: KSPComputeEigenvalues - Computes the extreme eigenvalues for the
61: preconditioned operator. Called after or during KSPSolve().
63: Not Collective
65: Input Parameter:
66: + ksp - iterative context obtained from KSPCreate()
67: - n - size of arrays r and c. The number of eigenvalues computed (neig) will, in
68: general, be less than this.
70: Output Parameters:
71: + r - real part of computed eigenvalues
72: . c - complex part of computed eigenvalues
73: - neig - number of eigenvalues computed (will be less than or equal to n)
75: Options Database Keys:
76: + -ksp_compute_eigenvalues - Prints eigenvalues to stdout
77: - -ksp_plot_eigenvalues - Plots eigenvalues in an x-window display
79: Notes:
80: The number of eigenvalues estimated depends on the size of the Krylov space
81: generated during the KSPSolve() ; for example, with
82: CG it corresponds to the number of CG iterations, for GMRES it is the number
83: of GMRES iterations SINCE the last restart. Any extra space in r[] and c[]
84: will be ignored.
86: KSPComputeEigenvalues() does not usually provide accurate estimates; it is
87: intended only for assistance in understanding the convergence of iterative
88: methods, not for eigenanalysis.
90: One must call KSPSetComputeEigenvalues() before calling KSPSetUp()
91: in order for this routine to work correctly.
93: Many users may just want to use the monitoring routine
94: KSPSingularValueMonitor() (which can be set with option -ksp_singmonitor)
95: to print the singular values at each iteration of the linear solve.
97: Level: advanced
99: .keywords: KSP, compute, extreme, singular, values
101: .seealso: KSPSetComputeSingularValues(), KSPSingularValueMonitor(), KSPComputeExtremeSingularValues()
102: @*/
103: int KSPComputeEigenvalues(KSP ksp,int n,PetscReal *r,PetscReal *c,int *neig)
104: {
112: if (!ksp->calc_sings) {
113: SETERRQ(4,"Eigenvalues not requested before KSPSetUp()");
114: }
116: if (ksp->ops->computeeigenvalues) {
117: (*ksp->ops->computeeigenvalues)(ksp,n,r,c,neig);
118: } else {
119: *neig = 0;
120: }
121: return(0);
122: }
126: /*@
127: KSPSetUpOnBlocks - Sets up the preconditioner for each block in
128: the block Jacobi, block Gauss-Seidel, and overlapping Schwarz
129: methods.
131: Collective on KSP
133: Input Parameter:
134: . ksp - the KSP context
136: Notes:
137: KSPSetUpOnBlocks() is a routine that the user can optinally call for
138: more precise profiling (via -log_summary) of the setup phase for these
139: block preconditioners. If the user does not call KSPSetUpOnBlocks(),
140: it will automatically be called from within KSPSolve().
141:
142: Calling KSPSetUpOnBlocks() is the same as calling PCSetUpOnBlocks()
143: on the PC context within the KSP context.
145: Level: advanced
147: .keywords: KSP, setup, blocks
149: .seealso: PCSetUpOnBlocks(), KSPSetUp(), PCSetUp()
150: @*/
151: int KSPSetUpOnBlocks(KSP ksp)
152: {
157: PCSetUpOnBlocks(ksp->B);
158: return(0);
159: }
163: /*@
164: KSPSetUp - Sets up the internal data structures for the
165: later use of an iterative solver.
167: Collective on KSP
169: Input Parameter:
170: . ksp - iterative context obtained from KSPCreate()
172: Level: developer
174: .keywords: KSP, setup
176: .seealso: KSPCreate(), KSPSolve(), KSPDestroy()
177: @*/
178: int KSPSetUp(KSP ksp)
179: {
185: /* reset the convergence flag from the previous solves */
186: ksp->reason = KSP_CONVERGED_ITERATING;
188: if (!ksp->type_name){
189: KSPSetType(ksp,KSPGMRES);
190: }
192: if (ksp->setupcalled == 2) return(0);
194: PetscLogEventBegin(KSP_SetUp,ksp,ksp->vec_rhs,ksp->vec_sol,0);
195: PCSetVector(ksp->B,ksp->vec_rhs);
197: if (ksp->setupcalled == 0) {
198: (*ksp->ops->setup)(ksp);
199: }
201: /* scale the matrix if requested */
202: if (ksp->dscale) {
203: Mat mat,pmat;
204: PCGetOperators(ksp->B,&mat,&pmat,PETSC_NULL);
205: if (mat == pmat) {
206: PetscScalar *xx;
207: int i,n;
208: PetscTruth zeroflag = PETSC_FALSE;
210: if (!ksp->diagonal) { /* allocate vector to hold diagonal */
211: VecDuplicate(ksp->vec_rhs,&ksp->diagonal);
212: }
213: MatGetDiagonal(mat,ksp->diagonal);
214: VecGetLocalSize(ksp->diagonal,&n);
215: VecGetArray(ksp->diagonal,&xx);
216: for (i=0; i<n; i++) {
217: if (xx[i] != 0.0) xx[i] = 1.0/sqrt(PetscAbsScalar(xx[i]));
218: else {
219: xx[i] = 1.0;
220: zeroflag = PETSC_TRUE;
221: }
222: }
223: VecRestoreArray(ksp->diagonal,&xx);
224: if (zeroflag) {
225: PetscLogInfo(ksp,"KSPSetUp:Zero detected in diagonal of matrix, using 1 at those locations\n");
226: }
227: MatDiagonalScale(mat,ksp->diagonal,ksp->diagonal);
228: ksp->dscalefix2 = PETSC_FALSE;
229: } else {
230: SETERRQ(1,"No support for diagonal scaling of linear system if preconditioner matrix not actual matrix");
231: }
232: }
233: PetscLogEventEnd(KSP_SetUp,ksp,ksp->vec_rhs,ksp->vec_sol,0);
234: PCSetUp(ksp->B);
235: ksp->setupcalled = 2;
236: return(0);
237: }
239: static const char *convergedreasons[] = {"preconditioner is indefinite", "matrix or preconditioner is nonsymmetric",
240: "breakdown in BICG", "breakdown",
241: "residual norm increased by dtol", "reach maximum number of iterations",
242: "not used", "not used",
243: "never reached", "not used",
244: "residual norm decreased by relative tolerance", "residual norm decreased by absolute tolerance",
245: "only one iteration requested", "negative curvature obtained in QCG",
246: "constrained in QCG", "small step length reached"};
250: /*@
251: KSPSolve - Solves linear system.
253: Collective on KSP
255: Parameter:
256: . ksp - iterative context obtained from KSPCreate()
258: Options Database Keys:
259: + -ksp_compute_eigenvalues - compute preconditioned operators eigenvalues
260: . -ksp_plot_eigenvalues - plot the computed eigenvalues in an X-window
261: . -ksp_compute_eigenvalues_explicitly - compute the eigenvalues by forming the
262: dense operator and useing LAPACK
263: . -ksp_plot_eigenvalues_explicitly - plot the explicitly computing eigenvalues
264: . -ksp_view_binary - save matrix and right hand side that define linear system to the
265: default binary viewer (can be
266: read later with src/ksp/examples/tutorials/ex10.c for testing solvers)
267: - -ksp_view - print the ksp data structure at the end of the system solution
269: Notes:
271: The input and output are set with KSPSetRhs() and KSPSetSolution().
272: The operator is specified with PCSetOperators().
274: Call KSPGetConvergedReason() to determine if the solver converged or failed and
275: why. The number of iterations can be obtained from KSPGetIterationNumber().
276:
277: If using a direct method (e.g., via the KSP solver
278: KSPPREONLY and a preconditioner such as PCLU/PCILU),
279: then its=1. See KSPSetTolerances() and KSPDefaultConverged()
280: for more details.
282: Understanding Convergence:
283: The routines KSPSetMonitor(), KSPComputeEigenvalues(), and
284: KSPComputeEigenvaluesExplicitly() provide information on additional
285: options to monitor convergence and print eigenvalue information.
287: Level: beginner
289: .keywords: KSP, solve, linear system
291: .seealso: KSPCreate(), KSPSetUp(), KSPDestroy(), KSPSetTolerances(), KSPDefaultConverged(),
292: KSPSolveTranspose(), KSPGetIterationNumber()
293: @*/
294: int KSPSolve(KSP ksp)
295: {
296: int ierr,rank;
297: PetscTruth flag1,flag2,flg;
298: PetscScalar zero = 0.0;
303: PetscOptionsHasName(ksp->prefix,"-ksp_view_binary",&flg);
304: if (flg) {
305: Mat mat;
306: PCGetOperators(ksp->B,&mat,PETSC_NULL,PETSC_NULL);
307: MatView(mat,PETSC_VIEWER_BINARY_(ksp->comm));
308: VecView(ksp->vec_rhs,PETSC_VIEWER_BINARY_(ksp->comm));
309: }
311: PetscLogEventBegin(KSP_Solve,ksp,ksp->vec_rhs,ksp->vec_sol,0);
313: /* reset the residual history list if requested */
314: if (ksp->res_hist_reset) ksp->res_hist_len = 0;
316: KSPSetUp(ksp);
317: KSPSetUpOnBlocks(ksp);
319: ksp->transpose_solve = PETSC_FALSE;
320: PCPreSolve(ksp->B,ksp);
321: /* diagonal scale RHS if called for */
322: if (ksp->dscale) {
323: VecPointwiseMult(ksp->diagonal,ksp->vec_rhs,ksp->vec_rhs);
324: /* second time in, but matrix was scaled back to original */
325: if (ksp->dscalefix && ksp->dscalefix2) {
326: Mat mat;
328: PCGetOperators(ksp->B,&mat,PETSC_NULL,PETSC_NULL);
329: MatDiagonalScale(mat,ksp->diagonal,ksp->diagonal);
330: }
331: }
333: KSPSetUp(ksp);
334: if (ksp->guess_zero) { VecSet(&zero,ksp->vec_sol);}
335: if (ksp->guess_knoll) {
336: PCApply(ksp->B,ksp->vec_rhs,ksp->vec_sol,PC_LEFT);
337: ksp->guess_zero = PETSC_FALSE;
338: }
339: (*ksp->ops->solve)(ksp);
340: if (!ksp->reason) {
341: SETERRQ(1,"Internal error, solver returned without setting converged reason");
342: }
343: if (ksp->printreason) {
344: if (ksp->reason > 0) {
345: PetscPrintf(ksp->comm,"Linear solve converged due to %s\n",convergedreasons[ksp->reason+8]);
346: } else {
347: PetscPrintf(ksp->comm,"Linear solve did not converge due to %s\n",convergedreasons[ksp->reason+8]);
348: }
349: }
351: /* diagonal scale solution if called for */
352: if (ksp->dscale) {
353: VecPointwiseMult(ksp->diagonal,ksp->vec_sol,ksp->vec_sol);
354: /* unscale right hand side and matrix */
355: if (ksp->dscalefix) {
356: Mat mat;
358: VecReciprocal(ksp->diagonal);
359: VecPointwiseMult(ksp->diagonal,ksp->vec_rhs,ksp->vec_rhs);
360: PCGetOperators(ksp->B,&mat,PETSC_NULL,PETSC_NULL);
361: MatDiagonalScale(mat,ksp->diagonal,ksp->diagonal);
362: VecReciprocal(ksp->diagonal);
363: ksp->dscalefix2 = PETSC_TRUE;
364: }
365: }
366: PCPostSolve(ksp->B,ksp);
367: PetscLogEventEnd(KSP_Solve,ksp,ksp->vec_rhs,ksp->vec_sol,0);
369: MPI_Comm_rank(ksp->comm,&rank);
371: PetscOptionsHasName(ksp->prefix,"-ksp_compute_eigenvalues",&flag1);
372: PetscOptionsHasName(ksp->prefix,"-ksp_plot_eigenvalues",&flag2);
373: if (flag1 || flag2) {
374: int nits,n,i,neig;
375: PetscReal *r,*c;
376:
377: KSPGetIterationNumber(ksp,&nits);
378: n = nits+2;
380: if (!n) {
381: PetscPrintf(ksp->comm,"Zero iterations in solver, cannot approximate any eigenvalues\n");
382: } else {
383: PetscMalloc(2*n*sizeof(PetscReal),&r);
384: c = r + n;
385: KSPComputeEigenvalues(ksp,n,r,c,&neig);
386: if (flag1) {
387: PetscPrintf(ksp->comm,"Iteratively computed eigenvalues\n");
388: for (i=0; i<neig; i++) {
389: if (c[i] >= 0.0) {PetscPrintf(ksp->comm,"%g + %gi\n",r[i],c[i]);}
390: else {PetscPrintf(ksp->comm,"%g - %gi\n",r[i],-c[i]);}
391: }
392: }
393: if (flag2 && !rank) {
394: PetscViewer viewer;
395: PetscDraw draw;
396: PetscDrawSP drawsp;
398: PetscViewerDrawOpen(PETSC_COMM_SELF,0,"Iteratively Computed Eigenvalues",
399: PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
400: PetscViewerDrawGetDraw(viewer,0,&draw);
401: PetscDrawSPCreate(draw,1,&drawsp);
402: for (i=0; i<neig; i++) {
403: PetscDrawSPAddPoint(drawsp,r+i,c+i);
404: }
405: PetscDrawSPDraw(drawsp);
406: PetscDrawSPDestroy(drawsp);
407: PetscViewerDestroy(viewer);
408: }
409: PetscFree(r);
410: }
411: }
413: PetscOptionsHasName(ksp->prefix,"-ksp_compute_eigenvalues_explicitly",&flag1);
414: PetscOptionsHasName(ksp->prefix,"-ksp_plot_eigenvalues_explicitly",&flag2);
415: if (flag1 || flag2) {
416: int n,i;
417: PetscReal *r,*c;
418: VecGetSize(ksp->vec_sol,&n);
419: PetscMalloc(2*n*sizeof(PetscReal),&r);
420: c = r + n;
421: KSPComputeEigenvaluesExplicitly(ksp,n,r,c);
422: if (flag1) {
423: PetscPrintf(ksp->comm,"Explicitly computed eigenvalues\n");
424: for (i=0; i<n; i++) {
425: if (c[i] >= 0.0) {PetscPrintf(ksp->comm,"%g + %gi\n",r[i],c[i]);}
426: else {PetscPrintf(ksp->comm,"%g - %gi\n",r[i],-c[i]);}
427: }
428: }
429: if (flag2 && !rank) {
430: PetscViewer viewer;
431: PetscDraw draw;
432: PetscDrawSP drawsp;
434: PetscViewerDrawOpen(PETSC_COMM_SELF,0,"Explicitly Computed Eigenvalues",0,320,300,300,&viewer);
435: PetscViewerDrawGetDraw(viewer,0,&draw);
436: PetscDrawSPCreate(draw,1,&drawsp);
437: for (i=0; i<n; i++) {
438: PetscDrawSPAddPoint(drawsp,r+i,c+i);
439: }
440: PetscDrawSPDraw(drawsp);
441: PetscDrawSPDestroy(drawsp);
442: PetscViewerDestroy(viewer);
443: }
444: PetscFree(r);
445: }
447: PetscOptionsHasName(ksp->prefix,"-ksp_view_operator",&flag2);
448: if (flag2) {
449: Mat A,B;
450: PCGetOperators(ksp->B,&A,PETSC_NULL,PETSC_NULL);
451: MatComputeExplicitOperator(A,&B);
452: PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(ksp->comm),PETSC_VIEWER_ASCII_MATLAB);
453: MatView(B,PETSC_VIEWER_STDOUT_(ksp->comm));
454: PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(ksp->comm));
455: MatDestroy(B);
456: }
457: PetscOptionsHasName(ksp->prefix,"-ksp_view_operator_binary",&flag2);
458: if (flag2) {
459: Mat A,B;
460: PCGetOperators(ksp->B,&A,PETSC_NULL,PETSC_NULL);
461: MatComputeExplicitOperator(A,&B);
462: MatView(B,PETSC_VIEWER_BINARY_(ksp->comm));
463: MatDestroy(B);
464: }
465: PetscOptionsHasName(ksp->prefix,"-ksp_view_preconditioned_operator_binary",&flag2);
466: if (flag2) {
467: Mat B;
468: KSPComputeExplicitOperator(ksp,&B);
469: MatView(B,PETSC_VIEWER_BINARY_(ksp->comm));
470: MatDestroy(B);
471: }
472: PetscOptionsHasName(ksp->prefix,"-ksp_view",&flg);
473: if (flg) {
474: KSPView(ksp,PETSC_VIEWER_STDOUT_(ksp->comm));
475: }
476: return(0);
477: }
481: /*@
482: KSPSolveTranspose - Solves the transpose of a linear system. Usually
483: accessed through KSPSolveTranspose().
485: Collective on KSP
487: Input Parameter:
488: . ksp - iterative context obtained from KSPCreate()
490: Notes:
491: On return, the parameter "its" contains either the iteration
492: number at which convergence was successfully reached, or the
493: negative of the iteration at which divergence or breakdown was detected.
495: Currently only supported by KSPType of KSPPREONLY. This routine is usally
496: only used internally by the BiCG solver on the subblocks in BJacobi and ASM.
498: Level: developer
500: .keywords: KSP, solve, linear system
502: .seealso: KSPCreate(), KSPSetUp(), KSPDestroy(), KSPSetTolerances(), KSPDefaultConverged(),
503: KSPSolve()
504: @*/
505: int KSPSolveTranspose(KSP ksp)
506: {
507: int ierr;
508: PetscScalar zero = 0.0;
513: KSPSetUp(ksp);
514: if (ksp->guess_zero) { VecSet(&zero,ksp->vec_sol);}
515: ksp->transpose_solve = PETSC_TRUE;
516: (*ksp->ops->solve)(ksp);
517: return(0);
518: }
522: /*@C
523: KSPDestroy - Destroys KSP context.
525: Collective on KSP
527: Input Parameter:
528: . ksp - iterative context obtained from KSPCreate()
530: Level: developer
532: .keywords: KSP, destroy
534: .seealso: KSPCreate(), KSPSetUp(), KSPSolve()
535: @*/
536: int KSPDestroy(KSP ksp)
537: {
538: int i,ierr;
542: if (--ksp->refct > 0) return(0);
544: /* if memory was published with AMS then destroy it */
545: PetscObjectDepublish(ksp);
547: if (ksp->ops->destroy) {
548: (*ksp->ops->destroy)(ksp);
549: }
550: for (i=0; i<ksp->numbermonitors; i++) {
551: if (ksp->monitordestroy[i]) {
552: (*ksp->monitordestroy[i])(ksp->monitorcontext[i]);
553: }
554: }
555: PCDestroy(ksp->B);
556: if (ksp->diagonal) {VecDestroy(ksp->diagonal);}
557: PetscLogObjectDestroy(ksp);
558: PetscHeaderDestroy(ksp);
559: return(0);
560: }
564: /*@
565: KSPSetPreconditionerSide - Sets the preconditioning side.
567: Collective on KSP
569: Input Parameter:
570: . ksp - iterative context obtained from KSPCreate()
572: Output Parameter:
573: . side - the preconditioning side, where side is one of
574: .vb
575: PC_LEFT - left preconditioning (default)
576: PC_RIGHT - right preconditioning
577: PC_SYMMETRIC - symmetric preconditioning
578: .ve
580: Options Database Keys:
581: + -ksp_left_pc - Sets left preconditioning
582: . -ksp_right_pc - Sets right preconditioning
583: - -ksp_symmetric_pc - Sets symmetric preconditioning
585: Notes:
586: Left preconditioning is used by default. Symmetric preconditioning is
587: currently available only for the KSPQCG method. Note, however, that
588: symmetric preconditioning can be emulated by using either right or left
589: preconditioning and a pre or post processing step.
591: Level: intermediate
593: .keywords: KSP, set, right, left, symmetric, side, preconditioner, flag
595: .seealso: KSPGetPreconditionerSide()
596: @*/
597: int KSPSetPreconditionerSide(KSP ksp,PCSide side)
598: {
601: ksp->pc_side = side;
602: return(0);
603: }
607: /*@C
608: KSPGetPreconditionerSide - Gets the preconditioning side.
610: Not Collective
612: Input Parameter:
613: . ksp - iterative context obtained from KSPCreate()
615: Output Parameter:
616: . side - the preconditioning side, where side is one of
617: .vb
618: PC_LEFT - left preconditioning (default)
619: PC_RIGHT - right preconditioning
620: PC_SYMMETRIC - symmetric preconditioning
621: .ve
623: Level: intermediate
625: .keywords: KSP, get, right, left, symmetric, side, preconditioner, flag
627: .seealso: KSPSetPreconditionerSide()
628: @*/
629: int KSPGetPreconditionerSide(KSP ksp,PCSide *side)
630: {
634: *side = ksp->pc_side;
635: return(0);
636: }
640: /*@
641: KSPGetTolerances - Gets the relative, absolute, divergence, and maximum
642: iteration tolerances used by the default KSP convergence tests.
644: Not Collective
646: Input Parameter:
647: . ksp - the Krylov subspace context
648:
649: Output Parameters:
650: + rtol - the relative convergence tolerance
651: . atol - the absolute convergence tolerance
652: . dtol - the divergence tolerance
653: - maxits - maximum number of iterations
655: Notes:
656: The user can specify PETSC_NULL for any parameter that is not needed.
658: Level: intermediate
660: .keywords: KSP, get, tolerance, absolute, relative, divergence, convergence,
661: maximum, iterations
663: .seealso: KSPSetTolerances()
664: @*/
665: int KSPGetTolerances(KSP ksp,PetscReal *rtol,PetscReal *atol,PetscReal *dtol,int *maxits)
666: {
669: if (atol) *atol = ksp->atol;
670: if (rtol) *rtol = ksp->rtol;
671: if (dtol) *dtol = ksp->divtol;
672: if (maxits) *maxits = ksp->max_it;
673: return(0);
674: }
678: /*@
679: KSPSetTolerances - Sets the relative, absolute, divergence, and maximum
680: iteration tolerances used by the default KSP convergence testers.
682: Collective on KSP
684: Input Parameters:
685: + ksp - the Krylov subspace context
686: . rtol - the relative convergence tolerance
687: (relative decrease in the residual norm)
688: . atol - the absolute convergence tolerance
689: (absolute size of the residual norm)
690: . dtol - the divergence tolerance
691: (amount residual can increase before KSPDefaultConverged()
692: concludes that the method is diverging)
693: - maxits - maximum number of iterations to use
695: Options Database Keys:
696: + -ksp_atol <atol> - Sets atol
697: . -ksp_rtol <rtol> - Sets rtol
698: . -ksp_divtol <dtol> - Sets dtol
699: - -ksp_max_it <maxits> - Sets maxits
701: Notes:
702: Use PETSC_DEFAULT to retain the default value of any of the tolerances.
704: See KSPDefaultConverged() for details on the use of these parameters
705: in the default convergence test. See also KSPSetConvergenceTest()
706: for setting user-defined stopping criteria.
708: Level: intermediate
710: .keywords: KSP, set, tolerance, absolute, relative, divergence,
711: convergence, maximum, iterations
713: .seealso: KSPGetTolerances(), KSPDefaultConverged(), KSPSetConvergenceTest()
714: @*/
715: int KSPSetTolerances(KSP ksp,PetscReal rtol,PetscReal atol,PetscReal dtol,int maxits)
716: {
719: if (atol != PETSC_DEFAULT) ksp->atol = atol;
720: if (rtol != PETSC_DEFAULT) ksp->rtol = rtol;
721: if (dtol != PETSC_DEFAULT) ksp->divtol = dtol;
722: if (maxits != PETSC_DEFAULT) ksp->max_it = maxits;
723: return(0);
724: }
728: /*@
729: KSPSetInitialGuessNonzero - Tells the iterative solver that the
730: initial guess is nonzero; otherwise KSP assumes the initial guess
731: is to be zero (and thus zeros it out before solving).
733: Collective on KSP
735: Input Parameters:
736: + ksp - iterative context obtained from KSPCreate()
737: - flg - PETSC_TRUE indicates the guess is non-zero, PETSC_FALSE indicates the guess is zero
739: Level: beginner
741: Notes:
742: If this is not called the X vector is zeroed in the call to KSPSolve().
744: .keywords: KSP, set, initial guess, nonzero
746: .seealso: KSPGetInitialGuessNonzero(), KSPSetInitialGuessKnoll(), KSPGetInitialGuessKnoll()
747: @*/
748: int KSPSetInitialGuessNonzero(KSP ksp,PetscTruth flg)
749: {
751: ksp->guess_zero = (PetscTruth)!(int)flg;
752: return(0);
753: }
757: /*@
758: KSPGetInitialGuessNonzero - Determines whether the KSP solver is using
759: a zero initial guess.
761: Not Collective
763: Input Parameter:
764: . ksp - iterative context obtained from KSPCreate()
766: Output Parameter:
767: . flag - PETSC_TRUE if guess is nonzero, else PETSC_FALSE
769: Level: intermediate
771: .keywords: KSP, set, initial guess, nonzero
773: .seealso: KSPSetInitialGuessNonzero(), KSPSetInitialGuessKnoll(), KSPGetInitialGuessKnoll()
774: @*/
775: int KSPGetInitialGuessNonzero(KSP ksp,PetscTruth *flag)
776: {
778: if (ksp->guess_zero) *flag = PETSC_FALSE;
779: else *flag = PETSC_TRUE;
780: return(0);
781: }
785: /*@
786: KSPSetInitialGuessKnoll - Tells the iterative solver to use PCApply(pc,b,..) to compute the initial guess (The Knoll trick)
788: Collective on KSP
790: Input Parameters:
791: + ksp - iterative context obtained from KSPCreate()
792: - flg - PETSC_TRUE or PETSC_FALSE
794: Level: advanced
797: .keywords: KSP, set, initial guess, nonzero
799: .seealso: KSPGetInitialGuessKnoll(), KSPSetInitialGuessNonzero(), KSPGetInitialGuessNonzero()
800: @*/
801: int KSPSetInitialGuessKnoll(KSP ksp,PetscTruth flg)
802: {
804: ksp->guess_knoll = flg;
805: return(0);
806: }
810: /*@
811: KSPGetInitialGuessKnoll - Determines whether the KSP solver is using the Knoll trick (using PCApply(pc,b,...) to compute
812: the initial guess
814: Not Collective
816: Input Parameter:
817: . ksp - iterative context obtained from KSPCreate()
819: Output Parameter:
820: . flag - PETSC_TRUE if using Knoll trick, else PETSC_FALSE
822: Level: advanced
824: .keywords: KSP, set, initial guess, nonzero
826: .seealso: KSPSetInitialGuessKnoll(), KSPSetInitialGuessNonzero(), KSPGetInitialGuessNonzero()
827: @*/
828: int KSPGetInitialGuessKnoll(KSP ksp,PetscTruth *flag)
829: {
831: *flag = ksp->guess_knoll;
832: return(0);
833: }
837: /*@
838: KSPSetComputeSingularValues - Sets a flag so that the extreme singular
839: values will be calculated via a Lanczos or Arnoldi process as the linear
840: system is solved.
842: Collective on KSP
844: Input Parameters:
845: + ksp - iterative context obtained from KSPCreate()
846: - flg - PETSC_TRUE or PETSC_FALSE
848: Options Database Key:
849: . -ksp_singmonitor - Activates KSPSetComputeSingularValues()
851: Notes:
852: Currently this option is not valid for all iterative methods.
854: Many users may just want to use the monitoring routine
855: KSPSingularValueMonitor() (which can be set with option -ksp_singmonitor)
856: to print the singular values at each iteration of the linear solve.
858: Level: advanced
860: .keywords: KSP, set, compute, singular values
862: .seealso: KSPComputeExtremeSingularValues(), KSPSingularValueMonitor()
863: @*/
864: int KSPSetComputeSingularValues(KSP ksp,PetscTruth flg)
865: {
868: ksp->calc_sings = flg;
869: return(0);
870: }
874: /*@
875: KSPSetComputeEigenvalues - Sets a flag so that the extreme eigenvalues
876: values will be calculated via a Lanczos or Arnoldi process as the linear
877: system is solved.
879: Collective on KSP
881: Input Parameters:
882: + ksp - iterative context obtained from KSPCreate()
883: - flg - PETSC_TRUE or PETSC_FALSE
885: Notes:
886: Currently this option is not valid for all iterative methods.
888: Level: advanced
890: .keywords: KSP, set, compute, eigenvalues
892: .seealso: KSPComputeEigenvalues(), KSPComputeEigenvaluesExplicitly()
893: @*/
894: int KSPSetComputeEigenvalues(KSP ksp,PetscTruth flg)
895: {
898: ksp->calc_sings = flg;
899: return(0);
900: }
904: /*@
905: KSPSetRhs - Sets the right-hand-side vector for the linear system to
906: be solved.
908: Collective on KSP and Vec
910: Input Parameters:
911: + ksp - iterative context obtained from KSPCreate()
912: - b - right-hand-side vector
914: Level: developer
916: .keywords: KSP, set, right-hand-side, rhs
918: .seealso: KSPGetRhs(), KSPSetSolution(), KSPSolve()
919: @*/
920: int KSPSetRhs(KSP ksp,Vec b)
921: {
925: ksp->vec_rhs = (b);
926: return(0);
927: }
931: /*@C
932: KSPGetRhs - Gets the right-hand-side vector for the linear system to
933: be solved.
935: Not Collective
937: Input Parameter:
938: . ksp - iterative context obtained from KSPCreate()
940: Output Parameter:
941: . r - right-hand-side vector
943: Level: developer
945: .keywords: KSP, get, right-hand-side, rhs
947: .seealso: KSPSetRhs(), KSPGetSolution(), KSPSolve()
948: @*/
949: int KSPGetRhs(KSP ksp,Vec *r)
950: {
953: *r = ksp->vec_rhs;
954: return(0);
955: }
959: /*@
960: KSPSetSolution - Sets the location of the solution for the
961: linear system to be solved.
963: Collective on KSP and Vec
965: Input Parameters:
966: + ksp - iterative context obtained from KSPCreate()
967: - x - solution vector
969: Level: developer
971: .keywords: KSP, set, solution
973: .seealso: KSPSetRhs(), KSPGetSolution(), KSPSolve()
974: @*/
975: int KSPSetSolution(KSP ksp,Vec x)
976: {
980: ksp->vec_sol = (x);
981: return(0);
982: }
986: /*@C
987: KSPGetSolution - Gets the location of the solution for the
988: linear system to be solved. Note that this may not be where the solution
989: is stored during the iterative process; see KSPBuildSolution().
991: Not Collective
993: Input Parameters:
994: . ksp - iterative context obtained from KSPCreate()
996: Output Parameters:
997: . v - solution vector
999: Level: developer
1001: .keywords: KSP, get, solution
1003: .seealso: KSPGetRhs(), KSPSetSolution(), KSPBuildSolution(), KSPSolve()
1004: @*/
1005: int KSPGetSolution(KSP ksp,Vec *v)
1006: {
1010: *v = ksp->vec_sol;
1011: return(0);
1012: }
1016: /*@
1017: KSPSetPC - Sets the preconditioner to be used to calculate the
1018: application of the preconditioner on a vector.
1020: Collective on KSP
1022: Input Parameters:
1023: + ksp - iterative context obtained from KSPCreate()
1024: - B - the preconditioner object
1026: Notes:
1027: Use KSPGetPC() to retrieve the preconditioner context (for example,
1028: to free it at the end of the computations).
1030: Level: developer
1032: .keywords: KSP, set, precondition, Binv
1034: .seealso: KSPGetPC()
1035: @*/
1036: int KSPSetPC(KSP ksp,PC B)
1037: {
1044: if (ksp->B) {PCDestroy(ksp->B);}
1045: ksp->B = B;
1046: PetscObjectReference((PetscObject)ksp->B);
1047: return(0);
1048: }
1052: /*@C
1053: KSPGetPC - Returns a pointer to the preconditioner context
1054: set with KSPSetPC().
1056: Not Collective
1058: Input Parameters:
1059: . ksp - iterative context obtained from KSPCreate()
1061: Output Parameter:
1062: . B - preconditioner context
1064: Level: developer
1066: .keywords: KSP, get, preconditioner, Binv
1068: .seealso: KSPSetPC()
1069: @*/
1070: int KSPGetPC(KSP ksp,PC *B)
1071: {
1075: *B = ksp->B;
1076: return(0);
1077: }
1081: /*@C
1082: KSPSetMonitor - Sets an ADDITIONAL function to be called at every iteration to monitor
1083: the residual/error etc.
1084:
1085: Collective on KSP
1087: Input Parameters:
1088: + ksp - iterative context obtained from KSPCreate()
1089: . monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring
1090: . mctx - [optional] context for private data for the
1091: monitor routine (use PETSC_NULL if no context is desired)
1092: - monitordestroy - [optional] routine that frees monitor context
1093: (may be PETSC_NULL)
1095: Calling Sequence of monitor:
1096: $ monitor (KSP ksp, int it, PetscReal rnorm, void *mctx)
1098: + ksp - iterative context obtained from KSPCreate()
1099: . it - iteration number
1100: . rnorm - (estimated) 2-norm of (preconditioned) residual
1101: - mctx - optional monitoring context, as set by KSPSetMonitor()
1103: Options Database Keys:
1104: + -ksp_monitor - sets KSPDefaultMonitor()
1105: . -ksp_truemonitor - sets KSPTrueMonitor()
1106: . -ksp_xmonitor - sets line graph monitor,
1107: uses KSPLGMonitorCreate()
1108: . -ksp_xtruemonitor - sets line graph monitor,
1109: uses KSPLGMonitorCreate()
1110: . -ksp_singmonitor - sets KSPSingularValueMonitor()
1111: - -ksp_cancelmonitors - cancels all monitors that have
1112: been hardwired into a code by
1113: calls to KSPSetMonitor(), but
1114: does not cancel those set via
1115: the options database.
1117: Notes:
1118: The default is to do nothing. To print the residual, or preconditioned
1119: residual if KSPSetNormType(ksp,KSP_PRECONDITIONED_NORM) was called, use
1120: KSPDefaultMonitor() as the monitoring routine, with a null monitoring
1121: context.
1123: Several different monitoring routines may be set by calling
1124: KSPSetMonitor() multiple times; all will be called in the
1125: order in which they were set.
1127: Level: beginner
1129: .keywords: KSP, set, monitor
1131: .seealso: KSPDefaultMonitor(), KSPLGMonitorCreate(), KSPClearMonitor()
1132: @*/
1133: int KSPSetMonitor(KSP ksp,int (*monitor)(KSP,int,PetscReal,void*),void *mctx,int (*monitordestroy)(void*))
1134: {
1137: if (ksp->numbermonitors >= MAXKSPMONITORS) {
1138: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many KSP monitors set");
1139: }
1140: ksp->monitor[ksp->numbermonitors] = monitor;
1141: ksp->monitordestroy[ksp->numbermonitors] = monitordestroy;
1142: ksp->monitorcontext[ksp->numbermonitors++] = (void*)mctx;
1143: return(0);
1144: }
1148: /*@
1149: KSPClearMonitor - Clears all monitors for a KSP object.
1151: Collective on KSP
1153: Input Parameters:
1154: . ksp - iterative context obtained from KSPCreate()
1156: Options Database Key:
1157: . -ksp_cancelmonitors - Cancels all monitors that have
1158: been hardwired into a code by calls to KSPSetMonitor(),
1159: but does not cancel those set via the options database.
1161: Level: intermediate
1163: .keywords: KSP, set, monitor
1165: .seealso: KSPDefaultMonitor(), KSPLGMonitorCreate(), KSPSetMonitor()
1166: @*/
1167: int KSPClearMonitor(KSP ksp)
1168: {
1171: ksp->numbermonitors = 0;
1172: return(0);
1173: }
1177: /*@C
1178: KSPGetMonitorContext - Gets the monitoring context, as set by
1179: KSPSetMonitor() for the FIRST monitor only.
1181: Not Collective
1183: Input Parameter:
1184: . ksp - iterative context obtained from KSPCreate()
1186: Output Parameter:
1187: . ctx - monitoring context
1189: Level: intermediate
1191: .keywords: KSP, get, monitor, context
1193: .seealso: KSPDefaultMonitor(), KSPLGMonitorCreate()
1194: @*/
1195: int KSPGetMonitorContext(KSP ksp,void **ctx)
1196: {
1199: *ctx = (ksp->monitorcontext[0]);
1200: return(0);
1201: }
1205: /*@
1206: KSPSetResidualHistory - Sets the array used to hold the residual history.
1207: If set, this array will contain the residual norms computed at each
1208: iteration of the solver.
1210: Not Collective
1212: Input Parameters:
1213: + ksp - iterative context obtained from KSPCreate()
1214: . a - array to hold history
1215: . na - size of a
1216: - reset - PETSC_TRUE indicates the history counter is reset to zero
1217: for each new linear solve
1219: Level: advanced
1221: Notes: The array is NOT freed by PETSc so the user needs to keep track of
1222: it and destroy once the KSP object is destroyed.
1224: If 'na' is PETSC_DECIDE or 'a' is PETSC_NULL, then a default array of
1225: length 1000 is allocated.
1227: .keywords: KSP, set, residual, history, norm
1229: .seealso: KSPGetResidualHistory()
1231: @*/
1232: int KSPSetResidualHistory(KSP ksp,PetscReal a[],int na,PetscTruth reset)
1233: {
1238: if (na != PETSC_DECIDE && a != PETSC_NULL) {
1239: ksp->res_hist = a;
1240: ksp->res_hist_max = na;
1241: } else {
1242: ksp->res_hist_max = 1000;
1243: PetscMalloc(ksp->res_hist_max*sizeof(PetscReal),&ksp->res_hist);
1244: }
1245: ksp->res_hist_len = 0;
1246: ksp->res_hist_reset = reset;
1249: return(0);
1250: }
1254: /*@C
1255: KSPGetResidualHistory - Gets the array used to hold the residual history
1256: and the number of residuals it contains.
1258: Not Collective
1260: Input Parameter:
1261: . ksp - iterative context obtained from KSPCreate()
1263: Output Parameters:
1264: + a - pointer to array to hold history (or PETSC_NULL)
1265: - na - number of used entries in a (or PETSC_NULL)
1267: Level: advanced
1269: Notes:
1270: Can only be called after a KSPSetResidualHistory() otherwise a and na are set to zero
1272: The Fortran version of this routine has a calling sequence
1273: $ call KSPGetResidualHistory(KSP ksp, integer na, integer ierr)
1275: .keywords: KSP, get, residual, history, norm
1277: .seealso: KSPGetResidualHistory()
1279: @*/
1280: int KSPGetResidualHistory(KSP ksp,PetscReal *a[],int *na)
1281: {
1284: if (a) *a = ksp->res_hist;
1285: if (na) *na = ksp->res_hist_len;
1286: return(0);
1287: }
1291: /*@C
1292: KSPSetConvergenceTest - Sets the function to be used to determine
1293: convergence.
1295: Collective on KSP
1297: Input Parameters:
1298: + ksp - iterative context obtained from KSPCreate()
1299: . converge - pointer to int function
1300: - cctx - context for private data for the convergence routine (may be null)
1302: Calling sequence of converge:
1303: $ converge (KSP ksp, int it, PetscReal rnorm, KSPConvergedReason *reason,void *mctx)
1305: + ksp - iterative context obtained from KSPCreate()
1306: . it - iteration number
1307: . rnorm - (estimated) 2-norm of (preconditioned) residual
1308: . reason - the reason why it has converged or diverged
1309: - cctx - optional convergence context, as set by KSPSetConvergenceTest()
1312: Notes:
1313: Must be called after the KSP type has been set so put this after
1314: a call to KSPSetType(), or KSPSetFromOptions().
1316: The default convergence test, KSPDefaultConverged(), aborts if the
1317: residual grows to more than 10000 times the initial residual.
1319: The default is a combination of relative and absolute tolerances.
1320: The residual value that is tested may be an approximation; routines
1321: that need exact values should compute them.
1323: Level: advanced
1325: .keywords: KSP, set, convergence, test, context
1327: .seealso: KSPDefaultConverged(), KSPGetConvergenceContext()
1328: @*/
1329: int KSPSetConvergenceTest(KSP ksp,int (*converge)(KSP,int,PetscReal,KSPConvergedReason*,void*),void *cctx)
1330: {
1333: ksp->converged = converge;
1334: ksp->cnvP = (void*)cctx;
1335: return(0);
1336: }
1340: /*@C
1341: KSPGetConvergenceContext - Gets the convergence context set with
1342: KSPSetConvergenceTest().
1344: Not Collective
1346: Input Parameter:
1347: . ksp - iterative context obtained from KSPCreate()
1349: Output Parameter:
1350: . ctx - monitoring context
1352: Level: advanced
1354: .keywords: KSP, get, convergence, test, context
1356: .seealso: KSPDefaultConverged(), KSPSetConvergenceTest()
1357: @*/
1358: int KSPGetConvergenceContext(KSP ksp,void **ctx)
1359: {
1362: *ctx = ksp->cnvP;
1363: return(0);
1364: }
1368: /*@C
1369: KSPBuildSolution - Builds the approximate solution in a vector provided.
1370: This routine is NOT commonly needed (see KSPSolve()).
1372: Collective on KSP
1374: Input Parameter:
1375: . ctx - iterative context obtained from KSPCreate()
1377: Output Parameter:
1378: Provide exactly one of
1379: + v - location to stash solution.
1380: - V - the solution is returned in this location. This vector is created
1381: internally. This vector should NOT be destroyed by the user with
1382: VecDestroy().
1384: Notes:
1385: This routine can be used in one of two ways
1386: .vb
1387: KSPBuildSolution(ksp,PETSC_NULL,&V);
1388: or
1389: KSPBuildSolution(ksp,v,PETSC_NULL);
1390: .ve
1391: In the first case an internal vector is allocated to store the solution
1392: (the user cannot destroy this vector). In the second case the solution
1393: is generated in the vector that the user provides. Note that for certain
1394: methods, such as KSPCG, the second case requires a copy of the solution,
1395: while in the first case the call is essentially free since it simply
1396: returns the vector where the solution already is stored.
1398: Level: advanced
1400: .keywords: KSP, build, solution
1402: .seealso: KSPGetSolution(), KSPBuildResidual()
1403: @*/
1404: int KSPBuildSolution(KSP ksp,Vec v,Vec *V)
1405: {
1410: if (!V && !v) SETERRQ(PETSC_ERR_ARG_WRONG,"Must provide either v or V");
1411: if (!V) V = &v;
1412: (*ksp->ops->buildsolution)(ksp,v,V);
1413: return(0);
1414: }
1418: /*@C
1419: KSPBuildResidual - Builds the residual in a vector provided.
1421: Collective on KSP
1423: Input Parameter:
1424: . ksp - iterative context obtained from KSPCreate()
1426: Output Parameters:
1427: + v - optional location to stash residual. If v is not provided,
1428: then a location is generated.
1429: . t - work vector. If not provided then one is generated.
1430: - V - the residual
1432: Notes:
1433: Regardless of whether or not v is provided, the residual is
1434: returned in V.
1436: Level: advanced
1438: .keywords: KSP, build, residual
1440: .seealso: KSPBuildSolution()
1441: @*/
1442: int KSPBuildResidual(KSP ksp,Vec t,Vec v,Vec *V)
1443: {
1444: int flag = 0,ierr;
1445: Vec w = v,tt = t;
1449: if (!w) {
1450: VecDuplicate(ksp->vec_rhs,&w);
1451: PetscLogObjectParent((PetscObject)ksp,w);
1452: }
1453: if (!tt) {
1454: VecDuplicate(ksp->vec_rhs,&tt); flag = 1;
1455: PetscLogObjectParent((PetscObject)ksp,tt);
1456: }
1457: (*ksp->ops->buildresidual)(ksp,tt,w,V);
1458: if (flag) {VecDestroy(tt);}
1459: return(0);
1460: }
1464: /*@
1465: KSPSetDiagonalScale - Tells KSP to diagonally scale the system
1466: before solving. This actually CHANGES the matrix (and right hand side).
1468: Collective on KSP
1470: Input Parameter:
1471: + ksp - the KSP context
1472: - scale - PETSC_TRUE or PETSC_FALSE
1474: Notes:
1475: BE CAREFUL with this routine: it actually scales the matrix and right
1476: hand side that define the system. After the system is solved the matrix
1477: and right hand side remain scaled.
1479: This routine is only used if the matrix and preconditioner matrix are
1480: the same thing.
1481:
1482: If you use this with the PCType Eisenstat preconditioner than you can
1483: use the PCEisenstatNoDiagonalScaling() option, or -pc_eisenstat_no_diagonal_scaling
1484: to save some unneeded, redundant flops.
1486: Level: intermediate
1488: .keywords: KSP, set, options, prefix, database
1490: .seealso: KSPGetDiagonalScale(), KSPSetDiagonalScaleFix()
1491: @*/
1492: int KSPSetDiagonalScale(KSP ksp,PetscTruth scale)
1493: {
1496: ksp->dscale = scale;
1497: return(0);
1498: }
1502: /*@C
1503: KSPGetDiagonalScale - Checks if KSP solver scales the matrix and
1504: right hand side
1506: Not Collective
1508: Input Parameter:
1509: . ksp - the KSP context
1511: Output Parameter:
1512: . scale - PETSC_TRUE or PETSC_FALSE
1514: Notes:
1515: BE CAREFUL with this routine: it actually scales the matrix and right
1516: hand side that define the system. After the system is solved the matrix
1517: and right hand side remain scaled.
1519: This routine is only used if the matrix and preconditioner matrix are
1520: the same thing.
1522: Level: intermediate
1524: .keywords: KSP, set, options, prefix, database
1526: .seealso: KSPSetDiagonalScale(), KSPSetDiagonalScaleFix()
1527: @*/
1528: int KSPGetDiagonalScale(KSP ksp,PetscTruth *scale)
1529: {
1533: *scale = ksp->dscale;
1534: return(0);
1535: }
1539: /*@
1540: KSPSetDiagonalScaleFix - Tells KSP to diagonally scale the system
1541: back after solving.
1543: Collective on KSP
1545: Input Parameter:
1546: + ksp - the KSP context
1547: - fix - PETSC_TRUE to scale back after the system solve, PETSC_FALSE to not
1548: rescale (default)
1550: Notes:
1551: Must be called after KSPSetDiagonalScale()
1553: Using this will slow things down, because it rescales the matrix before and
1554: after each linear solve. This is intended mainly for testing to allow one
1555: to easily get back the original system to make sure the solution computed is
1556: accurate enough.
1558: This routine is only used if the matrix and preconditioner matrix are
1559: the same thing.
1561: Level: intermediate
1563: .keywords: KSP, set, options, prefix, database
1565: .seealso: KSPGetDiagonalScale(), KSPSetDiagonalScale(), KSPGetDiagonalScaleFix()
1566: @*/
1567: int KSPSetDiagonalScaleFix(KSP ksp,PetscTruth fix)
1568: {
1571: ksp->dscalefix = fix;
1572: return(0);
1573: }
1577: /*@
1578: KSPGetDiagonalScaleFix - Determines if KSP diagonally scales the system
1579: back after solving.
1581: Collective on KSP
1583: Input Parameter:
1584: . ksp - the KSP context
1586: Output Parameter:
1587: . fix - PETSC_TRUE to scale back after the system solve, PETSC_FALSE to not
1588: rescale (default)
1590: Notes:
1591: Must be called after KSPSetDiagonalScale()
1593: If PETSC_TRUE will slow things down, because it rescales the matrix before and
1594: after each linear solve. This is intended mainly for testing to allow one
1595: to easily get back the original system to make sure the solution computed is
1596: accurate enough.
1598: This routine is only used if the matrix and preconditioner matrix are
1599: the same thing.
1601: Level: intermediate
1603: .keywords: KSP, set, options, prefix, database
1605: .seealso: KSPGetDiagonalScale(), KSPSetDiagonalScale(), KSPSetDiagonalScaleFix()
1606: @*/
1607: int KSPGetDiagonalScaleFix(KSP ksp,PetscTruth *fix)
1608: {
1612: *fix = ksp->dscalefix;
1613: return(0);
1614: }