Actual source code: iguess.c
1: /*$Id: iguess.c,v 1.38 2001/08/07 03:03:45 balay Exp $*/
3: #include src/sles/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: int KSPGuessCreate(KSP ksp,int maxl,void **ITG)
20: {
21: KSPIGUESS *itg;
22: int ierr;
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: VecDuplicateVecs(ksp->vec_rhs,maxl,&itg->xtilde);
33: PetscLogObjectParents(ksp,maxl,itg->xtilde);
34: VecDuplicateVecs(ksp->vec_rhs,maxl,&itg->btilde);
35: PetscLogObjectParents(ksp,maxl,itg->btilde);
36: *ITG = (void *)itg;
37: return(0);
38: }
42: int 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: int KSPGuessFormB(KSP ksp,KSPIGUESS *itg,Vec b)
58: {
59: int i,ierr;
60: PetscScalar tmp;
64: for (i=1; i<=itg->curl; i++) {
65: VecDot(itg->btilde[i-1],b,&(itg->alpha[i-1]));
66: tmp = -itg->alpha[i-1];
67: VecAXPY(&tmp,itg->btilde[i-1],b);
68: }
69: return(0);
70: }
74: int KSPGuessFormX(KSP ksp,KSPIGUESS *itg,Vec x)
75: {
76: int i,ierr;
80: VecCopy(x,itg->xtilde[itg->curl]);
81: for (i=1; i<=itg->curl; i++) {
82: VecAXPY(&itg->alpha[i-1],itg->xtilde[i-1],x);
83: }
84: return(0);
85: }
89: int KSPGuessUpdate(KSP ksp,Vec x,KSPIGUESS *itg)
90: {
91: PetscReal normax,norm;
92: PetscScalar tmp;
93: MatStructure pflag;
94: int curl = itg->curl,i,ierr;
95: Mat Amat,Pmat;
99: PCGetOperators(ksp->B,&Amat,&Pmat,&pflag);
100: if (curl == itg->maxl) {
101: KSP_MatMult(ksp,Amat,x,itg->btilde[0]);
102: VecNorm(itg->btilde[0],NORM_2,&normax);
103: tmp = 1.0/normax; VecScale(&tmp,itg->btilde[0]);
104: /* VCOPY(ksp->vc,x,itg->xtilde[0]); */
105: VecScale(&tmp,itg->xtilde[0]);
106: } else {
107: KSP_MatMult(ksp,Amat,itg->xtilde[curl],itg->btilde[curl]);
108: for (i=1; i<=curl; i++) {
109: VecDot(itg->btilde[curl],itg->btilde[i-1],itg->alpha+i-1);
110: }
111: for (i=1; i<=curl; i++) {
112: tmp = -itg->alpha[i-1];
113: VecAXPY(&tmp,itg->btilde[i-1],itg->btilde[curl]);
114: VecAXPY(&itg->alpha[i-1],itg->xtilde[i-1],itg->xtilde[curl]);
115: }
116: VecNorm(itg->btilde[curl],NORM_2,&norm);
117: tmp = 1.0/norm; VecScale(&tmp,itg->btilde[curl]);
118: VecNorm(itg->xtilde[curl],NORM_2,&norm);
119: VecScale(&tmp,itg->xtilde[curl]);
120: itg->curl++;
121: }
122: return(0);
123: }