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: }