Actual source code: dvd_initv.c

slepc-3.5.2 2014-10-10
Report Typos and Errors
  1: /*
  2:   SLEPc eigensolver: "davidson"

  4:   Step: init subspace V

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

 10:    This file is part of SLEPc.

 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: static PetscErrorCode dvd_initV_classic_0(dvdDashboard *d);
 29: static PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d);
 30: static 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,PetscInt user, PetscBool krylov)
 41: {
 42:   PetscErrorCode  ierr;
 43:   dvdInitV        *data;

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

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

 69: static PetscErrorCode dvd_initV_classic_0(dvdDashboard *d)
 70: {
 71:   PetscErrorCode  ierr;
 72:   dvdInitV        *data = (dvdInitV*)d->initV_data;
 73:   PetscInt        i, user = PetscMin(data->user, d->eps->ncv),
 74:                   k = PetscMin(data->k, d->eps->ncv);

 77:   /* Generate a set of random initial vectors and orthonormalize them */
 78:   for (i=user; i<k; i++) {
 79:     BVSetRandomColumn(d->eps->V,i,d->eps->rand);
 80:   }
 81:   d->V_tra_s = 0; d->V_tra_e = 0;
 82:   d->V_new_s = 0; d->V_new_e = i;

 84:   /* After that the user vectors will be destroyed */
 85:   data->user = 0;
 86:   return(0);
 87: }

 91: static PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d)
 92: {
 94:   dvdInitV       *data = (dvdInitV*)d->initV_data;
 95:   PetscInt       i, user = PetscMin(data->user, d->eps->ncv),
 96:                  k = PetscMin(data->k, d->eps->ncv);
 97:   Vec            av,v1,v2;

100:   /* If needed, generate a random vector for starting the arnoldi method */
101:   if (user == 0) {
102:     BVSetRandomColumn(d->eps->V,0,d->eps->rand);
103:     user = 1;
104:   }

106:   /* Perform k steps of Arnoldi with the operator K^{-1}*(t[1]*A-t[2]*B) */
107:   dvd_orthV(d->eps->V,0,user,d->eps->rand);
108:   for (i=user; i<k; i++) {
109:     /* aux <- theta[1]A*in - theta[0]*B*in */
110:     BVGetColumn(d->eps->V,i,&v1);
111:     BVGetColumn(d->eps->V,i-user,&v2);
112:     BVGetColumn(d->auxBV,0,&av);
113:     if (d->B) {
114:       MatMult(d->A,v2,v1);
115:       MatMult(d->B,v2,av);
116:       VecAXPBY(av,d->target[1],-d->target[0],v1);
117:     } else {
118:       MatMult(d->A,v2,av);
119:       VecAXPBY(av,-d->target[0],d->target[1],v2);
120:     }
121:     d->improvex_precond(d,0,av,v1);
122:     BVRestoreColumn(d->eps->V,i,&v1);
123:     BVRestoreColumn(d->eps->V,i-user,&v2);
124:     BVRestoreColumn(d->auxBV,0,&av);
125:     dvd_orthV(d->eps->V,i,i+1,d->eps->rand);
126:   }

128:   d->V_tra_s = 0; d->V_tra_e = 0;
129:   d->V_new_s = 0; d->V_new_e = i;

131:   /* After that the user vectors will be destroyed */
132:   data->user = 0;
133:   return(0);
134: }

138: static PetscErrorCode dvd_initV_d(dvdDashboard *d)
139: {
140:   PetscErrorCode  ierr;
141:   dvdInitV        *data = (dvdInitV*)d->initV_data;

144:   /* Restore changes in dvdDashboard */
145:   d->initV_data = data->old_initV_data;

147:   /* Free local data */
148:   PetscFree(data);
149:   return(0);
150: }