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-2010, Universidad 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_classic_d(dvdDashboard *d);
31: PetscErrorCode dvd_initV_user_0(dvdDashboard *d);
32: PetscErrorCode dvd_initV_user_d(dvdDashboard *d);
34: PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d);
35: PetscErrorCode dvd_initV_krylov_d(dvdDashboard *d);
37: /*
38: Fill V with a random subspace
39: */
41: typedef struct {
42: PetscInt k; /* number of vectors initialized */
43: void *old_initV_data; /* old initV data */
44: } dvdInitV_Classic;
48: PetscErrorCode dvd_initV_classic(dvdDashboard *d, dvdBlackboard *b, PetscInt k)
49: {
50: PetscErrorCode ierr;
51: dvdInitV_Classic
52: *data;
56: /* Setting configuration constrains */
57: b->max_size_V = PetscMax(b->max_size_V, k);
59: /* Setup the step */
60: if (b->state >= DVD_STATE_CONF) {
61: PetscMalloc(sizeof(dvdInitV_Classic), &data);
62: data->k = k;
63: data->old_initV_data = d->initV_data;
64: d->initV_data = data;
65: d->initV = dvd_initV_classic_0;
66: DVD_FL_ADD(d->destroyList, dvd_initV_classic_d);
67: }
69: return(0);
70: }
75: PetscErrorCode dvd_initV_classic_0(dvdDashboard *d)
76: {
77: PetscErrorCode ierr;
78: dvdInitV_Classic
79: *data = (dvdInitV_Classic*)d->initV_data;
80: PetscInt i;
84: /* Generate a set of random initial vectors and orthonormalize them */
85: for (i=0; i<PetscMin(data->k,d->max_size_V); i++) {
86: SlepcVecSetRandom(d->V[i], d->eps->rand);
87: }
88: d->size_V = i;
89: d->V_imm_s = 0; d->V_imm_e = 0;
90: d->V_tra_s = 0; d->V_tra_e = 0;
91: d->V_new_s = 0; d->V_new_e = i;
92:
93: return(0);
94: }
99: PetscErrorCode dvd_initV_classic_d(dvdDashboard *d)
100: {
101: PetscErrorCode ierr;
102: dvdInitV_Classic
103: *data = (dvdInitV_Classic*)d->initV_data;
107: /* Restore changes in dvdDashboard */
108: d->initV_data = data->old_initV_data;
110: /* Free local data */
111: PetscFree(data);
113: return(0);
114: }
116: /*
117: Fill V with user vectors
118: */
120: typedef struct {
121: Vec *userV; /* custom initial search subspace */
122: PetscInt size_userV, /* size of userV */
123: k; /* desired initial subspace size */
124: void *old_initV_data; /* old initV data */
125: } dvdInitV_User;
129: PetscErrorCode dvd_initV_user(dvdDashboard *d, dvdBlackboard *b, Vec *userV,
130: PetscInt size_userV, PetscInt k)
131: {
132: PetscErrorCode ierr;
133: dvdInitV_User *data;
137: /* Setting configuration constrains */
138: b->max_size_V = PetscMax(b->max_size_V, k);
140: /* Setup the step */
141: if (b->state >= DVD_STATE_CONF) {
142: PetscMalloc(sizeof(dvdInitV_User), &data);
143: data->k = k;
144: data->size_userV = size_userV;
145: data->userV = userV;
146: data->old_initV_data = d->initV_data;
147: d->initV_data = data;
148: d->initV = dvd_initV_user_0;
149: DVD_FL_ADD(d->destroyList, dvd_initV_user_d);
150: }
152: return(0);
153: }
157: PetscErrorCode dvd_initV_user_0(dvdDashboard *d)
158: {
159: PetscErrorCode ierr;
160: dvdInitV_User *data = (dvdInitV_User*)d->initV_data;
161: PetscInt i;
165: /* Generate a set of random initial vectors and orthonormalize them */
166: for (i=0; i<PetscMin(data->size_userV,d->max_size_V); i++) {
167: VecCopy(data->userV[i], d->V[i]);
168: }
169: for (; i<PetscMin(data->k,d->max_size_V); i++) {
170: SlepcVecSetRandom(d->V[i], d->eps->rand);
171: }
172: d->size_V = i;
173: d->V_imm_s = 0; d->V_imm_e = 0;
174: d->V_tra_s = 0; d->V_tra_e = 0;
175: d->V_new_s = 0; d->V_new_e = i;
176:
177: return(0);
178: }
182: PetscErrorCode dvd_initV_user_d(dvdDashboard *d)
183: {
184: PetscErrorCode ierr;
185: dvdInitV_User *data = (dvdInitV_User*)d->initV_data;
189: /* Restore changes in dvdDashboard */
190: d->initV_data = data->old_initV_data;
192: /* Free local data */
193: PetscFree(data);
195: return(0);
196: }
199: /*
200: Start with a krylov subspace with the matrix A
201: */
203: typedef struct {
204: PetscInt k; /* number of steps of arnoldi */
205: void *old_initV_data; /* old initV data */
206: } dvdInitV_Krylov;
210: PetscErrorCode dvd_initV_krylov(dvdDashboard *d, dvdBlackboard *b, PetscInt k)
211: {
212: PetscErrorCode ierr;
213: dvdInitV_Krylov *data;
217: /* Setting configuration constrains */
218: b->max_size_auxV = PetscMax(b->max_size_auxV, 2);
220: /* Setup the step */
221: if (b->state >= DVD_STATE_CONF) {
222: PetscMalloc(sizeof(dvdInitV_Krylov), &data);
223: data->k = k;
224: data->old_initV_data = d->initV_data;
225: d->initV_data = data;
226: d->initV = dvd_initV_krylov_0;
227: DVD_FL_ADD(d->destroyList, dvd_initV_krylov_d);
228: }
230: return(0);
231: }
236: PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d)
237: {
238: PetscErrorCode ierr;
239: dvdInitV_Krylov *data = (dvdInitV_Krylov*)d->initV_data;
240: PetscReal norm;
241: PetscInt i;
242: Vec *cX = d->BcX? d->BcX : ( (d->cY && !d->W)? d->cY : d->cX );
246: /* Generate a random vector for starting the arnoldi method */
247: SlepcVecSetRandom(d->V[0], d->eps->rand);
248: IPNorm(d->ipV, d->V[0], &norm);
249: VecScale(d->V[0], 1.0/norm);
251: /* Perform k steps of Arnoldi with the operator K^{-1}*(t[1]*A-t[2]*B) */
252: for (i=1; i<PetscMin(data->k,d->max_size_V); i++) {
253: /* aux <- theta[1]A*in - theta[0]*B*in */
254: if (d->B) {
255: MatMult(d->A, d->V[i-1], d->V[i]);
256: MatMult(d->B, d->V[i-1], d->auxV[0]);
257: VecAXPBY(d->V[i], -d->target[0], d->target[1], d->auxV[0]);
258:
259: } else {
260: MatMult(d->A, d->V[i-1], d->V[i]);
261: VecAXPBY(d->V[i], -d->target[0], d->target[1], d->V[i-1]);
262:
263: }
264: dvd_orthV(d->ipV, d->eps->DS, d->eps->nds, cX, d->size_cX, d->V, i,
265: i+1, d->auxS, d->auxV[0], d->eps->rand);
266: }
268: d->size_V = i;
269: d->V_imm_s = 0; d->V_imm_e = 0;
270: d->V_tra_s = 0; d->V_tra_e = 0;
271: d->V_new_s = 0; d->V_new_e = i;
273: return(0);
274: }
278: PetscErrorCode dvd_initV_krylov_d(dvdDashboard *d)
279: {
280: PetscErrorCode ierr;
281: dvdInitV_Krylov *data = (dvdInitV_Krylov*)d->initV_data;
285: /* Restore changes in dvdDashboard */
286: d->initV_data = data->old_initV_data;
288: /* Free local data */
289: PetscFree(data);
291: return(0);
292: }