| 1619 |
slepc |
1 |
/*
|
|
|
2 |
SLEPc eigensolver: "davidson"
|
|
|
3 |
|
|
|
4 |
Method: General Davidson Method
|
|
|
5 |
|
|
|
6 |
References:
|
|
|
7 |
- Ernest R. Davidson. Super-matrix methods. Computer Physics Communications,
|
|
|
8 |
53:49–60, May 1989.
|
|
|
9 |
|
|
|
10 |
TODO:
|
|
|
11 |
- If the problem is symmetric, H=V*A*V is symmetric too, we can do some ops:
|
|
|
12 |
*) Use a LAPACK eigensolver that only modify the upper triangular part
|
|
|
13 |
of H, so we can save H in the lower one, and in a vector for the
|
|
|
14 |
diagonal. That expends only 2*n^2 + n of memory.
|
|
|
15 |
|
|
|
16 |
- In the interface, support static preconditioners of PETSc (PC) and others
|
|
|
17 |
with shift parameter.
|
|
|
18 |
|
| 1624 |
slepc |
19 |
- (DONE) Start with a krylov subspace, the H matrix will be used as the starting
|
| 1619 |
slepc |
20 |
projected problem matrix, and A*V <- V*H + f*e_m^T.
|
|
|
21 |
|
|
|
22 |
- Implements with BLAS3 prods Z <- V*U
|
|
|
23 |
*/
|
|
|
24 |
|
|
|
25 |
|
|
|
26 |
/*
|
|
|
27 |
Dashboard struct: contains the methods that will be employed and the tunning
|
|
|
28 |
options.
|
|
|
29 |
*/
|
|
|
30 |
|
|
|
31 |
#include "petsc.h"
|
|
|
32 |
#include "private/epsimpl.h"
|
|
|
33 |
|
|
|
34 |
|
|
|
35 |
typedef struct _dvdFunctionList {
|
|
|
36 |
void *f;
|
|
|
37 |
void *d;
|
|
|
38 |
struct _dvdFunctionList *next;
|
|
|
39 |
} dvdFunctionList;
|
|
|
40 |
|
|
|
41 |
typedef struct _dvdDashboard {
|
|
|
42 |
/**** Function steps ****/
|
|
|
43 |
/* Initialize V */
|
|
|
44 |
PetscInt (*initV)(struct _dvdDashboard*);
|
|
|
45 |
void *initV_data;
|
|
|
46 |
|
|
|
47 |
/* Find the approximate eigenpairs from V */
|
|
|
48 |
PetscInt (*calcPairs)(struct _dvdDashboard*);
|
|
|
49 |
void *calcPairs_data;
|
|
|
50 |
|
|
|
51 |
/* Test for convergence */
|
|
|
52 |
PetscTruth (*testConv)(struct _dvdDashboard*, PetscScalar eigvr,
|
|
|
53 |
PetscScalar eigvi, PetscScalar res, PetscReal *error);
|
|
|
54 |
void *testConv_data;
|
|
|
55 |
|
|
|
56 |
/* Number of converged eigenpairs */
|
|
|
57 |
PetscInt nconv;
|
|
|
58 |
|
|
|
59 |
/* Improve the selected eigenpairs */
|
|
|
60 |
PetscInt (*improveX)(struct _dvdDashboard*);
|
|
|
61 |
void *improveX_data;
|
|
|
62 |
|
|
|
63 |
/* Check for restarting */
|
|
|
64 |
PetscTruth (*isRestarting)(struct _dvdDashboard*);
|
|
|
65 |
void *isRestarting_data;
|
|
|
66 |
|
|
|
67 |
/* Perform restarting */
|
|
|
68 |
PetscInt (*restartV)(struct _dvdDashboard*);
|
|
|
69 |
void *restartV_data;
|
|
|
70 |
|
|
|
71 |
/* Update V */
|
|
|
72 |
PetscInt (*updateV)(struct _dvdDashboard*);
|
|
|
73 |
void *updateV_data;
|
|
|
74 |
|
|
|
75 |
/**** Problem specification ****/
|
|
|
76 |
Mat A, B; /* Problem matrices */
|
|
|
77 |
PetscInt nev; /* number of eigenpairs */
|
|
|
78 |
EPSWhich which; /* spectrum selection */
|
|
|
79 |
PetscTruth
|
|
|
80 |
withTarget; /* if there is a target */
|
|
|
81 |
PetscScalar
|
|
|
82 |
target; /* target value */
|
|
|
83 |
PetscReal tol; /* tolerance */
|
|
|
84 |
|
|
|
85 |
/**** Subspaces specification ****/
|
|
|
86 |
Vec *V, /* searching subspace */
|
|
|
87 |
*cX, /* converged eigenvectors */
|
|
|
88 |
*X, /* best eigenvectors in V */
|
|
|
89 |
*oldX, /* eigenvectors from the previous iteration */
|
|
|
90 |
*D, /* improved X vectors */
|
|
|
91 |
*W; /* A*V */
|
|
|
92 |
PetscInt size_V, /* size of V */
|
|
|
93 |
size_X, /* size of X */
|
|
|
94 |
size_oldX, /* size of oldX */
|
|
|
95 |
size_D, /* size of D */
|
|
|
96 |
size_cX, /* size of cX */
|
|
|
97 |
size_W, /* size of W */
|
|
|
98 |
max_size_V, /* max size of V */
|
|
|
99 |
max_size_X, /* max size of X */
|
|
|
100 |
max_size_oldX, /* max size of oldX */
|
|
|
101 |
max_size_D, /* max size of D */
|
|
|
102 |
max_size_W, /* max size of W */
|
|
|
103 |
size_uW; /* size of updated W from V */
|
|
|
104 |
|
|
|
105 |
/**** Auxiliary space ****/
|
|
|
106 |
Vec *auxV; /* auxiliary vectors */
|
|
|
107 |
PetscScalar
|
|
|
108 |
*auxS; /* auxiliary scalars */
|
|
|
109 |
PetscInt
|
|
|
110 |
size_auxV, /* max size of auxV */
|
|
|
111 |
size_auxS; /* max size of auxS */
|
|
|
112 |
|
|
|
113 |
/**** Eigenvalues and errors ****/
|
|
|
114 |
PetscScalar
|
|
|
115 |
*ceigr, *ceigi, /* converged eigenvalues */
|
|
|
116 |
*eigr, *eigi; /* current eigenvalues */
|
|
|
117 |
PetscReal
|
|
|
118 |
*errest; /* error eigenpairs */
|
|
|
119 |
|
|
|
120 |
/**** Shared function and variables ****/
|
|
|
121 |
PetscInt (*e_Vchanged)(struct _dvdDashboard*, PetscInt s_imm,
|
|
|
122 |
PetscInt e_imm, PetscInt s_new, PetscInt e_new);
|
|
|
123 |
void *e_Vchanged_data;
|
|
|
124 |
|
|
|
125 |
PetscInt (*calcpairs_residual)(struct _dvdDashboard*, PetscInt s, PetscInt e,
|
|
|
126 |
Vec *R);
|
|
|
127 |
void *calcpairs_residual_data;
|
|
|
128 |
|
|
|
129 |
PetscInt (*e_newIteration)(struct _dvdDashboard*);
|
|
|
130 |
void *e_newIteration_data;
|
|
|
131 |
|
|
|
132 |
dvdFunctionList
|
|
|
133 |
*destroyList; /* destructor list */
|
|
|
134 |
|
|
|
135 |
PetscInt
|
|
|
136 |
n_calcPairs, /* says to calcPairs how many ones */
|
|
|
137 |
n_oldX, /* says to calcParis how many old eigenvalues computes */
|
|
|
138 |
n_convPairs; /* says to updateV how many eigenvectors in X converged */
|
|
|
139 |
|
|
|
140 |
PetscScalar *H; /* Projected problem */
|
|
|
141 |
PetscInt ldH, /* leading dimension of H */
|
|
|
142 |
size_H; /* columns in H */
|
|
|
143 |
|
|
|
144 |
} dvdDashboard;
|
|
|
145 |
|
|
|
146 |
#define DVD_FL_ADD(list, fun) { \
|
|
|
147 |
dvdFunctionList *fl=(list); \
|
|
|
148 |
PetscErrorCode ierr; \
|
|
|
149 |
ierr = PetscMalloc(sizeof(dvdFunctionList), &(list)); CHKERRQ(ierr); \
|
|
|
150 |
(list)->f = (fun); \
|
|
|
151 |
(list)->next = fl; }
|
|
|
152 |
|
|
|
153 |
#define DVD_FL_CALL1(list, t, arg0) { \
|
|
|
154 |
dvdFunctionList *fl; \
|
|
|
155 |
for(fl=(list); fl; fl=fl->next) (*(t)fl->f)((arg0)); }
|
|
|
156 |
|
|
|
157 |
#define DVD_FL_DEL(list) { \
|
|
|
158 |
dvdFunctionList *fl=(list), *oldfl; \
|
|
|
159 |
PetscErrorCode ierr; \
|
|
|
160 |
while(fl) { \
|
|
|
161 |
oldfl = fl; fl = fl->next; ierr = PetscFree(oldfl); CHKERRQ(ierr); }}
|
|
|
162 |
|
|
|
163 |
/*
|
|
|
164 |
The blackboard configuration structure: saves information about the memory
|
|
|
165 |
and other requirements
|
|
|
166 |
*/
|
|
|
167 |
typedef struct {
|
|
|
168 |
PetscInt max_size_V, /* max size of V */
|
|
|
169 |
max_size_X, /* max size of X */
|
|
|
170 |
max_size_oldX, /* max size of oldX */
|
|
|
171 |
max_size_auxV, /* max size of auxiliary vecs */
|
|
|
172 |
max_size_auxS, /* max size of auxiliary scalars */
|
|
|
173 |
own_vecs, /* number of global vecs */
|
|
|
174 |
own_scalars; /* number of local scalars */
|
|
|
175 |
Vec *free_vecs; /* free global vectors */
|
|
|
176 |
PetscScalar
|
|
|
177 |
*free_scalars; /* free scalars */
|
|
|
178 |
PetscInt state; /* method states:
|
|
|
179 |
0: preconfiguring
|
|
|
180 |
1: configuring
|
|
|
181 |
2: running
|
|
|
182 |
*/
|
|
|
183 |
} dvdBlackboard;
|
|
|
184 |
|
|
|
185 |
#define DVD_STATE_PRECONF 0
|
|
|
186 |
#define DVD_STATE_CONF 1
|
|
|
187 |
#define DVD_STATE_RUN 2
|
|
|
188 |
|
|
|
189 |
/* Shared types */
|
|
|
190 |
typedef void* dvdPrecondData;
|
|
|
191 |
typedef PetscErrorCode (*dvdPrecond)(dvdPrecondData, PetscInt i, Vec x, Vec Px);
|
|
|
192 |
typedef PetscInt (*dvdDestructor)(dvdDashboard*);
|
|
|
193 |
typedef PetscInt (*e_Vchanged_type)(dvdDashboard*, PetscInt s_imm,
|
|
|
194 |
PetscInt e_imm, PetscInt s_new, PetscInt e_new);
|
|
|
195 |
typedef PetscTruth (*isRestarting_type)(dvdDashboard*);
|
|
|
196 |
typedef PetscInt (*e_newIteration_type)(dvdDashboard*);
|
|
|
197 |
|
|
|
198 |
/* Routines for initV step */
|
|
|
199 |
PetscInt dvd_initV_classic(dvdDashboard *d, dvdBlackboard *b, PetscInt k);
|
|
|
200 |
PetscInt dvd_initV_krylov(dvdDashboard *d, dvdBlackboard *b, PetscInt k,
|
|
|
201 |
Mat OP, IP ip);
|
|
|
202 |
|
|
|
203 |
/* Routines for calcPairs step */
|
|
|
204 |
PetscInt dvd_calcpairs_rr(dvdDashboard *d, dvdBlackboard *b);
|
|
|
205 |
|
|
|
206 |
/* Routines for improveX step */
|
|
|
207 |
PetscInt dvd_improvex_gdbasic(dvdDashboard *d, dvdBlackboard *b, dvdPrecond P,
|
|
|
208 |
dvdPrecondData Pd);
|
|
|
209 |
|
|
|
210 |
/* Routines for testConv step */
|
|
|
211 |
PetscInt dvd_testconv_basic(dvdDashboard *d, dvdBlackboard *b);
|
|
|
212 |
|
|
|
213 |
/* Routines for management of V */
|
|
|
214 |
PetscInt dvd_managementV_basic(dvdDashboard *d, dvdBlackboard *b,
|
|
|
215 |
PetscInt bs, PetscInt max_size_V,
|
|
|
216 |
PetscInt restart_size_X, PetscInt plusk);
|
|
|
217 |
|
|
|
218 |
/* Some utilities */
|
|
|
219 |
PetscInt dvd_orthV(dvdDashboard *d, dvdBlackboard *b, IP ip);
|
|
|
220 |
PetscErrorCode dvd_static_precond_PC(dvdDashboard *d, PC pc, dvdPrecond *pf,
|
|
|
221 |
dvdPrecondData *pd);
|
|
|
222 |
PetscErrorCode dvd_jacobi_precond(dvdDashboard *d, Vec diagA, dvdPrecond *pf,
|
|
|
223 |
dvdPrecondData *pd);
|
|
|
224 |
PetscInt dvd_isrestarting_whenfinish(dvdDashboard *d, dvdBlackboard *b);
|
|
|
225 |
|
|
|
226 |
/* Methods */
|
|
|
227 |
PetscErrorCode dvd_schm_basic_preconf(dvdDashboard *d, dvdBlackboard *b,
|
|
|
228 |
PetscInt max_size_V, PetscInt min_size_V, PetscInt bs, PetscInt size_initV,
|
|
|
229 |
PetscInt plusk);
|
|
|
230 |
PetscErrorCode dvd_schm_basic_conf(dvdDashboard *d, dvdBlackboard *b,
|
|
|
231 |
PetscInt max_size_V, PetscInt min_size_V, PetscInt bs, PetscInt size_initV,
|
|
|
232 |
PetscInt plusk, PC pc, Vec diagA, IP ip);
|
|
|
233 |
|
|
|
234 |
/* BLAS routines */
|
|
|
235 |
PetscErrorCode SlepcDenseMatProd(PetscScalar *C, PetscInt _ldC, PetscScalar b,
|
|
|
236 |
PetscScalar a,
|
|
|
237 |
const PetscScalar *A, PetscInt _ldA, PetscInt rA, PetscInt cA, PetscTruth At,
|
|
|
238 |
const PetscScalar *B, PetscInt _ldB, PetscInt rB, PetscInt cB, PetscTruth Bt);
|
| 1626 |
slepc |
239 |
PetscErrorCode SlepcUpdateVectorsZ(Vec *Y, Vec *X, PetscInt cX,
|
|
|
240 |
const PetscScalar *M, PetscInt ldM, PetscInt rM, PetscInt cM);
|