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: }