Actual source code: iguess.c

  1: #define PETSCKSP_DLL

 3:  #include src/ksp/ksp/kspimpl.h
  4: /* 
  5:   This code inplements Paul Fischer's initial guess code for situations where
  6:   a linear system is solved repeatedly 
  7:  */

  9: typedef struct {
 10:     int         curl,     /* Current number of basis vectors */
 11:                 maxl;     /* Maximum number of basis vectors */
 12:     PetscScalar *alpha;   /* */
 13:     Vec         *xtilde,  /* Saved x vectors */
 14:                 *btilde;  /* Saved b vectors */
 15: } KSPIGUESS;

 19: PetscErrorCode PETSCKSP_DLLEXPORT KSPGuessCreate(KSP ksp,int  maxl,void **ITG)
 20: {
 21:   KSPIGUESS *itg;

 24:   *ITG = 0;
 27:   PetscMalloc(sizeof(KSPIGUESS),&itg);
 28:   itg->curl = 0;
 29:   itg->maxl = maxl;
 30:   PetscMalloc(maxl * sizeof(PetscScalar),&itg->alpha);
 31:   PetscLogObjectMemory(ksp,sizeof(KSPIGUESS) + maxl*sizeof(PetscScalar));
 32:   KSPGetVecs(ksp,maxl,&itg->xtilde);
 33:   PetscLogObjectParents(ksp,maxl,itg->xtilde);
 34:   KSPGetVecs(ksp,maxl,&itg->btilde);
 35:   PetscLogObjectParents(ksp,maxl,itg->btilde);
 36:   *ITG = (void*)itg;
 37:   return(0);
 38: }

 42: PetscErrorCode PETSCKSP_DLLEXPORT KSPGuessDestroy(KSP ksp,KSPIGUESS *itg)
 43: {

 48:   PetscFree(itg->alpha);
 49:   VecDestroyVecs(itg->btilde,itg->maxl);
 50:   VecDestroyVecs(itg->xtilde,itg->maxl);
 51:   PetscFree(itg);
 52:   return(0);
 53: }

 57: PetscErrorCode PETSCKSP_DLLEXPORT KSPGuessFormB(KSP ksp,KSPIGUESS *itg,Vec b)
 58: {
 60:   int         i;
 61:   PetscScalar tmp;

 67:   for (i=1; i<=itg->curl; i++) {
 68:     VecDot(itg->btilde[i-1],b,&(itg->alpha[i-1]));
 69:     tmp = -itg->alpha[i-1];
 70:     VecAXPY(b,tmp,itg->btilde[i-1]);
 71:   }
 72:   return(0);
 73: }

 77: PetscErrorCode PETSCKSP_DLLEXPORT KSPGuessFormX(KSP ksp,KSPIGUESS *itg,Vec x)
 78: {
 80:   int i;

 86:   VecCopy(x,itg->xtilde[itg->curl]);
 87:   for (i=1; i<=itg->curl; i++) {
 88:     VecAXPY(x,itg->alpha[i-1],itg->xtilde[i-1]);
 89:   }
 90:   return(0);
 91: }

 95: PetscErrorCode PETSCKSP_DLLEXPORT KSPGuessUpdate(KSP ksp,Vec x,KSPIGUESS *itg)
 96: {
 97:   PetscReal    normax,norm;
 98:   PetscScalar  tmp;
 99:   MatStructure pflag;
101:   int          curl = itg->curl,i;
102:   Mat          Amat,Pmat;

108:   PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);
109:   if (curl == itg->maxl) {
110:     KSP_MatMult(ksp,Amat,x,itg->btilde[0]);
111:     VecNorm(itg->btilde[0],NORM_2,&normax);
112:     tmp = 1.0/normax; VecScale(itg->btilde[0],tmp);
113:     /* VCOPY(ksp->vc,x,itg->xtilde[0]); */
114:     VecScale(itg->xtilde[0],tmp);
115:   } else {
116:     KSP_MatMult(ksp,Amat,itg->xtilde[curl],itg->btilde[curl]);
117:     for (i=1; i<=curl; i++) {
118:       VecDot(itg->btilde[curl],itg->btilde[i-1],itg->alpha+i-1);
119:     }
120:     for (i=1; i<=curl; i++) {
121:       tmp  = -itg->alpha[i-1];
122:       VecAXPY(itg->btilde[curl],tmp,itg->btilde[i-1]);
123:       VecAXPY(itg->xtilde[curl],itg->alpha[i-1],itg->xtilde[i-1]);
124:     }
125:     VecNorm(itg->btilde[curl],NORM_2,&norm);
126:     tmp = 1.0/norm; VecScale(itg->btilde[curl],tmp);
127:     VecNorm(itg->xtilde[curl],NORM_2,&norm);
128:     VecScale(itg->xtilde[curl],tmp);
129:     itg->curl++;
130:   }
131:   return(0);
132: }