Actual source code: cr.c

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

  6: static PetscErrorCode KSPSetUp_CR(KSP ksp)
  7: {

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

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

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

 40:   /* R is the true residual norm, RT is the preconditioned residual norm */
 41:   PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);
 42:   if (!ksp->guess_zero) {
 43:     KSP_MatMult(ksp,Amat,X,R);     /*   R <- A*X           */
 44:     VecAYPX(&mone,B,R);            /*   R <- B-R == B-A*X  */
 45:   } else {
 46:     VecCopy(B,R);                  /*   R <- B (X is 0)    */
 47:   }
 48:   KSP_PCApply(ksp,R,P);     /*   P   <- B*R         */
 49:   KSP_MatMult(ksp,Amat,P,AP);      /*   AP  <- A*P         */
 50:   VecCopy(P,RT);                   /*   RT  <- P           */
 51:   VecCopy(AP,ART);                 /*   ART <- AP          */
 52:   VecDot(RT,ART,&btop);          /*   (RT,ART)           */
 53:   if (ksp->normtype == KSP_PRECONDITIONED_NORM) {
 54:     VecNorm(RT,NORM_2,&dp);        /*   dp <- RT'*RT       */
 55:   } else if (ksp->normtype == KSP_UNPRECONDITIONED_NORM) {
 56:     VecNorm(R,NORM_2,&dp);         /*   dp <- R'*R         */
 57:   } else if (ksp->normtype == KSP_NATURAL_NORM) {
 58:     dp = sqrt(PetscAbsScalar(btop));                    /* dp = sqrt(R,AR)      */
 59:   }
 60:   ksp->its = 0;
 61:   KSPMonitor(ksp,0,dp);
 62:   PetscObjectTakeAccess(ksp);
 63:   ksp->rnorm              = dp;
 64:   PetscObjectGrantAccess(ksp);
 65:   KSPLogResidualHistory(ksp,dp);
 66:   (*ksp->converged)(ksp,0,dp,&ksp->reason,ksp->cnvP);
 67:   if (ksp->reason) return(0);

 69:   i = 0;
 70:   do {
 71:     KSP_PCApply(ksp,AP,Q);/*   Q <- B* AP          */
 72:                                                         /* Step 3                */

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

 77:     VecAXPY(&ai,P,X);            /*   X   <- X + ai*P     */
 78:     ai     = -ai;
 79:     VecAXPY(&ai,Q,RT);           /*   RT  <- RT - ai*Q    */
 80:     KSP_MatMult(ksp,Amat,RT,ART);/*   ART <-   A*RT       */
 81:     bbot = btop;
 82:     VecDot(RT,ART,&btop);

 84:     if (ksp->normtype == KSP_PRECONDITIONED_NORM) {
 85:       VecNorm(RT,NORM_2,&dp);      /*   dp <- || RT ||      */
 86:     } else if (ksp->normtype == KSP_NATURAL_NORM) {
 87:       dp = sqrt(PetscAbsScalar(btop));                  /* dp = sqrt(R,AR)       */
 88:     } else if (ksp->normtype == KSP_NO_NORM) {
 89:       dp = 0.0;
 90:     } else if (ksp->normtype == KSP_UNPRECONDITIONED_NORM) {
 91:       VecAXPY(&ai,AP,R);           /*   R   <- R - ai*AP    */
 92:       VecNorm(R,NORM_2,&dp);       /*   dp <- R'*R          */
 93:     } else {
 94:       SETERRQ1(PETSC_ERR_SUP,"KSPNormType of %d not supported",(int)ksp->normtype);
 95:     }

 97:     PetscObjectTakeAccess(ksp);
 98:     ksp->its++;
 99:     ksp->rnorm = dp;
100:     PetscObjectGrantAccess(ksp);

102:     KSPLogResidualHistory(ksp,dp);
103:     KSPMonitor(ksp,i+1,dp);
104:     (*ksp->converged)(ksp,i+1,dp,&ksp->reason,ksp->cnvP);
105:     if (ksp->reason) break;

107:     bi = btop/bbot;
108:     VecAYPX(&bi,RT,P);              /*   P <- RT + Bi P     */
109:     VecAYPX(&bi,ART,AP);            /*   AP <- ART + Bi AP  */
110:     i++;
111:   } while (i<ksp->max_it);
112:   if (i >= ksp->max_it) {
113:     ksp->reason =  KSP_DIVERGED_ITS;
114:   }
115:   return(0);
116: }


119: /*MC
120:      KSPCR - This code implements the (preconditioned) conjugate residuals method

122:    Options Database Keys:
123: .   see KSPSolve()

125:    Level: beginner

127:    Notes: The operator and the preconditioner must be symmetric for this method

129: .seealso: KSPCreate(), KSPSetType(), KSPType (for list of available types), KSP, KSPCG
130: M*/
134: PetscErrorCode KSPCreate_CR(KSP ksp)
135: {
137:   ksp->pc_side                   = PC_LEFT;
138:   ksp->ops->setup                = KSPSetUp_CR;
139:   ksp->ops->solve                = KSPSolve_CR;
140:   ksp->ops->destroy              = KSPDefaultDestroy;
141:   ksp->ops->buildsolution        = KSPDefaultBuildSolution;
142:   ksp->ops->buildresidual        = KSPDefaultBuildResidual;
143:   ksp->ops->setfromoptions       = 0;
144:   ksp->ops->view                 = 0;
145:   return(0);
146: }