Actual source code: itres.c

petsc-master 2019-08-22
Report Typos and Errors

  2:  #include <petsc/private/kspimpl.h>

  4: /*@
  5:    KSPInitialResidual - Computes the residual. Either b - A*C*u = b - A*x with right
  6:      preconditioning or C*(b - A*x) with left preconditioning; that later
  7:      residual is often called the "preconditioned residual".

  9:    Collective on ksp

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

 16:    Output Parameters:
 17: .  vres     - calculated residual

 19:    Notes:
 20:    This routine assumes that an iterative method, designed for
 21: $     A x = b
 22:    will be used with a preconditioner, C, such that the actual problem is either
 23: $     AC u = b (right preconditioning) or
 24: $     CA x = Cb (left preconditioning).
 25:    This means that the calculated residual will be scaled and/or preconditioned;
 26:    the true residual
 27: $     b-Ax
 28:    is returned in the vt2 temporary.

 30:    Level: developer

 32: .seealso:  KSPMonitor()
 33: @*/

 35: PetscErrorCode  KSPInitialResidual(KSP ksp,Vec vsoln,Vec vt1,Vec vt2,Vec vres,Vec vb)
 36: {
 37:   Mat            Amat,Pmat;

 45:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
 46:   PCGetOperators(ksp->pc,&Amat,&Pmat);
 47:   if (!ksp->guess_zero) {
 48:     /* skip right scaling since current guess already has it */
 49:     KSP_MatMult(ksp,Amat,vsoln,vt1);
 50:     VecCopy(vb,vt2);
 51:     VecAXPY(vt2,-1.0,vt1);
 52:     if (ksp->pc_side == PC_RIGHT) {
 53:       PCDiagonalScaleLeft(ksp->pc,vt2,vres);
 54:     } else if (ksp->pc_side == PC_LEFT) {
 55:         KSP_PCApply(ksp,vt2,vres);
 56:         PCDiagonalScaleLeft(ksp->pc,vres,vres);
 57:     } else if (ksp->pc_side == PC_SYMMETRIC) {
 58:       PCApplySymmetricLeft(ksp->pc,vt2,vres);
 59:     } else SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP, "Invalid preconditioning side %d", (int)ksp->pc_side);
 60:   } else {
 61:     VecCopy(vb,vt2);
 62:     if (ksp->pc_side == PC_RIGHT) {
 63:       PCDiagonalScaleLeft(ksp->pc,vb,vres);
 64:     } else if (ksp->pc_side == PC_LEFT) {
 65:       KSP_PCApply(ksp,vb,vres);
 66:       PCDiagonalScaleLeft(ksp->pc,vres,vres);
 67:     } else if (ksp->pc_side == PC_SYMMETRIC) {
 68:       PCApplySymmetricLeft(ksp->pc, vb, vres);
 69:     } else SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP, "Invalid preconditioning side %d", (int)ksp->pc_side);
 70:   }
 71:   return(0);
 72: }

 74: /*@
 75:    KSPUnwindPreconditioner - Unwinds the preconditioning in the solution. That is,
 76:      takes solution to the preconditioned problem and gets the solution to the
 77:      original problem from it.

 79:    Collective on ksp

 81:    Input Parameters:
 82: +  ksp  - iterative context
 83: .  vsoln - solution vector
 84: -  vt1   - temporary work vector

 86:    Output Parameter:
 87: .  vsoln - contains solution on output

 89:    Notes:
 90:    If preconditioning either symmetrically or on the right, this routine solves
 91:    for the correction to the unpreconditioned problem.  If preconditioning on
 92:    the left, nothing is done.

 94:    Level: advanced

 96: .seealso: KSPSetPCSide()
 97: @*/
 98: PetscErrorCode  KSPUnwindPreconditioner(KSP ksp,Vec vsoln,Vec vt1)
 99: {

105:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
106:   if (ksp->pc_side == PC_RIGHT) {
107:     KSP_PCApply(ksp,vsoln,vt1);
108:     PCDiagonalScaleRight(ksp->pc,vt1,vsoln);
109:   } else if (ksp->pc_side == PC_SYMMETRIC) {
110:     PCApplySymmetricRight(ksp->pc,vsoln,vt1);
111:     VecCopy(vt1,vsoln);
112:   } else {
113:     PCDiagonalScaleRight(ksp->pc,vsoln,vsoln);
114:   }
115:   return(0);
116: }