Actual source code: cr.c

  1: /*$Id: cr.c,v 1.64 2001/08/07 03:03:49 balay Exp $*/

  3: /*                       
  4:            This implements Preconditioned Conjugate Residuals.       
  5: */
 6:  #include src/sles/ksp/kspimpl.h

  8: static int KSPSetUp_CR(KSP ksp)
  9: {

 13:   if (ksp->pc_side == PC_RIGHT) {SETERRQ(2,"no right preconditioning for KSPCR");}
 14:   else if (ksp->pc_side == PC_SYMMETRIC) {SETERRQ(2,"no symmetric preconditioning for KSPCR");}
 15:   KSPDefaultGetWork(ksp,6);
 16:   return(0);
 17: }

 19: static int  KSPSolve_CR(KSP ksp,int *its)
 20: {
 21:   int          i = 0, maxit, cerr = 0, ierr;
 22:   MatStructure pflag;
 23:   PetscReal    dp;
 24:   PetscScalar  ai, bi;
 25:   PetscScalar  apq,btop, bbot, tmp, mone = -1.0;
 26:   Vec          X,B,R,RT,P,AP,ART,Q;
 27:   Mat          Amat, Pmat;


 31:   maxit   = ksp->max_it;
 32:   X       = ksp->vec_sol;
 33:   B       = ksp->vec_rhs;
 34:   R       = ksp->work[0];
 35:   RT      = ksp->work[1];
 36:   P       = ksp->work[2];
 37:   AP      = ksp->work[3];
 38:   ART     = ksp->work[4];
 39:   Q       = ksp->work[5];

 41:                                       /*  we follow Rati Chandra's PhD */
 42:   PCGetOperators(ksp->B,&Amat,&Pmat,&pflag);
 43:                                                  /*                      */
 44:   if (!ksp->guess_zero) {
 45:     KSP_MatMult(ksp,Amat,X,R);      /*   r <- Ax            */
 46:     VecAYPX(&mone,B,R);     /*   r <- b-r == b-Ax   */
 47:   } else {
 48:     VecCopy(B,R);           /*   r <- b (x is 0)    */
 49:   }
 50:   KSP_PCApply(ksp,ksp->B,R,P);      /*   P <- Br            */
 51:   KSP_MatMult(ksp,Amat,P,AP);       /*   AP <- A p          */
 52:   VecCopy(P,RT);            /*   rt <- p            */
 53:   VecCopy(AP,ART);          /*   ART <- AP          */
 54:   ierr   = VecDot(RT,ART,&btop);   /*   (RT,ART)           */
 55:   if (ksp->normtype == KSP_PRECONDITIONED_NORM) {
 56:     VecNorm(P,NORM_2,&dp);  /*   dp <- z'*z         */
 57:   } else if (ksp->normtype == KSP_UNPRECONDITIONED_NORM) {
 58:     VecNorm(R,NORM_2,&dp);  /*   dp <- r'*r         */
 59:   } else if (ksp->normtype == KSP_NATURAL_NORM) {
 60:     dp = PetscAbsScalar(btop);                  /* dp = (R,AR) (fdi)*/
 61:   }
 62:   (*ksp->converged)(ksp,0,dp,&ksp->reason,ksp->cnvP);
 63:   if (ksp->reason) {*its = 0; return(0);}
 64:   KSPMonitor(ksp,0,dp);
 65:   PetscObjectTakeAccess(ksp);
 66:   ksp->its = 0;
 67:   ksp->rnorm              = dp;
 68:   PetscObjectGrantAccess(ksp);
 69:   KSPLogResidualHistory(ksp,dp);

 71:   for ( i=0; i<maxit; i++) {
 72:     ierr   = KSP_PCApply(ksp,ksp->B,AP,Q); /*   q <- B AP          */
 73:                                                   /* Step 3              */

 75:     ierr   = VecDot(AP,Q,&apq);
 76:     ai = btop/apq;                              /* ai = (RT,ART)/(AP,Q) */

 78:     ierr   = VecAXPY(&ai,P,X);     /*   x <- x + ai p      */
 79:     tmp    = -ai;
 80:     ierr   = VecAXPY(&tmp,Q,RT);   /*   rt <- rt - ai q    */
 81:     ierr   = KSP_MatMult(ksp,Amat,RT,ART); /*   RT <-   ART        */
 82:     bbot = btop;
 83:     ierr   = VecDot(RT,ART,&btop);

 85:     if (ksp->normtype == KSP_PRECONDITIONED_NORM) {
 86:       VecNorm(RT,NORM_2,&dp); /*   dp <- r'*r         */
 87:     } else if (ksp->normtype == KSP_NATURAL_NORM) {
 88:       dp = PetscAbsScalar(btop);                /* dp = (R,AR) (fdi)*/
 89:     } else { dp = 0.0; }

 91:     PetscObjectTakeAccess(ksp);
 92:     ksp->its++;
 93:     ksp->rnorm = dp;
 94:     PetscObjectGrantAccess(ksp);
 95:                                                   /* Step 2              */
 96:     KSPLogResidualHistory(ksp,dp);
 97:     KSPMonitor(ksp,i+1,dp);
 98:     (*ksp->converged)(ksp,i+1,dp,&ksp->reason,ksp->cnvP);
 99:     if (ksp->reason) break;

101:     bi = btop/bbot;
102:     VecAYPX(&bi,RT,P);      /*   P <- rt + Bi P     */
103:     VecAYPX(&bi,ART,AP);    /*   AP <- Art + Bi AP  */
104:   }
105:   if (i == maxit) i--;
106:   if (cerr <= 0) *its = -(i+1);
107:   else           *its = i + 1;
108:   return(0);
109: }


112: EXTERN_C_BEGIN
113: int KSPCreate_CR(KSP ksp)
114: {
116:   ksp->pc_side                   = PC_LEFT;
117:   ksp->ops->setup                = KSPSetUp_CR;
118:   ksp->ops->solve                = KSPSolve_CR;
119:   ksp->ops->destroy              = KSPDefaultDestroy;
120:   ksp->ops->buildsolution        = KSPDefaultBuildSolution;
121:   ksp->ops->buildresidual        = KSPDefaultBuildResidual;
122:   ksp->ops->setfromoptions       = 0;
123:   ksp->ops->view                 = 0;
124:   return(0);
125: }
126: EXTERN_C_END