| 545 |
dsic.upv.es!jroman |
1 |
/*
|
|
|
2 |
EPS routines related to problem setup.
|
| 1376 |
slepc |
3 |
|
|
|
4 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| 1672 |
slepc |
5 |
SLEPc - Scalable Library for Eigenvalue Problem Computations
|
|
|
6 |
Copyright (c) 2002-2009, Universidad Politecnica de Valencia, Spain
|
| 1376 |
slepc |
7 |
|
| 1672 |
slepc |
8 |
This file is part of SLEPc.
|
|
|
9 |
|
|
|
10 |
SLEPc is free software: you can redistribute it and/or modify it under the
|
|
|
11 |
terms of version 3 of the GNU Lesser General Public License as published by
|
|
|
12 |
the Free Software Foundation.
|
|
|
13 |
|
|
|
14 |
SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
15 |
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
16 |
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
|
|
17 |
more details.
|
|
|
18 |
|
|
|
19 |
You should have received a copy of the GNU Lesser General Public License
|
|
|
20 |
along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
|
| 1376 |
slepc |
21 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| 545 |
dsic.upv.es!jroman |
22 |
*/
|
| 1376 |
slepc |
23 |
|
| 1521 |
slepc |
24 |
#include "private/epsimpl.h" /*I "slepceps.h" I*/
|
| 527 |
dsic.upv.es!antodo |
25 |
|
|
|
26 |
#undef __FUNCT__
|
|
|
27 |
#define __FUNCT__ "EPSSetUp"
|
|
|
28 |
/*@
|
|
|
29 |
EPSSetUp - Sets up all the internal data structures necessary for the
|
|
|
30 |
execution of the eigensolver. Then calls STSetUp() for any set-up
|
|
|
31 |
operations associated to the ST object.
|
|
|
32 |
|
|
|
33 |
Collective on EPS
|
|
|
34 |
|
|
|
35 |
Input Parameter:
|
|
|
36 |
. eps - eigenproblem solver context
|
|
|
37 |
|
|
|
38 |
Level: advanced
|
|
|
39 |
|
|
|
40 |
Notes:
|
|
|
41 |
This function need not be called explicitly in most cases, since EPSSolve()
|
|
|
42 |
calls it. It can be useful when one wants to measure the set-up time
|
|
|
43 |
separately from the solve time.
|
|
|
44 |
|
|
|
45 |
This function sets a random initial vector if none has been provided.
|
|
|
46 |
|
|
|
47 |
.seealso: EPSCreate(), EPSSolve(), EPSDestroy(), STSetUp()
|
|
|
48 |
@*/
|
|
|
49 |
PetscErrorCode EPSSetUp(EPS eps)
|
|
|
50 |
{
|
|
|
51 |
PetscErrorCode ierr;
|
| 1385 |
slepc |
52 |
Vec v0,w0;
|
| 527 |
dsic.upv.es!antodo |
53 |
Mat A,B;
|
| 1220 |
slepc |
54 |
PetscInt N;
|
| 1789 |
antodo |
55 |
PetscTruth isCayley;
|
| 527 |
dsic.upv.es!antodo |
56 |
|
|
|
57 |
PetscFunctionBegin;
|
|
|
58 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
|
|
59 |
|
|
|
60 |
if (eps->setupcalled) PetscFunctionReturn(0);
|
|
|
61 |
|
|
|
62 |
ierr = PetscLogEventBegin(EPS_SetUp,eps,0,0,0);CHKERRQ(ierr);
|
|
|
63 |
|
|
|
64 |
/* Set default solver type */
|
| 1422 |
slepc |
65 |
if (!((PetscObject)eps)->type_name) {
|
| 1198 |
slepc |
66 |
ierr = EPSSetType(eps,EPSKRYLOVSCHUR);CHKERRQ(ierr);
|
| 527 |
dsic.upv.es!antodo |
67 |
}
|
| 691 |
dsic.upv.es!antodo |
68 |
|
| 527 |
dsic.upv.es!antodo |
69 |
ierr = STGetOperators(eps->OP,&A,&B);CHKERRQ(ierr);
|
|
|
70 |
/* Set default problem type */
|
|
|
71 |
if (!eps->problem_type) {
|
|
|
72 |
if (B==PETSC_NULL) {
|
|
|
73 |
ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr);
|
|
|
74 |
}
|
|
|
75 |
else {
|
|
|
76 |
ierr = EPSSetProblemType(eps,EPS_GNHEP);CHKERRQ(ierr);
|
|
|
77 |
}
|
|
|
78 |
} else if ((B && !eps->isgeneralized) || (!B && eps->isgeneralized)) {
|
|
|
79 |
SETERRQ(0,"Warning: Inconsistent EPS state");
|
|
|
80 |
}
|
|
|
81 |
|
| 1358 |
slepc |
82 |
if (eps->ispositive) {
|
|
|
83 |
ierr = STGetBilinearForm(eps->OP,&B);CHKERRQ(ierr);
|
|
|
84 |
ierr = IPSetBilinearForm(eps->ip,B,IPINNER_HERMITIAN);CHKERRQ(ierr);
|
|
|
85 |
ierr = MatDestroy(B);CHKERRQ(ierr);
|
|
|
86 |
} else {
|
|
|
87 |
ierr = IPSetBilinearForm(eps->ip,PETSC_NULL,IPINNER_HERMITIAN);CHKERRQ(ierr);
|
|
|
88 |
}
|
|
|
89 |
|
| 1385 |
slepc |
90 |
/* Create random initial vectors if not set */
|
| 780 |
dsic.upv.es!jroman |
91 |
/* right */
|
| 1385 |
slepc |
92 |
ierr = EPSGetInitialVector(eps,&v0);CHKERRQ(ierr);
|
|
|
93 |
if (!v0) {
|
|
|
94 |
ierr = MatGetVecs(A,&v0,PETSC_NULL);CHKERRQ(ierr);
|
|
|
95 |
ierr = SlepcVecSetRandom(v0);CHKERRQ(ierr);
|
|
|
96 |
eps->vec_initial = v0;
|
| 527 |
dsic.upv.es!antodo |
97 |
}
|
| 780 |
dsic.upv.es!jroman |
98 |
/* left */
|
| 1385 |
slepc |
99 |
ierr = EPSGetLeftInitialVector(eps,&w0);CHKERRQ(ierr);
|
|
|
100 |
if (!w0) {
|
|
|
101 |
ierr = MatGetVecs(A,PETSC_NULL,&w0);CHKERRQ(ierr);
|
|
|
102 |
ierr = SlepcVecSetRandom(w0);CHKERRQ(ierr);
|
|
|
103 |
eps->vec_initial_left = w0;
|
| 780 |
dsic.upv.es!jroman |
104 |
}
|
| 527 |
dsic.upv.es!antodo |
105 |
|
| 1385 |
slepc |
106 |
ierr = VecGetSize(eps->vec_initial,&N);CHKERRQ(ierr);
|
| 1220 |
slepc |
107 |
if (eps->nev > N) eps->nev = N;
|
|
|
108 |
if (eps->ncv > N) eps->ncv = N;
|
|
|
109 |
|
| 527 |
dsic.upv.es!antodo |
110 |
ierr = (*eps->ops->setup)(eps);CHKERRQ(ierr);
|
| 543 |
dsic.upv.es!jroman |
111 |
ierr = STSetUp(eps->OP); CHKERRQ(ierr);
|
| 527 |
dsic.upv.es!antodo |
112 |
|
| 1789 |
antodo |
113 |
ierr = PetscTypeCompare((PetscObject)eps->OP,STCAYLEY,&isCayley);CHKERRQ(ierr);
|
|
|
114 |
if (isCayley && eps->problem_type == EPS_PGNHEP) {
|
|
|
115 |
SETERRQ(PETSC_ERR_SUP,"Cayley spectral transformation is not compatible with PGNHEP");
|
|
|
116 |
}
|
|
|
117 |
|
| 527 |
dsic.upv.es!antodo |
118 |
if (eps->nds>0) {
|
|
|
119 |
if (!eps->ds_ortho) {
|
|
|
120 |
/* orthonormalize vectors in DS if necessary */
|
| 1755 |
antodo |
121 |
ierr = IPQRDecomposition(eps->ip,eps->DS,0,eps->nds,PETSC_NULL,0);CHKERRQ(ierr);
|
| 527 |
dsic.upv.es!antodo |
122 |
}
|
| 1755 |
antodo |
123 |
ierr = IPOrthogonalize(eps->ip,0,PETSC_NULL,eps->nds,PETSC_NULL,eps->DS,eps->vec_initial,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
|
| 527 |
dsic.upv.es!antodo |
124 |
}
|
|
|
125 |
|
|
|
126 |
ierr = STCheckNullSpace(eps->OP,eps->nds,eps->DS);CHKERRQ(ierr);
|
| 1800 |
jroman |
127 |
|
|
|
128 |
/* Build balancing matrix if required */
|
|
|
129 |
if (!eps->balance) eps->balance = EPSBALANCE_NONE;
|
| 1804 |
jroman |
130 |
if (!eps->ishermitian && (eps->balance==EPSBALANCE_ONESIDE || eps->balance==EPSBALANCE_TWOSIDE)) {
|
| 1800 |
jroman |
131 |
if (!eps->D) {
|
|
|
132 |
ierr = VecDuplicate(eps->vec_initial,&eps->D);CHKERRQ(ierr);
|
|
|
133 |
}
|
|
|
134 |
ierr = EPSBuildBalance_Krylov(eps);CHKERRQ(ierr);
|
| 1804 |
jroman |
135 |
ierr = STSetBalanceMatrix(eps->OP,eps->D);CHKERRQ(ierr);
|
| 1800 |
jroman |
136 |
}
|
|
|
137 |
|
| 527 |
dsic.upv.es!antodo |
138 |
ierr = PetscLogEventEnd(EPS_SetUp,eps,0,0,0);CHKERRQ(ierr);
|
|
|
139 |
eps->setupcalled = 1;
|
|
|
140 |
PetscFunctionReturn(0);
|
|
|
141 |
}
|
|
|
142 |
|
|
|
143 |
#undef __FUNCT__
|
|
|
144 |
#define __FUNCT__ "EPSSetInitialVector"
|
|
|
145 |
/*@
|
| 1385 |
slepc |
146 |
EPSSetInitialVector - Sets the initial vector from which the
|
|
|
147 |
eigensolver starts to iterate.
|
| 527 |
dsic.upv.es!antodo |
148 |
|
|
|
149 |
Collective on EPS and Vec
|
|
|
150 |
|
|
|
151 |
Input Parameters:
|
|
|
152 |
+ eps - the eigensolver context
|
|
|
153 |
- vec - the vector
|
|
|
154 |
|
|
|
155 |
Level: intermediate
|
|
|
156 |
|
| 1385 |
slepc |
157 |
.seealso: EPSGetInitialVector(), EPSSetLeftInitialVector()
|
| 527 |
dsic.upv.es!antodo |
158 |
|
|
|
159 |
@*/
|
|
|
160 |
PetscErrorCode EPSSetInitialVector(EPS eps,Vec vec)
|
|
|
161 |
{
|
|
|
162 |
PetscErrorCode ierr;
|
|
|
163 |
|
|
|
164 |
PetscFunctionBegin;
|
|
|
165 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
|
|
166 |
PetscValidHeaderSpecific(vec,VEC_COOKIE,2);
|
|
|
167 |
PetscCheckSameComm(eps,1,vec,2);
|
| 1279 |
slepc |
168 |
ierr = PetscObjectReference((PetscObject)vec);CHKERRQ(ierr);
|
| 1385 |
slepc |
169 |
if (eps->vec_initial) {
|
|
|
170 |
ierr = VecDestroy(eps->vec_initial); CHKERRQ(ierr);
|
| 527 |
dsic.upv.es!antodo |
171 |
}
|
| 1385 |
slepc |
172 |
eps->vec_initial = vec;
|
| 527 |
dsic.upv.es!antodo |
173 |
PetscFunctionReturn(0);
|
|
|
174 |
}
|
|
|
175 |
|
|
|
176 |
#undef __FUNCT__
|
| 1385 |
slepc |
177 |
#define __FUNCT__ "EPSGetInitialVector"
|
| 527 |
dsic.upv.es!antodo |
178 |
/*@
|
| 1385 |
slepc |
179 |
EPSGetInitialVector - Gets the initial vector associated with the
|
|
|
180 |
eigensolver; if the vector was not set it will return a 0 pointer or
|
|
|
181 |
a vector randomly generated by EPSSetUp().
|
| 527 |
dsic.upv.es!antodo |
182 |
|
| 1385 |
slepc |
183 |
Not collective, but vector is shared by all processors that share the EPS
|
| 527 |
dsic.upv.es!antodo |
184 |
|
|
|
185 |
Input Parameter:
|
|
|
186 |
. eps - the eigensolver context
|
|
|
187 |
|
|
|
188 |
Output Parameter:
|
|
|
189 |
. vec - the vector
|
|
|
190 |
|
|
|
191 |
Level: intermediate
|
|
|
192 |
|
| 1385 |
slepc |
193 |
.seealso: EPSSetInitialVector(), EPSGetLeftInitialVector()
|
| 527 |
dsic.upv.es!antodo |
194 |
|
|
|
195 |
@*/
|
| 1385 |
slepc |
196 |
PetscErrorCode EPSGetInitialVector(EPS eps,Vec *vec)
|
| 527 |
dsic.upv.es!antodo |
197 |
{
|
|
|
198 |
PetscFunctionBegin;
|
|
|
199 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
| 1385 |
slepc |
200 |
PetscValidPointer(vec,2);
|
|
|
201 |
*vec = eps->vec_initial;
|
| 527 |
dsic.upv.es!antodo |
202 |
PetscFunctionReturn(0);
|
|
|
203 |
}
|
|
|
204 |
|
|
|
205 |
#undef __FUNCT__
|
| 780 |
dsic.upv.es!jroman |
206 |
#define __FUNCT__ "EPSSetLeftInitialVector"
|
|
|
207 |
/*@
|
| 1385 |
slepc |
208 |
EPSSetLeftInitialVector - Sets the initial vector from which the eigensolver
|
|
|
209 |
starts to iterate, corresponding to the left recurrence (two-sided solvers).
|
| 780 |
dsic.upv.es!jroman |
210 |
|
|
|
211 |
Collective on EPS and Vec
|
|
|
212 |
|
|
|
213 |
Input Parameters:
|
|
|
214 |
+ eps - the eigensolver context
|
|
|
215 |
- vec - the vector
|
|
|
216 |
|
|
|
217 |
Level: intermediate
|
|
|
218 |
|
| 1385 |
slepc |
219 |
.seealso: EPSGetLeftInitialVector(), EPSSetInitialVector()
|
| 780 |
dsic.upv.es!jroman |
220 |
|
|
|
221 |
@*/
|
|
|
222 |
PetscErrorCode EPSSetLeftInitialVector(EPS eps,Vec vec)
|
|
|
223 |
{
|
|
|
224 |
PetscErrorCode ierr;
|
|
|
225 |
|
|
|
226 |
PetscFunctionBegin;
|
|
|
227 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
|
|
228 |
PetscValidHeaderSpecific(vec,VEC_COOKIE,2);
|
|
|
229 |
PetscCheckSameComm(eps,1,vec,2);
|
| 1295 |
slepc |
230 |
ierr = PetscObjectReference((PetscObject)vec);CHKERRQ(ierr);
|
| 1385 |
slepc |
231 |
if (eps->vec_initial_left) {
|
|
|
232 |
ierr = VecDestroy(eps->vec_initial_left); CHKERRQ(ierr);
|
| 780 |
dsic.upv.es!jroman |
233 |
}
|
| 1385 |
slepc |
234 |
eps->vec_initial_left = vec;
|
| 780 |
dsic.upv.es!jroman |
235 |
PetscFunctionReturn(0);
|
|
|
236 |
}
|
|
|
237 |
|
|
|
238 |
#undef __FUNCT__
|
|
|
239 |
#define __FUNCT__ "EPSGetLeftInitialVector"
|
|
|
240 |
/*@
|
| 1385 |
slepc |
241 |
EPSGetLeftInitialVector - Gets the left initial vector associated with the
|
|
|
242 |
eigensolver; if the vector was not set it will return a 0 pointer or
|
|
|
243 |
a vector randomly generated by EPSSetUp().
|
| 780 |
dsic.upv.es!jroman |
244 |
|
|
|
245 |
Not collective, but vector is shared by all processors that share the EPS
|
|
|
246 |
|
| 1385 |
slepc |
247 |
Input Parameter:
|
|
|
248 |
. eps - the eigensolver context
|
| 780 |
dsic.upv.es!jroman |
249 |
|
|
|
250 |
Output Parameter:
|
|
|
251 |
. vec - the vector
|
|
|
252 |
|
|
|
253 |
Level: intermediate
|
|
|
254 |
|
| 1385 |
slepc |
255 |
.seealso: EPSSetLeftInitialVector(), EPSGetLeftInitialVector()
|
| 780 |
dsic.upv.es!jroman |
256 |
|
|
|
257 |
@*/
|
| 1385 |
slepc |
258 |
PetscErrorCode EPSGetLeftInitialVector(EPS eps,Vec *vec)
|
| 780 |
dsic.upv.es!jroman |
259 |
{
|
|
|
260 |
PetscFunctionBegin;
|
|
|
261 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
| 1385 |
slepc |
262 |
PetscValidPointer(vec,2);
|
|
|
263 |
*vec = eps->vec_initial_left;
|
| 780 |
dsic.upv.es!jroman |
264 |
PetscFunctionReturn(0);
|
|
|
265 |
}
|
|
|
266 |
|
|
|
267 |
#undef __FUNCT__
|
| 527 |
dsic.upv.es!antodo |
268 |
#define __FUNCT__ "EPSSetOperators"
|
|
|
269 |
/*@
|
|
|
270 |
EPSSetOperators - Sets the matrices associated with the eigenvalue problem.
|
|
|
271 |
|
|
|
272 |
Collective on EPS and Mat
|
|
|
273 |
|
|
|
274 |
Input Parameters:
|
|
|
275 |
+ eps - the eigenproblem solver context
|
|
|
276 |
. A - the matrix associated with the eigensystem
|
|
|
277 |
- B - the second matrix in the case of generalized eigenproblems
|
|
|
278 |
|
|
|
279 |
Notes:
|
|
|
280 |
To specify a standard eigenproblem, use PETSC_NULL for parameter B.
|
|
|
281 |
|
|
|
282 |
Level: beginner
|
|
|
283 |
|
|
|
284 |
.seealso: EPSSolve(), EPSGetST(), STGetOperators()
|
|
|
285 |
@*/
|
|
|
286 |
PetscErrorCode EPSSetOperators(EPS eps,Mat A,Mat B)
|
|
|
287 |
{
|
|
|
288 |
PetscErrorCode ierr;
|
| 982 |
slepc |
289 |
PetscInt m,n;
|
| 527 |
dsic.upv.es!antodo |
290 |
|
|
|
291 |
PetscFunctionBegin;
|
|
|
292 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
|
|
293 |
PetscValidHeaderSpecific(A,MAT_COOKIE,2);
|
|
|
294 |
if (B) PetscValidHeaderSpecific(B,MAT_COOKIE,3);
|
| 1014 |
slepc |
295 |
PetscCheckSameComm(eps,1,A,2);
|
|
|
296 |
if (B) PetscCheckSameComm(eps,1,B,3);
|
| 527 |
dsic.upv.es!antodo |
297 |
|
|
|
298 |
/* Check for square matrices */
|
|
|
299 |
ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
|
|
|
300 |
if (m!=n) { SETERRQ(1,"A is a non-square matrix"); }
|
|
|
301 |
if (B) {
|
|
|
302 |
ierr = MatGetSize(B,&m,&n);CHKERRQ(ierr);
|
|
|
303 |
if (m!=n) { SETERRQ(1,"B is a non-square matrix"); }
|
|
|
304 |
}
|
|
|
305 |
|
|
|
306 |
ierr = STSetOperators(eps->OP,A,B);CHKERRQ(ierr);
|
|
|
307 |
eps->setupcalled = 0; /* so that next solve call will call setup */
|
| 780 |
dsic.upv.es!jroman |
308 |
|
|
|
309 |
/* Destroy randomly generated initial vectors */
|
| 1385 |
slepc |
310 |
if (eps->vec_initial) {
|
|
|
311 |
ierr = VecDestroy(eps->vec_initial);CHKERRQ(ierr);
|
|
|
312 |
eps->vec_initial = PETSC_NULL;
|
| 527 |
dsic.upv.es!antodo |
313 |
}
|
| 1385 |
slepc |
314 |
if (eps->vec_initial_left) {
|
|
|
315 |
ierr = VecDestroy(eps->vec_initial_left);CHKERRQ(ierr);
|
|
|
316 |
eps->vec_initial_left = PETSC_NULL;
|
|
|
317 |
}
|
| 527 |
dsic.upv.es!antodo |
318 |
|
|
|
319 |
PetscFunctionReturn(0);
|
|
|
320 |
}
|
|
|
321 |
|
| 1516 |
slepc |
322 |
#undef __FUNCT__
|
|
|
323 |
#define __FUNCT__ "EPSGetOperators"
|
|
|
324 |
/*@
|
|
|
325 |
EPSGetOperators - Gets the matrices associated with the eigensystem.
|
|
|
326 |
|
|
|
327 |
Collective on EPS and Mat
|
|
|
328 |
|
|
|
329 |
Input Parameter:
|
|
|
330 |
. eps - the EPS context
|
|
|
331 |
|
|
|
332 |
Output Parameters:
|
|
|
333 |
+ A - the matrix associated with the eigensystem
|
|
|
334 |
- B - the second matrix in the case of generalized eigenproblems
|
|
|
335 |
|
|
|
336 |
Level: intermediate
|
|
|
337 |
|
|
|
338 |
.seealso: EPSSolve(), EPSGetST(), STGetOperators(), STSetOperators()
|
|
|
339 |
@*/
|
|
|
340 |
PetscErrorCode EPSGetOperators(EPS eps, Mat *A, Mat *B)
|
|
|
341 |
{
|
|
|
342 |
PetscErrorCode ierr;
|
|
|
343 |
ST st;
|
|
|
344 |
|
|
|
345 |
PetscFunctionBegin;
|
|
|
346 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
|
|
347 |
if (A) PetscValidPointer(A,2);
|
|
|
348 |
if (B) PetscValidPointer(B,3);
|
|
|
349 |
ierr = EPSGetST(eps,&st);CHKERRQ(ierr);
|
|
|
350 |
ierr = STGetOperators(st,A,B);CHKERRQ(ierr);
|
|
|
351 |
PetscFunctionReturn(0);
|
|
|
352 |
}
|
|
|
353 |
|
| 527 |
dsic.upv.es!antodo |
354 |
#undef __FUNCT__
|
|
|
355 |
#define __FUNCT__ "EPSAttachDeflationSpace"
|
|
|
356 |
/*@
|
|
|
357 |
EPSAttachDeflationSpace - Add vectors to the basis of the deflation space.
|
|
|
358 |
|
|
|
359 |
Not Collective
|
|
|
360 |
|
|
|
361 |
Input Parameter:
|
|
|
362 |
+ eps - the eigenproblem solver context
|
|
|
363 |
. n - number of vectors to add
|
|
|
364 |
. ds - set of basis vectors of the deflation space
|
|
|
365 |
- ortho - PETSC_TRUE if basis vectors of deflation space are orthonormal
|
|
|
366 |
|
|
|
367 |
Notes:
|
|
|
368 |
When a deflation space is given, the eigensolver seeks the eigensolution
|
|
|
369 |
in the restriction of the problem to the orthogonal complement of this
|
|
|
370 |
space. This can be used for instance in the case that an invariant
|
|
|
371 |
subspace is known beforehand (such as the nullspace of the matrix).
|
|
|
372 |
|
|
|
373 |
The basis vectors can be provided all at once or incrementally with
|
|
|
374 |
several calls to EPSAttachDeflationSpace().
|
|
|
375 |
|
|
|
376 |
Use a value of PETSC_TRUE for parameter ortho if all the vectors passed
|
|
|
377 |
in are known to be mutually orthonormal.
|
|
|
378 |
|
|
|
379 |
Level: intermediate
|
|
|
380 |
|
|
|
381 |
.seealso: EPSRemoveDeflationSpace()
|
|
|
382 |
@*/
|
| 1509 |
slepc |
383 |
PetscErrorCode EPSAttachDeflationSpace(EPS eps,PetscInt n,Vec *ds,PetscTruth ortho)
|
| 527 |
dsic.upv.es!antodo |
384 |
{
|
|
|
385 |
PetscErrorCode ierr;
|
| 1755 |
antodo |
386 |
PetscInt i,nloc;
|
|
|
387 |
Vec *newds;
|
|
|
388 |
PetscScalar *pV;
|
| 527 |
dsic.upv.es!antodo |
389 |
|
|
|
390 |
PetscFunctionBegin;
|
|
|
391 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
| 1755 |
antodo |
392 |
if (n<=0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE, "Argument 2 out of range");
|
|
|
393 |
/* allocate space for previous and new vectors */
|
|
|
394 |
ierr = PetscMalloc((n+eps->nds)*sizeof(Vec), &newds);CHKERRQ(ierr);
|
|
|
395 |
ierr = VecGetLocalSize(ds[0],&nloc);CHKERRQ(ierr);
|
|
|
396 |
ierr = PetscMalloc((n+eps->nds)*nloc*sizeof(PetscScalar),&pV);CHKERRQ(ierr);
|
|
|
397 |
for (i=0;i<n+eps->nds;i++) {
|
|
|
398 |
ierr = VecCreateMPIWithArray(((PetscObject)eps)->comm,nloc,PETSC_DECIDE,pV+i*nloc,&newds[i]);CHKERRQ(ierr);
|
| 527 |
dsic.upv.es!antodo |
399 |
}
|
| 1755 |
antodo |
400 |
/* copy and free previous vectors */
|
| 527 |
dsic.upv.es!antodo |
401 |
if (eps->nds > 0) {
|
| 1755 |
antodo |
402 |
ierr = VecGetArray(eps->DS[0],&pV);CHKERRQ(ierr);
|
|
|
403 |
for (i=0;i<eps->nds;i++) {
|
|
|
404 |
ierr = VecCopy(eps->DS[i],newds[i]);CHKERRQ(ierr);
|
|
|
405 |
ierr = VecDestroy(eps->DS[i]);CHKERRQ(ierr);
|
|
|
406 |
}
|
|
|
407 |
ierr = PetscFree(pV);CHKERRQ(ierr);
|
|
|
408 |
ierr = PetscFree(eps->DS);CHKERRQ(ierr);
|
| 527 |
dsic.upv.es!antodo |
409 |
}
|
| 1755 |
antodo |
410 |
/* copy new vectors */
|
|
|
411 |
eps->DS = newds;
|
| 527 |
dsic.upv.es!antodo |
412 |
for (i=0; i<n; i++) {
|
|
|
413 |
ierr = VecCopy(ds[i],eps->DS[i + eps->nds]);CHKERRQ(ierr);
|
|
|
414 |
}
|
|
|
415 |
eps->nds += n;
|
|
|
416 |
if (!ortho) eps->ds_ortho = PETSC_FALSE;
|
|
|
417 |
eps->setupcalled = 0;
|
|
|
418 |
PetscFunctionReturn(0);
|
|
|
419 |
}
|
|
|
420 |
|
|
|
421 |
#undef __FUNCT__
|
|
|
422 |
#define __FUNCT__ "EPSRemoveDeflationSpace"
|
|
|
423 |
/*@
|
|
|
424 |
EPSRemoveDeflationSpace - Removes the deflation space.
|
|
|
425 |
|
|
|
426 |
Not Collective
|
|
|
427 |
|
|
|
428 |
Input Parameter:
|
|
|
429 |
. eps - the eigenproblem solver context
|
|
|
430 |
|
|
|
431 |
Level: intermediate
|
|
|
432 |
|
|
|
433 |
.seealso: EPSAttachDeflationSpace()
|
|
|
434 |
@*/
|
|
|
435 |
PetscErrorCode EPSRemoveDeflationSpace(EPS eps)
|
|
|
436 |
{
|
|
|
437 |
PetscErrorCode ierr;
|
| 1695 |
slepc |
438 |
PetscInt i;
|
| 1755 |
antodo |
439 |
PetscScalar *pV;
|
| 527 |
dsic.upv.es!antodo |
440 |
|
|
|
441 |
PetscFunctionBegin;
|
|
|
442 |
PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
|
|
|
443 |
if (eps->nds > 0) {
|
| 1755 |
antodo |
444 |
ierr = VecGetArray(eps->DS[0],&pV);CHKERRQ(ierr);
|
| 1695 |
slepc |
445 |
for (i=0;i<eps->nds;i++) {
|
|
|
446 |
ierr = VecDestroy(eps->DS[i]);CHKERRQ(ierr);
|
|
|
447 |
}
|
| 1755 |
antodo |
448 |
ierr = PetscFree(pV);CHKERRQ(ierr);
|
| 1695 |
slepc |
449 |
ierr = PetscFree(eps->DS);CHKERRQ(ierr);
|
| 527 |
dsic.upv.es!antodo |
450 |
}
|
|
|
451 |
eps->ds_ortho = PETSC_TRUE;
|
|
|
452 |
eps->setupcalled = 0;
|
|
|
453 |
PetscFunctionReturn(0);
|
|
|
454 |
}
|