Actual source code: sles.c
1: /*$Id: sles.c,v 1.151 2001/08/07 03:03:26 balay Exp $*/
3: #include src/sles/slesimpl.h
5: /* Logging support */
6: int SLES_COOKIE;
7: int SLES_SetUp, SLES_Solve;
9: static int SLESPublish_Petsc(PetscObject obj)
10: {
11: #if defined(PETSC_HAVE_AMS)
12: int ierr;
13: #endif
14:
16: #if defined(PETSC_HAVE_AMS)
17: PetscObjectPublishBaseBegin(obj);
18: PetscObjectPublishBaseEnd(obj);
19: #endif
20: return(0);
21: }
23: /*@C
24: SLESView - Prints the SLES data structure.
26: Collective on SLES
28: Input Parameters:
29: + SLES - the SLES context
30: - viewer - optional visualization context
32: Options Database Key:
33: . -sles_view - Calls SLESView() at end of SLESSolve()
35: Note:
36: The available visualization contexts include
37: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
38: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
39: output where only the first processor opens
40: the file. All other processors send their
41: data to the first processor to print.
43: The user can open alternative visualization contexts with
44: . PetscViewerASCIIOpen() - output to a specified file
46: Level: beginner
48: .keywords: SLES, view
50: .seealso: PetscViewerASCIIOpen()
51: @*/
52: int SLESView(SLES sles,PetscViewer viewer)
53: {
54: KSP ksp;
55: PC pc;
56: int ierr;
60: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(sles->comm);
63: SLESGetPC(sles,&pc);
64: SLESGetKSP(sles,&ksp);
65: KSPView(ksp,viewer);
66: PCView(pc,viewer);
67: return(0);
68: }
70: /*@C
71: SLESSetOptionsPrefix - Sets the prefix used for searching for all
72: SLES options in the database.
74: Collective on SLES
76: Input Parameter:
77: + sles - the SLES context
78: - prefix - the prefix to prepend to all option names
80: Notes:
81: A hyphen (-) must NOT be given at the beginning of the prefix name.
82: The first character of all runtime options is AUTOMATICALLY the
83: hyphen.
85: This prefix is particularly useful for nested use of SLES. For
86: example, the block Jacobi and block diagonal preconditioners use
87: the prefix "sub_" for options relating to the individual blocks.
89: Level: intermediate
91: .keywords: SLES, set, options, prefix, database
93: .seealso: SLESAppendOptionsPrefix(), SLESGetOptionsPrefix()
94: @*/
95: int SLESSetOptionsPrefix(SLES sles,char *prefix)
96: {
101: PetscObjectSetOptionsPrefix((PetscObject)sles,prefix);
102: KSPSetOptionsPrefix(sles->ksp,prefix);
103: PCSetOptionsPrefix(sles->pc,prefix);
104: return(0);
105: }
107: /*@C
108: SLESAppendOptionsPrefix - Appends to the prefix used for searching for all
109: SLES options in the database.
111: Collective on SLES
113: Input Parameter:
114: + sles - the SLES context
115: - prefix - the prefix to prepend to all option names
117: Notes:
118: A hyphen (-) must NOT be given at the beginning of the prefix name.
119: The first character of all runtime options is AUTOMATICALLY the
120: hyphen.
122: This prefix is particularly useful for nested use of SLES. For
123: example, the block Jacobi and block diagonal preconditioners use
124: the prefix "sub_" for options relating to the individual blocks.
126: Level: intermediate
128: .keywords: SLES, append, options, prefix, database
130: .seealso: SLESSetOptionsPrefix(), SLESGetOptionsPrefix()
131: @*/
132: int SLESAppendOptionsPrefix(SLES sles,char *prefix)
133: {
138: PetscObjectAppendOptionsPrefix((PetscObject)sles,prefix);
139: KSPAppendOptionsPrefix(sles->ksp,prefix);
140: PCAppendOptionsPrefix(sles->pc,prefix);
141: return(0);
142: }
144: /*@C
145: SLESGetOptionsPrefix - Gets the prefix used for searching for all
146: SLES options in the database.
148: Not Collective
150: Input Parameter:
151: . sles - the SLES context
153: Output Parameter:
154: . prefix - pointer to the prefix string used
156: Notes:
157: This prefix is particularly useful for nested use of SLES. For
158: example, the block Jacobi and block diagonal preconditioners use
159: the prefix "sub" for options relating to the individual blocks.
161: On the fortran side, the user should pass in a string 'prifix' of
162: sufficient length to hold the prefix.
164: Level: intermediate
166: .keywords: SLES, get, options, prefix, database
168: .seealso: SLESSetOptionsPrefix()
169: @*/
170: int SLESGetOptionsPrefix(SLES sles,char **prefix)
171: {
176: PetscObjectGetOptionsPrefix((PetscObject)sles,prefix);
177: return(0);
178: }
180: /*@
181: SLESSetFromOptions - Sets various SLES parameters from user options.
182: Also takes all KSP and PC options.
184: Collective on SLES
186: Input Parameter:
187: . sles - the SLES context
189: Level: beginner
191: Options Database:
192: + -sles_view - print actual solver options used
193: - -sles_view_binary - save matrix and vector used for solver
195: .keywords: SLES, set, options, database
197: .seealso: KSPSetFromOptions(),
198: PCSetFromOptions(), SLESGetPC(), SLESGetKSP()
199: @*/
200: int SLESSetFromOptions(SLES sles)
201: {
202: int ierr;
203: PetscTruth flag;
207: PetscOptionsBegin(sles->comm,sles->prefix,"Linear solver (SLES) options","SLES");
208: PetscOptionsName("-sles_diagonal_scale","Diagonal scale matrix before building preconditioner","SLESSetDiagonalScale",&flag);
209: if (flag) {
210: SLESSetDiagonalScale(sles,PETSC_TRUE);
211: }
212: PetscOptionsName("-sles_diagonal_scale_fix","Fix diagonaled scaled matrix after solve","SLESSetDiagonalScaleFix",&flag);
213: if (flag) {
214: SLESSetDiagonalScaleFix(sles);
215: }
216: PetscOptionsName("-sles_view","Print detailed information on solver used","SLESView",0);
217: PetscOptionsName("-sles_view_binary","Saves matrix and vector used in solve","SLESSetFromOptions",0);
218: PetscOptionsEnd();
219: KSPSetPC(sles->ksp,sles->pc);
220: KSPSetFromOptions(sles->ksp);
221: PCSetFromOptions(sles->pc);
222: return(0);
223: }
225: /*@C
226: SLESCreate - Creates a linear equation solver context.
228: Collective on MPI_Comm
230: Input Parameter:
231: . comm - MPI communicator
233: Output Parameter:
234: . sles - the newly created SLES context
236: Level: beginner
238: .keywords: SLES, create, context
240: .seealso: SLESSolve(), SLESDestroy(), SLES
241: @*/
242: int SLESCreate(MPI_Comm comm,SLES *outsles)
243: {
244: int ierr;
245: SLES sles;
249: *outsles = 0;
250: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
251: SLESInitializePackage(PETSC_NULL);
252: #endif
254: PetscHeaderCreate(sles,_p_SLES,int,SLES_COOKIE,0,"SLES",comm,SLESDestroy,SLESView);
255: PetscLogObjectCreate(sles);
256: sles->bops->publish = SLESPublish_Petsc;
257: KSPCreate(comm,&sles->ksp);
258: PCCreate(comm,&sles->pc);
259: PetscLogObjectParent(sles,sles->ksp);
260: PetscLogObjectParent(sles,sles->pc);
261: sles->setupcalled = 0;
262: sles->dscale = PETSC_FALSE;
263: sles->dscalefix = PETSC_FALSE;
264: sles->diagonal = PETSC_NULL;
265: *outsles = sles;
266: PetscPublishAll(sles);
267: return(0);
268: }
270: /*@C
271: SLESDestroy - Destroys the SLES context.
273: Collective on SLES
275: Input Parameters:
276: . sles - the SLES context
278: Level: beginner
280: .keywords: SLES, destroy, context
282: .seealso: SLESCreate(), SLESSolve()
283: @*/
284: int SLESDestroy(SLES sles)
285: {
290: if (--sles->refct > 0) return(0);
292: PetscObjectDepublish(sles);
293: KSPDestroy(sles->ksp);
294: PCDestroy(sles->pc);
295: if (sles->diagonal) {VecDestroy(sles->diagonal);}
296: PetscLogObjectDestroy(sles);
297: PetscHeaderDestroy(sles);
298: return(0);
299: }
301: /*@
302: SLESSetUp - Performs set up required for solving a linear system.
304: Collective on SLES
306: Input Parameters:
307: + sles - the SLES context
308: . b - the right hand side
309: - x - location to hold solution
311: Note:
312: For basic use of the SLES solvers the user need not explicitly call
313: SLESSetUp(), since these actions will automatically occur during
314: the call to SLESSolve(). However, if one wishes to generate
315: performance data for this computational phase (for example, for
316: incomplete factorization using the ILU preconditioner) using the
317: PETSc log facilities, calling SLESSetUp() is required.
319: Level: advanced
321: .keywords: SLES, solve, linear system
323: .seealso: SLESCreate(), SLESDestroy(), SLESDestroy()
324: @*/
325: int SLESSetUp(SLES sles,Vec b,Vec x)
326: {
328: KSP ksp;
329: PC pc;
330: Mat mat,pmat;
339: ksp = sles->ksp; pc = sles->pc;
340: KSPSetRhs(ksp,b);
341: KSPSetSolution(ksp,x);
342: if (!sles->setupcalled) {
343: PetscLogEventBegin(SLES_SetUp,sles,b,x,0);
344: KSPSetPC(ksp,pc);
345: PCSetVector(pc,b);
346: KSPSetUp(sles->ksp);
348: /* scale the matrix if requested */
349: if (sles->dscale) {
350: PCGetOperators(pc,&mat,&pmat,PETSC_NULL);
351: if (mat == pmat) {
352: PetscScalar *xx;
353: int i,n;
354: PetscTruth zeroflag = PETSC_FALSE;
357: if (!sles->diagonal) { /* allocate vector to hold diagonal */
358: VecDuplicate(b,&sles->diagonal);
359: }
360: MatGetDiagonal(mat,sles->diagonal);
361: VecGetLocalSize(sles->diagonal,&n);
362: VecGetArray(sles->diagonal,&xx);
363: for (i=0; i<n; i++) {
364: if (xx[i] != 0.0) xx[i] = 1.0/sqrt(PetscAbsScalar(xx[i]));
365: else {
366: xx[i] = 1.0;
367: zeroflag = PETSC_TRUE;
368: }
369: }
370: VecRestoreArray(sles->diagonal,&xx);
371: if (zeroflag) {
372: PetscLogInfo(pc,"SLESSetUp:Zero detected in diagonal of matrix, using 1 at those locationsn");
373: }
374: MatDiagonalScale(mat,sles->diagonal,sles->diagonal);
375: sles->dscalefix2 = PETSC_FALSE;
376: }
377: }
379: PCSetUp(sles->pc);
380: sles->setupcalled = 1;
381: PetscLogEventEnd(SLES_SetUp,sles,b,x,0);
382: }
383: return(0);
384: }
386: /*@
387: SLESSolve - Solves a linear system.
389: Collective on SLES
391: Input Parameters:
392: + sles - the SLES context
393: - b - the right hand side
395: Output Parameters:
396: + x - the approximate solution
397: - its - the number of iterations until termination
399: Options Database:
400: + -sles_diagonal_scale - diagonally scale linear system before solving
401: . -sles_diagonal_scale_fix - unscale the matrix and right hand side when done
402: . -sles_view - print information about the solver used
403: - -sles_view_binary - save the matrix and right hand side to the default binary file (can be
404: read later with src/sles/examples/tutorials/ex10.c for testing solvers)
406: Notes:
407: Call KSPGetConvergedReason() to determine if the solver converged or failed and
408: why.
410: On return, the parameter "its" contains the iteration number at which convergence
411: was successfully reached or divergence/failure was detected
413: If using a direct method (e.g., via the KSP solver
414: KSPPREONLY and a preconditioner such as PCLU/PCILU),
415: then its=1. See KSPSetTolerances() and KSPDefaultConverged()
416: for more details. Also, see KSPSolve() for more details
417: about iterative solver options.
419: Setting a Nonzero Initial Guess:
420: By default, SLES assumes an initial guess of zero by zeroing
421: the initial value for the solution vector, x. To use a nonzero
422: initial guess, the user must call
423: .vb
424: SLESGetKSP(sles,&ksp);
425: KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);
426: .ve
428: Solving Successive Linear Systems:
429: When solving multiple linear systems of the same size with the
430: same method, several options are available.
432: (1) To solve successive linear systems having the SAME
433: preconditioner matrix (i.e., the same data structure with exactly
434: the same matrix elements) but different right-hand-side vectors,
435: the user should simply call SLESSolve() multiple times. The
436: preconditioner setup operations (e.g., factorization for ILU) will
437: be done during the first call to SLESSolve() only; such operations
438: will NOT be repeated for successive solves.
440: (2) To solve successive linear systems that have DIFFERENT
441: preconditioner matrices (i.e., the matrix elements and/or the
442: matrix data structure change), the user MUST call SLESSetOperators()
443: and SLESSolve() for each solve. See SLESSetOperators() for
444: options that can save work for such cases.
446: Level: beginner
448: .keywords: SLES, solve, linear system
450: .seealso: SLESCreate(), SLESSetOperators(), SLESGetKSP(), KSPSetTolerances(),
451: KSPDefaultConverged(), KSPSetInitialGuessNonzero(), KSPGetResidualNorm(),
452: KSPSolve()
453: @*/
454: int SLESSolve(SLES sles,Vec b,Vec x,int *its)
455: {
456: int ierr;
457: PetscTruth flg;
458: KSP ksp;
459: PC pc;
467: if (b == x) SETERRQ(PETSC_ERR_ARG_IDN,"b and x must be different vectors");
469: PetscOptionsHasName(sles->prefix,"-sles_view_binary",&flg);
470: if (flg) {
471: Mat mat;
472: PCGetOperators(sles->pc,&mat,PETSC_NULL,PETSC_NULL);
473: MatView(mat,PETSC_VIEWER_BINARY_(sles->comm));
474: VecView(b,PETSC_VIEWER_BINARY_(sles->comm));
475: }
476: ksp = sles->ksp;
477: pc = sles->pc;
478: SLESSetUp(sles,b,x);
479: SLESSetUpOnBlocks(sles);
480: PetscLogEventBegin(SLES_Solve,sles,b,x,0);
481: /* diagonal scale RHS if called for */
482: if (sles->dscale) {
483: VecPointwiseMult(sles->diagonal,b,b);
484: /* second time in, but matrix was scaled back to original */
485: if (sles->dscalefix && sles->dscalefix2) {
486: Mat mat;
488: PCGetOperators(pc,&mat,PETSC_NULL,PETSC_NULL);
489: MatDiagonalScale(mat,sles->diagonal,sles->diagonal);
490: }
491: }
492: PCPreSolve(pc,ksp);
493: KSPSolve(ksp,its);
494: PCPostSolve(pc,ksp);
495: /* diagonal scale solution if called for */
496: if (sles->dscale) {
497: VecPointwiseMult(sles->diagonal,x,x);
498: /* unscale right hand side and matrix */
499: if (sles->dscalefix) {
500: Mat mat;
502: VecReciprocal(sles->diagonal);
503: VecPointwiseMult(sles->diagonal,b,b);
504: PCGetOperators(pc,&mat,PETSC_NULL,PETSC_NULL);
505: MatDiagonalScale(mat,sles->diagonal,sles->diagonal);
506: VecReciprocal(sles->diagonal);
507: sles->dscalefix2 = PETSC_TRUE;
508: }
509: }
510: PetscLogEventEnd(SLES_Solve,sles,b,x,0);
511: PetscOptionsHasName(sles->prefix,"-sles_view",&flg);
512: if (flg && !PetscPreLoadingOn) { SLESView(sles,PETSC_VIEWER_STDOUT_WORLD); }
513: return(0);
514: }
516: /*@
517: SLESSolveTranspose - Solves the transpose of a linear system.
519: Collective on SLES
521: Input Parameters:
522: + sles - the SLES context
523: - b - the right hand side
525: Output Parameters:
526: + x - the approximate solution
527: - its - the number of iterations until termination
529: Notes:
530: On return, the parameter "its" contains
531: + <its> - the iteration number at which convergence
532: was successfully reached, or
533: - <-its> - the negative of the iteration at which
534: divergence or breakdown was detected.
536: Currently works only with the KSPPREONLY method.
538: Setting a Nonzero Initial Guess:
539: By default, SLES assumes an initial guess of zero by zeroing
540: the initial value for the solution vector, x. To use a nonzero
541: initial guess, the user must call
542: .vb
543: SLESGetKSP(sles,&ksp);
544: KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);
545: .ve
547: Solving Successive Linear Systems:
548: When solving multiple linear systems of the same size with the
549: same method, several options are available.
551: (1) To solve successive linear systems having the SAME
552: preconditioner matrix (i.e., the same data structure with exactly
553: the same matrix elements) but different right-hand-side vectors,
554: the user should simply call SLESSolve() multiple times. The
555: preconditioner setup operations (e.g., factorization for ILU) will
556: be done during the first call to SLESSolve() only; such operations
557: will NOT be repeated for successive solves.
559: (2) To solve successive linear systems that have DIFFERENT
560: preconditioner matrices (i.e., the matrix elements and/or the
561: matrix data structure change), the user MUST call SLESSetOperators()
562: and SLESSolve() for each solve. See SLESSetOperators() for
563: options that can save work for such cases.
565: Level: intermediate
567: .keywords: SLES, solve, linear system
569: .seealso: SLESCreate(), SLESSetOperators(), SLESGetKSP(), KSPSetTolerances(),
570: KSPDefaultConverged(), KSPSetInitialGuessNonzero(), KSPGetResidualNorm(),
571: KSPSolve()
572: @*/
573: int SLESSolveTranspose(SLES sles,Vec b,Vec x,int *its)
574: {
575: int ierr;
576: PetscTruth flg;
577: KSP ksp;
578: PC pc;
584: if (b == x) SETERRQ(PETSC_ERR_ARG_IDN,"b and x must be different vectors");
588: ksp = sles->ksp; pc = sles->pc;
589: KSPSetRhs(ksp,b);
590: KSPSetSolution(ksp,x);
591: KSPSetPC(ksp,pc);
592: if (!sles->setupcalled) {
593: SLESSetUp(sles,b,x);
594: }
595: PCSetUpOnBlocks(pc);
596: PetscLogEventBegin(SLES_Solve,sles,b,x,0);
597: KSPSolveTranspose(ksp,its);
598: PetscLogEventEnd(SLES_Solve,sles,b,x,0);
599: PetscOptionsHasName(sles->prefix,"-sles_view",&flg);
600: if (flg) { SLESView(sles,PETSC_VIEWER_STDOUT_WORLD); }
601: return(0);
602: }
604: /*@C
605: SLESGetKSP - Returns the KSP context for a SLES solver.
607: Not Collective, but if KSP will be a parallel object if SLES is
609: Input Parameter:
610: . sles - the SLES context
612: Output Parameter:
613: . ksp - the Krylov space context
615: Notes:
616: The user can then directly manipulate the KSP context to set various
617: options (e.g., by calling KSPSetType()), etc.
619: Level: beginner
620:
621: .keywords: SLES, get, KSP, context
623: .seealso: SLESGetPC()
624: @*/
625: int SLESGetKSP(SLES sles,KSP *ksp)
626: {
629: *ksp = sles->ksp;
630: return(0);
631: }
633: /*@C
634: SLESGetPC - Returns the preconditioner (PC) context for a SLES solver.
636: Not Collective, but if PC will be a parallel object if SLES is
638: Input Parameter:
639: . sles - the SLES context
641: Output Parameter:
642: . pc - the preconditioner context
644: Notes:
645: The user can then directly manipulate the PC context to set various
646: options (e.g., by calling PCSetType()), etc.
648: Level: beginner
650: .keywords: SLES, get, PC, context
652: .seealso: SLESGetKSP()
653: @*/
654: int SLESGetPC(SLES sles,PC *pc)
655: {
658: *pc = sles->pc;
659: return(0);
660: }
662: #include src/mat/matimpl.h
663: /*@
664: SLESSetOperators - Sets the matrix associated with the linear system
665: and a (possibly) different one associated with the preconditioner.
667: Collective on SLES and Mat
669: Input Parameters:
670: + sles - the SLES context
671: . Amat - the matrix associated with the linear system
672: . Pmat - the matrix to be used in constructing the preconditioner, usually the
673: same as Amat.
674: - flag - flag indicating information about the preconditioner matrix structure
675: during successive linear solves. This flag is ignored the first time a
676: linear system is solved, and thus is irrelevant when solving just one linear
677: system.
679: Notes:
680: The flag can be used to eliminate unnecessary work in the preconditioner
681: during the repeated solution of linear systems of the same size. The
682: available options are
683: $ SAME_PRECONDITIONER -
684: $ Pmat is identical during successive linear solves.
685: $ This option is intended for folks who are using
686: $ different Amat and Pmat matrices and want to reuse the
687: $ same preconditioner matrix. For example, this option
688: $ saves work by not recomputing incomplete factorization
689: $ for ILU/ICC preconditioners.
690: $ SAME_NONZERO_PATTERN -
691: $ Pmat has the same nonzero structure during
692: $ successive linear solves.
693: $ DIFFERENT_NONZERO_PATTERN -
694: $ Pmat does not have the same nonzero structure.
696: Caution:
697: If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion
698: and does not check the structure of the matrix. If you erroneously
699: claim that the structure is the same when it actually is not, the new
700: preconditioner will not function correctly. Thus, use this optimization
701: feature carefully!
703: If in doubt about whether your preconditioner matrix has changed
704: structure or not, use the flag DIFFERENT_NONZERO_PATTERN.
706: Level: beginner
708: .keywords: SLES, set, operators, matrix, preconditioner, linear system
710: .seealso: SLESSolve(), SLESGetPC(), PCGetOperators()
711: @*/
712: int SLESSetOperators(SLES sles,Mat Amat,Mat Pmat,MatStructure flag)
713: {
718: PCSetOperators(sles->pc,Amat,Pmat,flag);
719: sles->setupcalled = 0; /* so that next solve call will call setup */
720: return(0);
721: }
723: /*@
724: SLESSetUpOnBlocks - Sets up the preconditioner for each block in
725: the block Jacobi, block Gauss-Seidel, and overlapping Schwarz
726: methods.
728: Collective on SLES
730: Input Parameter:
731: . sles - the SLES context
733: Notes:
734: SLESSetUpOnBlocks() is a routine that the user can optinally call for
735: more precise profiling (via -log_summary) of the setup phase for these
736: block preconditioners. If the user does not call SLESSetUpOnBlocks(),
737: it will automatically be called from within SLESSolve().
738:
739: Calling SLESSetUpOnBlocks() is the same as calling PCSetUpOnBlocks()
740: on the PC context within the SLES context.
742: Level: advanced
744: .keywords: SLES, setup, blocks
746: .seealso: PCSetUpOnBlocks(), SLESSetUp(), PCSetUp()
747: @*/
748: int SLESSetUpOnBlocks(SLES sles)
749: {
751: PC pc;
755: SLESGetPC(sles,&pc);
756: PCSetUpOnBlocks(pc);
757: return(0);
758: }
760: /*@C
761: SLESSetDiagonalScale - Tells SLES to diagonally scale the system
762: before solving. This actually CHANGES the matrix (and right hand side).
764: Collective on SLES
766: Input Parameter:
767: + sles - the SLES context
768: - scale - PETSC_TRUE or PETSC_FALSE
770: Notes:
771: BE CAREFUL with this routine: it actually scales the matrix and right
772: hand side that define the system. After the system is solved the matrix
773: and right hand side remain scaled.
775: This routine is only used if the matrix and preconditioner matrix are
776: the same thing.
777:
778: If you use this with the PCType Eisenstat preconditioner than you can
779: use the PCEisenstatNoDiagonalScaling() option, or -pc_eisenstat_no_diagonal_scaling
780: to save some unneeded, redundant flops.
782: Level: intermediate
784: .keywords: SLES, set, options, prefix, database
786: .seealso: SLESGetDiagonalScale(), SLESSetDiagonalScaleFix()
787: @*/
788: int SLESSetDiagonalScale(SLES sles,PetscTruth scale)
789: {
792: sles->dscale = scale;
793: return(0);
794: }
796: /*@C
797: SLESGetDiagonalScale - Checks if SLES solver scales the matrix and
798: right hand side
800: Not Collective
802: Input Parameter:
803: . sles - the SLES context
805: Output Parameter:
806: . scale - PETSC_TRUE or PETSC_FALSE
808: Notes:
809: BE CAREFUL with this routine: it actually scales the matrix and right
810: hand side that define the system. After the system is solved the matrix
811: and right hand side remain scaled.
813: This routine is only used if the matrix and preconditioner matrix are
814: the same thing.
816: Level: intermediate
818: .keywords: SLES, set, options, prefix, database
820: .seealso: SLESSetDiagonalScale(), SLESSetDiagonalScaleFix()
821: @*/
822: int SLESGetDiagonalScale(SLES sles,PetscTruth *scale)
823: {
826: *scale = sles->dscale;
827: return(0);
828: }
830: /*@C
831: SLESSetDiagonalScaleFix - Tells SLES to diagonally scale the system
832: back after solving.
834: Collective on SLES
836: Input Parameter:
837: . sles - the SLES context
840: Notes:
841: Must be called after SLESSetDiagonalScale()
843: Using this will slow things down, because it rescales the matrix before and
844: after each linear solve. This is intended mainly for testing to allow one
845: to easily get back the original system to make sure the solution computed is
846: accurate enough.
848: This routine is only used if the matrix and preconditioner matrix are
849: the same thing.
851: Level: intermediate
853: .keywords: SLES, set, options, prefix, database
855: .seealso: SLESGetDiagonalScale(), SLESSetDiagonalScale()
856: @*/
857: int SLESSetDiagonalScaleFix(SLES sles)
858: {
861: if (!sles->dscale) {
862: SETERRQ(1,"Must call after SLESSetDiagonalScale(); if setting with command line options you must setn
863: -sles_diagonal_scale option if you set the -sles_diagonal_scale_fix option");
864: }
865: sles->dscalefix = PETSC_TRUE;
866: return(0);
867: }