447  const int nev = problem_->getNEV();
 
  463  Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxtest;
 
  468  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > convtest;
 
  469  if (globalTest_ == Teuchos::null) {
 
  473    convtest = globalTest_;
 
  475  Teuchos::RCP<StatusTestWithOrdering<ScalarType,MV,OP> > ordertest
 
  478  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > locktest;
 
  480    if (lockingTest_ == Teuchos::null) {
 
  484      locktest = lockingTest_;
 
  488  Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
 
  489  alltests.push_back(ordertest);
 
  490  if (locktest != Teuchos::null) alltests.push_back(locktest);
 
  491  if (debugTest_ != Teuchos::null) alltests.push_back(debugTest_);
 
  492  if (maxtest != Teuchos::null) alltests.push_back(maxtest);
 
  493  Teuchos::RCP<StatusTestCombo<ScalarType,MV,OP> > combotest
 
  496  Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest;
 
  497  if ( printer->isVerbosity(
Debug) ) {
 
  506  Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP> > ortho;
 
  507  if (ortho_==
"SVQB") {
 
  509  } 
else if (ortho_==
"DGKS") {
 
  511  } 
else if (ortho_==
"ICGS") {
 
  514    TEUCHOS_TEST_FOR_EXCEPTION(ortho_!=
"SVQB"&&ortho_!=
"DGKS"&&ortho_!=
"ICGS",std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): Invalid orthogonalization type.");
 
  519  Teuchos::ParameterList plist;
 
  520  plist.set(
"Block Size",blockSize_);
 
  521  plist.set(
"Full Ortho",fullOrtho_);
 
  525  Teuchos::RCP<LOBPCG<ScalarType,MV,OP> > lobpcg_solver
 
  528  Teuchos::RCP< const MV > probauxvecs = problem_->getAuxVecs();
 
  529  if (probauxvecs != Teuchos::null) {
 
  530    lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) );
 
  537  int curNumLocked = 0;
 
  538  Teuchos::RCP<MV> lockvecs;
 
  540    lockvecs = MVT::Clone(*problem_->getInitVec(),maxLocked_);
 
  542  std::vector<MagnitudeType> lockvals;
 
  551  Teuchos::RCP<MV> workMV;
 
  552  if (fullOrtho_ == 
false && recover_ == 
true) {
 
  553    workMV = MVT::Clone(*problem_->getInitVec(),2*3*blockSize_);
 
  555  else if (useLocking_) {
 
  556    if (problem_->getM() != Teuchos::null) {
 
  557      workMV = MVT::Clone(*problem_->getInitVec(),4*blockSize_);
 
  560      workMV = MVT::Clone(*problem_->getInitVec(),2*blockSize_);
 
  567  problem_->setSolution(sol);
 
  570  if (state_ != Teuchos::null) {
 
  571    lobpcg_solver->initialize(*state_);
 
  576#ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  577    Teuchos::TimeMonitor slvtimer(*_timerSolve);
 
  583        lobpcg_solver->iterate();
 
  590        if (debugTest_ != Teuchos::null && debugTest_->getStatus() == 
Passed) {
 
  591          throw AnasaziError(
"Anasazi::LOBPCGSolMgr::solve(): User-specified debug status test returned Passed.");
 
  598        else if (ordertest->getStatus() == 
Passed || (maxtest != Teuchos::null && maxtest->getStatus() == 
Passed) ) {
 
  609        else if (locktest != Teuchos::null && locktest->getStatus() == 
Passed) {
 
  611#ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  612          Teuchos::TimeMonitor lcktimer(*_timerLocking);
 
  616          TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() <= 0,std::logic_error,
 
  617              "Anasazi::LOBPCGSolMgr::solve(): status test mistake: howMany() non-positive.");
 
  618          TEUCHOS_TEST_FOR_EXCEPTION(locktest->howMany() != (
int)locktest->whichVecs().size(),std::logic_error,
 
  619              "Anasazi::LOBPCGSolMgr::solve(): status test mistake: howMany() not consistent with whichVecs().");
 
  620          TEUCHOS_TEST_FOR_EXCEPTION(curNumLocked == maxLocked_,std::logic_error,
 
  621              "Anasazi::LOBPCGSolMgr::solve(): status test mistake: locking not deactivated.");
 
  623          int numnew = locktest->howMany();
 
  624          std::vector<int> indnew = locktest->whichVecs();
 
  627          if (curNumLocked + numnew > maxLocked_) {
 
  628            numnew = maxLocked_ - curNumLocked;
 
  629            indnew.resize(numnew);
 
  634          bool hadP = lobpcg_solver->hasP();
 
  638            printer->print(
Debug,
"Locking vectors: ");
 
  639            for (
unsigned int i=0; i<indnew.size(); i++) {printer->stream(
Debug) << 
" " << indnew[i];}
 
  640            printer->print(
Debug,
"\n");
 
  642          std::vector<MagnitudeType> newvals(numnew);
 
  643          Teuchos::RCP<const MV> newvecs;
 
  647            newvecs = MVT::CloneView(*lobpcg_solver->getRitzVectors(),indnew);
 
  649            std::vector<Value<ScalarType> > allvals = lobpcg_solver->getRitzValues();
 
  650            for (
int i=0; i<numnew; i++) {
 
  651              newvals[i] = allvals[indnew[i]].realpart;
 
  656            std::vector<int> indlock(numnew);
 
  657            for (
int i=0; i<numnew; i++) indlock[i] = curNumLocked+i;
 
  658            MVT::SetBlock(*newvecs,indlock,*lockvecs);
 
  659            newvecs = Teuchos::null;
 
  662          lockvals.insert(lockvals.end(),newvals.begin(),newvals.end());
 
  663          curNumLocked += numnew;
 
  666            std::vector<int> indlock(curNumLocked);
 
  667            for (
int i=0; i<curNumLocked; i++) indlock[i] = i;
 
  668            Teuchos::RCP<const MV> curlocked = MVT::CloneView(*lockvecs,indlock);
 
  669            if (probauxvecs != Teuchos::null) {
 
  670              lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs,curlocked) );
 
  673              lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(curlocked) );
 
  677          ordertest->setAuxVals(lockvals);
 
  681            Teuchos::RCP<MV> newstateX, newstateMX, newstateP, newstateMP;
 
  686            std::vector<int> bsind(blockSize_);
 
  687            for (
int i=0; i<blockSize_; i++) bsind[i] = i;
 
  688            newstateX = MVT::CloneViewNonConst(*workMV,bsind);
 
  689            MVT::SetBlock(*state.
X,bsind,*newstateX);
 
  691            if (state.
MX != Teuchos::null) {
 
  692              std::vector<int> block3(blockSize_);
 
  693              for (
int i=0; i<blockSize_; i++) block3[i] = 2*blockSize_+i;
 
  694              newstateMX = MVT::CloneViewNonConst(*workMV,block3);
 
  695              MVT::SetBlock(*state.
MX,bsind,*newstateMX);
 
  700              Teuchos::RCP<MV> newX = MVT::CloneViewNonConst(*newstateX,indnew);
 
  701              MVT::MvRandom(*newX);
 
  703              if (newstateMX != Teuchos::null) {
 
  704                Teuchos::RCP<MV> newMX = MVT::CloneViewNonConst(*newstateMX,indnew);
 
  705                OPT::Apply(*problem_->getM(),*newX,*newMX);
 
  709            Teuchos::Array<Teuchos::RCP<const MV> > curauxvecs = lobpcg_solver->getAuxVecs();
 
  710            Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
 
  712            ortho->projectAndNormalizeMat(*newstateX,curauxvecs,dummyC,Teuchos::null,newstateMX);
 
  717              std::vector<int> block2(blockSize_);
 
  718              for (
int i=0; i<blockSize_; i++) block2[i] = blockSize_+i;
 
  719              newstateP = MVT::CloneViewNonConst(*workMV,block2);
 
  720              MVT::SetBlock(*state.
P,bsind,*newstateP);
 
  722              if (state.
MP != Teuchos::null) {
 
  723                std::vector<int> block4(blockSize_);
 
  724                for (
int i=0; i<blockSize_; i++) block4[i] = 3*blockSize_+i;
 
  725                newstateMP = MVT::CloneViewNonConst(*workMV,block4);
 
  726                MVT::SetBlock(*state.
MP,bsind,*newstateMP);
 
  731                curauxvecs.push_back(newstateX);
 
  732                ortho->projectAndNormalizeMat(*newstateP,curauxvecs,dummyC,Teuchos::null,newstateMP);
 
  736                ortho->projectAndNormalizeMat(*newstateP,curauxvecs,dummyC,Teuchos::null,newstateMP);
 
  741            newstate.
X  = newstateX;
 
  742            newstate.
MX = newstateMX;
 
  743            newstate.
P  = newstateP;
 
  744            newstate.
MP = newstateMP;
 
  745            lobpcg_solver->initialize(newstate);
 
  748          if (curNumLocked == maxLocked_) {
 
  750            combotest->removeTest(locktest);
 
  754          TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): Invalid return from lobpcg_solver::iterate().");
 
  763        if (fullOrtho_==
true || recover_==
false) {
 
  767          printer->stream(
Warnings) << 
"Error! Caught LOBPCGRitzFailure at iteration " << lobpcg_solver->getNumIters() << std::endl
 
  768            << 
"Will not try to recover." << std::endl;
 
  771        printer->stream(
Warnings) << 
"Error! Caught LOBPCGRitzFailure at iteration " << lobpcg_solver->getNumIters() << std::endl
 
  772          << 
"Full orthogonalization is off; will try to recover." << std::endl;
 
  778        Teuchos::RCP<MV> restart, Krestart, Mrestart;
 
  779        int localsize = lobpcg_solver->hasP() ? 3*blockSize_ : 2*blockSize_;
 
  780        bool hasM = problem_->getM() != Teuchos::null;
 
  782          std::vector<int> recind(localsize);
 
  783          for (
int i=0; i<localsize; i++) recind[i] = i;
 
  784          restart = MVT::CloneViewNonConst(*workMV,recind);
 
  787          std::vector<int> recind(localsize);
 
  788          for (
int i=0; i<localsize; i++) recind[i] = localsize+i;
 
  789          Krestart = MVT::CloneViewNonConst(*workMV,recind);
 
  802          std::vector<int> blk1(blockSize_);
 
  803          for (
int i=0; i < blockSize_; i++) blk1[i] = i;
 
  804          MVT::SetBlock(*curstate.
X,blk1,*restart);
 
  808            MVT::SetBlock(*curstate.
MX,blk1,*Mrestart);
 
  814          std::vector<int> blk2(blockSize_);
 
  815          for (
int i=0; i < blockSize_; i++) blk2[i] = blockSize_+i;
 
  816          MVT::SetBlock(*curstate.
H,blk2,*restart);
 
  820            MVT::SetBlock(*curstate.
MH,blk2,*Mrestart);
 
  824        if (localsize == 3*blockSize_) {
 
  825          std::vector<int> blk3(blockSize_);
 
  826          for (
int i=0; i < blockSize_; i++) blk3[i] = 2*blockSize_+i;
 
  827          MVT::SetBlock(*curstate.
P,blk3,*restart);
 
  831            MVT::SetBlock(*curstate.
MP,blk3,*Mrestart);
 
  835        Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummyC;
 
  836        Teuchos::Array<Teuchos::RCP<const MV> > Q;
 
  838          if (curNumLocked > 0) {
 
  839            std::vector<int> indlock(curNumLocked);
 
  840            for (
int i=0; i<curNumLocked; i++) indlock[i] = i;
 
  841            Teuchos::RCP<const MV> curlocked = MVT::CloneView(*lockvecs,indlock);
 
  842            Q.push_back(curlocked);
 
  844          if (probauxvecs != Teuchos::null) {
 
  845            Q.push_back(probauxvecs);
 
  848        int rank = ortho->projectAndNormalizeMat(*restart,Q,dummyC,Teuchos::null,Mrestart);
 
  849        if (rank < blockSize_) {
 
  851          printer->stream(
Errors) << 
"Error! Recovered basis only rank " << rank << 
". Block size is " << blockSize_ << 
".\n" 
  852            << 
"Recovery failed." << std::endl;
 
  856        if (rank < localsize) {
 
  858          std::vector<int> redind(localsize);
 
  859          for (
int i=0; i<localsize; i++) redind[i] = i;
 
  861          restart = MVT::CloneViewNonConst(*restart,redind);
 
  862          Krestart = MVT::CloneViewNonConst(*Krestart,redind);
 
  870        Teuchos::SerialDenseMatrix<int,ScalarType> KK(localsize,localsize), MM(localsize,localsize), S(localsize,localsize);
 
  871        std::vector<MagnitudeType> theta(localsize);
 
  875        MVT::MvTransMv(1.0,*restart,*Mrestart,MM);
 
  878        OPT::Apply(*problem_->getOperator(),*restart,*Krestart);
 
  881        MVT::MvTransMv(1.0,*restart,*Krestart,KK);
 
  883        msutils::directSolver(localsize,KK,Teuchos::rcpFromRef(MM),S,theta,rank,1);
 
  884        if (rank < blockSize_) {
 
  885          printer->stream(
Errors) << 
"Error! Recovered basis of rank " << rank << 
" produced only " << rank << 
"ritz vectors.\n" 
  886            << 
"Block size is " << blockSize_ << 
".\n" 
  887            << 
"Recovery failed." << std::endl;
 
  894          Teuchos::BLAS<int,ScalarType> blas;
 
  895          std::vector<int> order(rank);
 
  897          sorter->sort( theta, Teuchos::rcpFromRef(order),rank );   
 
  899          Teuchos::SerialDenseMatrix<int,ScalarType> curS(Teuchos::View,S,rank,rank);
 
  900          msutils::permuteVectors(order,curS);
 
  903        Teuchos::SerialDenseMatrix<int,ScalarType> S1(Teuchos::View,S,localsize,blockSize_);
 
  907        Teuchos::RCP<MV> newX;
 
  909          std::vector<int> bsind(blockSize_);
 
  910          for (
int i=0; i<blockSize_; i++) bsind[i] = i;
 
  911          newX = MVT::CloneViewNonConst(*Krestart,bsind);
 
  913        MVT::MvTimesMatAddMv(1.0,*restart,S1,0.0,*newX);
 
  916        theta.resize(blockSize_);
 
  917        newstate.
T = Teuchos::rcpFromRef(theta);
 
  919        lobpcg_solver->initialize(newstate);
 
  923          << 
"Anasazi::LOBPCGSolMgr::solve() caught unexpected exception from Anasazi::LOBPCG::iterate() at iteration " << lobpcg_solver->getNumIters() << std::endl
 
  924          << err.what() << std::endl
 
  925          << 
"Anasazi::LOBPCGSolMgr::solve() returning Unconverged with no solutions." << std::endl;
 
  931    sol.
numVecs = ordertest->howMany();
 
  933      sol.
Evecs = MVT::Clone(*problem_->getInitVec(),sol.
numVecs);
 
  936      std::vector<MagnitudeType> vals(sol.
numVecs);
 
  939      std::vector<int> which = ordertest->whichVecs();
 
  943      std::vector<int> inlocked(0), insolver(0);
 
  944      for (
unsigned int i=0; i<which.size(); i++) {
 
  946          TEUCHOS_TEST_FOR_EXCEPTION(which[i] >= blockSize_,std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): positive indexing mistake from ordertest.");
 
  947          insolver.push_back(which[i]);
 
  951          TEUCHOS_TEST_FOR_EXCEPTION(which[i] < -curNumLocked,std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): negative indexing mistake from ordertest.");
 
  952          inlocked.push_back(which[i] + curNumLocked);
 
  956      TEUCHOS_TEST_FOR_EXCEPTION(insolver.size() + inlocked.size() != (
unsigned int)sol.
numVecs,std::logic_error,
"Anasazi::LOBPCGSolMgr::solve(): indexing mistake.");
 
  959      if (insolver.size() > 0) {
 
  961        int lclnum = insolver.size();
 
  962        std::vector<int> tosol(lclnum);
 
  963        for (
int i=0; i<lclnum; i++) tosol[i] = i;
 
  964        Teuchos::RCP<const MV> v = MVT::CloneView(*lobpcg_solver->getRitzVectors(),insolver);
 
  965        MVT::SetBlock(*v,tosol,*sol.
Evecs);
 
  967        std::vector<Value<ScalarType> > fromsolver = lobpcg_solver->getRitzValues();
 
  968        for (
unsigned int i=0; i<insolver.size(); i++) {
 
  969          vals[i] = fromsolver[insolver[i]].realpart;
 
  974      if (inlocked.size() > 0) {
 
  975        int solnum = insolver.size();
 
  977        int lclnum = inlocked.size();
 
  978        std::vector<int> tosol(lclnum);
 
  979        for (
int i=0; i<lclnum; i++) tosol[i] = solnum + i;
 
  980        Teuchos::RCP<const MV> v = MVT::CloneView(*lockvecs,inlocked);
 
  981        MVT::SetBlock(*v,tosol,*sol.
Evecs);
 
  983        for (
unsigned int i=0; i<inlocked.size(); i++) {
 
  984          vals[i+solnum] = lockvals[inlocked[i]];
 
  990        std::vector<int> order(sol.
numVecs);
 
  991        sorter->sort( vals, Teuchos::rcpFromRef(order), sol.
numVecs);
 
  993        for (
int i=0; i<sol.
numVecs; i++) {
 
  994          sol.
Evals[i].realpart = vals[i];
 
  995          sol.
Evals[i].imagpart = MT::zero();
 
 1007  lobpcg_solver->currentStatus(printer->stream(
FinalSummary));
 
 1010#ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
 1012    Teuchos::TimeMonitor::summarize( printer->stream( 
TimingDetails ) );
 
 1016  problem_->setSolution(sol);
 
 1017  printer->stream(
Debug) << 
"Returning " << sol.
numVecs << 
" eigenpairs to eigenproblem." << std::endl;
 
 1020  numIters_ = lobpcg_solver->getNumIters();