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