Actual source code: dvd_initv.c
slepc-3.5.2 2014-10-10
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: }