Actual source code: dvd_initv.c

  1: /*
  2:   SLEPc eigensolver: "davidson"

  4:   Step: init subspace V

  6:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  7:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  8:    Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain

 10:    This file is part of SLEPc.
 11:       
 12:    SLEPc is free software: you can redistribute it and/or modify it under  the
 13:    terms of version 3 of the GNU Lesser General Public License as published by
 14:    the Free Software Foundation.

 16:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY 
 17:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS 
 18:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for 
 19:    more details.

 21:    You  should have received a copy of the GNU Lesser General  Public  License
 22:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
 23:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 24: */

 26:  #include davidson.h

 28: PetscErrorCode dvd_initV_classic_0(dvdDashboard *d);
 29: PetscErrorCode dvd_initV_classic_d(dvdDashboard *d);

 31: PetscErrorCode dvd_initV_user_0(dvdDashboard *d);
 32: PetscErrorCode dvd_initV_user_d(dvdDashboard *d);

 34: PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d);
 35: PetscErrorCode dvd_initV_krylov_d(dvdDashboard *d);

 37: /*
 38:   Fill V with a random subspace
 39: */

 41: typedef struct {
 42:   PetscInt k;           /* number of vectors initialized */
 43:   void *old_initV_data; /* old initV data */
 44: } dvdInitV_Classic;

 48: PetscErrorCode dvd_initV_classic(dvdDashboard *d, dvdBlackboard *b, PetscInt k)
 49: {
 50:   PetscErrorCode  ierr;
 51:   dvdInitV_Classic
 52:                   *data;


 56:   /* Setting configuration constrains */
 57:   b->max_size_V = PetscMax(b->max_size_V, k);

 59:   /* Setup the step */
 60:   if (b->state >= DVD_STATE_CONF) {
 61:     PetscMalloc(sizeof(dvdInitV_Classic), &data);
 62:     data->k = k;
 63:     data->old_initV_data = d->initV_data;
 64:     d->initV_data = data;
 65:     d->initV = dvd_initV_classic_0;
 66:     DVD_FL_ADD(d->destroyList, dvd_initV_classic_d);
 67:   }

 69:   return(0);
 70: }


 75: PetscErrorCode dvd_initV_classic_0(dvdDashboard *d)
 76: {
 77:   PetscErrorCode  ierr;
 78:   dvdInitV_Classic
 79:                   *data = (dvdInitV_Classic*)d->initV_data;
 80:   PetscInt        i;


 84:   /* Generate a set of random initial vectors and orthonormalize them */
 85:   for (i=0; i<PetscMin(data->k,d->max_size_V); i++) {
 86:     SlepcVecSetRandom(d->V[i], d->eps->rand);
 87:   }
 88:   d->size_V = i;
 89:   d->V_imm_s = 0; d->V_imm_e = 0;
 90:   d->V_tra_s = 0; d->V_tra_e = 0;
 91:   d->V_new_s = 0; d->V_new_e = i;
 92: 
 93:   return(0);
 94: }


 99: PetscErrorCode dvd_initV_classic_d(dvdDashboard *d)
100: {
101:   PetscErrorCode  ierr;
102:   dvdInitV_Classic
103:                   *data = (dvdInitV_Classic*)d->initV_data;


107:   /* Restore changes in dvdDashboard */
108:   d->initV_data = data->old_initV_data;

110:   /* Free local data */
111:   PetscFree(data);

113:   return(0);
114: }

116: /*
117:   Fill V with user vectors
118: */

120: typedef struct {
121:   Vec *userV;           /* custom initial search subspace */
122:   PetscInt size_userV,  /* size of userV */
123:     k;                  /* desired initial subspace size */
124:   void *old_initV_data; /* old initV data */
125: } dvdInitV_User;

129: PetscErrorCode dvd_initV_user(dvdDashboard *d, dvdBlackboard *b, Vec *userV,
130:                         PetscInt size_userV, PetscInt k)
131: {
132:   PetscErrorCode  ierr;
133:   dvdInitV_User   *data;


137:   /* Setting configuration constrains */
138:   b->max_size_V = PetscMax(b->max_size_V, k);

140:   /* Setup the step */
141:   if (b->state >= DVD_STATE_CONF) {
142:     PetscMalloc(sizeof(dvdInitV_User), &data);
143:     data->k = k;
144:     data->size_userV = size_userV;
145:     data->userV = userV;
146:     data->old_initV_data = d->initV_data;
147:     d->initV_data = data;
148:     d->initV = dvd_initV_user_0;
149:     DVD_FL_ADD(d->destroyList, dvd_initV_user_d);
150:   }

152:   return(0);
153: }

157: PetscErrorCode dvd_initV_user_0(dvdDashboard *d)
158: {
159:   PetscErrorCode  ierr;
160:   dvdInitV_User   *data = (dvdInitV_User*)d->initV_data;
161:   PetscInt        i;


165:   /* Generate a set of random initial vectors and orthonormalize them */
166:   for (i=0; i<PetscMin(data->size_userV,d->max_size_V); i++) {
167:     VecCopy(data->userV[i], d->V[i]);
168:   }
169:   for (; i<PetscMin(data->k,d->max_size_V); i++) {
170:     SlepcVecSetRandom(d->V[i], d->eps->rand);
171:   }
172:   d->size_V = i;
173:   d->V_imm_s = 0; d->V_imm_e = 0;
174:   d->V_tra_s = 0; d->V_tra_e = 0;
175:   d->V_new_s = 0; d->V_new_e = i;
176: 
177:   return(0);
178: }

182: PetscErrorCode dvd_initV_user_d(dvdDashboard *d)
183: {
184:   PetscErrorCode  ierr;
185:   dvdInitV_User   *data = (dvdInitV_User*)d->initV_data;


189:   /* Restore changes in dvdDashboard */
190:   d->initV_data = data->old_initV_data;

192:   /* Free local data */
193:   PetscFree(data);

195:   return(0);
196: }


199: /*
200:   Start with a krylov subspace with the matrix A
201: */

203: typedef struct {
204:   PetscInt k;           /* number of steps of arnoldi */
205:   void *old_initV_data; /* old initV data */
206: } dvdInitV_Krylov;

210: PetscErrorCode dvd_initV_krylov(dvdDashboard *d, dvdBlackboard *b, PetscInt k)
211: {
212:   PetscErrorCode  ierr;
213:   dvdInitV_Krylov *data;


217:   /* Setting configuration constrains */
218:   b->max_size_auxV = PetscMax(b->max_size_auxV, 2);

220:   /* Setup the step */
221:   if (b->state >= DVD_STATE_CONF) {
222:     PetscMalloc(sizeof(dvdInitV_Krylov), &data);
223:     data->k = k;
224:     data->old_initV_data = d->initV_data;
225:     d->initV_data = data;
226:     d->initV = dvd_initV_krylov_0;
227:     DVD_FL_ADD(d->destroyList, dvd_initV_krylov_d);
228:   }

230:   return(0);
231: }


236: PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d)
237: {
238:   PetscErrorCode  ierr;
239:   dvdInitV_Krylov *data = (dvdInitV_Krylov*)d->initV_data;
240:   PetscReal       norm;
241:   PetscInt        i;
242:   Vec             *cX = d->BcX? d->BcX : ( (d->cY && !d->W)? d->cY : d->cX );


246:   /* Generate a random vector for starting the arnoldi method */
247:   SlepcVecSetRandom(d->V[0], d->eps->rand);
248:   IPNorm(d->ipV, d->V[0], &norm);
249:   VecScale(d->V[0], 1.0/norm);

251:   /* Perform k steps of Arnoldi with the operator K^{-1}*(t[1]*A-t[2]*B) */
252:   for (i=1; i<PetscMin(data->k,d->max_size_V); i++) {
253:    /* aux <- theta[1]A*in - theta[0]*B*in */
254:     if (d->B) {
255:       MatMult(d->A, d->V[i-1], d->V[i]);
256:       MatMult(d->B, d->V[i-1], d->auxV[0]);
257:       VecAXPBY(d->V[i], -d->target[0], d->target[1], d->auxV[0]);
258: 
259:     } else {
260:       MatMult(d->A, d->V[i-1], d->V[i]);
261:       VecAXPBY(d->V[i], -d->target[0], d->target[1], d->V[i-1]);
262: 
263:     }
264:     dvd_orthV(d->ipV, d->eps->DS, d->eps->nds, cX, d->size_cX, d->V, i,
265:                      i+1, d->auxS, d->auxV[0], d->eps->rand);
266:   }

268:   d->size_V = i;
269:   d->V_imm_s = 0; d->V_imm_e = 0;
270:   d->V_tra_s = 0; d->V_tra_e = 0;
271:   d->V_new_s = 0; d->V_new_e = i;

273:   return(0);
274: }

278: PetscErrorCode dvd_initV_krylov_d(dvdDashboard *d)
279: {
280:   PetscErrorCode  ierr;
281:   dvdInitV_Krylov *data = (dvdInitV_Krylov*)d->initV_data;


285:   /* Restore changes in dvdDashboard */
286:   d->initV_data = data->old_initV_data;

288:   /* Free local data */
289:   PetscFree(data);

291:   return(0);
292: }