| 1376 |
slepc |
1 |
/*
|
|
|
2 |
This file implements a wrapper to the BLOPEX solver
|
| 1199 |
slepc |
3 |
|
| 1376 |
slepc |
4 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| 1672 |
slepc |
5 |
SLEPc - Scalable Library for Eigenvalue Problem Computations
|
| 2575 |
eromero |
6 |
Copyright (c) 2002-2011, Universitat 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 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| 1199 |
slepc |
22 |
*/
|
| 1376 |
slepc |
23 |
|
| 2729 |
jroman |
24 |
#include <slepc-private/stimpl.h> /*I "slepcst.h" I*/
|
|
|
25 |
#include <slepc-private/epsimpl.h> /*I "slepceps.h" I*/
|
| 1499 |
slepc |
26 |
#include "slepc-interface.h"
|
| 2423 |
jroman |
27 |
#include <blopex_lobpcg.h>
|
|
|
28 |
#include <blopex_interpreter.h>
|
|
|
29 |
#include <blopex_multivector.h>
|
|
|
30 |
#include <blopex_temp_multivector.h>
|
| 1199 |
slepc |
31 |
|
| 1947 |
jroman |
32 |
PetscErrorCode EPSSolve_BLOPEX(EPS);
|
|
|
33 |
|
| 1199 |
slepc |
34 |
typedef struct {
|
|
|
35 |
lobpcg_Tolerance tol;
|
|
|
36 |
lobpcg_BLASLAPACKFunctions blap_fn;
|
|
|
37 |
mv_MultiVectorPtr eigenvectors;
|
| 1499 |
slepc |
38 |
mv_MultiVectorPtr Y;
|
| 1199 |
slepc |
39 |
mv_InterfaceInterpreter ii;
|
|
|
40 |
KSP ksp;
|
| 2435 |
jroman |
41 |
Vec w;
|
| 1199 |
slepc |
42 |
} EPS_BLOPEX;
|
|
|
43 |
|
|
|
44 |
#undef __FUNCT__
|
|
|
45 |
#define __FUNCT__ "Precond_FnSingleVector"
|
|
|
46 |
static void Precond_FnSingleVector(void *data,void *x,void *y)
|
|
|
47 |
{
|
| 2317 |
jroman |
48 |
PetscErrorCode ierr;
|
|
|
49 |
EPS eps = (EPS)data;
|
|
|
50 |
EPS_BLOPEX *blopex = (EPS_BLOPEX*)eps->data;
|
|
|
51 |
PetscInt lits;
|
| 1199 |
slepc |
52 |
|
|
|
53 |
PetscFunctionBegin;
|
| 2730 |
jroman |
54 |
ierr = KSPSolve(blopex->ksp,(Vec)x,(Vec)y); CHKERRABORT(((PetscObject)eps)->comm,ierr);
|
|
|
55 |
ierr = KSPGetIterationNumber(blopex->ksp,&lits); CHKERRABORT(((PetscObject)eps)->comm,ierr);
|
| 1499 |
slepc |
56 |
eps->OP->lineariterations+= lits;
|
| 1199 |
slepc |
57 |
PetscFunctionReturnVoid();
|
|
|
58 |
}
|
|
|
59 |
|
|
|
60 |
#undef __FUNCT__
|
|
|
61 |
#define __FUNCT__ "Precond_FnMultiVector"
|
|
|
62 |
static void Precond_FnMultiVector(void *data,void *x,void *y)
|
|
|
63 |
{
|
| 2317 |
jroman |
64 |
EPS eps = (EPS)data;
|
|
|
65 |
EPS_BLOPEX *blopex = (EPS_BLOPEX*)eps->data;
|
| 1199 |
slepc |
66 |
|
|
|
67 |
PetscFunctionBegin;
|
|
|
68 |
blopex->ii.Eval(Precond_FnSingleVector,data,x,y);
|
|
|
69 |
PetscFunctionReturnVoid();
|
|
|
70 |
}
|
|
|
71 |
|
|
|
72 |
#undef __FUNCT__
|
|
|
73 |
#define __FUNCT__ "OperatorASingleVector"
|
|
|
74 |
static void OperatorASingleVector(void *data,void *x,void *y)
|
|
|
75 |
{
|
| 2316 |
jroman |
76 |
PetscErrorCode ierr;
|
|
|
77 |
EPS eps = (EPS)data;
|
| 2435 |
jroman |
78 |
EPS_BLOPEX *blopex = (EPS_BLOPEX*)eps->data;
|
|
|
79 |
Mat A,B;
|
| 1499 |
slepc |
80 |
|
| 1199 |
slepc |
81 |
PetscFunctionBegin;
|
| 2730 |
jroman |
82 |
ierr = STGetOperators(eps->OP,&A,&B);CHKERRABORT(((PetscObject)eps)->comm,ierr);
|
|
|
83 |
ierr = MatMult(A,(Vec)x,(Vec)y);CHKERRABORT(((PetscObject)eps)->comm,ierr);
|
| 2435 |
jroman |
84 |
if (eps->OP->sigma != 0.0) {
|
| 2730 |
jroman |
85 |
if (B) { ierr = MatMult(B,(Vec)x,blopex->w);CHKERRABORT(((PetscObject)eps)->comm,ierr); }
|
|
|
86 |
else { ierr = VecCopy((Vec)x,blopex->w);CHKERRABORT(((PetscObject)eps)->comm,ierr); }
|
|
|
87 |
ierr = VecAXPY((Vec)y,-eps->OP->sigma,blopex->w);CHKERRABORT(((PetscObject)eps)->comm,ierr);
|
| 2435 |
jroman |
88 |
}
|
| 1199 |
slepc |
89 |
PetscFunctionReturnVoid();
|
|
|
90 |
}
|
|
|
91 |
|
|
|
92 |
#undef __FUNCT__
|
|
|
93 |
#define __FUNCT__ "OperatorAMultiVector"
|
|
|
94 |
static void OperatorAMultiVector(void *data,void *x,void *y)
|
|
|
95 |
{
|
| 2316 |
jroman |
96 |
EPS eps = (EPS)data;
|
|
|
97 |
EPS_BLOPEX *blopex = (EPS_BLOPEX*)eps->data;
|
| 1199 |
slepc |
98 |
|
|
|
99 |
PetscFunctionBegin;
|
|
|
100 |
blopex->ii.Eval(OperatorASingleVector,data,x,y);
|
|
|
101 |
PetscFunctionReturnVoid();
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
#undef __FUNCT__
|
| 1499 |
slepc |
105 |
#define __FUNCT__ "OperatorBSingleVector"
|
|
|
106 |
static void OperatorBSingleVector(void *data,void *x,void *y)
|
|
|
107 |
{
|
| 2316 |
jroman |
108 |
PetscErrorCode ierr;
|
|
|
109 |
EPS eps = (EPS)data;
|
|
|
110 |
Mat B;
|
| 1499 |
slepc |
111 |
|
|
|
112 |
PetscFunctionBegin;
|
| 2730 |
jroman |
113 |
ierr = STGetOperators(eps->OP,PETSC_NULL,&B);CHKERRABORT(((PetscObject)eps)->comm,ierr);
|
|
|
114 |
ierr = MatMult(B,(Vec)x,(Vec)y);CHKERRABORT(((PetscObject)eps)->comm,ierr);
|
| 1499 |
slepc |
115 |
PetscFunctionReturnVoid();
|
|
|
116 |
}
|
|
|
117 |
|
|
|
118 |
#undef __FUNCT__
|
|
|
119 |
#define __FUNCT__ "OperatorBMultiVector"
|
|
|
120 |
static void OperatorBMultiVector(void *data,void *x,void *y)
|
|
|
121 |
{
|
| 2316 |
jroman |
122 |
EPS eps = (EPS)data;
|
|
|
123 |
EPS_BLOPEX *blopex = (EPS_BLOPEX*)eps->data;
|
| 1499 |
slepc |
124 |
|
|
|
125 |
PetscFunctionBegin;
|
|
|
126 |
blopex->ii.Eval(OperatorBSingleVector,data,x,y);
|
|
|
127 |
PetscFunctionReturnVoid();
|
|
|
128 |
}
|
|
|
129 |
|
|
|
130 |
#undef __FUNCT__
|
| 1199 |
slepc |
131 |
#define __FUNCT__ "EPSSetUp_BLOPEX"
|
|
|
132 |
PetscErrorCode EPSSetUp_BLOPEX(EPS eps)
|
|
|
133 |
{
|
| 2739 |
jroman |
134 |
#if defined(PETSC_MISSING_LAPACK_POTRF) || defined(PETSC_MISSING_LAPACK_SYGV)
|
|
|
135 |
PetscFunctionBegin;
|
|
|
136 |
SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF/SYGV - Lapack routine is unavailable.");
|
|
|
137 |
#else
|
| 2317 |
jroman |
138 |
PetscErrorCode ierr;
|
| 2372 |
jroman |
139 |
PetscInt i;
|
| 2317 |
jroman |
140 |
EPS_BLOPEX *blopex = (EPS_BLOPEX *)eps->data;
|
| 2461 |
jroman |
141 |
PetscBool isPrecond;
|
| 1199 |
slepc |
142 |
|
|
|
143 |
PetscFunctionBegin;
|
| 1499 |
slepc |
144 |
if (!eps->ishermitian) {
|
| 2214 |
jroman |
145 |
SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"blopex only works for hermitian problems");
|
| 1199 |
slepc |
146 |
}
|
| 1942 |
jroman |
147 |
if (!eps->which) eps->which = EPS_SMALLEST_REAL;
|
| 1199 |
slepc |
148 |
if (eps->which!=EPS_SMALLEST_REAL) {
|
| 2214 |
jroman |
149 |
SETERRQ(((PetscObject)eps)->comm,1,"Wrong value of eps->which");
|
| 1199 |
slepc |
150 |
}
|
| 1499 |
slepc |
151 |
|
| 2104 |
eromero |
152 |
/* Change the default sigma to inf if necessary */
|
|
|
153 |
if (eps->which == EPS_LARGEST_MAGNITUDE || eps->which == EPS_LARGEST_REAL ||
|
|
|
154 |
eps->which == EPS_LARGEST_IMAGINARY) {
|
| 2331 |
jroman |
155 |
ierr = STSetDefaultShift(eps->OP,3e300);CHKERRQ(ierr);
|
| 2104 |
eromero |
156 |
}
|
|
|
157 |
|
| 2330 |
jroman |
158 |
ierr = STSetUp(eps->OP);CHKERRQ(ierr);
|
| 2331 |
jroman |
159 |
ierr = PetscTypeCompare((PetscObject)eps->OP,STPRECOND,&isPrecond);CHKERRQ(ierr);
|
|
|
160 |
if (!isPrecond) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"blopex only works with STPRECOND");
|
|
|
161 |
ierr = STGetKSP(eps->OP,&blopex->ksp);CHKERRQ(ierr);
|
| 1199 |
slepc |
162 |
|
| 1928 |
jroman |
163 |
eps->ncv = eps->nev = PetscMin(eps->nev,eps->n);
|
| 2499 |
jroman |
164 |
if (eps->mpd) { ierr = PetscInfo(eps,"Warning: parameter mpd ignored\n");CHKERRQ(ierr); }
|
| 1928 |
jroman |
165 |
if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv);
|
| 1499 |
slepc |
166 |
|
|
|
167 |
ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
|
|
|
168 |
ierr = EPSDefaultGetWork(eps,1);CHKERRQ(ierr);
|
| 1199 |
slepc |
169 |
|
| 2621 |
eromero |
170 |
blopex->tol.absolute = eps->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:eps->tol;
|
| 1199 |
slepc |
171 |
blopex->tol.relative = 1e-50;
|
|
|
172 |
|
| 1499 |
slepc |
173 |
SLEPCSetupInterpreter(&blopex->ii);
|
|
|
174 |
blopex->eigenvectors = mv_MultiVectorCreateFromSampleVector(&blopex->ii,eps->ncv,eps->V);
|
| 2372 |
jroman |
175 |
for (i=0;i<eps->ncv;i++) { ierr = PetscObjectReference((PetscObject)eps->V[i]);CHKERRQ(ierr); }
|
| 1199 |
slepc |
176 |
mv_MultiVectorSetRandom(blopex->eigenvectors,1234);
|
| 2435 |
jroman |
177 |
ierr = VecDuplicate(eps->V[0],&blopex->w);CHKERRQ(ierr);
|
| 1499 |
slepc |
178 |
|
|
|
179 |
if (eps->nds > 0) {
|
| 2331 |
jroman |
180 |
blopex->Y = mv_MultiVectorCreateFromSampleVector(&blopex->ii,eps->nds,eps->DS);
|
| 2372 |
jroman |
181 |
for (i=0;i<eps->nds;i++) { ierr = PetscObjectReference((PetscObject)eps->DS[i]);CHKERRQ(ierr); }
|
| 1499 |
slepc |
182 |
} else
|
|
|
183 |
blopex->Y = PETSC_NULL;
|
| 1974 |
eromero |
184 |
|
| 2320 |
jroman |
185 |
#if defined(PETSC_USE_COMPLEX)
|
| 1974 |
eromero |
186 |
blopex->blap_fn.zpotrf = PETSC_zpotrf_interface;
|
|
|
187 |
blopex->blap_fn.zhegv = PETSC_zsygv_interface;
|
|
|
188 |
#else
|
| 1199 |
slepc |
189 |
blopex->blap_fn.dpotrf = PETSC_dpotrf_interface;
|
|
|
190 |
blopex->blap_fn.dsygv = PETSC_dsygv_interface;
|
| 1974 |
eromero |
191 |
#endif
|
| 1199 |
slepc |
192 |
|
| 2499 |
jroman |
193 |
if (eps->extraction) { ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr); }
|
| 1426 |
slepc |
194 |
|
| 1947 |
jroman |
195 |
/* dispatch solve method */
|
| 2214 |
jroman |
196 |
if (eps->leftvecs) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Left vectors not supported in this solver");
|
| 1947 |
jroman |
197 |
eps->ops->solve = EPSSolve_BLOPEX;
|
| 1199 |
slepc |
198 |
PetscFunctionReturn(0);
|
| 2739 |
jroman |
199 |
#endif
|
| 1199 |
slepc |
200 |
}
|
|
|
201 |
|
|
|
202 |
#undef __FUNCT__
|
|
|
203 |
#define __FUNCT__ "EPSSolve_BLOPEX"
|
|
|
204 |
PetscErrorCode EPSSolve_BLOPEX(EPS eps)
|
|
|
205 |
{
|
| 2725 |
jroman |
206 |
EPS_BLOPEX *blopex = (EPS_BLOPEX *)eps->data;
|
|
|
207 |
int i,j,info,its,nconv;
|
|
|
208 |
double *residhist=PETSC_NULL;
|
| 2587 |
jroman |
209 |
PetscErrorCode ierr;
|
| 2725 |
jroman |
210 |
#if defined(PETSC_USE_COMPLEX)
|
|
|
211 |
komplex *lambdahist=PETSC_NULL;
|
|
|
212 |
#else
|
|
|
213 |
double *lambdahist=PETSC_NULL;
|
|
|
214 |
#endif
|
| 1199 |
slepc |
215 |
|
|
|
216 |
PetscFunctionBegin;
|
| 2587 |
jroman |
217 |
if (eps->numbermonitors>0) {
|
| 2725 |
jroman |
218 |
#if defined(PETSC_USE_COMPLEX)
|
|
|
219 |
ierr = PetscMalloc(eps->ncv*(eps->max_it+1)*sizeof(komplex),&lambdahist);CHKERRQ(ierr);
|
|
|
220 |
#else
|
| 2587 |
jroman |
221 |
ierr = PetscMalloc(eps->ncv*(eps->max_it+1)*sizeof(double),&lambdahist);CHKERRQ(ierr);
|
| 2725 |
jroman |
222 |
#endif
|
| 2587 |
jroman |
223 |
ierr = PetscMalloc(eps->ncv*(eps->max_it+1)*sizeof(double),&residhist);CHKERRQ(ierr);
|
|
|
224 |
}
|
|
|
225 |
|
| 2372 |
jroman |
226 |
#if defined(PETSC_USE_COMPLEX)
|
|
|
227 |
info = lobpcg_solve_complex(blopex->eigenvectors,eps,OperatorAMultiVector,
|
| 2316 |
jroman |
228 |
eps->isgeneralized?eps:PETSC_NULL,eps->isgeneralized?OperatorBMultiVector:PETSC_NULL,
|
| 1499 |
slepc |
229 |
eps,Precond_FnMultiVector,blopex->Y,
|
| 1524 |
slepc |
230 |
blopex->blap_fn,blopex->tol,eps->max_it,0,&its,
|
| 2587 |
jroman |
231 |
(komplex*)eps->eigr,lambdahist,eps->ncv,eps->errest,residhist,eps->ncv);
|
| 2372 |
jroman |
232 |
#else
|
|
|
233 |
info = lobpcg_solve_double(blopex->eigenvectors,eps,OperatorAMultiVector,
|
|
|
234 |
eps->isgeneralized?eps:PETSC_NULL,eps->isgeneralized?OperatorBMultiVector:PETSC_NULL,
|
|
|
235 |
eps,Precond_FnMultiVector,blopex->Y,
|
|
|
236 |
blopex->blap_fn,blopex->tol,eps->max_it,0,&its,
|
| 2587 |
jroman |
237 |
eps->eigr,lambdahist,eps->ncv,eps->errest,residhist,eps->ncv);
|
| 2372 |
jroman |
238 |
#endif
|
| 2214 |
jroman |
239 |
if (info>0) SETERRQ1(((PetscObject)eps)->comm,PETSC_ERR_LIB,"Error in blopex (code=%d)",info);
|
| 1199 |
slepc |
240 |
|
| 2587 |
jroman |
241 |
if (eps->numbermonitors>0) {
|
|
|
242 |
for (i=0;i<its;i++) {
|
|
|
243 |
nconv = 0;
|
|
|
244 |
for (j=0;j<eps->ncv;j++) { if (residhist[j+i*eps->ncv]>eps->tol) break; else nconv++; }
|
| 2725 |
jroman |
245 |
ierr = EPSMonitor(eps,i,nconv,(PetscScalar*)lambdahist+i*eps->ncv,eps->eigi,residhist+i*eps->ncv,eps->ncv);CHKERRQ(ierr);
|
| 2587 |
jroman |
246 |
}
|
|
|
247 |
ierr = PetscFree(lambdahist);CHKERRQ(ierr);
|
|
|
248 |
ierr = PetscFree(residhist);CHKERRQ(ierr);
|
|
|
249 |
}
|
|
|
250 |
|
| 1509 |
slepc |
251 |
eps->its = its;
|
| 1199 |
slepc |
252 |
eps->nconv = eps->ncv;
|
| 2435 |
jroman |
253 |
if (eps->OP->sigma != 0.0) {
|
|
|
254 |
for (i=0;i<eps->nconv;i++) eps->eigr[i]+=eps->OP->sigma;
|
|
|
255 |
}
|
| 1199 |
slepc |
256 |
if (info==-1) eps->reason = EPS_DIVERGED_ITS;
|
|
|
257 |
else eps->reason = EPS_CONVERGED_TOL;
|
|
|
258 |
PetscFunctionReturn(0);
|
|
|
259 |
}
|
|
|
260 |
|
|
|
261 |
#undef __FUNCT__
|
| 2348 |
jroman |
262 |
#define __FUNCT__ "EPSReset_BLOPEX"
|
|
|
263 |
PetscErrorCode EPSReset_BLOPEX(EPS eps)
|
|
|
264 |
{
|
|
|
265 |
PetscErrorCode ierr;
|
|
|
266 |
EPS_BLOPEX *blopex = (EPS_BLOPEX *)eps->data;
|
|
|
267 |
|
|
|
268 |
PetscFunctionBegin;
|
|
|
269 |
mv_MultiVectorDestroy(blopex->eigenvectors);
|
|
|
270 |
mv_MultiVectorDestroy(blopex->Y);
|
| 2435 |
jroman |
271 |
ierr = VecDestroy(&blopex->w);CHKERRQ(ierr);
|
| 2348 |
jroman |
272 |
ierr = EPSReset_Default(eps);CHKERRQ(ierr);
|
|
|
273 |
PetscFunctionReturn(0);
|
|
|
274 |
}
|
|
|
275 |
|
|
|
276 |
#undef __FUNCT__
|
| 1199 |
slepc |
277 |
#define __FUNCT__ "EPSDestroy_BLOPEX"
|
|
|
278 |
PetscErrorCode EPSDestroy_BLOPEX(EPS eps)
|
|
|
279 |
{
|
|
|
280 |
PetscErrorCode ierr;
|
|
|
281 |
|
|
|
282 |
PetscFunctionBegin;
|
|
|
283 |
LOBPCG_DestroyRandomContext();
|
|
|
284 |
ierr = PetscFree(eps->data);CHKERRQ(ierr);
|
|
|
285 |
PetscFunctionReturn(0);
|
|
|
286 |
}
|
|
|
287 |
|
| 2448 |
eromero |
288 |
#undef __FUNCT__
|
|
|
289 |
#define __FUNCT__ "EPSSetFromOptions_BLOPEX"
|
|
|
290 |
PetscErrorCode EPSSetFromOptions_BLOPEX(EPS eps)
|
|
|
291 |
{
|
|
|
292 |
PetscErrorCode ierr;
|
|
|
293 |
|
|
|
294 |
PetscFunctionBegin;
|
|
|
295 |
ierr = PetscOptionsHead("EPS BLOPEX Options");CHKERRQ(ierr);
|
|
|
296 |
LOBPCG_SetFromOptionsRandomContext();
|
|
|
297 |
ierr = PetscOptionsTail();CHKERRQ(ierr);
|
|
|
298 |
PetscFunctionReturn(0);
|
|
|
299 |
}
|
|
|
300 |
|
| 1199 |
slepc |
301 |
EXTERN_C_BEGIN
|
|
|
302 |
#undef __FUNCT__
|
|
|
303 |
#define __FUNCT__ "EPSCreate_BLOPEX"
|
|
|
304 |
PetscErrorCode EPSCreate_BLOPEX(EPS eps)
|
|
|
305 |
{
|
|
|
306 |
PetscErrorCode ierr;
|
|
|
307 |
|
|
|
308 |
PetscFunctionBegin;
|
| 2372 |
jroman |
309 |
ierr = PetscNewLog(eps,EPS_BLOPEX,&eps->data);CHKERRQ(ierr);
|
| 1199 |
slepc |
310 |
eps->ops->setup = EPSSetUp_BLOPEX;
|
| 2448 |
eromero |
311 |
eps->ops->setfromoptions = EPSSetFromOptions_BLOPEX;
|
| 1199 |
slepc |
312 |
eps->ops->destroy = EPSDestroy_BLOPEX;
|
| 2348 |
jroman |
313 |
eps->ops->reset = EPSReset_BLOPEX;
|
| 1199 |
slepc |
314 |
eps->ops->backtransform = EPSBackTransform_Default;
|
|
|
315 |
eps->ops->computevectors = EPSComputeVectors_Default;
|
| 2348 |
jroman |
316 |
ierr = STSetType(eps->OP,STPRECOND);CHKERRQ(ierr);
|
|
|
317 |
ierr = STPrecondSetKSPHasMat(eps->OP,PETSC_TRUE);CHKERRQ(ierr);
|
| 2695 |
jroman |
318 |
LOBPCG_InitRandomContext(((PetscObject)eps)->comm,eps->rand);
|
| 1199 |
slepc |
319 |
PetscFunctionReturn(0);
|
|
|
320 |
}
|
|
|
321 |
EXTERN_C_END
|