23 double _tol,
int _maxIter,
int _verb) :
31 maxIterEigenSolve(_maxIter),
50 double _tol,
int _maxIter,
int _verb) :
58 maxIterEigenSolve(_maxIter),
78 double _tol,
int _maxIter,
int _verb) :
86 maxIterEigenSolve(_maxIter),
106 double _tol,
int _maxIter,
int _verb) :
114 maxIterEigenSolve(_maxIter),
134 return ARPACKm3::reSolve(numEigen, Q, lambda, 0);
139 int ARPACKm3::reSolve(
int numEigen,
Epetra_MultiVector &Q,
double *lambda,
int startingEV) {
190 if (numEigen <= startingEV) {
194 int info = myVerify.inputArguments(numEigen, K, M, 0, Q, minimumSpaceDimension(numEigen));
198 int myPid = MyComm.MyPID();
200 int localSize = Q.MyLength();
201 int NCV = Q.NumVectors();
204 if (NCV > Q.GlobalLength()) {
205 if (numEigen >= Q.GlobalLength()) {
207 cerr <<
" !! The number of requested eigenvalues must be smaller than the dimension";
208 cerr <<
" of the matrix !!\n";
212 NCV = Q.GlobalLength();
215 int localVerbose = verbose*(myPid == 0);
218 highMem = (highMem > currentSize()) ? highMem : currentSize();
223 int *wI =
new (nothrow)
int[lwI];
227 memRequested +=
sizeof(int)*lwI/(1024.0*1024.0);
230 int *ipntr = wI + 11;
231 int *select = wI + 22;
233 int lworkl = NCV*(NCV+8);
234 int lwD = lworkl + 4*localSize;
235 double *wD =
new (nothrow)
double[lwD];
240 memRequested +=
sizeof(double)*(4*localSize+lworkl)/(1024.0*1024.0);
242 double *pointer = wD;
244 double *workl = pointer;
245 pointer = pointer + lworkl;
247 double *resid = pointer;
248 pointer = pointer + localSize;
250 double *workd = pointer;
252 double *v = Q.Values();
254 highMem = (highMem > currentSize()) ? highMem : currentSize();
258 if (startingEV > 0) {
260 memset(resid, 0, localSize*
sizeof(
double));
261 for (
int jj = 0; jj < startingEV; ++jj)
262 for (
int ii = 0; ii < localSize; ++ii)
263 resid[ii] += v[ii + jj*localSize];
268 iparam[3-1] = maxIterEigenSolve;
280 double *vTmp =
new (nothrow)
double[localSize];
286 memRequested +=
sizeof(double)*localSize/(1024.0*1024.0);
288 highMem = (highMem > currentSize()) ? highMem : currentSize();
290 if (localVerbose > 0) {
292 cout <<
" *|* Problem: ";
294 cout <<
"K*Q = M*Q D ";
296 cout <<
"K*Q = Q D ";
298 cout <<
" *|* Algorithm = ARPACK (mode 3)" << endl;
299 cout <<
" *|* Number of requested eigenvalues = " << numEigen << endl;
301 cout.setf(ios::scientific, ios::floatfield);
302 cout <<
" *|* Tolerance for convergence = " << tolEigenSolve << endl;
304 cout <<
" *|* User-defined starting vector (Combination of " << startingEV <<
" vectors)\n";
305 cout <<
"\n -- Start iterations -- \n";
312 timeOuterLoop -= MyWatch.WallTime();
315 highMem = (highMem > currentSize()) ? highMem : currentSize();
319 callFortran.PSAUPD(MPIComm->
Comm(), &ido,
'G', localSize, which, numEigen, tolEigenSolve,
320 resid, NCV, v, localSize, iparam, ipntr, workd, workl, lworkl, &info, localVerbose);
322 callFortran.SAUPD(&ido,
'G', localSize, which, numEigen, tolEigenSolve, resid, NCV, v,
323 localSize, iparam, ipntr, workd, workl, lworkl, &info, localVerbose);
325 callFortran.SAUPD(&ido,
'G', localSize, which, numEigen, tolEigenSolve, resid, NCV, v,
326 localSize, iparam, ipntr, workd, workl, lworkl, &info, localVerbose);
331 v3.ResetView(workd + ipntr[0] - 1);
333 timeMassOp -= MyWatch.WallTime();
337 memcpy(v1.Values(), v3.Values(), localSize*
sizeof(double));
338 timeMassOp += MyWatch.WallTime();
341 v2.ResetView(workd + ipntr[1] - 1);
342 timeStifOp -= MyWatch.WallTime();
343 K->ApplyInverse(v1, v2);
344 timeStifOp += MyWatch.WallTime();
351 v1.ResetView(workd + ipntr[2] - 1);
352 v2.ResetView(workd + ipntr[1] - 1);
353 timeStifOp -= MyWatch.WallTime();
354 K->ApplyInverse(v1, v2);
355 timeStifOp += MyWatch.WallTime();
362 v1.ResetView(workd + ipntr[0] - 1);
363 v2.ResetView(workd + ipntr[1] - 1);
364 timeMassOp -= MyWatch.WallTime();
368 memcpy(v2.Values(), v1.Values(), localSize*
sizeof(double));
369 timeMassOp += MyWatch.WallTime();
375 timeOuterLoop += MyWatch.WallTime();
376 highMem = (highMem > currentSize()) ? highMem : currentSize();
381 cerr <<
" Error with DSAUPD, info = " << info << endl;
388 timePostProce -= MyWatch.WallTime();
391 callFortran.PSEUPD(MPIComm->
Comm(), 1,
'A', select, lambda, v, localSize, sigma,
'G',
392 localSize, which, numEigen, tolEigenSolve, resid, NCV, v, localSize, iparam, ipntr,
393 workd, workl, lworkl, &info);
395 callFortran.SEUPD(1,
'A', select, lambda, v, localSize, sigma,
'G', localSize, which,
396 numEigen, tolEigenSolve, resid, NCV, v, localSize, iparam, ipntr, workd, workl,
399 callFortran.SEUPD(1,
'A', select, lambda, v, localSize, sigma,
'G', localSize, which,
400 numEigen, tolEigenSolve, resid, NCV, v, localSize, iparam, ipntr, workd, workl,
403 timePostProce += MyWatch.WallTime();
404 highMem = (highMem > currentSize()) ? highMem : currentSize();
410 cerr <<
" Error with DSEUPD, info = " << info << endl;
418 outerIter = iparam[3-1];
419 knownEV = iparam[5-1];
420 orthoOp = iparam[11-1];
427 return (info == 0) ? knownEV : info;
432 void ARPACKm3::initializeCounters() {
450 void ARPACKm3::algorithmInfo()
const {
452 int myPid = MyComm.MyPID();
455 cout <<
" Algorithm: ARPACK (Mode 3)\n";
461 void ARPACKm3::memoryInfo()
const {
463 int myPid = MyComm.MyPID();
465 double maxHighMem = 0.0;
466 double tmp = highMem;
467 MyComm.MaxAll(&tmp, &maxHighMem, 1);
469 double maxMemRequested = 0.0;
471 MyComm.MaxAll(&tmp, &maxMemRequested, 1);
475 cout.setf(ios::fixed, ios::floatfield);
476 cout <<
" Memory requested per processor by the eigensolver = (EST) ";
478 cout << maxMemRequested <<
" MB " << endl;
480 cout <<
" High water mark in eigensolver = (EST) ";
482 cout << maxHighMem <<
" MB " << endl;
489 void ARPACKm3::operationInfo()
const {
491 int myPid = MyComm.MyPID();
494 cout <<
" --- Operations ---\n\n";
495 cout <<
" Total number of mass matrix multiplications = ";
497 cout << massOp << endl;
498 cout <<
" Total number of orthogonalizations = ";
500 cout << orthoOp << endl;
501 cout <<
" Total number of stiffness matrix operations = ";
503 cout << stifOp << endl;
505 cout <<
" Total number of outer iterations = ";
507 cout << outerIter << endl;
514 void ARPACKm3::timeInfo()
const {
516 int myPid = MyComm.MyPID();
519 cout <<
" --- Timings ---\n\n";
520 cout.setf(ios::fixed, ios::floatfield);
522 cout <<
" Total time for outer loop = ";
524 cout << timeOuterLoop <<
" s" << endl;
525 cout <<
" Time for mass matrix operations = ";
527 cout << timeMassOp <<
" s ";
529 cout << 100*timeMassOp/timeOuterLoop <<
" %\n";
530 cout <<
" Time for stiffness matrix solves = ";
532 cout << timeStifOp <<
" s ";
534 cout << 100*timeStifOp/timeOuterLoop <<
" %\n";
536 cout <<
" Total time for post-processing = ";
538 cout << timePostProce <<
" s\n";