Line data Source code
1 : /*
2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 : SLEPc - Scalable Library for Eigenvalue Problem Computations
4 : Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5 :
6 : This file is part of SLEPc.
7 : SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 : */
10 : /*
11 : PEP routines related to problem setup
12 : */
13 :
14 : #include <slepc/private/pepimpl.h> /*I "slepcpep.h" I*/
15 :
16 : /*
17 : Let the solver choose the ST type that should be used by default,
18 : otherwise set it to SHIFT.
19 : This is called at PEPSetFromOptions (before STSetFromOptions)
20 : and also at PEPSetUp (in case PEPSetFromOptions was not called).
21 : */
22 333 : PetscErrorCode PEPSetDefaultST(PEP pep)
23 : {
24 333 : PetscFunctionBegin;
25 333 : PetscTryTypeMethod(pep,setdefaultst);
26 333 : if (!((PetscObject)pep->st)->type_name) PetscCall(STSetType(pep->st,STSHIFT));
27 333 : PetscFunctionReturn(PETSC_SUCCESS);
28 : }
29 :
30 : /*
31 : This is used in Q-Arnoldi and STOAR to set the transform flag by
32 : default, otherwise the user has to explicitly run with -st_transform
33 : */
34 30 : PetscErrorCode PEPSetDefaultST_Transform(PEP pep)
35 : {
36 30 : PetscFunctionBegin;
37 30 : PetscCall(STSetTransform(pep->st,PETSC_TRUE));
38 30 : PetscFunctionReturn(PETSC_SUCCESS);
39 : }
40 :
41 : /*@
42 : PEPSetDSType - Sets the type of the internal DS object based on the current
43 : settings of the polynomial eigensolver.
44 :
45 : Collective
46 :
47 : Input Parameter:
48 : . pep - polynomial eigensolver context
49 :
50 : Note:
51 : This function need not be called explicitly, since it will be called at
52 : both PEPSetFromOptions() and PEPSetUp().
53 :
54 : Level: developer
55 :
56 : .seealso: PEPSetFromOptions(), PEPSetUp()
57 : @*/
58 332 : PetscErrorCode PEPSetDSType(PEP pep)
59 : {
60 332 : PetscFunctionBegin;
61 332 : PetscValidHeaderSpecific(pep,PEP_CLASSID,1);
62 332 : PetscTryTypeMethod(pep,setdstype);
63 332 : PetscFunctionReturn(PETSC_SUCCESS);
64 : }
65 :
66 : /*@
67 : PEPSetUp - Sets up all the internal data structures necessary for the
68 : execution of the PEP solver.
69 :
70 : Collective
71 :
72 : Input Parameter:
73 : . pep - solver context
74 :
75 : Notes:
76 : This function need not be called explicitly in most cases, since PEPSolve()
77 : calls it. It can be useful when one wants to measure the set-up time
78 : separately from the solve time.
79 :
80 : Level: developer
81 :
82 : .seealso: PEPCreate(), PEPSolve(), PEPDestroy()
83 : @*/
84 176 : PetscErrorCode PEPSetUp(PEP pep)
85 : {
86 176 : SlepcSC sc;
87 176 : PetscBool istrivial,flg;
88 176 : PetscInt k;
89 176 : KSP ksp;
90 176 : PC pc;
91 176 : PetscMPIInt size;
92 176 : MatSolverType stype;
93 :
94 176 : PetscFunctionBegin;
95 176 : PetscValidHeaderSpecific(pep,PEP_CLASSID,1);
96 176 : if (pep->state) PetscFunctionReturn(PETSC_SUCCESS);
97 173 : PetscCall(PetscLogEventBegin(PEP_SetUp,pep,0,0,0));
98 :
99 : /* reset the convergence flag from the previous solves */
100 173 : pep->reason = PEP_CONVERGED_ITERATING;
101 :
102 : /* set default solver type (PEPSetFromOptions was not called) */
103 173 : if (!((PetscObject)pep)->type_name) PetscCall(PEPSetType(pep,PEPTOAR));
104 173 : if (!pep->st) PetscCall(PEPGetST(pep,&pep->st));
105 173 : PetscCall(PEPSetDefaultST(pep));
106 173 : if (!pep->ds) PetscCall(PEPGetDS(pep,&pep->ds));
107 173 : PetscCall(PEPSetDSType(pep));
108 173 : if (!pep->rg) PetscCall(PEPGetRG(pep,&pep->rg));
109 173 : if (!((PetscObject)pep->rg)->type_name) PetscCall(RGSetType(pep->rg,RGINTERVAL));
110 :
111 : /* check matrices, transfer them to ST */
112 173 : PetscCheck(pep->A,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_WRONGSTATE,"PEPSetOperators must be called first");
113 173 : PetscCall(STSetMatrices(pep->st,pep->nmat,pep->A));
114 :
115 : /* set problem dimensions */
116 173 : PetscCall(MatGetSize(pep->A[0],&pep->n,NULL));
117 173 : PetscCall(MatGetLocalSize(pep->A[0],&pep->nloc,NULL));
118 :
119 : /* set default problem type */
120 173 : if (!pep->problem_type) PetscCall(PEPSetProblemType(pep,PEP_GENERAL));
121 173 : if (pep->nev > (pep->nmat-1)*pep->n) pep->nev = (pep->nmat-1)*pep->n;
122 173 : if (pep->ncv > (pep->nmat-1)*pep->n) pep->ncv = (pep->nmat-1)*pep->n;
123 :
124 : /* check consistency of refinement options */
125 173 : if (pep->refine) {
126 29 : if (!pep->scheme) { /* set default scheme */
127 4 : PetscCall(PEPRefineGetKSP(pep,&ksp));
128 4 : PetscCall(KSPGetPC(ksp,&pc));
129 4 : PetscCall(PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg));
130 4 : if (flg) PetscCall(PetscObjectTypeCompareAny((PetscObject)pc,&flg,PCLU,PCCHOLESKY,""));
131 8 : pep->scheme = flg? PEP_REFINE_SCHEME_MBE: PEP_REFINE_SCHEME_SCHUR;
132 : }
133 29 : if (pep->scheme==PEP_REFINE_SCHEME_MBE) {
134 8 : PetscCall(PEPRefineGetKSP(pep,&ksp));
135 8 : PetscCall(KSPGetPC(ksp,&pc));
136 8 : PetscCall(PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg));
137 8 : if (flg) PetscCall(PetscObjectTypeCompareAny((PetscObject)pc,&flg,PCLU,PCCHOLESKY,""));
138 8 : PetscCheck(flg,PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"The MBE scheme for refinement requires a direct solver in KSP");
139 8 : PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size));
140 8 : if (size>1) { /* currently selected PC is a factorization */
141 0 : PetscCall(PCFactorGetMatSolverType(pc,&stype));
142 0 : PetscCall(PetscStrcmp(stype,MATSOLVERPETSC,&flg));
143 0 : PetscCheck(!flg,PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"For Newton refinement, you chose to solve linear systems with a factorization, but in parallel runs you need to select an external package");
144 : }
145 : }
146 29 : if (pep->scheme==PEP_REFINE_SCHEME_SCHUR) {
147 9 : PetscCheck(pep->npart==1,PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"The Schur scheme for refinement does not support subcommunicators");
148 : }
149 : }
150 : /* call specific solver setup */
151 173 : PetscUseTypeMethod(pep,setup);
152 :
153 : /* set tolerance if not yet set */
154 173 : if (pep->tol==(PetscReal)PETSC_DETERMINE) pep->tol = SLEPC_DEFAULT_TOL;
155 173 : if (pep->refine) {
156 57 : if (pep->rtol==(PetscReal)PETSC_DETERMINE) pep->rtol = PetscMax(pep->tol/1000,PETSC_MACHINE_EPSILON);
157 43 : if (pep->rits==PETSC_DETERMINE) pep->rits = (pep->refine==PEP_REFINE_SIMPLE)? 10: 1;
158 : }
159 :
160 : /* set default extraction */
161 173 : if (!pep->extract) {
162 146 : pep->extract = (pep->basis==PEP_BASIS_MONOMIAL)? PEP_EXTRACT_NORM: PEP_EXTRACT_NONE;
163 : }
164 :
165 : /* fill sorting criterion context */
166 173 : switch (pep->which) {
167 56 : case PEP_LARGEST_MAGNITUDE:
168 56 : pep->sc->comparison = SlepcCompareLargestMagnitude;
169 56 : pep->sc->comparisonctx = NULL;
170 56 : break;
171 0 : case PEP_SMALLEST_MAGNITUDE:
172 0 : pep->sc->comparison = SlepcCompareSmallestMagnitude;
173 0 : pep->sc->comparisonctx = NULL;
174 0 : break;
175 2 : case PEP_LARGEST_REAL:
176 2 : pep->sc->comparison = SlepcCompareLargestReal;
177 2 : pep->sc->comparisonctx = NULL;
178 2 : break;
179 0 : case PEP_SMALLEST_REAL:
180 0 : pep->sc->comparison = SlepcCompareSmallestReal;
181 0 : pep->sc->comparisonctx = NULL;
182 0 : break;
183 0 : case PEP_LARGEST_IMAGINARY:
184 0 : pep->sc->comparison = SlepcCompareLargestImaginary;
185 0 : pep->sc->comparisonctx = NULL;
186 0 : break;
187 0 : case PEP_SMALLEST_IMAGINARY:
188 0 : pep->sc->comparison = SlepcCompareSmallestImaginary;
189 0 : pep->sc->comparisonctx = NULL;
190 0 : break;
191 106 : case PEP_TARGET_MAGNITUDE:
192 106 : pep->sc->comparison = SlepcCompareTargetMagnitude;
193 106 : pep->sc->comparisonctx = &pep->target;
194 106 : break;
195 0 : case PEP_TARGET_REAL:
196 0 : pep->sc->comparison = SlepcCompareTargetReal;
197 0 : pep->sc->comparisonctx = &pep->target;
198 0 : break;
199 : case PEP_TARGET_IMAGINARY:
200 : #if defined(PETSC_USE_COMPLEX)
201 : pep->sc->comparison = SlepcCompareTargetImaginary;
202 : pep->sc->comparisonctx = &pep->target;
203 : #endif
204 : break;
205 8 : case PEP_ALL:
206 8 : pep->sc->comparison = SlepcCompareSmallestReal;
207 8 : pep->sc->comparisonctx = NULL;
208 8 : break;
209 : case PEP_WHICH_USER:
210 : break;
211 : }
212 173 : pep->sc->map = NULL;
213 173 : pep->sc->mapobj = NULL;
214 :
215 : /* fill sorting criterion for DS */
216 173 : if (pep->which!=PEP_ALL) {
217 165 : PetscCall(DSGetSlepcSC(pep->ds,&sc));
218 165 : PetscCall(RGIsTrivial(pep->rg,&istrivial));
219 165 : sc->rg = istrivial? NULL: pep->rg;
220 165 : sc->comparison = pep->sc->comparison;
221 165 : sc->comparisonctx = pep->sc->comparisonctx;
222 165 : sc->map = SlepcMap_ST;
223 165 : sc->mapobj = (PetscObject)pep->st;
224 : }
225 : /* setup ST */
226 173 : PetscCall(STSetUp(pep->st));
227 :
228 : /* compute matrix coefficients */
229 173 : PetscCall(STGetTransform(pep->st,&flg));
230 173 : if (!flg) {
231 143 : if (pep->which!=PEP_ALL && pep->solvematcoeffs) PetscCall(STMatSetUp(pep->st,1.0,pep->solvematcoeffs));
232 : } else {
233 30 : PetscCheck(pep->basis==PEP_BASIS_MONOMIAL,PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Cannot use ST-transform with non-monomial basis in PEP");
234 : }
235 :
236 : /* compute scale factor if no set by user */
237 173 : PetscCall(PEPComputeScaleFactor(pep));
238 :
239 : /* build balancing matrix if required */
240 173 : if (pep->scale==PEP_SCALE_DIAGONAL || pep->scale==PEP_SCALE_BOTH) {
241 18 : if (!pep->Dl) PetscCall(BVCreateVec(pep->V,&pep->Dl));
242 18 : if (!pep->Dr) PetscCall(BVCreateVec(pep->V,&pep->Dr));
243 18 : PetscCall(PEPBuildDiagonalScaling(pep));
244 : }
245 :
246 : /* process initial vectors */
247 173 : if (pep->nini<0) {
248 3 : k = -pep->nini;
249 3 : PetscCheck(k<=pep->ncv,PetscObjectComm((PetscObject)pep),PETSC_ERR_USER_INPUT,"The number of initial vectors is larger than ncv");
250 3 : PetscCall(BVInsertVecs(pep->V,0,&k,pep->IS,PETSC_TRUE));
251 3 : PetscCall(SlepcBasisDestroy_Private(&pep->nini,&pep->IS));
252 3 : pep->nini = k;
253 : }
254 173 : PetscCall(PetscLogEventEnd(PEP_SetUp,pep,0,0,0));
255 173 : pep->state = PEP_STATE_SETUP;
256 173 : PetscFunctionReturn(PETSC_SUCCESS);
257 : }
258 :
259 : /*@
260 : PEPSetOperators - Sets the coefficient matrices associated with the polynomial
261 : eigenvalue problem.
262 :
263 : Collective
264 :
265 : Input Parameters:
266 : + pep - the eigenproblem solver context
267 : . nmat - number of matrices in array A
268 : - A - the array of matrices associated with the eigenproblem
269 :
270 : Notes:
271 : The polynomial eigenproblem is defined as P(l)*x=0, where l is
272 : the eigenvalue, x is the eigenvector, and P(l) is defined as
273 : P(l) = A_0 + l*A_1 + ... + l^d*A_d, with d=nmat-1 (the degree of P).
274 : For non-monomial bases, this expression is different.
275 :
276 : Level: beginner
277 :
278 : .seealso: PEPSolve(), PEPGetOperators(), PEPGetNumMatrices(), PEPSetBasis()
279 : @*/
280 174 : PetscErrorCode PEPSetOperators(PEP pep,PetscInt nmat,Mat A[])
281 : {
282 174 : PetscInt i,n=0,m,m0=0,mloc,nloc,mloc0=0;
283 :
284 174 : PetscFunctionBegin;
285 174 : PetscValidHeaderSpecific(pep,PEP_CLASSID,1);
286 522 : PetscValidLogicalCollectiveInt(pep,nmat,2);
287 174 : PetscCheck(nmat>0,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_OUTOFRANGE,"Non-positive value of nmat: %" PetscInt_FMT,nmat);
288 174 : PetscCheck(nmat>2,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_OUTOFRANGE,"Cannot solve linear eigenproblems with PEP; use EPS instead");
289 174 : PetscAssertPointer(A,3);
290 :
291 835 : for (i=0;i<nmat;i++) {
292 661 : PetscValidHeaderSpecific(A[i],MAT_CLASSID,3);
293 661 : PetscCheckSameComm(pep,1,A[i],3);
294 661 : PetscCall(MatGetSize(A[i],&m,&n));
295 661 : PetscCall(MatGetLocalSize(A[i],&mloc,&nloc));
296 661 : PetscCheck(m==n,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_WRONG,"A[%" PetscInt_FMT "] is a non-square matrix (%" PetscInt_FMT " rows, %" PetscInt_FMT " cols)",i,m,n);
297 661 : PetscCheck(mloc==nloc,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_WRONG,"A[%" PetscInt_FMT "] does not have equal row and column local sizes (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,mloc,nloc);
298 661 : if (!i) { m0 = m; mloc0 = mloc; }
299 661 : PetscCheck(m==m0,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_INCOMP,"Dimensions of A[%" PetscInt_FMT "] do not match with previous matrices (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,m,m0);
300 661 : PetscCheck(mloc==mloc0,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_INCOMP,"Local dimensions of A[%" PetscInt_FMT "] do not match with previous matrices (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,mloc,mloc0);
301 661 : PetscCall(PetscObjectReference((PetscObject)A[i]));
302 : }
303 :
304 174 : if (pep->state && (n!=pep->n || nloc!=pep->nloc)) PetscCall(PEPReset(pep));
305 170 : else if (pep->nmat) {
306 1 : PetscCall(MatDestroyMatrices(pep->nmat,&pep->A));
307 1 : PetscCall(PetscFree2(pep->pbc,pep->nrma));
308 1 : PetscCall(PetscFree(pep->solvematcoeffs));
309 : }
310 :
311 174 : PetscCall(PetscMalloc1(nmat,&pep->A));
312 174 : PetscCall(PetscCalloc2(3*nmat,&pep->pbc,nmat,&pep->nrma));
313 835 : for (i=0;i<nmat;i++) {
314 661 : pep->A[i] = A[i];
315 661 : pep->pbc[i] = 1.0; /* default to monomial basis */
316 : }
317 174 : pep->nmat = nmat;
318 174 : pep->state = PEP_STATE_INITIAL;
319 174 : PetscFunctionReturn(PETSC_SUCCESS);
320 : }
321 :
322 : /*@
323 : PEPGetOperators - Gets the matrices associated with the polynomial eigensystem.
324 :
325 : Not Collective
326 :
327 : Input Parameters:
328 : + pep - the PEP context
329 : - k - the index of the requested matrix (starting in 0)
330 :
331 : Output Parameter:
332 : . A - the requested matrix
333 :
334 : Level: intermediate
335 :
336 : .seealso: PEPSolve(), PEPSetOperators(), PEPGetNumMatrices()
337 : @*/
338 57 : PetscErrorCode PEPGetOperators(PEP pep,PetscInt k,Mat *A)
339 : {
340 57 : PetscFunctionBegin;
341 57 : PetscValidHeaderSpecific(pep,PEP_CLASSID,1);
342 57 : PetscAssertPointer(A,3);
343 57 : PetscCheck(k>=0 && k<pep->nmat,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %" PetscInt_FMT,pep->nmat-1);
344 57 : *A = pep->A[k];
345 57 : PetscFunctionReturn(PETSC_SUCCESS);
346 : }
347 :
348 : /*@
349 : PEPGetNumMatrices - Returns the number of matrices stored in the PEP.
350 :
351 : Not Collective
352 :
353 : Input Parameter:
354 : . pep - the PEP context
355 :
356 : Output Parameters:
357 : . nmat - the number of matrices passed in PEPSetOperators()
358 :
359 : Level: intermediate
360 :
361 : .seealso: PEPSetOperators()
362 : @*/
363 1 : PetscErrorCode PEPGetNumMatrices(PEP pep,PetscInt *nmat)
364 : {
365 1 : PetscFunctionBegin;
366 1 : PetscValidHeaderSpecific(pep,PEP_CLASSID,1);
367 1 : PetscAssertPointer(nmat,2);
368 1 : *nmat = pep->nmat;
369 1 : PetscFunctionReturn(PETSC_SUCCESS);
370 : }
371 :
372 : /*@
373 : PEPSetInitialSpace - Specify a basis of vectors that constitute the initial
374 : space, that is, the subspace from which the solver starts to iterate.
375 :
376 : Collective
377 :
378 : Input Parameters:
379 : + pep - the polynomial eigensolver context
380 : . n - number of vectors
381 : - is - set of basis vectors of the initial space
382 :
383 : Notes:
384 : Some solvers start to iterate on a single vector (initial vector). In that case,
385 : the other vectors are ignored.
386 :
387 : These vectors do not persist from one PEPSolve() call to the other, so the
388 : initial space should be set every time.
389 :
390 : The vectors do not need to be mutually orthonormal, since they are explicitly
391 : orthonormalized internally.
392 :
393 : Common usage of this function is when the user can provide a rough approximation
394 : of the wanted eigenspace. Then, convergence may be faster.
395 :
396 : Level: intermediate
397 :
398 : .seealso: PEPSetUp()
399 : @*/
400 5 : PetscErrorCode PEPSetInitialSpace(PEP pep,PetscInt n,Vec is[])
401 : {
402 5 : PetscFunctionBegin;
403 5 : PetscValidHeaderSpecific(pep,PEP_CLASSID,1);
404 15 : PetscValidLogicalCollectiveInt(pep,n,2);
405 5 : PetscCheck(n>=0,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_OUTOFRANGE,"Argument n cannot be negative");
406 5 : if (n>0) {
407 5 : PetscAssertPointer(is,3);
408 5 : PetscValidHeaderSpecific(*is,VEC_CLASSID,3);
409 : }
410 5 : PetscCall(SlepcBasisReference_Private(n,is,&pep->nini,&pep->IS));
411 5 : if (n>0) pep->state = PEP_STATE_INITIAL;
412 5 : PetscFunctionReturn(PETSC_SUCCESS);
413 : }
414 :
415 : /*
416 : PEPSetDimensions_Default - Set reasonable values for ncv, mpd if not set
417 : by the user. This is called at setup.
418 : */
419 138 : PetscErrorCode PEPSetDimensions_Default(PEP pep,PetscInt nev,PetscInt *ncv,PetscInt *mpd)
420 : {
421 138 : PetscBool krylov;
422 138 : PetscInt dim;
423 :
424 138 : PetscFunctionBegin;
425 138 : PetscCall(PetscObjectTypeCompareAny((PetscObject)pep,&krylov,PEPTOAR,PEPSTOAR,PEPQARNOLDI,""));
426 138 : dim = (pep->nmat-1)*pep->n;
427 138 : if (*ncv!=PETSC_DETERMINE) { /* ncv set */
428 68 : if (krylov) {
429 58 : PetscCheck(*ncv>nev || (*ncv==nev && *ncv==dim),PetscObjectComm((PetscObject)pep),PETSC_ERR_USER_INPUT,"The value of ncv must be at least nev+1");
430 : } else {
431 10 : PetscCheck(*ncv>=nev,PetscObjectComm((PetscObject)pep),PETSC_ERR_USER_INPUT,"The value of ncv must be at least nev");
432 : }
433 70 : } else if (*mpd!=PETSC_DETERMINE) { /* mpd set */
434 0 : *ncv = PetscMin(dim,nev+(*mpd));
435 : } else { /* neither set: defaults depend on nev being small or large */
436 70 : if (nev<500) *ncv = PetscMin(dim,PetscMax(2*nev,nev+15));
437 : else {
438 0 : *mpd = 500;
439 0 : *ncv = PetscMin(dim,nev+(*mpd));
440 : }
441 : }
442 138 : if (*mpd==PETSC_DETERMINE) *mpd = *ncv;
443 138 : PetscFunctionReturn(PETSC_SUCCESS);
444 : }
445 :
446 : /*@
447 : PEPAllocateSolution - Allocate memory storage for common variables such
448 : as eigenvalues and eigenvectors.
449 :
450 : Collective
451 :
452 : Input Parameters:
453 : + pep - eigensolver context
454 : - extra - number of additional positions, used for methods that require a
455 : working basis slightly larger than ncv
456 :
457 : Developer Notes:
458 : This is SLEPC_EXTERN because it may be required by user plugin PEP
459 : implementations.
460 :
461 : Level: developer
462 :
463 : .seealso: PEPSetUp()
464 : @*/
465 194 : PetscErrorCode PEPAllocateSolution(PEP pep,PetscInt extra)
466 : {
467 194 : PetscInt oldsize,requested,requestedbv;
468 194 : Vec t;
469 :
470 194 : PetscFunctionBegin;
471 194 : requested = (pep->lineariz? pep->ncv: pep->ncv*(pep->nmat-1)) + extra;
472 194 : requestedbv = pep->ncv + extra;
473 :
474 : /* oldsize is zero if this is the first time setup is called */
475 194 : PetscCall(BVGetSizes(pep->V,NULL,NULL,&oldsize));
476 :
477 : /* allocate space for eigenvalues and friends */
478 194 : if (requested != oldsize || !pep->eigr) {
479 190 : PetscCall(PetscFree4(pep->eigr,pep->eigi,pep->errest,pep->perm));
480 190 : PetscCall(PetscMalloc4(requested,&pep->eigr,requested,&pep->eigi,requested,&pep->errest,requested,&pep->perm));
481 : }
482 :
483 : /* allocate V */
484 194 : if (!pep->V) PetscCall(PEPGetBV(pep,&pep->V));
485 194 : if (!oldsize) {
486 173 : if (!((PetscObject)pep->V)->type_name) PetscCall(BVSetType(pep->V,BVMAT));
487 173 : PetscCall(STMatCreateVecsEmpty(pep->st,&t,NULL));
488 173 : PetscCall(BVSetSizesFromVec(pep->V,t,requestedbv));
489 173 : PetscCall(VecDestroy(&t));
490 21 : } else PetscCall(BVResize(pep->V,requestedbv,PETSC_FALSE));
491 194 : PetscFunctionReturn(PETSC_SUCCESS);
492 : }
|