Date: 2013-09-02T10:04:05+00:00

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-2013, 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: 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,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);
     48:   if (krylov)
     49:     b->max_size_auxV = PetscMax(b->max_size_auxV, 1);

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

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

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

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

     93: PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d)
     94: {
     95:   PetscErrorCode  ierr;
     96:   dvdInitV        *data = (dvdInitV*)d->initV_data;
     97:   PetscInt        i, user = PetscMin(data->user, d->max_size_V),
     98:                   k = PetscMin(data->k, d->max_size_V);
     99:   Vec             *cX = d->BcX? d->BcX : ((d->cY && !d->W)? d->cY : d->cX);

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

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

    126:   d->V_tra_s = 0; d->V_tra_e = 0;
    127:   d->V_new_s = 0; d->V_new_e = i;

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

    136: PetscErrorCode dvd_initV_d(dvdDashboard *d)
    137: {
    138:   PetscErrorCode  ierr;
    139:   dvdInitV        *data = (dvdInitV*)d->initV_data;

    142:   /* Restore changes in dvdDashboard */
    143:   d->initV_data = data->old_initV_data;

    145:   /* Free local data */
    146:   PetscFree(data);
    147:   return(0);
    148: }