Actual source code: itres.c

  1: /*$Id: itres.c,v 1.54 2001/08/07 03:03:45 balay Exp $*/

 3:  #include src/ksp/ksp/kspimpl.h

  7: /*@C
  8:    KSPInitialResidual - Computes the residual.

 10:    Collective on KSP

 12:    Input Parameters:
 13: +  vsoln    - solution to use in computing residual
 14: .  vt1, vt2 - temporary work vectors
 15: .  vres     - calculated residual
 16: -  vb       - right-hand-side vector

 18:    Notes:
 19:    This routine assumes that an iterative method, designed for
 20: $     A x = b
 21:    will be used with a preconditioner, C, such that the actual problem is either
 22: $     AC u = f (right preconditioning) or
 23: $     CA x = Cf (left preconditioning).

 25:    Level: developer

 27: .keywords: KSP, residual

 29: .seealso:  KSPMonitor()
 30: @*/
 31: int KSPInitialResidual(KSP ksp,Vec vsoln,Vec vt1,Vec vt2,Vec vres,Vec vb)
 32: {
 33:   PetscScalar   mone = -1.0;
 34:   MatStructure  pflag;
 35:   Mat           Amat,Pmat;
 36:   int           ierr;

 43:   PCGetOperators(ksp->B,&Amat,&Pmat,&pflag);
 44:   if (!ksp->guess_zero) {
 45:     /* skip right scaling since current guess already has it */
 46:     KSP_MatMult(ksp,Amat,vsoln,vt1);
 47:     VecCopy(vb,vt2);
 48:     VecAXPY(&mone,vt1,vt2);
 49:     (ksp->pc_side == PC_RIGHT)?(VecCopy(vt2,vres)):(KSP_PCApply(ksp,ksp->B,vt2,vres));
 50:     PCDiagonalScaleLeft(ksp->B,vres,vres);
 51:   } else {
 52:     if (ksp->pc_side == PC_RIGHT) {
 53:       PCDiagonalScaleLeft(ksp->B,vb,vres);
 54:     } else if (ksp->pc_side == PC_LEFT) {
 55:       KSP_PCApply(ksp,ksp->B,vb,vres);
 56:       PCDiagonalScaleLeft(ksp->B,vres,vres);
 57:     } else if (ksp->pc_side == PC_SYMMETRIC) {
 58:       PCApplySymmetricLeft(ksp->B, vb, vres);
 59:     } else {
 60:       SETERRQ1(PETSC_ERR_SUP, "Invalid preconditioning side %d", ksp->pc_side);
 61:   }

 63:   }
 64:   return(0);
 65: }

 69: /*@
 70:    KSPUnwindPreconditioner - Unwinds the preconditioning in the solution. That is,
 71:      takes solution to the preconditioned problem and gets the solution to the 
 72:      original problem from it.

 74:    Collective on KSP

 76:    Input Parameters:
 77: +  ksp  - iterative context
 78: .  vsoln - solution vector 
 79: -  vt1   - temporary work vector

 81:    Output Parameter:
 82: .  vsoln - contains solution on output  

 84:    Notes:
 85:    If preconditioning either symmetrically or on the right, this routine solves 
 86:    for the correction to the unpreconditioned problem.  If preconditioning on 
 87:    the left, nothing is done.

 89:    Level: advanced

 91: .keywords: KSP, unwind, preconditioner

 93: .seealso: KSPSetPreconditionerSide()
 94: @*/
 95: int KSPUnwindPreconditioner(KSP ksp,Vec vsoln,Vec vt1)
 96: {

102:   if (ksp->pc_side == PC_RIGHT) {
103:     KSP_PCApply(ksp,ksp->B,vsoln,vt1);
104:     PCDiagonalScaleRight(ksp->B,vt1,vsoln);
105:   } else if (ksp->pc_side == PC_SYMMETRIC) {
106:     PCApplySymmetricRight(ksp->B,vsoln,vt1);
107:     VecCopy(vt1,vsoln);
108:   } else {
109:     PCDiagonalScaleRight(ksp->B,vsoln,vsoln);
110:   }
111:   return(0);
112: }