Actual source code: sles.c
1: /*$Id: sles.c,v 1.148 2001/03/23 23:23:00 balay Exp $*/
3: #include "src/sles/slesimpl.h" /*I "petscsles.h" I*/
5: static int SLESPublish_Petsc(PetscObject obj)
6: {
7: #if defined(PETSC_HAVE_AMS)
8: int ierr;
9: #endif
10:
12: #if defined(PETSC_HAVE_AMS)
13: PetscObjectPublishBaseBegin(obj);
14: PetscObjectPublishBaseEnd(obj);
15: #endif
16: return(0);
17: }
19: /*@C
20: SLESView - Prints the SLES data structure.
22: Collective on SLES
24: Input Parameters:
25: + SLES - the SLES context
26: - viewer - optional visualization context
28: Options Database Key:
29: . -sles_view - Calls SLESView() at end of SLESSolve()
31: Note:
32: The available visualization contexts include
33: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
34: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
35: output where only the first processor opens
36: the file. All other processors send their
37: data to the first processor to print.
39: The user can open alternative visualization contexts with
40: . PetscViewerASCIIOpen() - output to a specified file
42: Level: beginner
44: .keywords: SLES, view
46: .seealso: PetscViewerASCIIOpen()
47: @*/
48: int SLESView(SLES sles,PetscViewer viewer)
49: {
50: KSP ksp;
51: PC pc;
52: int ierr;
56: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(sles->comm);
59: SLESGetPC(sles,&pc);
60: SLESGetKSP(sles,&ksp);
61: KSPView(ksp,viewer);
62: PCView(pc,viewer);
63: return(0);
64: }
66: /*@C
67: SLESSetOptionsPrefix - Sets the prefix used for searching for all
68: SLES options in the database.
70: Collective on SLES
72: Input Parameter:
73: + sles - the SLES context
74: - prefix - the prefix to prepend to all option names
76: Notes:
77: A hyphen (-) must NOT be given at the beginning of the prefix name.
78: The first character of all runtime options is AUTOMATICALLY the
79: hyphen.
81: This prefix is particularly useful for nested use of SLES. For
82: example, the block Jacobi and block diagonal preconditioners use
83: the prefix "sub_" for options relating to the individual blocks.
85: Level: intermediate
87: .keywords: SLES, set, options, prefix, database
89: .seealso: SLESAppendOptionsPrefix(), SLESGetOptionsPrefix()
90: @*/
91: int SLESSetOptionsPrefix(SLES sles,char *prefix)
92: {
97: PetscObjectSetOptionsPrefix((PetscObject)sles,prefix);
98: KSPSetOptionsPrefix(sles->ksp,prefix);
99: PCSetOptionsPrefix(sles->pc,prefix);
100: return(0);
101: }
103: /*@C
104: SLESAppendOptionsPrefix - Appends to the prefix used for searching for all
105: SLES options in the database.
107: Collective on SLES
109: Input Parameter:
110: + sles - the SLES context
111: - prefix - the prefix to prepend to all option names
113: Notes:
114: A hyphen (-) must NOT be given at the beginning of the prefix name.
115: The first character of all runtime options is AUTOMATICALLY the
116: hyphen.
118: This prefix is particularly useful for nested use of SLES. For
119: example, the block Jacobi and block diagonal preconditioners use
120: the prefix "sub_" for options relating to the individual blocks.
122: Level: intermediate
124: .keywords: SLES, append, options, prefix, database
126: .seealso: SLESSetOptionsPrefix(), SLESGetOptionsPrefix()
127: @*/
128: int SLESAppendOptionsPrefix(SLES sles,char *prefix)
129: {
134: PetscObjectAppendOptionsPrefix((PetscObject)sles,prefix);
135: KSPAppendOptionsPrefix(sles->ksp,prefix);
136: PCAppendOptionsPrefix(sles->pc,prefix);
137: return(0);
138: }
140: /*@C
141: SLESGetOptionsPrefix - Gets the prefix used for searching for all
142: SLES options in the database.
144: Not Collective
146: Input Parameter:
147: . sles - the SLES context
149: Output Parameter:
150: . prefix - pointer to the prefix string used
152: Notes:
153: This prefix is particularly useful for nested use of SLES. For
154: example, the block Jacobi and block diagonal preconditioners use
155: the prefix "sub" for options relating to the individual blocks.
157: On the fortran side, the user should pass in a string 'prifix' of
158: sufficient length to hold the prefix.
160: Level: intermediate
162: .keywords: SLES, get, options, prefix, database
164: .seealso: SLESSetOptionsPrefix()
165: @*/
166: int SLESGetOptionsPrefix(SLES sles,char **prefix)
167: {
172: PetscObjectGetOptionsPrefix((PetscObject)sles,prefix);
173: return(0);
174: }
176: /*@
177: SLESSetFromOptions - Sets various SLES parameters from user options.
178: Also takes all KSP and PC options.
180: Collective on SLES
182: Input Parameter:
183: . sles - the SLES context
185: Level: beginner
187: .keywords: SLES, set, options, database
189: .seealso: KSPSetFromOptions(),
190: PCSetFromOptions(), SLESGetPC(), SLESGetKSP()
191: @*/
192: int SLESSetFromOptions(SLES sles)
193: {
194: int ierr;
195: PetscTruth flag;
199: PetscOptionsBegin(sles->comm,sles->prefix,"Linear solver (SLES) options","SLES");
200: PetscOptionsName("-sles_diagonal_scale","Diagonal scale matrix before building preconditioner","SLESSetDiagonalScale",&flag);
201: if (flag) {
202: SLESSetDiagonalScale(sles,PETSC_TRUE);
203: }
204: PetscOptionsName("-sles_diagonal_scale_fix","Fix diagonaled scaled matrix after solve","SLESSetDiagonalScaleFix",&flag);
205: if (flag) {
206: SLESSetDiagonalScaleFix(sles);
207: }
208: PetscOptionsEnd();
209: KSPSetPC(sles->ksp,sles->pc);
210: KSPSetFromOptions(sles->ksp);
211: PCSetFromOptions(sles->pc);
212: return(0);
213: }
215: /*@C
216: SLESCreate - Creates a linear equation solver context.
218: Collective on MPI_Comm
220: Input Parameter:
221: . comm - MPI communicator
223: Output Parameter:
224: . sles - the newly created SLES context
226: Level: beginner
228: .keywords: SLES, create, context
230: .seealso: SLESSolve(), SLESDestroy(), SLES
231: @*/
232: int SLESCreate(MPI_Comm comm,SLES *outsles)
233: {
234: int ierr;
235: SLES sles;
238: *outsles = 0;
239: PetscHeaderCreate(sles,_p_SLES,int,SLES_COOKIE,0,"SLES",comm,SLESDestroy,SLESView);
240: PetscLogObjectCreate(sles);
241: sles->bops->publish = SLESPublish_Petsc;
242: KSPCreate(comm,&sles->ksp);
243: PCCreate(comm,&sles->pc);
244: PetscLogObjectParent(sles,sles->ksp);
245: PetscLogObjectParent(sles,sles->pc);
246: sles->setupcalled = 0;
247: sles->dscale = PETSC_FALSE;
248: sles->dscalefix = PETSC_FALSE;
249: sles->diagonal = PETSC_NULL;
250: *outsles = sles;
251: PetscPublishAll(sles);
252: return(0);
253: }
255: /*@C
256: SLESDestroy - Destroys the SLES context.
258: Collective on SLES
260: Input Parameters:
261: . sles - the SLES context
263: Level: beginner
265: .keywords: SLES, destroy, context
267: .seealso: SLESCreate(), SLESSolve()
268: @*/
269: int SLESDestroy(SLES sles)
270: {
275: if (--sles->refct > 0) return(0);
277: PetscObjectDepublish(sles);
278: KSPDestroy(sles->ksp);
279: PCDestroy(sles->pc);
280: if (sles->diagonal) {VecDestroy(sles->diagonal);}
281: PetscLogObjectDestroy(sles);
282: PetscHeaderDestroy(sles);
283: return(0);
284: }
286: /*@
287: SLESSetUp - Performs set up required for solving a linear system.
289: Collective on SLES
291: Input Parameters:
292: + sles - the SLES context
293: . b - the right hand side
294: - x - location to hold solution
296: Note:
297: For basic use of the SLES solvers the user need not explicitly call
298: SLESSetUp(), since these actions will automatically occur during
299: the call to SLESSolve(). However, if one wishes to generate
300: performance data for this computational phase (for example, for
301: incomplete factorization using the ILU preconditioner) using the
302: PETSc log facilities, calling SLESSetUp() is required.
304: Level: advanced
306: .keywords: SLES, solve, linear system
308: .seealso: SLESCreate(), SLESDestroy(), SLESDestroy()
309: @*/
310: int SLESSetUp(SLES sles,Vec b,Vec x)
311: {
313: KSP ksp;
314: PC pc;
315: Mat mat,pmat;
324: ksp = sles->ksp; pc = sles->pc;
325: KSPSetRhs(ksp,b);
326: KSPSetSolution(ksp,x);
327: if (!sles->setupcalled) {
328: PetscLogEventBegin(SLES_SetUp,sles,b,x,0);
329: KSPSetPC(ksp,pc);
330: PCSetVector(pc,b);
331: KSPSetUp(sles->ksp);
333: /* scale the matrix if requested */
334: if (sles->dscale) {
335: PCGetOperators(pc,&mat,&pmat,PETSC_NULL);
336: if (mat == pmat) {
337: Scalar *xx;
338: int i,n;
339: PetscTruth zeroflag = PETSC_FALSE;
342: if (!sles->diagonal) { /* allocate vector to hold diagonal */
343: VecDuplicate(b,&sles->diagonal);
344: }
345: MatGetDiagonal(mat,sles->diagonal);
346: VecGetLocalSize(sles->diagonal,&n);
347: VecGetArray(sles->diagonal,&xx);
348: for (i=0; i<n; i++) {
349: if (xx[i] != 0.0) xx[i] = 1.0/sqrt(PetscAbsScalar(xx[i]));
350: else {
351: xx[i] = 1.0;
352: zeroflag = PETSC_TRUE;
353: }
354: }
355: VecRestoreArray(sles->diagonal,&xx);
356: if (zeroflag) {
357: PetscLogInfo(pc,"SLESSetUp:Zero detected in diagonal of matrix, using 1 at those locationsn");
358: }
359: MatDiagonalScale(mat,sles->diagonal,sles->diagonal);
360: sles->dscalefix2 = PETSC_FALSE;
361: }
362: }
364: PCSetUp(sles->pc);
365: sles->setupcalled = 1;
366: PetscLogEventEnd(SLES_SetUp,sles,b,x,0);
367: }
368: return(0);
369: }
371: /*@
372: SLESSolve - Solves a linear system.
374: Collective on SLES
376: Input Parameters:
377: + sles - the SLES context
378: - b - the right hand side
380: Output Parameters:
381: + x - the approximate solution
382: - its - the number of iterations until termination
384: Options Database:
385: + -sles_diagonal_scale - diagonally scale linear system before solving
386: . -sles_diagonal_scale_fix - unscale the matrix and right hand side when done
387: . -sles_view - print information about the solver used
388: - -sles_view_binary - save the matrix and right hand side to the default binary file (can be
389: read later with src/sles/examples/tutorials/ex10.c for testing solvers)
391: Notes:
392: Call KSPGetConvergedReason() to determine if the solver converged or failed and
393: why.
395: On return, the parameter "its" contains the iteration number at which convergence
396: was successfully reached or divergence/failure was detected
398: If using a direct method (e.g., via the KSP solver
399: KSPPREONLY and a preconditioner such as PCLU/PCILU),
400: then its=1. See KSPSetTolerances() and KSPDefaultConverged()
401: for more details. Also, see KSPSolve() for more details
402: about iterative solver options.
404: Setting a Nonzero Initial Guess:
405: By default, SLES assumes an initial guess of zero by zeroing
406: the initial value for the solution vector, x. To use a nonzero
407: initial guess, the user must call
408: .vb
409: SLESGetKSP(sles,&ksp);
410: KSPSetInitialGuessNonzero(ksp);
411: .ve
413: Solving Successive Linear Systems:
414: When solving multiple linear systems of the same size with the
415: same method, several options are available.
417: (1) To solve successive linear systems having the SAME
418: preconditioner matrix (i.e., the same data structure with exactly
419: the same matrix elements) but different right-hand-side vectors,
420: the user should simply call SLESSolve() multiple times. The
421: preconditioner setup operations (e.g., factorization for ILU) will
422: be done during the first call to SLESSolve() only; such operations
423: will NOT be repeated for successive solves.
425: (2) To solve successive linear systems that have DIFFERENT
426: preconditioner matrices (i.e., the matrix elements and/or the
427: matrix data structure change), the user MUST call SLESSetOperators()
428: and SLESSolve() for each solve. See SLESSetOperators() for
429: options that can save work for such cases.
431: Level: beginner
433: .keywords: SLES, solve, linear system
435: .seealso: SLESCreate(), SLESSetOperators(), SLESGetKSP(), KSPSetTolerances(),
436: KSPDefaultConverged(), KSPSetInitialGuessNonzero(), KSPGetResidualNorm(),
437: KSPSolve()
438: @*/
439: int SLESSolve(SLES sles,Vec b,Vec x,int *its)
440: {
441: int ierr;
442: PetscTruth flg;
443: KSP ksp;
444: PC pc;
452: if (b == x) SETERRQ(PETSC_ERR_ARG_IDN,"b and x must be different vectors");
454: PetscOptionsHasName(sles->prefix,"-sles_view_binary",&flg);
455: if (flg) {
456: Mat mat;
457: PCGetOperators(sles->pc,&mat,PETSC_NULL,PETSC_NULL);
458: MatView(mat,PETSC_VIEWER_BINARY_(sles->comm));
459: VecView(b,PETSC_VIEWER_BINARY_(sles->comm));
460: }
461: ksp = sles->ksp;
462: pc = sles->pc;
463: SLESSetUp(sles,b,x);
464: SLESSetUpOnBlocks(sles);
465: PetscLogEventBegin(SLES_Solve,sles,b,x,0);
466: /* diagonal scale RHS if called for */
467: if (sles->dscale) {
468: VecPointwiseMult(sles->diagonal,b,b);
469: /* second time in, but matrix was scaled back to original */
470: if (sles->dscalefix && sles->dscalefix2) {
471: Mat mat;
473: PCGetOperators(pc,&mat,PETSC_NULL,PETSC_NULL);
474: MatDiagonalScale(mat,sles->diagonal,sles->diagonal);
475: }
476: }
477: PCPreSolve(pc,ksp);
478: KSPSolve(ksp,its);
479: PCPostSolve(pc,ksp);
480: /* diagonal scale solution if called for */
481: if (sles->dscale) {
482: VecPointwiseMult(sles->diagonal,x,x);
483: /* unscale right hand side and matrix */
484: if (sles->dscalefix) {
485: Mat mat;
487: VecReciprocal(sles->diagonal);
488: VecPointwiseMult(sles->diagonal,b,b);
489: PCGetOperators(pc,&mat,PETSC_NULL,PETSC_NULL);
490: MatDiagonalScale(mat,sles->diagonal,sles->diagonal);
491: VecReciprocal(sles->diagonal);
492: sles->dscalefix2 = PETSC_TRUE;
493: }
494: }
495: PetscLogEventEnd(SLES_Solve,sles,b,x,0);
496: PetscOptionsHasName(sles->prefix,"-sles_view",&flg);
497: if (flg && !PetscPreLoadingOn) { SLESView(sles,PETSC_VIEWER_STDOUT_WORLD); }
498: return(0);
499: }
501: /*@
502: SLESSolveTranspose - Solves the transpose of a linear system.
504: Collective on SLES
506: Input Parameters:
507: + sles - the SLES context
508: - b - the right hand side
510: Output Parameters:
511: + x - the approximate solution
512: - its - the number of iterations until termination
514: Notes:
515: On return, the parameter "its" contains
516: + <its> - the iteration number at which convergence
517: was successfully reached, or
518: - <-its> - the negative of the iteration at which
519: divergence or breakdown was detected.
521: Currently works only with the KSPPREONLY method.
523: Setting a Nonzero Initial Guess:
524: By default, SLES assumes an initial guess of zero by zeroing
525: the initial value for the solution vector, x. To use a nonzero
526: initial guess, the user must call
527: .vb
528: SLESGetKSP(sles,&ksp);
529: KSPSetInitialGuessNonzero(ksp);
530: .ve
532: Solving Successive Linear Systems:
533: When solving multiple linear systems of the same size with the
534: same method, several options are available.
536: (1) To solve successive linear systems having the SAME
537: preconditioner matrix (i.e., the same data structure with exactly
538: the same matrix elements) but different right-hand-side vectors,
539: the user should simply call SLESSolve() multiple times. The
540: preconditioner setup operations (e.g., factorization for ILU) will
541: be done during the first call to SLESSolve() only; such operations
542: will NOT be repeated for successive solves.
544: (2) To solve successive linear systems that have DIFFERENT
545: preconditioner matrices (i.e., the matrix elements and/or the
546: matrix data structure change), the user MUST call SLESSetOperators()
547: and SLESSolve() for each solve. See SLESSetOperators() for
548: options that can save work for such cases.
550: Level: intermediate
552: .keywords: SLES, solve, linear system
554: .seealso: SLESCreate(), SLESSetOperators(), SLESGetKSP(), KSPSetTolerances(),
555: KSPDefaultConverged(), KSPSetInitialGuessNonzero(), KSPGetResidualNorm(),
556: KSPSolve()
557: @*/
558: int SLESSolveTranspose(SLES sles,Vec b,Vec x,int *its)
559: {
560: int ierr;
561: PetscTruth flg;
562: KSP ksp;
563: PC pc;
569: if (b == x) SETERRQ(PETSC_ERR_ARG_IDN,"b and x must be different vectors");
573: ksp = sles->ksp; pc = sles->pc;
574: KSPSetRhs(ksp,b);
575: KSPSetSolution(ksp,x);
576: KSPSetPC(ksp,pc);
577: if (!sles->setupcalled) {
578: SLESSetUp(sles,b,x);
579: }
580: PCSetUpOnBlocks(pc);
581: PetscLogEventBegin(SLES_Solve,sles,b,x,0);
582: KSPSolveTranspose(ksp,its);
583: PetscLogEventEnd(SLES_Solve,sles,b,x,0);
584: PetscOptionsHasName(sles->prefix,"-sles_view",&flg);
585: if (flg) { SLESView(sles,PETSC_VIEWER_STDOUT_WORLD); }
586: return(0);
587: }
589: /*@C
590: SLESGetKSP - Returns the KSP context for a SLES solver.
592: Not Collective, but if KSP will be a parallel object if SLES is
594: Input Parameter:
595: . sles - the SLES context
597: Output Parameter:
598: . ksp - the Krylov space context
600: Notes:
601: The user can then directly manipulate the KSP context to set various
602: options (e.g., by calling KSPSetType()), etc.
604: Level: beginner
605:
606: .keywords: SLES, get, KSP, context
608: .seealso: SLESGetPC()
609: @*/
610: int SLESGetKSP(SLES sles,KSP *ksp)
611: {
614: *ksp = sles->ksp;
615: return(0);
616: }
618: /*@C
619: SLESGetPC - Returns the preconditioner (PC) context for a SLES solver.
621: Not Collective, but if PC will be a parallel object if SLES is
623: Input Parameter:
624: . sles - the SLES context
626: Output Parameter:
627: . pc - the preconditioner context
629: Notes:
630: The user can then directly manipulate the PC context to set various
631: options (e.g., by calling PCSetType()), etc.
633: Level: beginner
635: .keywords: SLES, get, PC, context
637: .seealso: SLESGetKSP()
638: @*/
639: int SLESGetPC(SLES sles,PC *pc)
640: {
643: *pc = sles->pc;
644: return(0);
645: }
647: #include "src/mat/matimpl.h"
648: /*@
649: SLESSetOperators - Sets the matrix associated with the linear system
650: and a (possibly) different one associated with the preconditioner.
652: Collective on SLES and Mat
654: Input Parameters:
655: + sles - the SLES context
656: . Amat - the matrix associated with the linear system
657: . Pmat - the matrix to be used in constructing the preconditioner, usually the
658: same as Amat.
659: - flag - flag indicating information about the preconditioner matrix structure
660: during successive linear solves. This flag is ignored the first time a
661: linear system is solved, and thus is irrelevant when solving just one linear
662: system.
664: Notes:
665: The flag can be used to eliminate unnecessary work in the preconditioner
666: during the repeated solution of linear systems of the same size. The
667: available options are
668: $ SAME_PRECONDITIONER -
669: $ Pmat is identical during successive linear solves.
670: $ This option is intended for folks who are using
671: $ different Amat and Pmat matrices and want to reuse the
672: $ same preconditioner matrix. For example, this option
673: $ saves work by not recomputing incomplete factorization
674: $ for ILU/ICC preconditioners.
675: $ SAME_NONZERO_PATTERN -
676: $ Pmat has the same nonzero structure during
677: $ successive linear solves.
678: $ DIFFERENT_NONZERO_PATTERN -
679: $ Pmat does not have the same nonzero structure.
681: Caution:
682: If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
683: and does not check the structure of the matrix. If you erroneously
684: claim that the structure is the same when it actually is not, the new
685: preconditioner will not function correctly. Thus, use this optimization
686: feature carefully!
688: If in doubt about whether your preconditioner matrix has changed
689: structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
691: Level: beginner
693: .keywords: SLES, set, operators, matrix, preconditioner, linear system
695: .seealso: SLESSolve(), SLESGetPC(), PCGetOperators()
696: @*/
697: int SLESSetOperators(SLES sles,Mat Amat,Mat Pmat,MatStructure flag)
698: {
703: PCSetOperators(sles->pc,Amat,Pmat,flag);
704: sles->setupcalled = 0; /* so that next solve call will call setup */
705: return(0);
706: }
708: /*@
709: SLESSetUpOnBlocks - Sets up the preconditioner for each block in
710: the block Jacobi, block Gauss-Seidel, and overlapping Schwarz
711: methods.
713: Collective on SLES
715: Input Parameter:
716: . sles - the SLES context
718: Notes:
719: SLESSetUpOnBlocks() is a routine that the user can optinally call for
720: more precise profiling (via -log_summary) of the setup phase for these
721: block preconditioners. If the user does not call SLESSetUpOnBlocks(),
722: it will automatically be called from within SLESSolve().
723:
724: Calling SLESSetUpOnBlocks() is the same as calling PCSetUpOnBlocks()
725: on the PC context within the SLES context.
727: Level: advanced
729: .keywords: SLES, setup, blocks
731: .seealso: PCSetUpOnBlocks(), SLESSetUp(), PCSetUp()
732: @*/
733: int SLESSetUpOnBlocks(SLES sles)
734: {
736: PC pc;
740: SLESGetPC(sles,&pc);
741: PCSetUpOnBlocks(pc);
742: return(0);
743: }
745: /*@C
746: SLESSetDiagonalScale - Tells SLES to diagonally scale the system
747: before solving. This actually CHANGES the matrix (and right hand side).
749: Collective on SLES
751: Input Parameter:
752: + sles - the SLES context
753: - scale - PETSC_TRUE or PETSC_FALSE
755: Notes:
756: BE CAREFUL with this routine: it actually scales the matrix and right
757: hand side that define the system. After the system is solved the matrix
758: and right hand side remain scaled.
760: This routine is only used if the matrix and preconditioner matrix are
761: the same thing.
762:
763: If you use this with the PCType Eisenstat preconditioner than you can
764: use the PCEisenstatNoDiagonalScaling() option, or -pc_eisenstat_no_diagonal_scaling
765: to save some unneeded, redundant flops.
767: Level: intermediate
769: .keywords: SLES, set, options, prefix, database
771: .seealso: SLESGetDiagonalScale(), SLESSetDiagonalScaleFix()
772: @*/
773: int SLESSetDiagonalScale(SLES sles,PetscTruth scale)
774: {
777: sles->dscale = scale;
778: return(0);
779: }
781: /*@C
782: SLESGetDiagonalScale - Checks if SLES solver scales the matrix and
783: right hand side
785: Not Collective
787: Input Parameter:
788: . sles - the SLES context
790: Output Parameter:
791: . scale - PETSC_TRUE or PETSC_FALSE
793: Notes:
794: BE CAREFUL with this routine: it actually scales the matrix and right
795: hand side that define the system. After the system is solved the matrix
796: and right hand side remain scaled.
798: This routine is only used if the matrix and preconditioner matrix are
799: the same thing.
801: Level: intermediate
803: .keywords: SLES, set, options, prefix, database
805: .seealso: SLESSetDiagonalScale(), SLESSetDiagonalScaleFix()
806: @*/
807: int SLESGetDiagonalScale(SLES sles,PetscTruth *scale)
808: {
811: *scale = sles->dscale;
812: return(0);
813: }
815: /*@C
816: SLESSetDiagonalScaleFix - Tells SLES to diagonally scale the system
817: back after solving.
819: Collective on SLES
821: Input Parameter:
822: . sles - the SLES context
825: Notes:
826: Must be called after SLESSetDiagonalScale()
828: Using this will slow things down, because it rescales the matrix before and
829: after each linear solve. This is intended mainly for testing to allow one
830: to easily get back the original system to make sure the solution computed is
831: accurate enough.
833: This routine is only used if the matrix and preconditioner matrix are
834: the same thing.
836: Level: intermediate
838: .keywords: SLES, set, options, prefix, database
840: .seealso: SLESGetDiagonalScale(), SLESSetDiagonalScale()
841: @*/
842: int SLESSetDiagonalScaleFix(SLES sles)
843: {
846: if (!sles->dscale) {
847: SETERRQ(1,"Must call after SLESSetDiagonalScale()");
848: }
849: sles->dscalefix = PETSC_TRUE;
850: return(0);
851: }