Actual source code: itres.c

      1: #define PETSCKSP_DLL

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

      7: /*@C
      8:    KSPInitialResidual - Computes the residual. Either b - A*C*x with right
      9:      preconditioning or C*b - C*A*x with left preconditioning; that later
     10:      residual is often called the "preconditioned residual".

     12:    Collective on KSP

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

     19:    Output Parameters:
     20: .  vres     - calculated residual

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

     33:    Level: developer

     35: .keywords: KSP, residual

     37: .seealso:  KSPMonitor()
     38: @*/
     39: PetscErrorCode PETSCKSP_DLLEXPORT KSPInitialResidual(KSP ksp,Vec vsoln,Vec vt1,Vec vt2,Vec vres,Vec vb)
     40: {
     41:   PetscScalar    mone = -1.0;
     42:   MatStructure   pflag;
     43:   Mat            Amat,Pmat;

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

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

     82:    Collective on KSP

     84:    Input Parameters:
     85: +  ksp  - iterative context
     86: .  vsoln - solution vector
     87: -  vt1   - temporary work vector

     89:    Output Parameter:
     90: .  vsoln - contains solution on output

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

     97:    Level: advanced

     99: .keywords: KSP, unwind, preconditioner

    101: .seealso: KSPSetPreconditionerSide()
    102: @*/
    103: PetscErrorCode PETSCKSP_DLLEXPORT KSPUnwindPreconditioner(KSP ksp,Vec vsoln,Vec vt1)
    104: {

    110:   if (ksp->pc_side == PC_RIGHT) {
    111:     KSP_PCApply(ksp,vsoln,vt1);
    112:     PCDiagonalScaleRight(ksp->pc,vt1,vsoln);
    113:   } else if (ksp->pc_side == PC_SYMMETRIC) {
    114:     PCApplySymmetricRight(ksp->pc,vsoln,vt1);
    115:     VecCopy(vt1,vsoln);
    116:   } else {
    117:     PCDiagonalScaleRight(ksp->pc,vsoln,vsoln);
    118:   }
    119:   return(0);
    120: }