Actual source code: borthog2.c

  1: /*
  2:     Routines used for the orthogonalization of the Hessenberg matrix.

  4:     Note that for the complex numbers version, the VecDot() and
  5:     VecMDot() arguments within the code MUST remain in the order
  6:     given for correct computation of inner products.
  7: */
 8:  #include src/ksp/ksp/impls/gmres/gmresp.h

 10: /*@C
 11:      KSPGMRESClassicalGramSchmidtOrthogonalization -  This is the basic orthogonalization routine 
 12:                 using classical Gram-Schmidt with possible iterative refinement to improve the stability

 14:      Collective on KSP

 16:   Input Parameters:
 17: +   ksp - KSP object, must be associated with GMRES, FGMRES, or LGMRES Krylov method
 18: -   its - one less then the current GMRES restart iteration, i.e. the size of the Krylov space

 20:    Options Database Keys:
 21: +   -ksp_gmres_classicalgramschmidt - Activates KSPGMRESClassicalGramSchmidtOrthogonalization()
 22: -   -ksp_gmres_cgs_refinement_type <never,ifneeded,always> - determine if iterative refinement is used to increase the 
 23:                                    stability of the classical Gram-Schmidt  orthogonalization.

 25:     Notes: Use KSPGMRESSetCGSRefinementType() to determine if iterative refinement is to be used

 27:    Level: intermediate

 29: .seelaso:  KSPGMRESSetOrthogonalization(), KSPGMRESClassicalGramSchmidtOrthogonalization(), KSPGMRESSetCGSRefinementType()

 31: @*/
 34: PetscErrorCode KSPGMRESClassicalGramSchmidtOrthogonalization(KSP  ksp,PetscInt it)
 35: {
 36:   KSP_GMRES      *gmres = (KSP_GMRES *)(ksp->data);
 38:   PetscInt       j;
 39:   PetscScalar    *hh,*hes,shh[500],*lhh;
 40:   PetscReal      hnrm, wnrm;
 41:   PetscTruth     refine = (PetscTruth)(gmres->cgstype == KSP_GMRES_CGS_REFINE_ALWAYS);

 44:   PetscLogEventBegin(KSP_GMRESOrthogonalization,ksp,0,0,0);
 45:   /* Don't allocate small arrays */
 46:   if (it < 501) lhh = shh;
 47:   else {
 48:     PetscMalloc((it+1) * sizeof(PetscScalar),&lhh);
 49:   }
 50: 
 51:   /* update Hessenberg matrix and do unmodified Gram-Schmidt */
 52:   hh  = HH(0,it);
 53:   hes = HES(0,it);

 55:   /* Clear hh and hes since we will accumulate values into them */
 56:   for (j=0; j<=it; j++) {
 57:     hh[j]  = 0.0;
 58:     hes[j] = 0.0;
 59:   }

 61:   /* 
 62:      This is really a matrix-vector product, with the matrix stored
 63:      as pointer to rows 
 64:   */
 65:   VecMDot(it+1,VEC_VV(it+1),&(VEC_VV(0)),lhh); /* <v,vnew> */
 66:   for (j=0; j<=it; j++) {
 67:     lhh[j] = - lhh[j];
 68:   }

 70:   /*
 71:          This is really a matrix vector product: 
 72:          [h[0],h[1],...]*[ v[0]; v[1]; ...] subtracted from v[it+1].
 73:   */
 74:   VecMAXPY(it+1,lhh,VEC_VV(it+1),&VEC_VV(0));
 75:   /* note lhh[j] is -<v,vnew> , hence the subtraction */
 76:   for (j=0; j<=it; j++) {
 77:     hh[j]  -= lhh[j];     /* hh += <v,vnew> */
 78:     hes[j] -= lhh[j];     /* hes += <v,vnew> */
 79:   }

 81:   /*
 82:    *  the second step classical Gram-Schmidt is only necessary
 83:    *  when a simple test criteria is not passed
 84:    */
 85:   if (gmres->cgstype == KSP_GMRES_CGS_REFINE_IFNEEDED) {
 86:     hnrm = 0.0;
 87:     for (j=0; j<=it; j++) {
 88:       hnrm  +=  PetscRealPart(lhh[j] * PetscConj(lhh[j]));
 89:     }
 90:     hnrm = sqrt(hnrm);
 91:     VecNorm(VEC_VV(it+1),NORM_2, &wnrm);
 92:     if (wnrm < 1.0286 * hnrm) {
 93:       refine = PETSC_TRUE;
 94:       PetscLogInfo(ksp,"KSPGMRESClassicalGramSchmidtOrthogonalization:Performing iterative refinement wnorm %g hnorm %g\n",wnrm,hnrm);
 95:     }
 96:   }

 98:   if (refine) {
 99:     VecMDot(it+1,VEC_VV(it+1),&(VEC_VV(0)),lhh); /* <v,vnew> */
100:     for (j=0; j<=it; j++) lhh[j] = - lhh[j];
101:     VecMAXPY(it+1,lhh,VEC_VV(it+1),&VEC_VV(0));
102:     /* note lhh[j] is -<v,vnew> , hence the subtraction */
103:     for (j=0; j<=it; j++) {
104:       hh[j]  -= lhh[j];     /* hh += <v,vnew> */
105:       hes[j] -= lhh[j];     /* hes += <v,vnew> */
106:     }
107:   }

109:   if (it >= 501) {PetscFree(lhh);}
110:   PetscLogEventEnd(KSP_GMRESOrthogonalization,ksp,0,0,0);
111:   return(0);
112: }