| 1619 |
slepc |
1 |
/*
|
|
|
2 |
SLEPc eigensolver: "davidson"
|
|
|
3 |
|
|
|
4 |
Step: calc the best eigenpairs in the subspace V.
|
|
|
5 |
|
|
|
6 |
For that, performs these steps:
|
|
|
7 |
1) Update W <- A * V
|
|
|
8 |
2) Update H <- V' * W
|
|
|
9 |
3) Obtain eigenpairs of H
|
|
|
10 |
4) Select some eigenpairs
|
|
|
11 |
5) Compute the Ritz pairs of the selected ones
|
| 2110 |
jroman |
12 |
|
|
|
13 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
14 |
SLEPc - Scalable Library for Eigenvalue Problem Computations
|
| 2575 |
eromero |
15 |
Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
|
| 2110 |
jroman |
16 |
|
|
|
17 |
This file is part of SLEPc.
|
|
|
18 |
|
|
|
19 |
SLEPc is free software: you can redistribute it and/or modify it under the
|
|
|
20 |
terms of version 3 of the GNU Lesser General Public License as published by
|
|
|
21 |
the Free Software Foundation.
|
|
|
22 |
|
|
|
23 |
SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
24 |
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
25 |
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
|
|
26 |
more details.
|
|
|
27 |
|
|
|
28 |
You should have received a copy of the GNU Lesser General Public License
|
|
|
29 |
along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
|
|
|
30 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| 1619 |
slepc |
31 |
*/
|
|
|
32 |
|
| 1985 |
eromero |
33 |
#include "davidson.h"
|
| 2283 |
jroman |
34 |
#include <slepcblaslapack.h>
|
| 1619 |
slepc |
35 |
|
| 2555 |
eromero |
36 |
PetscErrorCode dvd_calcpairs_proj(dvdDashboard *d);
|
| 2244 |
eromero |
37 |
PetscErrorCode dvd_calcpairs_qz_start(dvdDashboard *d);
|
| 2555 |
eromero |
38 |
PetscErrorCode dvd_calcpairs_projeig_eig(dvdDashboard *d);
|
| 2779 |
eromero |
39 |
PetscErrorCode dvd_calcpairs_projeig_ind(dvdDashboard *d);
|
| 2021 |
eromero |
40 |
PetscErrorCode dvd_calcpairs_projeig_qz_std(dvdDashboard *d);
|
|
|
41 |
PetscErrorCode dvd_calcpairs_projeig_qz_gen(dvdDashboard *d);
|
|
|
42 |
PetscErrorCode dvd_calcpairs_selectPairs_qz(dvdDashboard *d, PetscInt n);
|
| 2555 |
eromero |
43 |
PetscErrorCode dvd_calcpairs_selectPairs_eig(dvdDashboard *d, PetscInt n);
|
| 2021 |
eromero |
44 |
PetscErrorCode dvd_calcpairs_X(dvdDashboard *d, PetscInt r_s, PetscInt r_e,
|
|
|
45 |
Vec *X);
|
|
|
46 |
PetscErrorCode dvd_calcpairs_Y(dvdDashboard *d, PetscInt r_s, PetscInt r_e,
|
|
|
47 |
Vec *Y);
|
|
|
48 |
PetscErrorCode dvd_calcpairs_res_0(dvdDashboard *d, PetscInt r_s, PetscInt r_e,
|
| 2605 |
eromero |
49 |
Vec *R);
|
| 2682 |
jroman |
50 |
PetscErrorCode dvd_calcpairs_eig_res_0(dvdDashboard *d,PetscInt r_s,PetscInt r_e,Vec *R);
|
| 2021 |
eromero |
51 |
PetscErrorCode dvd_calcpairs_proj_res(dvdDashboard *d, PetscInt r_s,
|
|
|
52 |
PetscInt r_e, Vec *R);
|
| 2605 |
eromero |
53 |
PetscErrorCode dvd_calcpairs_updateV0(dvdDashboard *d, DvdReduction *r,
|
|
|
54 |
DvdMult_copy_func **sr);
|
|
|
55 |
PetscErrorCode dvd_calcpairs_updateV1(dvdDashboard *d);
|
|
|
56 |
PetscErrorCode dvd_calcpairs_updateW0(dvdDashboard *d, DvdReduction *r,
|
|
|
57 |
DvdMult_copy_func **sr);
|
|
|
58 |
PetscErrorCode dvd_calcpairs_updateW1(dvdDashboard *d);
|
|
|
59 |
PetscErrorCode dvd_calcpairs_updateAV0(dvdDashboard *d);
|
|
|
60 |
PetscErrorCode dvd_calcpairs_updateAV1(dvdDashboard *d, DvdReduction *r,
|
|
|
61 |
DvdMult_copy_func **sr);
|
|
|
62 |
PetscErrorCode dvd_calcpairs_updateBV0(dvdDashboard *d);
|
|
|
63 |
PetscErrorCode dvd_calcpairs_updateBV1(dvdDashboard *d, DvdReduction *r,
|
|
|
64 |
DvdMult_copy_func **sr);
|
|
|
65 |
PETSC_STATIC_INLINE PetscErrorCode dvd_calcpairs_updateBV0_gen(dvdDashboard *d,Vec *real_BV,PetscInt *size_cX,Vec **BV,PetscInt *size_BV,PetscInt *max_size_BV,PetscBool BV_shift,PetscInt *cX_in_proj,PetscScalar *MTX);
|
| 1619 |
slepc |
66 |
|
| 1735 |
eromero |
67 |
/**** Control routines ********************************************************/
|
| 1750 |
eromero |
68 |
#undef __FUNCT__
|
|
|
69 |
#define __FUNCT__ "dvd_calcpairs_qz"
|
| 2605 |
eromero |
70 |
PetscErrorCode dvd_calcpairs_qz(dvdDashboard *d, dvdBlackboard *b,
|
|
|
71 |
orthoV_type_t orth, IP ipI,
|
|
|
72 |
PetscInt cX_proj, PetscBool harm)
|
| 1750 |
eromero |
73 |
{
|
| 2555 |
eromero |
74 |
PetscErrorCode ierr;
|
| 2654 |
jroman |
75 |
PetscInt i,max_cS;
|
| 2779 |
eromero |
76 |
PetscBool std_probl,her_probl,ind_probl;
|
| 1750 |
eromero |
77 |
|
|
|
78 |
PetscFunctionBegin;
|
|
|
79 |
|
| 2012 |
eromero |
80 |
std_probl = DVD_IS(d->sEP, DVD_EP_STD)?PETSC_TRUE:PETSC_FALSE;
|
| 2555 |
eromero |
81 |
her_probl = DVD_IS(d->sEP, DVD_EP_HERMITIAN)?PETSC_TRUE:PETSC_FALSE;
|
| 2779 |
eromero |
82 |
ind_probl = DVD_IS(d->sEP, DVD_EP_INDEFINITE)?PETSC_TRUE:PETSC_FALSE;
|
| 1750 |
eromero |
83 |
|
|
|
84 |
/* Setting configuration constrains */
|
| 2320 |
jroman |
85 |
#if !defined(PETSC_USE_COMPLEX)
|
| 1966 |
eromero |
86 |
/* if the last converged eigenvalue is complex its conjugate pair is also
|
|
|
87 |
converged */
|
| 2605 |
eromero |
88 |
b->max_nev = PetscMax(b->max_nev, d->nev+(her_probl && !d->B?0:1));
|
| 1966 |
eromero |
89 |
#else
|
|
|
90 |
b->max_nev = PetscMax(b->max_nev, d->nev);
|
|
|
91 |
#endif
|
| 2605 |
eromero |
92 |
b->max_size_proj = PetscMax(b->max_size_proj, b->max_size_V+cX_proj);
|
|
|
93 |
d->size_real_V = b->max_size_V+b->max_nev;
|
|
|
94 |
d->W_shift = d->B?PETSC_TRUE:PETSC_FALSE;
|
|
|
95 |
d->size_real_W = harm?(b->max_size_V+(d->W_shift?b->max_nev:b->max_size_cP)):0;
|
|
|
96 |
d->size_real_AV = b->max_size_V+b->max_size_cP;
|
|
|
97 |
d->size_BDS = 0;
|
| 2779 |
eromero |
98 |
if (d->B && (her_probl || ind_probl) && (orth == DVD_ORTHOV_I || orth == DVD_ORTHOV_BOneMV)) {
|
| 2605 |
eromero |
99 |
d->size_real_BV = b->size_V; d->BV_shift = PETSC_TRUE;
|
|
|
100 |
if (orth == DVD_ORTHOV_BOneMV) d->size_BDS = d->eps->nds;
|
|
|
101 |
} else if (d->B) {
|
|
|
102 |
d->size_real_BV = b->max_size_V + b->max_size_P; d->BV_shift = PETSC_FALSE;
|
|
|
103 |
} else {
|
|
|
104 |
d->size_real_BV = 0; d->BV_shift = PETSC_FALSE;
|
|
|
105 |
}
|
|
|
106 |
b->own_vecs+= d->size_real_V + d->size_real_W + d->size_real_AV +
|
|
|
107 |
d->size_real_BV + d->size_BDS;
|
|
|
108 |
b->own_scalars+= b->max_size_proj*b->max_size_proj*2*(std_probl?1:2) +
|
| 1757 |
eromero |
109 |
/* H, G?, S, T? */
|
| 2605 |
eromero |
110 |
b->max_size_proj*b->max_size_proj*(std_probl?1:2) +
|
| 1757 |
eromero |
111 |
/* pX, pY? */
|
| 2779 |
eromero |
112 |
b->max_nev*b->max_nev*(her_probl?0:(!d->B?1:2)) +
|
| 2605 |
eromero |
113 |
/* cS?, cT? */
|
| 2779 |
eromero |
114 |
FromRealToScalar(d->size_real_V)*(ind_probl?1:0) + /* nBV */
|
|
|
115 |
FromRealToScalar(b->max_size_proj)*(ind_probl?1:0); /* nBpX */
|
| 2605 |
eromero |
116 |
b->max_size_auxV = PetscMax(b->max_size_auxV, b->max_size_X);
|
|
|
117 |
/* updateV0 */
|
| 2654 |
jroman |
118 |
max_cS = PetscMax(b->max_size_X,cX_proj);
|
| 1820 |
eromero |
119 |
b->max_size_auxS = PetscMax(PetscMax(
|
| 2605 |
eromero |
120 |
b->max_size_auxS,
|
| 2654 |
jroman |
121 |
b->max_size_X*b->max_size_proj*2*(std_probl?1:2) + /* updateAV1,BV1 */
|
|
|
122 |
max_cS*b->max_nev*(her_probl?0:(!d->B?1:2)) + /* updateV0,W0 */
|
| 2605 |
eromero |
123 |
/* SlepcReduction: in */
|
|
|
124 |
PetscMax(
|
| 2654 |
jroman |
125 |
b->max_size_X*b->max_size_proj*2*(std_probl?1:2) + /* updateAV1,BV1 */
|
|
|
126 |
max_cS*b->max_nev*(her_probl?0:(!d->B?1:2)), /* updateV0,W0 */
|
| 2605 |
eromero |
127 |
/* SlepcReduction: out */
|
|
|
128 |
PetscMax(
|
|
|
129 |
b->max_size_proj*b->max_size_proj, /* updateAV0,BV0 */
|
|
|
130 |
b->max_size_proj+b->max_nev))), /* dvd_orth */
|
|
|
131 |
std_probl?0:(b->max_size_proj*11+16) /* projeig */);
|
| 2556 |
eromero |
132 |
#if defined(PETSC_USE_COMPLEX)
|
|
|
133 |
b->max_size_auxS = PetscMax(b->max_size_auxS, b->max_size_V);
|
|
|
134 |
/* dvd_calcpairs_projeig_eig */
|
|
|
135 |
#endif
|
| 2779 |
eromero |
136 |
if (ind_probl)
|
|
|
137 |
b->max_size_auxS = PetscMax(b->max_size_auxS,2*b->max_size_proj);
|
|
|
138 |
/* SlepcDenseIOrth */
|
| 1750 |
eromero |
139 |
|
|
|
140 |
/* Setup the step */
|
|
|
141 |
if (b->state >= DVD_STATE_CONF) {
|
| 2605 |
eromero |
142 |
d->max_cX_in_proj = cX_proj;
|
|
|
143 |
d->max_size_P = b->max_size_P;
|
|
|
144 |
d->real_V = b->free_vecs; b->free_vecs+= d->size_real_V;
|
|
|
145 |
if (harm) {
|
|
|
146 |
d->real_W = b->free_vecs; b->free_vecs+= d->size_real_W;
|
|
|
147 |
} else {
|
|
|
148 |
d->real_W = PETSC_NULL;
|
|
|
149 |
}
|
|
|
150 |
d->real_AV = d->AV = b->free_vecs; b->free_vecs+= d->size_real_AV;
|
|
|
151 |
d->max_size_proj = b->max_size_proj;
|
|
|
152 |
d->real_H = b->free_scalars; b->free_scalars+= b->max_size_proj*b->max_size_proj;
|
|
|
153 |
d->ldH = b->max_size_proj;
|
|
|
154 |
d->pX = b->free_scalars; b->free_scalars+= b->max_size_proj*b->max_size_proj;
|
|
|
155 |
d->S = b->free_scalars; b->free_scalars+= b->max_size_proj*b->max_size_proj;
|
| 2555 |
eromero |
156 |
if (!her_probl) {
|
|
|
157 |
d->cS = b->free_scalars; b->free_scalars+= b->max_nev*b->max_nev;
|
| 2605 |
eromero |
158 |
d->max_size_cS = d->ldcS = b->max_nev;
|
| 2555 |
eromero |
159 |
} else {
|
|
|
160 |
d->cS = PETSC_NULL;
|
| 2605 |
eromero |
161 |
d->max_size_cS = d->ldcS = 0;
|
| 2779 |
eromero |
162 |
d->orthoV_type = orth;
|
|
|
163 |
if (ind_probl) {
|
|
|
164 |
d->real_nBV = b->free_scalars; b->free_scalars+= FromRealToScalar(d->size_real_V);
|
|
|
165 |
d->nBpX = b->free_scalars; b->free_scalars+= FromRealToScalar(d->max_size_proj);
|
|
|
166 |
} else
|
|
|
167 |
d->real_nBV = d->nBDS = d->nBpX = PETSC_NULL;
|
| 2555 |
eromero |
168 |
}
|
| 1795 |
eromero |
169 |
d->ipV = ipI;
|
|
|
170 |
d->ipW = ipI;
|
| 2605 |
eromero |
171 |
if (orth == DVD_ORTHOV_BOneMV) {
|
| 2555 |
eromero |
172 |
d->BDS = b->free_vecs; b->free_vecs+= d->eps->nds;
|
|
|
173 |
for (i=0; i<d->eps->nds; i++) {
|
|
|
174 |
ierr = MatMult(d->B, d->eps->DS[i], d->BDS[i]); CHKERRQ(ierr);
|
|
|
175 |
}
|
| 2605 |
eromero |
176 |
} else
|
|
|
177 |
d->BDS = PETSC_NULL;
|
| 1883 |
eromero |
178 |
if (d->B) {
|
| 2605 |
eromero |
179 |
d->real_BV = b->free_vecs; b->free_vecs+= d->size_real_BV;
|
| 2555 |
eromero |
180 |
} else {
|
| 2605 |
eromero |
181 |
d->size_real_BV = 0;
|
|
|
182 |
d->real_BV = PETSC_NULL;
|
|
|
183 |
d->BV_shift = PETSC_FALSE;
|
| 1883 |
eromero |
184 |
}
|
|
|
185 |
if (!std_probl) {
|
| 2605 |
eromero |
186 |
d->real_G = b->free_scalars; b->free_scalars+= b->max_size_proj*b->max_size_proj;
|
|
|
187 |
d->T = b->free_scalars; b->free_scalars+= b->max_size_proj*b->max_size_proj;
|
|
|
188 |
d->pY = b->free_scalars; b->free_scalars+= b->max_size_proj*b->max_size_proj;
|
|
|
189 |
} else {
|
|
|
190 |
d->real_G = PETSC_NULL;
|
|
|
191 |
d->T = PETSC_NULL;
|
|
|
192 |
d->pY = PETSC_NULL;
|
|
|
193 |
}
|
|
|
194 |
if (d->B && !her_probl) {
|
| 1966 |
eromero |
195 |
d->cT = b->free_scalars; b->free_scalars+= b->max_nev*b->max_nev;
|
|
|
196 |
d->ldcT = b->max_nev;
|
| 2247 |
eromero |
197 |
} else {
|
|
|
198 |
d->cT = PETSC_NULL;
|
|
|
199 |
d->ldcT = 0;
|
| 1750 |
eromero |
200 |
}
|
|
|
201 |
|
| 2555 |
eromero |
202 |
d->calcPairs = dvd_calcpairs_proj;
|
| 1750 |
eromero |
203 |
d->calcpairs_residual = dvd_calcpairs_res_0;
|
| 2682 |
jroman |
204 |
d->calcpairs_residual_eig = dvd_calcpairs_eig_res_0;
|
| 1883 |
eromero |
205 |
d->calcpairs_proj_res = dvd_calcpairs_proj_res;
|
| 2555 |
eromero |
206 |
d->calcpairs_selectPairs = PETSC_NULL;
|
| 1751 |
eromero |
207 |
d->ipI = ipI;
|
| 2244 |
eromero |
208 |
DVD_FL_ADD(d->startList, dvd_calcpairs_qz_start);
|
| 1750 |
eromero |
209 |
}
|
|
|
210 |
|
|
|
211 |
PetscFunctionReturn(0);
|
|
|
212 |
}
|
|
|
213 |
|
|
|
214 |
|
| 2244 |
eromero |
215 |
#undef __FUNCT__
|
|
|
216 |
#define __FUNCT__ "dvd_calcpairs_qz_start"
|
|
|
217 |
PetscErrorCode dvd_calcpairs_qz_start(dvdDashboard *d)
|
|
|
218 |
{
|
| 2779 |
eromero |
219 |
PetscBool her_probl,ind_probl;
|
| 2654 |
jroman |
220 |
PetscInt i;
|
| 2244 |
eromero |
221 |
|
|
|
222 |
PetscFunctionBegin;
|
|
|
223 |
her_probl = DVD_IS(d->sEP, DVD_EP_HERMITIAN)?PETSC_TRUE:PETSC_FALSE;
|
| 2779 |
eromero |
224 |
ind_probl = DVD_IS(d->sEP, DVD_EP_INDEFINITE)?PETSC_TRUE:PETSC_FALSE;
|
| 2244 |
eromero |
225 |
|
| 2605 |
eromero |
226 |
d->size_V = 0;
|
|
|
227 |
d->V = d->real_V;
|
|
|
228 |
d->cX = d->real_V;
|
|
|
229 |
d->size_cX = 0;
|
|
|
230 |
d->max_size_V = d->size_real_V;
|
|
|
231 |
d->W = d->real_W;
|
|
|
232 |
d->max_size_W = d->size_real_W;
|
|
|
233 |
d->size_W = 0;
|
| 2244 |
eromero |
234 |
d->size_AV = 0;
|
|
|
235 |
d->AV = d->real_AV;
|
| 2605 |
eromero |
236 |
d->max_size_AV = d->size_real_AV;
|
| 2244 |
eromero |
237 |
d->size_H = 0;
|
|
|
238 |
d->H = d->real_H;
|
| 2605 |
eromero |
239 |
if (d->cS) for (i=0; i<d->max_size_cS*d->max_size_cS; i++) d->cS[i] = 0.0;
|
| 2244 |
eromero |
240 |
d->size_BV = 0;
|
| 2605 |
eromero |
241 |
d->BV = d->real_BV;
|
|
|
242 |
d->max_size_BV = d->size_real_BV;
|
| 2244 |
eromero |
243 |
d->size_G = 0;
|
| 2247 |
eromero |
244 |
d->G = d->real_G;
|
| 2605 |
eromero |
245 |
if (d->cT) for (i=0; i<d->max_size_cS*d->max_size_cS; i++) d->cT[i] = 0.0;
|
|
|
246 |
d->cY = d->B && !her_probl ? d->W : PETSC_NULL;
|
|
|
247 |
d->BcX = d->orthoV_type == DVD_ORTHOV_I && d->B && her_probl ? d->BcX : PETSC_NULL;
|
|
|
248 |
d->size_cY = 0;
|
|
|
249 |
d->size_BcX = 0;
|
|
|
250 |
d->cX_in_V = d->cX_in_H = d->cX_in_G = d->cX_in_W = d->cX_in_AV = d->cX_in_BV = 0;
|
| 2779 |
eromero |
251 |
d->nBV = d->nBcX = d->real_nBV;
|
| 2244 |
eromero |
252 |
PetscFunctionReturn(0);
|
|
|
253 |
}
|
|
|
254 |
|
|
|
255 |
|
| 1750 |
eromero |
256 |
#undef __FUNCT__
|
| 2555 |
eromero |
257 |
#define __FUNCT__ "dvd_calcpairs_proj"
|
|
|
258 |
PetscErrorCode dvd_calcpairs_proj(dvdDashboard *d)
|
| 1750 |
eromero |
259 |
{
|
| 1753 |
eromero |
260 |
PetscErrorCode ierr;
|
|
|
261 |
DvdReduction r;
|
| 2663 |
jroman |
262 |
#define MAX_OPS 7
|
| 1753 |
eromero |
263 |
DvdReductionChunk
|
| 2605 |
eromero |
264 |
ops[MAX_OPS];
|
| 1753 |
eromero |
265 |
DvdMult_copy_func
|
| 2605 |
eromero |
266 |
sr[MAX_OPS], *sr0 = sr;
|
|
|
267 |
PetscInt size_in, i;
|
|
|
268 |
PetscScalar *in = d->auxS, *out;
|
|
|
269 |
PetscBool stdp;
|
| 1753 |
eromero |
270 |
|
| 1750 |
eromero |
271 |
PetscFunctionBegin;
|
|
|
272 |
|
| 2605 |
eromero |
273 |
stdp = DVD_IS(d->sEP, DVD_EP_STD)?PETSC_TRUE:PETSC_FALSE;
|
|
|
274 |
size_in =
|
| 2654 |
jroman |
275 |
(d->size_cX+d->V_tra_s-d->cX_in_H)*d->V_tra_s*(d->cT?2:(d->cS?1:0)) + /* updateV0,W0 */
|
| 2605 |
eromero |
276 |
(d->size_H*(d->V_new_e-d->V_new_s)*2+
|
| 2654 |
jroman |
277 |
(d->V_new_e-d->V_new_s)*(d->V_new_e-d->V_new_s))*(!stdp?2:1); /* updateAV1,BV1 */
|
| 2605 |
eromero |
278 |
|
|
|
279 |
out = in+size_in;
|
|
|
280 |
|
| 2682 |
jroman |
281 |
/* Check consistency */
|
|
|
282 |
if (2*size_in > d->size_auxS) { SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!"); }
|
| 2605 |
eromero |
283 |
|
| 1753 |
eromero |
284 |
/* Prepare reductions */
|
| 2605 |
eromero |
285 |
ierr = SlepcAllReduceSumBegin(ops, MAX_OPS, in, out, size_in, &r,
|
| 1753 |
eromero |
286 |
((PetscObject)d->V[0])->comm); CHKERRQ(ierr);
|
| 2605 |
eromero |
287 |
/* Allocate size_in */
|
|
|
288 |
d->auxS+= size_in;
|
|
|
289 |
d->size_auxS-= size_in;
|
| 1753 |
eromero |
290 |
|
| 2555 |
eromero |
291 |
/* Update AV, BV, W and the projected matrices */
|
| 2605 |
eromero |
292 |
/* 1. S <- S*MT */
|
|
|
293 |
ierr = dvd_calcpairs_updateV0(d, &r, &sr0); CHKERRQ(ierr);
|
|
|
294 |
ierr = dvd_calcpairs_updateW0(d, &r, &sr0); CHKERRQ(ierr);
|
|
|
295 |
ierr = dvd_calcpairs_updateAV0(d); CHKERRQ(ierr);
|
|
|
296 |
ierr = dvd_calcpairs_updateBV0(d); CHKERRQ(ierr);
|
|
|
297 |
/* 2. V <- orth(V, V_new) */
|
|
|
298 |
ierr = dvd_calcpairs_updateV1(d); CHKERRQ(ierr);
|
|
|
299 |
/* 3. AV <- [AV A * V(V_new_s:V_new_e-1)] */
|
|
|
300 |
/* Check consistency */
|
|
|
301 |
if (d->size_AV != d->V_new_s) { SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!"); }
|
|
|
302 |
for (i=d->V_new_s; i<d->V_new_e; i++) {
|
|
|
303 |
ierr = MatMult(d->A, d->V[i], d->AV[i]); CHKERRQ(ierr);
|
| 2555 |
eromero |
304 |
}
|
| 2605 |
eromero |
305 |
d->size_AV = d->V_new_e;
|
|
|
306 |
/* 4. BV <- [BV B * V(V_new_s:V_new_e-1)] */
|
|
|
307 |
if (d->B && d->orthoV_type != DVD_ORTHOV_BOneMV) {
|
|
|
308 |
/* Check consistency */
|
|
|
309 |
if (d->size_BV != d->V_new_s) { SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!"); }
|
|
|
310 |
for (i=d->V_new_s; i<d->V_new_e; i++) {
|
|
|
311 |
ierr = MatMult(d->B, d->V[i], d->BV[i]); CHKERRQ(ierr);
|
|
|
312 |
}
|
|
|
313 |
d->size_BV = d->V_new_e;
|
| 2021 |
eromero |
314 |
}
|
| 2605 |
eromero |
315 |
/* 5 <- W <- [W f(AV,BV)] */
|
|
|
316 |
ierr = dvd_calcpairs_updateW1(d); CHKERRQ(ierr);
|
|
|
317 |
ierr = dvd_calcpairs_updateAV1(d, &r, &sr0); CHKERRQ(ierr);
|
|
|
318 |
ierr = dvd_calcpairs_updateBV1(d, &r, &sr0); CHKERRQ(ierr);
|
| 1753 |
eromero |
319 |
|
| 2605 |
eromero |
320 |
/* Deallocate size_in */
|
|
|
321 |
d->auxS-= size_in;
|
|
|
322 |
d->size_auxS+= size_in;
|
|
|
323 |
|
| 1753 |
eromero |
324 |
/* Do reductions */
|
|
|
325 |
ierr = SlepcAllReduceSumEnd(&r); CHKERRQ(ierr);
|
|
|
326 |
|
| 2555 |
eromero |
327 |
/* Perform the transformation on the projected problem */
|
|
|
328 |
if (d->calcpairs_proj_trans) {
|
|
|
329 |
ierr = d->calcpairs_proj_trans(d); CHKERRQ(ierr);
|
|
|
330 |
}
|
|
|
331 |
|
| 2605 |
eromero |
332 |
d->V_tra_s = d->V_tra_e = 0;
|
|
|
333 |
d->V_new_s = d->V_new_e;
|
| 2555 |
eromero |
334 |
|
|
|
335 |
/* Solve the projected problem */
|
| 2605 |
eromero |
336 |
if (DVD_IS(d->sEP, DVD_EP_STD)) {
|
| 2779 |
eromero |
337 |
if (DVD_IS(d->sEP, DVD_EP_INDEFINITE)) {
|
|
|
338 |
ierr = dvd_calcpairs_projeig_ind(d); CHKERRQ(ierr);
|
|
|
339 |
} else if (DVD_IS(d->sEP, DVD_EP_HERMITIAN)) {
|
| 2605 |
eromero |
340 |
ierr = dvd_calcpairs_projeig_eig(d); CHKERRQ(ierr);
|
| 2021 |
eromero |
341 |
} else {
|
| 2605 |
eromero |
342 |
ierr = dvd_calcpairs_projeig_qz_std(d); CHKERRQ(ierr);
|
| 2021 |
eromero |
343 |
}
|
| 2605 |
eromero |
344 |
} else {
|
|
|
345 |
ierr = dvd_calcpairs_projeig_qz_gen(d); CHKERRQ(ierr);
|
|
|
346 |
}
|
| 1619 |
slepc |
347 |
|
| 1829 |
eromero |
348 |
/* Check consistency */
|
| 2605 |
eromero |
349 |
if (d->size_V != d->V_new_e || d->size_V+d->cX_in_H != d->size_H || d->cX_in_V != d->cX_in_H ||
|
|
|
350 |
d->size_V != d->size_AV || d->cX_in_H != d->cX_in_AV ||
|
|
|
351 |
(DVD_ISNOT(d->sEP, DVD_EP_STD) && (
|
|
|
352 |
d->size_V+d->cX_in_G != d->size_G || d->cX_in_H != d->cX_in_G ||
|
|
|
353 |
d->size_H != d->size_G || (d->BV && (
|
|
|
354 |
d->size_V != d->size_BV || d->cX_in_H != d->cX_in_BV)))) ||
|
|
|
355 |
(d->W && d->size_W != d->size_V)) {
|
| 2214 |
jroman |
356 |
SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!");
|
| 1829 |
eromero |
357 |
}
|
|
|
358 |
|
| 1619 |
slepc |
359 |
PetscFunctionReturn(0);
|
| 2663 |
jroman |
360 |
#undef MAX_OPS
|
| 1619 |
slepc |
361 |
}
|
|
|
362 |
|
| 1735 |
eromero |
363 |
/**** Basic routines **********************************************************/
|
|
|
364 |
|
|
|
365 |
#undef __FUNCT__
|
| 2605 |
eromero |
366 |
#define __FUNCT__ "dvd_calcpairs_updateV0"
|
|
|
367 |
/* auxV: V_tra_s, DvdMult_copy_func: 1 */
|
|
|
368 |
PetscErrorCode dvd_calcpairs_updateV0(dvdDashboard *d, DvdReduction *r,
|
|
|
369 |
DvdMult_copy_func **sr)
|
| 1795 |
eromero |
370 |
{
|
| 2021 |
eromero |
371 |
PetscErrorCode ierr;
|
| 2779 |
eromero |
372 |
PetscInt rm,i;
|
| 2605 |
eromero |
373 |
|
|
|
374 |
PetscFunctionBegin;
|
|
|
375 |
|
|
|
376 |
if (d->V_tra_s == 0 && d->V_tra_e == 0) { PetscFunctionReturn(0); }
|
|
|
377 |
|
| 2779 |
eromero |
378 |
/* Update nBcX and nBV */
|
|
|
379 |
if (d->nBcX && d->nBpX && d->nBV) {
|
|
|
380 |
d->nBV+= d->V_tra_s;
|
|
|
381 |
for (i=0; i<d->V_tra_s; i++) d->nBcX[d->size_cX+i] = d->nBpX[i];
|
|
|
382 |
for (i=d->V_tra_s; i<d->V_tra_e; i++) d->nBV[i-d->V_tra_s] = d->nBpX[i];
|
|
|
383 |
}
|
|
|
384 |
|
| 2605 |
eromero |
385 |
/* cX <- [cX V*MT(0:V_tra_s-1)], V <- V*MT(V_tra_s:V_tra_e) */
|
|
|
386 |
ierr = dvd_calcpairs_updateBV0_gen(d,d->real_V,&d->size_cX,&d->V,&d->size_V,&d->max_size_V,PETSC_TRUE,&d->cX_in_V,d->MTX);CHKERRQ(ierr);
|
|
|
387 |
|
|
|
388 |
/* Udpate cS for standard problems */
|
| 2624 |
eromero |
389 |
if (d->cS && !d->cT && !d->cY && (d->V_tra_s > d->max_cX_in_proj || d->size_cX >= d->nev)) {
|
| 2605 |
eromero |
390 |
/* Check consistency */
|
|
|
391 |
if (d->size_cS+d->V_tra_s != d->size_cX) { SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!"); }
|
|
|
392 |
|
|
|
393 |
/* auxV <- AV * MTX(0:V_tra_e-1) */
|
| 2654 |
jroman |
394 |
rm = d->size_cX>=d->nev?0:d->max_cX_in_proj;
|
|
|
395 |
ierr = SlepcUpdateVectorsZ(d->auxV, 0.0, 1.0, d->AV-d->cX_in_AV, d->size_AV+d->cX_in_AV, d->MTX, d->ldMTX, d->size_MT, d->V_tra_s-rm); CHKERRQ(ierr);
|
| 2605 |
eromero |
396 |
|
|
|
397 |
/* cS(:, size_cS:) <- cX' * auxV */
|
|
|
398 |
ierr = VecsMultS(&d->cS[d->ldcS*d->size_cS], 0, d->ldcS, d->cX, 0, d->size_cX-rm, d->auxV, 0, d->V_tra_s-rm, r, (*sr)++); CHKERRQ(ierr);
|
|
|
399 |
d->size_cS+= d->V_tra_s-rm;
|
|
|
400 |
}
|
| 2779 |
eromero |
401 |
|
| 2605 |
eromero |
402 |
PetscFunctionReturn(0);
|
|
|
403 |
}
|
|
|
404 |
|
|
|
405 |
|
|
|
406 |
#undef __FUNCT__
|
|
|
407 |
#define __FUNCT__ "dvd_calcpairs_updateV1"
|
|
|
408 |
/* auxS: size_cX+V_new_e+1 */
|
|
|
409 |
PetscErrorCode dvd_calcpairs_updateV1(dvdDashboard *d)
|
|
|
410 |
{
|
|
|
411 |
PetscErrorCode ierr;
|
| 1829 |
eromero |
412 |
Vec *cX = d->BcX? d->BcX : ( (d->cY && !d->W)? d->cY : d->cX );
|
| 1795 |
eromero |
413 |
|
|
|
414 |
PetscFunctionBegin;
|
|
|
415 |
|
| 2605 |
eromero |
416 |
if (d->V_new_s == d->V_new_e) { PetscFunctionReturn(0); }
|
|
|
417 |
|
|
|
418 |
/* Check consistency */
|
|
|
419 |
if (d->size_V != d->V_new_s) { SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!"); }
|
|
|
420 |
|
|
|
421 |
/* V <- gs([cX V(0:V_new_s-1)], V(V_new_s:V_new_e-1)) */
|
|
|
422 |
if (d->orthoV_type == DVD_ORTHOV_BOneMV) {
|
| 2779 |
eromero |
423 |
ierr = dvd_BorthV(d->ipV, d->eps->DS, d->BDS, d->nBDS, d->eps->nds, d->cX, d->real_BV, d->nBcX,
|
|
|
424 |
d->size_cX, d->V, d->BV, d->nBV, d->V_new_s, d->V_new_e,
|
| 2605 |
eromero |
425 |
d->auxS, d->eps->rand); CHKERRQ(ierr);
|
|
|
426 |
d->size_BV = d->V_new_e;
|
| 2555 |
eromero |
427 |
} else {
|
|
|
428 |
ierr = dvd_orthV(d->ipV, d->eps->DS, d->eps->nds, cX, d->size_cX, d->V,
|
| 2605 |
eromero |
429 |
d->V_new_s, d->V_new_e, d->auxS, d->eps->rand);
|
| 2555 |
eromero |
430 |
CHKERRQ(ierr);
|
|
|
431 |
}
|
| 2605 |
eromero |
432 |
d->size_V = d->V_new_e;
|
| 1795 |
eromero |
433 |
|
| 2021 |
eromero |
434 |
PetscFunctionReturn(0);
|
| 1795 |
eromero |
435 |
}
|
|
|
436 |
|
|
|
437 |
#undef __FUNCT__
|
| 2605 |
eromero |
438 |
#define __FUNCT__ "dvd_calcpairs_updateW0"
|
|
|
439 |
/* auxV: V_tra_s, DvdMult_copy_func: 2 */
|
|
|
440 |
PetscErrorCode dvd_calcpairs_updateW0(dvdDashboard *d, DvdReduction *r,
|
|
|
441 |
DvdMult_copy_func **sr)
|
| 1795 |
eromero |
442 |
{
|
| 2021 |
eromero |
443 |
PetscErrorCode ierr;
|
| 2605 |
eromero |
444 |
PetscInt rm;
|
| 1795 |
eromero |
445 |
|
|
|
446 |
PetscFunctionBegin;
|
|
|
447 |
|
| 2682 |
jroman |
448 |
if (d->V_tra_s == 0 && d->V_tra_e == 0) { PetscFunctionReturn(0); }
|
| 2605 |
eromero |
449 |
|
|
|
450 |
/* cY <- [cY W*MTY(0:V_tra_s-1)], W <- W*MTY(V_tra_s:V_tra_e) */
|
|
|
451 |
ierr = dvd_calcpairs_updateBV0_gen(d,d->real_W,&d->size_cY,&d->W,&d->size_W,&d->max_size_W,d->W_shift,&d->cX_in_W,d->MTY);CHKERRQ(ierr);
|
|
|
452 |
|
|
|
453 |
/* Udpate cS and cT */
|
| 2682 |
jroman |
454 |
if (d->cT && (d->V_tra_s > d->max_cX_in_proj || d->size_cX >= d->nev)) {
|
| 2605 |
eromero |
455 |
/* Check consistency */
|
| 2682 |
jroman |
456 |
if (d->size_cS+d->V_tra_s != d->size_cX || (d->W && d->size_cY != d->size_cX)) { SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!"); }
|
| 2605 |
eromero |
457 |
|
|
|
458 |
/* auxV <- AV * MTX(0:V_tra_e-1) */
|
|
|
459 |
rm = d->size_cX>=d->nev?0:d->max_cX_in_proj;
|
| 2654 |
jroman |
460 |
ierr = SlepcUpdateVectorsZ(d->auxV, 0.0, 1.0, d->AV-d->cX_in_H, d->size_AV-d->cX_in_H, d->MTX, d->ldMTX, d->size_MT, d->V_tra_s-rm); CHKERRQ(ierr);
|
| 2605 |
eromero |
461 |
|
|
|
462 |
/* cS(:, size_cS:) <- cY' * auxV */
|
| 2682 |
jroman |
463 |
ierr = VecsMultS(&d->cS[d->ldcS*d->size_cS], 0, d->ldcS, d->cY?d->cY:d->cX, 0, d->size_cX-rm, d->auxV, 0, d->V_tra_s-rm, r, (*sr)++); CHKERRQ(ierr);
|
| 2605 |
eromero |
464 |
|
|
|
465 |
/* auxV <- BV * MTX(0:V_tra_e-1) */
|
| 2654 |
jroman |
466 |
ierr = SlepcUpdateVectorsZ(d->auxV, 0.0, 1.0, d->BV-d->cX_in_H, d->size_BV-d->cX_in_H, d->MTX, d->ldMTX, d->size_MT, d->V_tra_s-rm); CHKERRQ(ierr);
|
| 2605 |
eromero |
467 |
|
|
|
468 |
/* cT(:, size_cS:) <- cY' * auxV */
|
| 2682 |
jroman |
469 |
ierr = VecsMultS(&d->cT[d->ldcS*d->size_cS], 0, d->ldcS, d->cY?d->cY:d->cX, 0, d->size_cX-rm, d->auxV, 0, d->V_tra_s-rm, r, (*sr)++); CHKERRQ(ierr);
|
| 2654 |
jroman |
470 |
|
| 2605 |
eromero |
471 |
d->size_cS+= d->V_tra_s-rm;
|
|
|
472 |
d->size_cT+= d->V_tra_s-rm;
|
|
|
473 |
}
|
|
|
474 |
|
|
|
475 |
PetscFunctionReturn(0);
|
|
|
476 |
}
|
|
|
477 |
|
|
|
478 |
|
|
|
479 |
#undef __FUNCT__
|
|
|
480 |
#define __FUNCT__ "dvd_calcpairs_updateW1"
|
|
|
481 |
/* auxS: size_cX+V_new_e+1 */
|
|
|
482 |
PetscErrorCode dvd_calcpairs_updateW1(dvdDashboard *d)
|
|
|
483 |
{
|
|
|
484 |
PetscErrorCode ierr;
|
| 2664 |
jroman |
485 |
Vec *cY = d->cY?d->cY:d->cX;
|
| 2605 |
eromero |
486 |
|
|
|
487 |
PetscFunctionBegin;
|
|
|
488 |
|
| 2664 |
jroman |
489 |
if (!d->W || d->V_new_s == d->V_new_e) { PetscFunctionReturn(0); }
|
| 2605 |
eromero |
490 |
|
|
|
491 |
/* Check consistency */
|
|
|
492 |
if (d->size_W != d->V_new_s) { SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!"); }
|
|
|
493 |
|
| 1795 |
eromero |
494 |
/* Update W */
|
| 2021 |
eromero |
495 |
ierr = d->calcpairs_W(d); CHKERRQ(ierr);
|
| 1795 |
eromero |
496 |
|
| 2605 |
eromero |
497 |
/* W <- gs([cY W(0:V_new_s-1)], W(V_new_s:V_new_e-1)) */
|
| 2664 |
jroman |
498 |
ierr = dvd_orthV(d->ipW, PETSC_NULL, 0, cY, d->size_cX, d->W-d->cX_in_W, d->V_new_s+d->cX_in_W, d->V_new_e+d->cX_in_W, d->auxS, d->eps->rand); CHKERRQ(ierr);
|
| 2605 |
eromero |
499 |
d->size_W = d->V_new_e;
|
| 1795 |
eromero |
500 |
|
| 2021 |
eromero |
501 |
PetscFunctionReturn(0);
|
| 1795 |
eromero |
502 |
}
|
|
|
503 |
|
|
|
504 |
#undef __FUNCT__
|
| 2605 |
eromero |
505 |
#define __FUNCT__ "dvd_calcpairs_updateAV0"
|
|
|
506 |
/* auxS: size_H*(V_tra_e-V_tra_s) */
|
|
|
507 |
PetscErrorCode dvd_calcpairs_updateAV0(dvdDashboard *d)
|
| 1619 |
slepc |
508 |
{
|
| 2021 |
eromero |
509 |
PetscErrorCode ierr;
|
| 2605 |
eromero |
510 |
PetscScalar *MTY = d->W?d->MTY:d->MTX;
|
| 2654 |
jroman |
511 |
PetscInt cMT, tra_s;
|
| 1619 |
slepc |
512 |
|
|
|
513 |
PetscFunctionBegin;
|
|
|
514 |
|
| 2605 |
eromero |
515 |
if (d->V_tra_s == 0 && d->V_tra_e == 0) { PetscFunctionReturn(0); }
|
| 1619 |
slepc |
516 |
|
| 2605 |
eromero |
517 |
/* AV(V_tra_s-cp-1:) = cAV*MTX(V_tra_s:) */
|
|
|
518 |
ierr = dvd_calcpairs_updateBV0_gen(d,d->real_AV,PETSC_NULL,&d->AV,&d->size_AV,&d->max_size_AV,PETSC_FALSE,&d->cX_in_AV,d->MTX);CHKERRQ(ierr);
|
|
|
519 |
tra_s = PetscMax(d->V_tra_s-d->max_cX_in_proj, 0);
|
|
|
520 |
cMT = d->V_tra_e - tra_s;
|
|
|
521 |
|
|
|
522 |
/* Update H <- MTY(tra_s)' * (H * MTX(tra_s:)) */
|
|
|
523 |
ierr = SlepcDenseMatProdTriang(d->auxS, 0, d->ldH, d->H, d->sH, d->ldH, d->size_H, d->size_H, PETSC_FALSE, &d->MTX[d->ldMTX*tra_s], 0, d->ldMTX, d->size_MT, cMT, PETSC_FALSE); CHKERRQ(ierr);
|
|
|
524 |
ierr = SlepcDenseMatProdTriang(d->H, d->sH, d->ldH, &MTY[d->ldMTX*tra_s], 0, d->ldMTX, d->size_MT, cMT, PETSC_TRUE, d->auxS, 0, d->ldH, d->size_H, cMT, PETSC_FALSE); CHKERRQ(ierr);
|
|
|
525 |
d->size_H = cMT;
|
| 2654 |
jroman |
526 |
d->cX_in_H = d->cX_in_AV;
|
| 2605 |
eromero |
527 |
|
| 2021 |
eromero |
528 |
PetscFunctionReturn(0);
|
| 1735 |
eromero |
529 |
}
|
| 1640 |
slepc |
530 |
|
| 2605 |
eromero |
531 |
|
| 1735 |
eromero |
532 |
#undef __FUNCT__
|
| 2605 |
eromero |
533 |
#define __FUNCT__ "dvd_calcpairs_updateAV1"
|
|
|
534 |
/* DvdMult_copy_func: 2 */
|
|
|
535 |
PetscErrorCode dvd_calcpairs_updateAV1(dvdDashboard *d, DvdReduction *r,
|
|
|
536 |
DvdMult_copy_func **sr)
|
| 1735 |
eromero |
537 |
{
|
| 2021 |
eromero |
538 |
PetscErrorCode ierr;
|
| 2605 |
eromero |
539 |
Vec *W = d->W?d->W:d->V;
|
| 1619 |
slepc |
540 |
|
| 1735 |
eromero |
541 |
PetscFunctionBegin;
|
| 1619 |
slepc |
542 |
|
| 2605 |
eromero |
543 |
if (d->V_new_s == d->V_new_e) { PetscFunctionReturn(0); }
|
| 1619 |
slepc |
544 |
|
| 2605 |
eromero |
545 |
/* Check consistency */
|
|
|
546 |
if (d->size_H != d->V_new_s+d->cX_in_H || d->size_V != d->V_new_e) {
|
|
|
547 |
SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!");
|
|
|
548 |
}
|
|
|
549 |
|
|
|
550 |
/* H = [H W(old)'*AV(new);
|
|
|
551 |
W(new)'*AV(old) W(new)'*AV(new) ],
|
|
|
552 |
being old=0:V_new_s-1, new=V_new_s:V_new_e-1 */
|
| 2624 |
eromero |
553 |
ierr = VecsMultS(d->H,d->sH,d->ldH,W-d->cX_in_H,d->V_new_s+d->cX_in_H, d->V_new_e+d->cX_in_H, d->AV-d->cX_in_H,d->V_new_s+d->cX_in_H,d->V_new_e+d->cX_in_H, r, (*sr)++); CHKERRQ(ierr);
|
| 2605 |
eromero |
554 |
d->size_H = d->V_new_e+d->cX_in_H;
|
|
|
555 |
|
| 2021 |
eromero |
556 |
PetscFunctionReturn(0);
|
| 1630 |
slepc |
557 |
}
|
| 1619 |
slepc |
558 |
|
| 1630 |
slepc |
559 |
#undef __FUNCT__
|
| 2605 |
eromero |
560 |
#define __FUNCT__ "dvd_calcpairs_updateBV0"
|
|
|
561 |
/* auxS: max(BcX*(size_cX+V_new_e+1), size_G*(V_tra_e-V_tra_s)) */
|
|
|
562 |
PetscErrorCode dvd_calcpairs_updateBV0(dvdDashboard *d)
|
| 1630 |
slepc |
563 |
{
|
| 2021 |
eromero |
564 |
PetscErrorCode ierr;
|
| 2605 |
eromero |
565 |
PetscScalar *MTY = d->W?d->MTY:d->MTX;
|
| 2654 |
jroman |
566 |
PetscInt cMT, tra_s, i;
|
| 2605 |
eromero |
567 |
PetscBool lindep;
|
|
|
568 |
PetscReal norm;
|
| 1626 |
slepc |
569 |
|
| 1630 |
slepc |
570 |
PetscFunctionBegin;
|
| 1619 |
slepc |
571 |
|
| 2605 |
eromero |
572 |
if (d->V_tra_s == 0 && d->V_tra_e == 0) { PetscFunctionReturn(0); }
|
| 1619 |
slepc |
573 |
|
| 2605 |
eromero |
574 |
/* BV <- BV*MTX */
|
|
|
575 |
ierr = dvd_calcpairs_updateBV0_gen(d,d->real_BV,PETSC_NULL,&d->BV,&d->size_BV,&d->max_size_BV,d->BV_shift,&d->cX_in_BV,d->MTX);CHKERRQ(ierr);
|
|
|
576 |
|
|
|
577 |
/* If BcX, BcX <- orth(BcX) */
|
|
|
578 |
if (d->BcX) {
|
|
|
579 |
for (i=0; i<d->V_tra_s; i++) {
|
|
|
580 |
ierr = IPOrthogonalize(d->ipI, 0, PETSC_NULL, d->size_BcX+i, PETSC_NULL,
|
|
|
581 |
d->BcX, d->BcX[d->size_BcX+i], PETSC_NULL,
|
|
|
582 |
&norm, &lindep); CHKERRQ(ierr);
|
|
|
583 |
if(lindep) SETERRQ(((PetscObject)d->ipI)->comm,1, "Error during orth(BcX, B*cX(new))");
|
|
|
584 |
ierr = VecScale(d->BcX[d->size_BcX+i], 1.0/norm); CHKERRQ(ierr);
|
|
|
585 |
}
|
|
|
586 |
d->size_BcX+= d->V_tra_s;
|
|
|
587 |
}
|
|
|
588 |
|
|
|
589 |
/* Update G <- MTY' * (G * MTX) */
|
|
|
590 |
if (d->G) {
|
|
|
591 |
tra_s = PetscMax(d->V_tra_s-d->max_cX_in_proj, 0);
|
|
|
592 |
cMT = d->V_tra_e - tra_s;
|
|
|
593 |
ierr = SlepcDenseMatProdTriang(d->auxS, 0, d->ldH, d->G, d->sG, d->ldH, d->size_G, d->size_G, PETSC_FALSE, &d->MTX[d->ldMTX*tra_s], 0, d->ldMTX, d->size_MT, cMT, PETSC_FALSE); CHKERRQ(ierr);
|
|
|
594 |
ierr = SlepcDenseMatProdTriang(d->G, d->sG, d->ldH, &MTY[d->ldMTX*tra_s], 0, d->ldMTX, d->size_MT, cMT, PETSC_TRUE, d->auxS, 0, d->ldH, d->size_G, cMT, PETSC_FALSE); CHKERRQ(ierr);
|
|
|
595 |
d->size_G = cMT;
|
| 2654 |
jroman |
596 |
d->cX_in_G = d->cX_in_V;
|
| 2605 |
eromero |
597 |
}
|
|
|
598 |
|
| 2021 |
eromero |
599 |
PetscFunctionReturn(0);
|
| 1619 |
slepc |
600 |
}
|
|
|
601 |
|
| 1795 |
eromero |
602 |
|
| 1630 |
slepc |
603 |
#undef __FUNCT__
|
| 2605 |
eromero |
604 |
#define __FUNCT__ "dvd_calcpairs_updateBV1"
|
|
|
605 |
/* DvdMult_copy_func: 2 */
|
|
|
606 |
PetscErrorCode dvd_calcpairs_updateBV1(dvdDashboard *d, DvdReduction *r,
|
|
|
607 |
DvdMult_copy_func **sr)
|
| 1619 |
slepc |
608 |
{
|
| 2021 |
eromero |
609 |
PetscErrorCode ierr;
|
| 2605 |
eromero |
610 |
Vec *W = d->W?d->W:d->V, *BV = d->BV?d->BV:d->V;
|
| 1619 |
slepc |
611 |
|
|
|
612 |
PetscFunctionBegin;
|
|
|
613 |
|
| 2605 |
eromero |
614 |
if (!d->G || d->V_new_s == d->V_new_e) { PetscFunctionReturn(0); }
|
| 1630 |
slepc |
615 |
|
| 2605 |
eromero |
616 |
/* G = [G W(old)'*BV(new);
|
|
|
617 |
W(new)'*BV(old) W(new)'*BV(new) ],
|
|
|
618 |
being old=0:V_new_s-1, new=V_new_s:V_new_e-1 */
|
| 2624 |
eromero |
619 |
ierr = VecsMultS(d->G,d->sG,d->ldH,W-d->cX_in_G,d->V_new_s+d->cX_in_G,d->V_new_e+d->cX_in_G,BV-d->cX_in_G,d->V_new_s+d->cX_in_G,d->V_new_e+d->cX_in_G,r,(*sr)++); CHKERRQ(ierr);
|
| 2605 |
eromero |
620 |
d->size_G = d->V_new_e+d->cX_in_G;
|
|
|
621 |
|
| 2021 |
eromero |
622 |
PetscFunctionReturn(0);
|
| 1619 |
slepc |
623 |
}
|
|
|
624 |
|
| 2556 |
eromero |
625 |
/* in complex, d->size_H real auxiliar values are needed */
|
| 1735 |
eromero |
626 |
#undef __FUNCT__
|
| 2555 |
eromero |
627 |
#define __FUNCT__ "dvd_calcpairs_projeig_eig"
|
|
|
628 |
PetscErrorCode dvd_calcpairs_projeig_eig(dvdDashboard *d)
|
|
|
629 |
{
|
|
|
630 |
PetscErrorCode ierr;
|
| 2556 |
eromero |
631 |
PetscReal *w;
|
|
|
632 |
#if defined(PETSC_USE_COMPLEX)
|
|
|
633 |
PetscInt i;
|
|
|
634 |
#endif
|
| 2555 |
eromero |
635 |
|
|
|
636 |
PetscFunctionBegin;
|
|
|
637 |
|
|
|
638 |
/* S <- H */
|
|
|
639 |
d->ldS = d->ldpX = d->size_H;
|
|
|
640 |
ierr = SlepcDenseCopyTriang(d->S, DVD_MAT_LTRIANG, d->size_H, d->H, d->sH, d->ldH,
|
| 2605 |
eromero |
641 |
d->size_H, d->size_H); CHKERRQ(ierr);
|
| 2555 |
eromero |
642 |
|
|
|
643 |
/* S = pX' * L * pX */
|
| 2556 |
eromero |
644 |
#if !defined(PETSC_USE_COMPLEX)
|
| 2605 |
eromero |
645 |
w = d->eigr-d->cX_in_H;
|
| 2556 |
eromero |
646 |
#else
|
|
|
647 |
w = (PetscReal*)d->auxS;
|
|
|
648 |
#endif
|
|
|
649 |
ierr = EPSDenseHEP(d->size_H, d->S, d->ldS, w, d->pX); CHKERRQ(ierr);
|
|
|
650 |
#if defined(PETSC_USE_COMPLEX)
|
| 2605 |
eromero |
651 |
for (i=0; i<d->size_H; i++) d->eigr[i-d->cX_in_H] = w[i];
|
| 2556 |
eromero |
652 |
#endif
|
| 2555 |
eromero |
653 |
|
|
|
654 |
d->calcpairs_selectPairs = dvd_calcpairs_selectPairs_eig;
|
|
|
655 |
|
|
|
656 |
PetscFunctionReturn(0);
|
|
|
657 |
}
|
|
|
658 |
|
|
|
659 |
|
| 2779 |
eromero |
660 |
/* in complex, d->size_H real auxiliar values are needed */
|
| 2555 |
eromero |
661 |
#undef __FUNCT__
|
| 2779 |
eromero |
662 |
#define __FUNCT__ "dvd_calcpairs_projeig_ind"
|
|
|
663 |
PetscErrorCode dvd_calcpairs_projeig_ind(dvdDashboard *d)
|
|
|
664 |
{
|
|
|
665 |
PetscErrorCode ierr;
|
|
|
666 |
PetscInt i,j;
|
|
|
667 |
|
|
|
668 |
PetscFunctionBegin;
|
|
|
669 |
|
|
|
670 |
/* S <- H */
|
|
|
671 |
d->ldS = d->ldpX = d->size_H;
|
|
|
672 |
ierr = SlepcDenseCopyTriang(d->S, 0, d->size_H, d->H, d->sH, d->ldH,
|
|
|
673 |
d->size_H, d->size_H); CHKERRQ(ierr);
|
|
|
674 |
|
|
|
675 |
/* S <- nBV * S */
|
|
|
676 |
for (i=0; i<d->size_H; i++) {
|
|
|
677 |
if (d->nBV[i] < 0.0)
|
|
|
678 |
for (j=0; j<d->size_H; j++) d->S[i+j*d->ldS]*= d->nBV[i];
|
|
|
679 |
}
|
|
|
680 |
|
|
|
681 |
/* S = pX * L */
|
|
|
682 |
ierr = EPSDenseNHEP(d->size_H, d->S, d->eigr-d->cX_in_H, d->eigi-d->cX_in_H, d->pX, PETSC_NULL); CHKERRQ(ierr);
|
|
|
683 |
|
|
|
684 |
d->calcpairs_selectPairs = dvd_calcpairs_selectPairs_eig;
|
|
|
685 |
|
|
|
686 |
PetscFunctionReturn(0);
|
|
|
687 |
}
|
|
|
688 |
|
|
|
689 |
#undef __FUNCT__
|
| 1750 |
eromero |
690 |
#define __FUNCT__ "dvd_calcpairs_projeig_qz_std"
|
| 2021 |
eromero |
691 |
PetscErrorCode dvd_calcpairs_projeig_qz_std(dvdDashboard *d)
|
| 1636 |
slepc |
692 |
{
|
|
|
693 |
PetscErrorCode ierr;
|
|
|
694 |
|
|
|
695 |
PetscFunctionBegin;
|
|
|
696 |
|
| 1750 |
eromero |
697 |
/* S <- H */
|
|
|
698 |
d->ldS = d->ldpX = d->size_H;
|
| 1752 |
eromero |
699 |
ierr = SlepcDenseCopyTriang(d->S, 0, d->size_H, d->H, d->sH, d->ldH,
|
|
|
700 |
d->size_H, d->size_H);
|
| 1750 |
eromero |
701 |
|
|
|
702 |
/* S = pX' * H * pX */
|
| 2021 |
eromero |
703 |
ierr = EPSDenseHessenberg(d->size_H, 0, d->S, d->ldS, d->pX); CHKERRQ(ierr);
|
| 2605 |
eromero |
704 |
ierr = EPSDenseSchur(d->size_H, 0, d->S, d->ldS, d->pX, d->eigr-d->cX_in_H, d->eigi-d->cX_in_H);
|
| 1750 |
eromero |
705 |
CHKERRQ(ierr);
|
| 1636 |
slepc |
706 |
|
| 2555 |
eromero |
707 |
d->calcpairs_selectPairs = dvd_calcpairs_selectPairs_qz;
|
|
|
708 |
|
| 1636 |
slepc |
709 |
PetscFunctionReturn(0);
|
|
|
710 |
}
|
|
|
711 |
|
| 2223 |
jroman |
712 |
#undef __FUNCT__
|
|
|
713 |
#define __FUNCT__ "dvd_calcpairs_projeig_qz_gen"
|
| 1750 |
eromero |
714 |
/*
|
|
|
715 |
auxS(dgges) = size_H (beta) + 8*size_H+16 (work)
|
|
|
716 |
auxS(zgges) = size_H (beta) + 1+2*size_H (work) + 8*size_H (rwork)
|
|
|
717 |
*/
|
| 2021 |
eromero |
718 |
PetscErrorCode dvd_calcpairs_projeig_qz_gen(dvdDashboard *d)
|
| 1750 |
eromero |
719 |
{
|
| 2392 |
jroman |
720 |
#if defined(SLEPC_MISSING_LAPACK_GGES)
|
|
|
721 |
PetscFunctionBegin;
|
|
|
722 |
SETERRQ(((PetscObject)(d->eps))->comm,PETSC_ERR_SUP,"GGES - Lapack routine is unavailable.");
|
|
|
723 |
#else
|
| 1750 |
eromero |
724 |
PetscErrorCode ierr;
|
|
|
725 |
PetscScalar *beta = d->auxS;
|
|
|
726 |
#if !defined(PETSC_USE_COMPLEX)
|
|
|
727 |
PetscScalar *auxS = beta + d->size_H;
|
|
|
728 |
PetscBLASInt n_auxS = d->size_auxS - d->size_H;
|
|
|
729 |
#else
|
| 1883 |
eromero |
730 |
PetscReal *auxR = (PetscReal*)(beta + d->size_H);
|
| 1750 |
eromero |
731 |
PetscScalar *auxS = (PetscScalar*)(auxR+8*d->size_H);
|
| 1883 |
eromero |
732 |
PetscBLASInt n_auxS = d->size_auxS - 9*d->size_H;
|
| 1750 |
eromero |
733 |
#endif
|
| 1795 |
eromero |
734 |
PetscInt i;
|
| 1750 |
eromero |
735 |
PetscBLASInt info,n,a;
|
|
|
736 |
|
|
|
737 |
PetscFunctionBegin;
|
| 2654 |
jroman |
738 |
if (d->pY) { PetscValidScalarPointer(d->pY,0); }
|
|
|
739 |
PetscValidScalarPointer(d->S,0);
|
|
|
740 |
PetscValidScalarPointer(d->T,0);
|
|
|
741 |
PetscValidScalarPointer(d->eigr,0);
|
|
|
742 |
PetscValidScalarPointer(d->eigi,0);
|
|
|
743 |
PetscValidScalarPointer(d->auxS,0);
|
|
|
744 |
|
| 1750 |
eromero |
745 |
/* S <- H, T <- G */
|
|
|
746 |
d->ldS = d->ldT = d->ldpX = d->ldpY = d->size_H;
|
| 1752 |
eromero |
747 |
ierr = SlepcDenseCopyTriang(d->S, 0, d->size_H, d->H, d->sH, d->ldH,
|
| 2139 |
jroman |
748 |
d->size_H, d->size_H);CHKERRQ(ierr);
|
| 1752 |
eromero |
749 |
ierr = SlepcDenseCopyTriang(d->T, 0, d->size_H, d->G, d->sG, d->ldH,
|
| 2139 |
jroman |
750 |
d->size_H, d->size_H);CHKERRQ(ierr);
|
| 1750 |
eromero |
751 |
|
|
|
752 |
/* S = Z'*H*Q, T = Z'*G*Q */
|
|
|
753 |
n = d->size_H;
|
|
|
754 |
#if !defined(PETSC_USE_COMPLEX)
|
| 1757 |
eromero |
755 |
LAPACKgges_(d->pY?"V":"N", "V", "N", PETSC_NULL, &n, d->S, &n, d->T, &n,
|
| 2624 |
eromero |
756 |
&a, d->eigr-d->cX_in_H, d->eigi-d->cX_in_H, beta, d->pY, &n, d->pX, &n,
|
| 1750 |
eromero |
757 |
auxS, &n_auxS, PETSC_NULL, &info);
|
|
|
758 |
#else
|
| 1757 |
eromero |
759 |
LAPACKgges_(d->pY?"V":"N", "V", "N", PETSC_NULL, &n, d->S, &n, d->T, &n,
|
| 2624 |
eromero |
760 |
&a, d->eigr-d->cX_in_H, beta, d->pY, &n, d->pX, &n,
|
| 1750 |
eromero |
761 |
auxS, &n_auxS, auxR, PETSC_NULL, &info);
|
|
|
762 |
#endif
|
| 2214 |
jroman |
763 |
if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB, "Error in Lapack GGES %d", info);
|
| 1750 |
eromero |
764 |
|
|
|
765 |
/* eigr[i] <- eigr[i] / beta[i] */
|
| 2624 |
eromero |
766 |
for (i=0; i<d->size_H; i++)
|
|
|
767 |
d->eigr[i-d->cX_in_H] /= beta[i],
|
|
|
768 |
d->eigi[i-d->cX_in_H] /= beta[i];
|
| 1750 |
eromero |
769 |
|
| 2555 |
eromero |
770 |
d->calcpairs_selectPairs = dvd_calcpairs_selectPairs_qz;
|
|
|
771 |
|
| 1750 |
eromero |
772 |
PetscFunctionReturn(0);
|
| 2392 |
jroman |
773 |
#endif
|
| 1750 |
eromero |
774 |
}
|
|
|
775 |
|
| 2555 |
eromero |
776 |
#undef __FUNCT__
|
|
|
777 |
#define __FUNCT__ "dvd_calcpairs_selectPairs_eig"
|
|
|
778 |
PetscErrorCode dvd_calcpairs_selectPairs_eig(dvdDashboard *d, PetscInt n)
|
|
|
779 |
{
|
|
|
780 |
PetscErrorCode ierr;
|
| 1750 |
eromero |
781 |
|
| 2555 |
eromero |
782 |
PetscFunctionBegin;
|
|
|
783 |
|
| 2605 |
eromero |
784 |
ierr = EPSSortDenseHEP(d->eps, d->size_H, 0, d->eigr-d->cX_in_H, d->pX, d->ldpX);
|
| 2555 |
eromero |
785 |
CHKERRQ(ierr);
|
|
|
786 |
|
|
|
787 |
if (d->calcpairs_eigs_trans) {
|
|
|
788 |
ierr = d->calcpairs_eigs_trans(d); CHKERRQ(ierr);
|
|
|
789 |
}
|
|
|
790 |
|
| 2779 |
eromero |
791 |
if (DVD_IS(d->sEP, DVD_EP_INDEFINITE)) {
|
|
|
792 |
ierr = SlepcDenseIOrth(d->pX,d->ldpX,d->size_H,d->size_H,d->nBV-d->cX_in_H,d->nBpX,d->auxS,d->size_auxS);CHKERRQ(ierr);
|
|
|
793 |
}
|
|
|
794 |
|
| 2555 |
eromero |
795 |
PetscFunctionReturn(0);
|
|
|
796 |
}
|
|
|
797 |
|
|
|
798 |
|
| 1750 |
eromero |
799 |
#undef __FUNCT__
|
|
|
800 |
#define __FUNCT__ "dvd_calcpairs_selectPairs_qz"
|
| 2021 |
eromero |
801 |
PetscErrorCode dvd_calcpairs_selectPairs_qz(dvdDashboard *d, PetscInt n)
|
| 1750 |
eromero |
802 |
{
|
| 1805 |
eromero |
803 |
PetscErrorCode ierr;
|
| 1750 |
eromero |
804 |
PetscFunctionBegin;
|
|
|
805 |
|
| 1805 |
eromero |
806 |
if ((d->ldpX != d->size_H) ||
|
|
|
807 |
( d->T &&
|
|
|
808 |
((d->ldS != d->ldT) || (d->ldpX != d->ldpY) ||
|
|
|
809 |
(d->ldpX != d->size_H)) ) ) {
|
| 2214 |
jroman |
810 |
SETERRQ(PETSC_COMM_SELF,1, "Error before ordering eigenpairs");
|
| 1750 |
eromero |
811 |
}
|
|
|
812 |
|
| 1829 |
eromero |
813 |
if (d->T) {
|
| 2624 |
eromero |
814 |
ierr = EPSSortDenseSchurGeneralized(d->eps, d->size_H, 0, n, d->S, d->T,
|
| 2605 |
eromero |
815 |
d->ldS, d->pY, d->pX, d->eigr-d->cX_in_H,
|
|
|
816 |
d->eigi-d->cX_in_H); CHKERRQ(ierr);
|
| 1829 |
eromero |
817 |
} else {
|
| 2624 |
eromero |
818 |
ierr = EPSSortDenseSchur(d->eps, d->size_H, 0, d->S, d->ldS, d->pX,
|
| 2605 |
eromero |
819 |
d->eigr-d->cX_in_H, d->eigi-d->cX_in_H); CHKERRQ(ierr);
|
| 1829 |
eromero |
820 |
}
|
| 1750 |
eromero |
821 |
|
| 2021 |
eromero |
822 |
if (d->calcpairs_eigs_trans) {
|
|
|
823 |
ierr = d->calcpairs_eigs_trans(d); CHKERRQ(ierr);
|
|
|
824 |
}
|
| 1883 |
eromero |
825 |
|
| 2022 |
eromero |
826 |
#if defined(PETSC_USE_COMPLEX)
|
| 2682 |
jroman |
827 |
if (d->T) {
|
|
|
828 |
ierr = EPSCleanDenseSchur(d->size_H,0,d->S,d->ldS,d->T,d->ldT,d->eigi-d->cX_in_H,d->pX,d->ldpX,PETSC_TRUE);CHKERRQ(ierr);
|
|
|
829 |
}
|
| 2022 |
eromero |
830 |
#endif
|
|
|
831 |
|
| 1750 |
eromero |
832 |
PetscFunctionReturn(0);
|
|
|
833 |
}
|
|
|
834 |
|
|
|
835 |
|
|
|
836 |
#undef __FUNCT__
|
| 2223 |
jroman |
837 |
#define __FUNCT__ "dvd_calcpairs_res_0"
|
| 1820 |
eromero |
838 |
/* Compute the residual vectors R(i) <- (AV - BV*eigr(i))*pX(i), and also
|
| 2682 |
jroman |
839 |
the norm associated to the Schur pair, where i = r_s..r_e
|
| 1820 |
eromero |
840 |
*/
|
| 2021 |
eromero |
841 |
PetscErrorCode dvd_calcpairs_res_0(dvdDashboard *d, PetscInt r_s, PetscInt r_e,
|
| 2605 |
eromero |
842 |
Vec *R)
|
| 1636 |
slepc |
843 |
{
|
| 2605 |
eromero |
844 |
PetscInt i;
|
| 1636 |
slepc |
845 |
PetscErrorCode ierr;
|
| 2605 |
eromero |
846 |
Vec *BV = d->BV?d->BV:d->V;
|
| 1636 |
slepc |
847 |
|
|
|
848 |
PetscFunctionBegin;
|
|
|
849 |
|
| 2605 |
eromero |
850 |
for (i=r_s; i<r_e; i++) {
|
| 2624 |
eromero |
851 |
/* nX(i) <- ||X(i)|| */
|
|
|
852 |
if (d->correctXnorm) {
|
|
|
853 |
/* R(i) <- V*pX(i) */
|
|
|
854 |
ierr = SlepcUpdateVectorsZ(&R[i-r_s], 0.0, 1.0,
|
|
|
855 |
&d->V[-d->cX_in_H], d->size_V+d->cX_in_H,
|
|
|
856 |
&d->pX[d->ldpX*(i+d->cX_in_H)], d->ldpX, d->size_H, 1); CHKERRQ(ierr);
|
|
|
857 |
ierr = VecNorm(R[i-r_s], NORM_2, &d->nX[i]);CHKERRQ(ierr);
|
|
|
858 |
} else
|
|
|
859 |
d->nX[i] = 1.0;
|
|
|
860 |
|
| 2605 |
eromero |
861 |
/* R(i-r_s) <- AV*pX(i) */
|
|
|
862 |
ierr = SlepcUpdateVectorsZ(&R[i-r_s], 0.0, 1.0,
|
|
|
863 |
&d->AV[-d->cX_in_H], d->size_AV+d->cX_in_H,
|
|
|
864 |
&d->pX[d->ldpX*(i+d->cX_in_H)], d->ldpX, d->size_H, 1); CHKERRQ(ierr);
|
| 1636 |
slepc |
865 |
|
| 2605 |
eromero |
866 |
/* R(i-r_s) <- R(i-r_s) - eigr(i)*BV*pX(i) */
|
|
|
867 |
ierr = SlepcUpdateVectorsZ(&R[i-r_s], 1.0, -d->eigr[i+d->cX_in_H],
|
|
|
868 |
&BV[-d->cX_in_H], d->size_V+d->cX_in_H,
|
|
|
869 |
&d->pX[d->ldpX*(i+d->cX_in_H)], d->ldpX, d->size_H, 1); CHKERRQ(ierr);
|
| 1636 |
slepc |
870 |
}
|
|
|
871 |
|
| 2021 |
eromero |
872 |
ierr = d->calcpairs_proj_res(d, r_s, r_e, R); CHKERRQ(ierr);
|
| 1883 |
eromero |
873 |
|
|
|
874 |
PetscFunctionReturn(0);
|
|
|
875 |
}
|
|
|
876 |
|
|
|
877 |
#undef __FUNCT__
|
|
|
878 |
#define __FUNCT__ "dvd_calcpairs_proj_res"
|
| 2021 |
eromero |
879 |
PetscErrorCode dvd_calcpairs_proj_res(dvdDashboard *d, PetscInt r_s,
|
|
|
880 |
PetscInt r_e, Vec *R)
|
| 1883 |
eromero |
881 |
{
|
|
|
882 |
PetscInt i;
|
|
|
883 |
PetscErrorCode ierr;
|
| 2216 |
jroman |
884 |
PetscBool lindep;
|
| 1883 |
eromero |
885 |
Vec *cX;
|
|
|
886 |
|
|
|
887 |
PetscFunctionBegin;
|
|
|
888 |
|
| 1829 |
eromero |
889 |
/* If exists the BcX, R <- orth(BcX, R), nR[i] <- ||R[i]|| */
|
|
|
890 |
if (d->BcX)
|
|
|
891 |
cX = d->BcX;
|
|
|
892 |
|
| 1795 |
eromero |
893 |
/* If exists left subspace, R <- orth(cY, R), nR[i] <- ||R[i]|| */
|
| 1829 |
eromero |
894 |
else if (d->cY)
|
|
|
895 |
cX = d->cY;
|
| 1751 |
eromero |
896 |
|
| 1795 |
eromero |
897 |
/* If fany configurations, R <- orth(cX, R), nR[i] <- ||R[i]|| */
|
| 1829 |
eromero |
898 |
else if (!(DVD_IS(d->sEP, DVD_EP_STD) && DVD_IS(d->sEP, DVD_EP_HERMITIAN)))
|
|
|
899 |
cX = d->cX;
|
|
|
900 |
|
|
|
901 |
/* Otherwise, nR[i] <- ||R[i]|| */
|
|
|
902 |
else
|
|
|
903 |
cX = PETSC_NULL;
|
|
|
904 |
|
| 2779 |
eromero |
905 |
if (cX) {
|
|
|
906 |
Vec auxV;
|
|
|
907 |
ierr = VecDuplicate(d->auxV[0],&auxV);CHKERRQ(ierr);
|
|
|
908 |
for (i=0; i<r_e-r_s; i++) {
|
|
|
909 |
if (cX && d->orthoV_type == DVD_ORTHOV_BOneMV) {
|
|
|
910 |
ierr = IPBOrthogonalize(d->ipV,d->eps->nds,d->eps->DS,d->BDS,d->nBDS,d->size_cX,PETSC_NULL,d->cX,d->real_BV,d->nBcX,R[i],auxV,PETSC_NULL,&d->nR[r_s+i],&lindep);CHKERRQ(ierr);
|
|
|
911 |
} else {
|
|
|
912 |
ierr = IPOrthogonalize(d->ipI, 0, PETSC_NULL, d->size_cX, PETSC_NULL, cX, R[i], PETSC_NULL, &d->nR[r_s+i], &lindep); CHKERRQ(ierr);
|
|
|
913 |
}
|
|
|
914 |
if(lindep || (PetscAbs(d->nR[r_s+i]) < PETSC_MACHINE_EPSILON)) {
|
|
|
915 |
ierr = PetscInfo2(d->eps,"The computed eigenvector residual %D is too low, %G!\n",r_s+i,d->nR[r_s+i]);CHKERRQ(ierr);
|
|
|
916 |
}
|
| 1795 |
eromero |
917 |
}
|
| 2779 |
eromero |
918 |
ierr = VecDestroy(&auxV);CHKERRQ(ierr);
|
|
|
919 |
}
|
|
|
920 |
if (!cX || (cX && d->orthoV_type == DVD_ORTHOV_BOneMV)) {
|
| 2682 |
jroman |
921 |
for(i=0; i<r_e-r_s; i++) {
|
|
|
922 |
ierr = VecNormBegin(R[i],NORM_2,&d->nR[r_s+i]); CHKERRQ(ierr);
|
|
|
923 |
}
|
|
|
924 |
for(i=0; i<r_e-r_s; i++) {
|
|
|
925 |
ierr = VecNormEnd(R[i],NORM_2,&d->nR[r_s+i]); CHKERRQ(ierr);
|
|
|
926 |
}
|
| 1751 |
eromero |
927 |
}
|
| 1636 |
slepc |
928 |
|
|
|
929 |
PetscFunctionReturn(0);
|
|
|
930 |
}
|
|
|
931 |
|
| 2682 |
jroman |
932 |
#undef __FUNCT__
|
|
|
933 |
#define __FUNCT__ "dvd_calcpairs_eig_res_0"
|
|
|
934 |
/* Compute the residual vectors R(i) <- (AV - BV*eigr(i))*pX(i), and also
|
|
|
935 |
the norm associated to the eigenpair, where i = r_s..r_e
|
|
|
936 |
R, vectors of Vec of size r_e-r_s,
|
|
|
937 |
auxV, PetscMax(r_e+cX_in_H, 2*(r_e-r_s)) vectors,
|
|
|
938 |
auxS, auxiliar vector of size (d->size_cX+r_e)^2+6(d->size_cX+r_e)+(r_e-r_s)*d->size_H
|
|
|
939 |
*/
|
|
|
940 |
PetscErrorCode dvd_calcpairs_eig_res_0(dvdDashboard *d,PetscInt r_s,PetscInt r_e,Vec *R)
|
|
|
941 |
{
|
|
|
942 |
PetscInt i,ldpX,size_in;
|
|
|
943 |
PetscErrorCode ierr;
|
|
|
944 |
Vec *Bx;
|
|
|
945 |
PetscScalar *pX,*pX0;
|
|
|
946 |
DvdReduction r;
|
|
|
947 |
DvdReductionChunk
|
|
|
948 |
ops[2];
|
|
|
949 |
DvdMult_copy_func
|
|
|
950 |
sr[2];
|
|
|
951 |
#if !defined(PETSC_USE_COMPLEX)
|
|
|
952 |
PetscScalar b[8];
|
|
|
953 |
Vec X[4];
|
|
|
954 |
#endif
|
|
|
955 |
|
|
|
956 |
PetscFunctionBegin;
|
|
|
957 |
|
|
|
958 |
/* Quick return */
|
|
|
959 |
if (!d->cS) { PetscFunctionReturn(0); }
|
|
|
960 |
|
|
|
961 |
size_in = (d->size_cX+r_e)*(d->cX_in_AV+r_e)*(d->cT?2:1);
|
|
|
962 |
/* Check consistency */
|
|
|
963 |
if (d->size_auxV < PetscMax(2*(r_e-r_s),d->cX_in_AV+r_e) || d->size_auxS <
|
|
|
964 |
(d->size_cX+r_e)*(d->size_cX+r_e) /* pX */ + PetscMax(PetscMax(
|
|
|
965 |
(d->size_cX+r_e)*6 /* dvd_compute_eigenvectors */,
|
|
|
966 |
d->size_H*(r_e-r_s) /* pX0 */),
|
|
|
967 |
2*size_in /* SlepcAllReduceSum */ )) { SETERRQ(PETSC_COMM_SELF,1, "Consistency broken!"); }
|
|
|
968 |
|
|
|
969 |
/* Prepare reductions */
|
|
|
970 |
ierr = SlepcAllReduceSumBegin(ops,2,d->auxS,d->auxS+size_in,size_in,&r,((PetscObject)d->V[0])->comm);CHKERRQ(ierr);
|
|
|
971 |
|
|
|
972 |
/* auxV <- AV * pX(0:r_e+cX_in_H) */
|
|
|
973 |
ierr = SlepcUpdateVectorsZ(d->auxV,0.0,1.0,d->AV-d->cX_in_AV,d->size_AV+d->cX_in_AV,d->pX,d->ldpX,d->size_H,d->cX_in_AV+r_e);CHKERRQ(ierr);
|
|
|
974 |
|
|
|
975 |
/* cS(:, size_cS:) <- cX' * auxV */
|
|
|
976 |
ierr = VecsMultS(&d->cS[d->ldcS*d->size_cS],0,d->ldcS,d->cY?d->cY:d->cX,0,d->size_cX+r_e,d->auxV,0,d->cX_in_AV+r_e,&r,&sr[0]);CHKERRQ(ierr);
|
|
|
977 |
|
|
|
978 |
if (d->cT) {
|
|
|
979 |
/* R <- BV * pX(0:r_e+cX_in_H) */
|
|
|
980 |
ierr = SlepcUpdateVectorsZ(d->auxV,0.0,1.0,d->BV-d->cX_in_BV,d->size_BV+d->cX_in_BV,d->pX,d->ldpX,d->size_G,d->cX_in_BV+r_e);CHKERRQ(ierr);
|
|
|
981 |
|
|
|
982 |
/* cS(:, size_cS:) <- cX' * auxV */
|
|
|
983 |
ierr = VecsMultS(&d->cT[d->ldcT*d->size_cT],0,d->ldcT,d->cY?d->cY:d->cX,0,d->size_cY+r_e,d->auxV,0,d->cX_in_BV+r_e,&r,&sr[1]);CHKERRQ(ierr);
|
|
|
984 |
}
|
|
|
985 |
|
|
|
986 |
/* Do reductions */
|
|
|
987 |
ierr = SlepcAllReduceSumEnd(&r); CHKERRQ(ierr);
|
|
|
988 |
|
|
|
989 |
/* qX <- eig(S,T) */
|
|
|
990 |
pX = d->auxS; d->auxS+= (d->size_cX+r_e)*(d->size_cX+r_e); d->size_auxS -= (d->size_cX+r_e)*(d->size_cX+r_e);
|
|
|
991 |
ldpX = d->size_cX+r_e;
|
|
|
992 |
pX0 = d->auxS;
|
|
|
993 |
ierr = EPSCleanDenseSchur(d->size_cX+r_e,0,d->cS,d->ldcS,d->cT,d->ldcT,d->ceigi,pX,ldpX,PETSC_FALSE);CHKERRQ(ierr);
|
|
|
994 |
ierr = dvd_compute_eigenvectors(d->size_cX+r_e,d->cS,d->ldcS,d->cT,d->ldcT,pX,ldpX,PETSC_NULL,0,d->auxS,d->size_auxS,PETSC_TRUE);CHKERRQ(ierr);
|
|
|
995 |
|
|
|
996 |
/* pX[i] <- pX[i] / ||pX[i]|| */
|
|
|
997 |
pX = &pX[ldpX*d->size_cX+r_s];
|
|
|
998 |
ierr = SlepcDenseNorm(pX,ldpX,d->size_cX+r_e,r_e-r_s,d->eigi+r_s);CHKERRQ(ierr);
|
|
|
999 |
|
|
|
1000 |
/* pX0 <- d->pX(0:d->cX_in_AV+r_e-1) * pX(size_cX-cX_in_H:) */
|
|
|
1001 |
ierr = SlepcDenseMatProd(pX0,d->size_H,0.0,1.0,d->pX,d->ldpX,d->size_H,d->cX_in_AV+r_e,PETSC_FALSE,&pX[d->size_cX-d->cX_in_H],ldpX,d->cX_in_AV+r_e,r_e-r_s,PETSC_FALSE);CHKERRQ(ierr);
|
|
|
1002 |
|
|
|
1003 |
/* auxV <- cX(0:size_cX-cX_in_AV)*pX + V*pX0 */
|
|
|
1004 |
ierr = SlepcUpdateVectorsZ(d->auxV,0.0,1.0,d->cX,d->size_cX-d->cX_in_AV,pX,ldpX,d->size_cX-d->cX_in_AV,r_e-r_s);CHKERRQ(ierr);
|
|
|
1005 |
ierr = SlepcUpdateVectorsZ(d->auxV,d->size_cX-d->cX_in_AV==0?0.0:1.0,1.0,d->V-d->cX_in_AV,d->size_V+d->cX_in_AV,pX0,d->size_H,d->size_H,r_e-r_s);CHKERRQ(ierr);
|
|
|
1006 |
d->auxS-= (d->size_cX+r_e)*(d->size_cX+r_e); d->size_auxS += (d->size_cX+r_e)*(d->size_cX+r_e);
|
|
|
1007 |
/* R <- A*auxV */
|
|
|
1008 |
for (i=0; i<r_e-r_s; i++) {
|
|
|
1009 |
ierr = MatMult(d->A,d->auxV[i],R[i]);CHKERRQ(ierr);
|
|
|
1010 |
}
|
|
|
1011 |
/* Bx <- B*auxV */
|
|
|
1012 |
if (d->B) {
|
|
|
1013 |
Bx = &d->auxV[r_e-r_s];
|
|
|
1014 |
for (i=0; i<r_e-r_s; i++) {
|
|
|
1015 |
ierr = MatMult(d->B,d->auxV[i],Bx[i]);CHKERRQ(ierr);
|
|
|
1016 |
}
|
|
|
1017 |
} else {
|
|
|
1018 |
Bx = d->auxV;
|
|
|
1019 |
}
|
|
|
1020 |
/* R <- (A - eig*B)*V*pX */
|
|
|
1021 |
for(i=0; i<r_e-r_s; i++) {
|
|
|
1022 |
#if !defined(PETSC_USE_COMPLEX)
|
|
|
1023 |
if (d->eigi[r_s+i] != 0.0) {
|
|
|
1024 |
/* [Ax_i Ax_i+1 Bx_i Bx_i+1]*= [ 1 0
|
|
|
1025 |
|
|
|
1026 |
-eigr_i -eigi_i
|
|
|
1027 |
eigi_i -eigr_i] */
|
|
|
1028 |
b[0] = b[5] = 1.0;
|
|
|
1029 |
b[2] = b[7] = -d->eigr[r_s+i];
|
|
|
1030 |
b[6] = -(b[3] = d->eigi[r_s+i]);
|
|
|
1031 |
b[1] = b[4] = 0.0;
|
|
|
1032 |
X[0] = R[i]; X[1] = R[i+1]; X[2] = Bx[i]; X[3] = Bx[i+1];
|
|
|
1033 |
ierr = SlepcUpdateVectorsD(X,4,1.0,b,4,4,2,d->auxS,d->size_auxS);CHKERRQ(ierr);
|
|
|
1034 |
i++;
|
|
|
1035 |
} else
|
|
|
1036 |
#endif
|
|
|
1037 |
{
|
|
|
1038 |
/* R <- Ax -eig*Bx */
|
|
|
1039 |
ierr = VecAXPBY(R[i], -d->eigr[r_s+i], 1.0, Bx[i]); CHKERRQ(ierr);
|
|
|
1040 |
}
|
|
|
1041 |
}
|
|
|
1042 |
|
|
|
1043 |
/* nR <- ||R|| */
|
|
|
1044 |
for(i=0; i<r_e-r_s; i++) {
|
|
|
1045 |
ierr = VecNormBegin(R[i],NORM_2,&d->nR[r_s+i]);CHKERRQ(ierr);
|
|
|
1046 |
}
|
|
|
1047 |
for(i=0; i<r_e-r_s; i++) {
|
|
|
1048 |
ierr = VecNormEnd(R[i],NORM_2,&d->nR[r_s+i]);CHKERRQ(ierr);
|
|
|
1049 |
}
|
|
|
1050 |
|
|
|
1051 |
PetscFunctionReturn(0);
|
|
|
1052 |
}
|
|
|
1053 |
|
|
|
1054 |
|
| 2605 |
eromero |
1055 |
/**** Pattern routines ********************************************************/
|
|
|
1056 |
|
|
|
1057 |
/* BV <- BV*MTX */
|
| 1735 |
eromero |
1058 |
#undef __FUNCT__
|
| 2605 |
eromero |
1059 |
#define __FUNCT__ "dvd_calcpairs_updateBV0_gen"
|
|
|
1060 |
PETSC_STATIC_INLINE PetscErrorCode dvd_calcpairs_updateBV0_gen(dvdDashboard *d,Vec *real_BV,PetscInt *size_cBV,Vec **BV,PetscInt *size_BV,PetscInt *max_size_BV,PetscBool BV_shift,PetscInt *cX_in_proj,PetscScalar *MTX)
|
| 1734 |
eromero |
1061 |
{
|
|
|
1062 |
PetscErrorCode ierr;
|
| 2605 |
eromero |
1063 |
PetscInt cMT, rm, cp, tra_s, i;
|
|
|
1064 |
Vec *nBV;
|
| 1734 |
eromero |
1065 |
|
|
|
1066 |
PetscFunctionBegin;
|
|
|
1067 |
|
| 2605 |
eromero |
1068 |
if (!real_BV || !*BV || (d->V_tra_s == 0 && d->V_tra_e == 0)) { PetscFunctionReturn(0); }
|
|
|
1069 |
|
|
|
1070 |
if (d->V_tra_s > d->max_cX_in_proj && !BV_shift) {
|
|
|
1071 |
tra_s = PetscMax(d->V_tra_s-d->max_cX_in_proj, 0);
|
|
|
1072 |
cMT = d->V_tra_e - tra_s;
|
|
|
1073 |
rm = d->V_tra_s - tra_s;
|
|
|
1074 |
cp = PetscMin(d->max_cX_in_proj - rm, *cX_in_proj);
|
|
|
1075 |
nBV = real_BV+d->max_cX_in_proj;
|
|
|
1076 |
/* BV(-cp-rm:-1-rm) <- BV(-cp:-1) */
|
|
|
1077 |
for (i=-cp; i<0; i++) {
|
|
|
1078 |
ierr = VecCopy((*BV)[i], nBV[i-rm]);CHKERRQ(ierr);
|
| 2555 |
eromero |
1079 |
}
|
| 2605 |
eromero |
1080 |
/* BV(-rm:) <- BV*MTX(tra_s:V_tra_e-1) */
|
| 2624 |
eromero |
1081 |
ierr = SlepcUpdateVectorsZ(&nBV[-rm], 0.0, 1.0, *BV-*cX_in_proj, *size_BV+*cX_in_proj, &MTX[d->ldMTX*tra_s], d->ldMTX, d->size_MT, cMT); CHKERRQ(ierr);
|
|
|
1082 |
*size_BV = d->V_tra_e - d->V_tra_s;
|
| 2605 |
eromero |
1083 |
*max_size_BV-= nBV - *BV;
|
|
|
1084 |
*BV = nBV;
|
|
|
1085 |
if (cX_in_proj && d->max_cX_in_proj>0) *cX_in_proj = cp+rm;
|
|
|
1086 |
} else if (d->V_tra_s <= d->max_cX_in_proj || BV_shift) {
|
|
|
1087 |
/* [BcX BV] <- [BcX BV*MTX] */
|
|
|
1088 |
ierr = SlepcUpdateVectorsZ(*BV-*cX_in_proj, 0.0, 1.0, *BV-*cX_in_proj, *size_BV+*cX_in_proj, MTX, d->ldMTX, d->size_MT, d->V_tra_e); CHKERRQ(ierr);
|
| 2624 |
eromero |
1089 |
*BV+= d->V_tra_s-*cX_in_proj;
|
|
|
1090 |
*max_size_BV-= d->V_tra_s-*cX_in_proj;
|
|
|
1091 |
*size_BV = d->V_tra_e - d->V_tra_s;
|
|
|
1092 |
if (size_cBV && BV_shift) *size_cBV = *BV - real_BV;
|
|
|
1093 |
if (d->max_cX_in_proj>0) *cX_in_proj = PetscMin(*BV - real_BV, d->max_cX_in_proj);
|
| 2605 |
eromero |
1094 |
} else { /* !BV_shift */
|
|
|
1095 |
/* BV <- BV*MTX(V_tra_s:) */
|
|
|
1096 |
ierr = SlepcUpdateVectorsZ(*BV, 0.0, 1.0, *BV, *size_BV,
|
|
|
1097 |
&MTX[d->V_tra_s*d->ldMTX], d->ldMTX, d->size_MT, d->V_tra_e-d->V_tra_s);
|
| 1795 |
eromero |
1098 |
CHKERRQ(ierr);
|
| 2605 |
eromero |
1099 |
*size_BV = d->V_tra_e - d->V_tra_s;
|
| 1795 |
eromero |
1100 |
}
|
| 1734 |
eromero |
1101 |
|
| 1756 |
eromero |
1102 |
PetscFunctionReturn(0);
|
|
|
1103 |
}
|