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-2011, Universitat 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_krylov_0(dvdDashboard *d);
 30: PetscErrorCode dvd_initV_d(dvdDashboard *d);

 32: typedef struct {
 33:   PetscInt k,           /* desired initial subspace size */
 34:   user;                 /* number of user initial vectors */
 35:   void *old_initV_data; /* old initV data */
 36: } dvdInitV;

 40: PetscErrorCode dvd_initV(dvdDashboard *d, dvdBlackboard *b, PetscInt k,
 41:                          PetscInt user, PetscBool krylov)
 42: {
 43:   PetscErrorCode  ierr;
 44:   dvdInitV        *data;


 48:   /* Setting configuration constrains */
 49:   b->max_size_V = PetscMax(b->max_size_V, k);
 50:   if (krylov)
 51:     b->max_size_auxV = PetscMax(b->max_size_auxV, 1);

 53:   /* Setup the step */
 54:   if (b->state >= DVD_STATE_CONF) {
 55:     PetscMalloc(sizeof(dvdInitV), &data);
 56:     data->k = k;
 57:     data->user = PetscMin(k, user);
 58:     data->old_initV_data = d->initV_data;
 59:     d->initV_data = data;
 60:     if (krylov) {
 61:       d->initV = dvd_initV_krylov_0;
 62:     } else {
 63:       d->initV = dvd_initV_classic_0;
 64:     }
 65:     DVD_FL_ADD(d->destroyList, dvd_initV_d);
 66:   }

 68:   return(0);
 69: }


 74: PetscErrorCode dvd_initV_classic_0(dvdDashboard *d)
 75: {
 76:   PetscErrorCode  ierr;
 77:   dvdInitV        *data = (dvdInitV*)d->initV_data;
 78:   PetscInt        i, user = PetscMin(data->user, d->max_size_V),
 79:                   k = PetscMin(data->k, d->max_size_V);


 83:   /* Generate a set of random initial vectors and orthonormalize them */
 84:   for (i=user; i<k; i++) {
 85:     SlepcVecSetRandom(d->V[i], d->eps->rand);
 86:   }
 87:   d->V_tra_s = 0; d->V_tra_e = 0;
 88:   d->V_new_s = 0; d->V_new_e = i;

 90:   /* After that the user vectors will be destroyed */
 91:   data->user = 0;
 92: 
 93:   return(0);
 94: }

 98: PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d)
 99: {
100:   PetscErrorCode  ierr;
101:   dvdInitV        *data = (dvdInitV*)d->initV_data;
102:   PetscInt        i, user = PetscMin(data->user, d->max_size_V),
103:                   k = PetscMin(data->k, d->max_size_V);
104:   Vec             *cX = d->BcX? d->BcX : ( (d->cY && !d->W)? d->cY : d->cX );


108:   /* If needed, generate a random vector for starting the arnoldi method */
109:   if (user == 0) {
110:     SlepcVecSetRandom(d->V[0], d->eps->rand);
111:     user = 1;
112:   }

114:   /* Perform k steps of Arnoldi with the operator K^{-1}*(t[1]*A-t[2]*B) */
115:   dvd_orthV(d->ipV, d->eps->DS, d->eps->nds, cX, d->size_cX, d->V, 0,
116:                    user, d->auxS, d->eps->rand);
117:   for (i=user; i<k; i++) {
118:     /* aux <- theta[1]A*in - theta[0]*B*in */
119:     if (d->B) {
120:       MatMult(d->A, d->V[i-user], d->V[i]);
121:       MatMult(d->B, d->V[i-user], d->auxV[0]);
122:       VecAXPBY(d->auxV[0], d->target[1], -d->target[0], d->V[i]);
123: 
124:     } else {
125:       MatMult(d->A, d->V[i-user], d->auxV[0]);
126:       VecAXPBY(d->auxV[0], -d->target[0], d->target[1], d->V[i-user]);
127: 
128:     }
129:     d->improvex_precond(d, 0, d->auxV[0], d->V[i]);
130:     dvd_orthV(d->ipV, d->eps->DS, d->eps->nds, cX, d->size_cX, d->V, i,
131:                      i+1, d->auxS, d->eps->rand);
132:   }

134:   d->V_tra_s = 0; d->V_tra_e = 0;
135:   d->V_new_s = 0; d->V_new_e = i;

137:   /* After that the user vectors will be destroyed */
138:   data->user = 0;

140:   return(0);
141: }

145: PetscErrorCode dvd_initV_d(dvdDashboard *d)
146: {
147:   PetscErrorCode  ierr;
148:   dvdInitV        *data = (dvdInitV*)d->initV_data;


152:   /* Restore changes in dvdDashboard */
153:   d->initV_data = data->old_initV_data;

155:   /* Free local data */
156:   PetscFree(data);

158:   return(0);
159: }