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:   PetscInt size_userV,  /* size of userV */
122:     k;                  /* desired initial subspace size */
123:   void *old_initV_data; /* old initV data */
124: } dvdInitV_User;

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


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

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

150:   return(0);
151: }

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


163:   /* The user vectors are already in V */
164:   i = PetscMin(data->size_userV,d->max_size_V);

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

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


187:   /* Restore changes in dvdDashboard */
188:   d->initV_data = data->old_initV_data;

190:   /* Free local data */
191:   PetscFree(data);

193:   return(0);
194: }


197: /*
198:   Start with a krylov subspace with the matrix A
199: */

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

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


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

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

228:   return(0);
229: }


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


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

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

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

271:   return(0);
272: }

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


283:   /* Restore changes in dvdDashboard */
284:   d->initV_data = data->old_initV_data;

286:   /* Free local data */
287:   PetscFree(data);

289:   return(0);
290: }