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: PetscInt size_userV, /* size of userV */
122: k; /* desired initial subspace size */
123: void *old_initV_data; /* old initV data */
124: } dvdInitV_User;
128: PetscErrorCode dvd_initV_user(dvdDashboard *d, dvdBlackboard *b,
129: PetscInt size_userV, PetscInt k)
130: {
131: PetscErrorCode ierr;
132: dvdInitV_User *data;
136: /* Setting configuration constrains */
137: b->max_size_V = PetscMax(b->max_size_V, k);
139: /* Setup the step */
140: if (b->state >= DVD_STATE_CONF) {
141: PetscMalloc(sizeof(dvdInitV_User), &data);
142: data->k = k;
143: data->size_userV = size_userV;
144: data->old_initV_data = d->initV_data;
145: d->initV_data = data;
146: d->initV = dvd_initV_user_0;
147: DVD_FL_ADD(d->destroyList, dvd_initV_user_d);
148: }
150: return(0);
151: }
155: PetscErrorCode dvd_initV_user_0(dvdDashboard *d)
156: {
157: PetscErrorCode ierr;
158: dvdInitV_User *data = (dvdInitV_User*)d->initV_data;
159: PetscInt i;
163: /* The user vectors are already in V */
164: i = PetscMin(data->size_userV,d->max_size_V);
166: /* Generate a set of random initial vectors and orthonormalize them */
167: for (; i<PetscMin(data->k,d->max_size_V); i++) {
168: SlepcVecSetRandom(d->V[i], d->eps->rand);
169: }
170: d->size_V = i;
171: d->V_imm_s = 0; d->V_imm_e = 0;
172: d->V_tra_s = 0; d->V_tra_e = 0;
173: d->V_new_s = 0; d->V_new_e = i;
174:
175: return(0);
176: }
180: PetscErrorCode dvd_initV_user_d(dvdDashboard *d)
181: {
182: PetscErrorCode ierr;
183: dvdInitV_User *data = (dvdInitV_User*)d->initV_data;
187: /* Restore changes in dvdDashboard */
188: d->initV_data = data->old_initV_data;
190: /* Free local data */
191: PetscFree(data);
193: return(0);
194: }
197: /*
198: Start with a krylov subspace with the matrix A
199: */
201: typedef struct {
202: PetscInt k; /* number of steps of arnoldi */
203: void *old_initV_data; /* old initV data */
204: } dvdInitV_Krylov;
208: PetscErrorCode dvd_initV_krylov(dvdDashboard *d, dvdBlackboard *b, PetscInt k)
209: {
210: PetscErrorCode ierr;
211: dvdInitV_Krylov *data;
215: /* Setting configuration constrains */
216: b->max_size_auxV = PetscMax(b->max_size_auxV, 2);
218: /* Setup the step */
219: if (b->state >= DVD_STATE_CONF) {
220: PetscMalloc(sizeof(dvdInitV_Krylov), &data);
221: data->k = k;
222: data->old_initV_data = d->initV_data;
223: d->initV_data = data;
224: d->initV = dvd_initV_krylov_0;
225: DVD_FL_ADD(d->destroyList, dvd_initV_krylov_d);
226: }
228: return(0);
229: }
234: PetscErrorCode dvd_initV_krylov_0(dvdDashboard *d)
235: {
236: PetscErrorCode ierr;
237: dvdInitV_Krylov *data = (dvdInitV_Krylov*)d->initV_data;
238: PetscReal norm;
239: PetscInt i;
240: Vec *cX = d->BcX? d->BcX : ( (d->cY && !d->W)? d->cY : d->cX );
244: /* Generate a random vector for starting the arnoldi method */
245: SlepcVecSetRandom(d->V[0], d->eps->rand);
246: IPNorm(d->ipV, d->V[0], &norm);
247: VecScale(d->V[0], 1.0/norm);
249: /* Perform k steps of Arnoldi with the operator K^{-1}*(t[1]*A-t[2]*B) */
250: for (i=1; i<PetscMin(data->k,d->max_size_V); i++) {
251: /* aux <- theta[1]A*in - theta[0]*B*in */
252: if (d->B) {
253: MatMult(d->A, d->V[i-1], d->V[i]);
254: MatMult(d->B, d->V[i-1], d->auxV[0]);
255: VecAXPBY(d->V[i], -d->target[0], d->target[1], d->auxV[0]);
256:
257: } else {
258: MatMult(d->A, d->V[i-1], d->V[i]);
259: VecAXPBY(d->V[i], -d->target[0], d->target[1], d->V[i-1]);
260:
261: }
262: dvd_orthV(d->ipV, d->eps->DS, d->eps->nds, cX, d->size_cX, d->V, i,
263: i+1, d->auxS, d->auxV[0], d->eps->rand);
264: }
266: d->size_V = i;
267: d->V_imm_s = 0; d->V_imm_e = 0;
268: d->V_tra_s = 0; d->V_tra_e = 0;
269: d->V_new_s = 0; d->V_new_e = i;
271: return(0);
272: }
276: PetscErrorCode dvd_initV_krylov_d(dvdDashboard *d)
277: {
278: PetscErrorCode ierr;
279: dvdInitV_Krylov *data = (dvdInitV_Krylov*)d->initV_data;
283: /* Restore changes in dvdDashboard */
284: d->initV_data = data->old_initV_data;
286: /* Free local data */
287: PetscFree(data);
289: return(0);
290: }