/** advance all the walkers with killnode==yes */ void WFMCUpdateAllWithReweight::advanceWalkers(WalkerIter_t it , WalkerIter_t it_end, bool measure) { for (; it != it_end; ++it) { Walker_t& thisWalker(**it); W.loadWalker(thisWalker,false); setScaledDriftPbyPandNodeCorr(m_tauovermass,W.G,drift); //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandomWithEngine(deltaR,RandomGen); //reject illegal positions or big displacement if (!W.makeMoveWithDrift(thisWalker,drift,deltaR, m_sqrttau)) { H.rejectedMove(W,thisWalker); H.auxHevaluate(W,thisWalker); continue; } ///W.R = m_sqrttau*deltaR + thisWalker.Drift; ///W.R += thisWalker.R; ///W.update(); //save old local energy RealType eold = thisWalker.Properties(LOCALENERGY); RealType enew = eold; //evaluate wave function RealType logpsi(Psi.evaluateLog(W)); bool accepted=false; enew=H.evaluate(W); RealType logGf = -0.5*Dot(deltaR,deltaR); setScaledDriftPbyPandNodeCorr(m_tauovermass,W.G,drift); deltaR = thisWalker.R - W.R - drift; RealType logGb = -m_oneover2tau*Dot(deltaR,deltaR); RealType prob= std::min(std::exp(logGb-logGf +2.0*(logpsi-thisWalker.Properties(LOGPSI))),1.0); if (RandomGen() > prob) { enew=eold; thisWalker.Age++; // thisWalker.Properties(R2ACCEPTED)=0.0; // thisWalker.Properties(R2PROPOSED)=rr_proposed; H.rejectedMove(W,thisWalker); } else { thisWalker.Age=0; accepted=true; W.saveWalker(thisWalker); // rr_accepted = rr_proposed; // thisWalker.resetProperty(logpsi,Psi.getPhase(),enew,rr_accepted,rr_proposed,nodecorr); thisWalker.resetProperty(logpsi,Psi.getPhase(),enew); H.auxHevaluate(W,thisWalker); H.saveProperty(thisWalker.getPropertyBase()); } thisWalker.Weight *= std::exp(-Tau*(enew -thisWalker.PropertyHistory[Eindex][Elength])); thisWalker.addPropertyHistoryPoint(Eindex,enew); if (accepted) ++nAccept; else ++nReject; } }
void VMCUpdatePbyP::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end) { while(it != it_end) { Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); W.R = thisWalker.R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); RealType psi_old = thisWalker.Properties(SIGN); RealType psi = psi_old; for(int iter=0; iter<nSubSteps; iter++) { makeGaussRandomWithEngine(deltaR,RandomGen); bool stucked=true; for(int iat=0; iat<W.getTotalNum(); iat++) { PosType dr = m_sqrttau*deltaR[iat]; PosType newpos = W.makeMove(iat,dr); RealType ratio = Psi.ratio(W,iat); RealType prob = std::min(1.0e0,ratio*ratio); if(RandomGen() < prob) { stucked=false; ++nAccept; W.acceptMove(iat); Psi.acceptMove(W,iat); } else { ++nReject; W.rejectMove(iat); Psi.rejectMove(iat); } } if(stucked) { ++nAllRejected; } } thisWalker.R = W.R; w_buffer.rewind(); W.updateBuffer(w_buffer); RealType logpsi = Psi.updateBuffer(W,w_buffer); //W.copyToBuffer(w_buffer); //RealType logpsi = Psi.evaluate(W,w_buffer); RealType eloc=H.evaluate(W); thisWalker.resetProperty(logpsi,Psi.getPhase(),eloc); H.saveProperty(thisWalker.getPropertyBase()); ++it; } }
/** evaluate everything before optimization */ void QMCCostFunctionSingle::checkConfigurations() { dG.resize(W.getTotalNum()); dL.resize(W.getTotalNum()); int numLocWalkers=W.getActiveWalkers(); Records.resize(numLocWalkers,6); typedef MCWalkerConfiguration::Walker_t Walker_t; MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); int nat = W.getTotalNum(); int iw=0; int totalElements=W.getTotalNum()*OHMMS_DIM; Etarget=0.0; while(it != it_end) { Walker_t& thisWalker(**it); //clean-up DataSet to save re-used values thisWalker.DataSet.clear(); //rewind the counter thisWalker.DataSet.rewind(); //MCWalkerConfiguraton::registerData add distance-table data W.registerData(thisWalker,thisWalker.DataSet); Return_t* saved=Records[iw]; #if defined(QMC_COMPLEX) app_error() << " Optimization is not working with complex wavefunctions yet" << endl; app_error() << " Needs to fix TrialWaveFunction::evaluateDeltaLog " << endl; Psi.evaluateDeltaLog(W, saved[LOGPSI_FIXED], saved[LOGPSI_FREE], dG, dL); thisWalker.DataSet.add(&(dG[0][0]),&(dG[0][0])+totalElements); #else Psi.evaluateDeltaLog(W, saved[LOGPSI_FIXED], saved[LOGPSI_FREE], thisWalker.Drift, dL); #endif thisWalker.DataSet.add(dL.first_address(),dL.last_address()); Etarget += saved[ENERGY_TOT] = H.evaluate(W); saved[ENERGY_FIXED] = H.getInvariantEnergy(); ++it; ++iw; } //Need to sum over the processors vector<Return_t> etemp(2); etemp[0]=Etarget; etemp[1]=static_cast<Return_t>(numLocWalkers); myComm->allreduce(etemp); Etarget = static_cast<Return_t>(etemp[0]/etemp[1]); NumSamples = static_cast<int>(etemp[1]); setTargetEnergy(Etarget); ReportCounter=0; }
void CSUpdateBase::updateCSWalkers(WalkerIter_t it, WalkerIter_t it_end) { int iw=0; while(it != it_end) { Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer((*it)->DataSet); w_buffer.rewind(); W.updateBuffer(**it,w_buffer); //evalaute the wavefunction and hamiltonian for(int ipsi=0; ipsi< nPsi; ipsi++) { //Need to modify the return value of OrbitalBase::registerData logpsi[ipsi]=Psi1[ipsi]->updateBuffer(W,(*it)->DataSet); Psi1[ipsi]->G=W.G; thisWalker.Properties(ipsi,LOGPSI)=logpsi[ipsi]; thisWalker.Properties(ipsi,LOCALENERGY)=H1[ipsi]->evaluate(W); H1[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi)); sumratio[ipsi]=1.0; } int indexij(0); RealType *rPtr=ratioIJ[iw]; for(int ipsi=0; ipsi< nPsi-1; ipsi++) { for(int jpsi=ipsi+1; jpsi< nPsi; jpsi++) { RealType r=std::exp(2.0*(logpsi[jpsi]-logpsi[ipsi])); rPtr[indexij++]=r*avgNorm[ipsi]/avgNorm[jpsi]; sumratio[ipsi] += r; sumratio[jpsi] += 1.0/r; } } //Re-use Multiplicity as the sumratio thisWalker.Multiplicity=sumratio[0]; for(int ipsi=0; ipsi< nPsi; ipsi++) { thisWalker.Properties(ipsi,UMBRELLAWEIGHT) = invsumratio[ipsi] =1.0/sumratio[ipsi]; } //DON't forget DRIFT!!! thisWalker.Drift=0.0; if(useDrift) { for(int ipsi=0; ipsi< nPsi; ipsi++) PAOps<RealType,DIM>::axpy(invsumratio[ipsi],Psi1[ipsi]->G,thisWalker.Drift); setScaledDrift(Tau,thisWalker.Drift); } ++it; ++iw; } }
void CompositeEstimatorSet::accumulate(MCWalkerConfiguration& W, MCWalkerConfiguration::iterator wit, MCWalkerConfiguration::iterator wit_end, RealType wgtnorm) { //initialize temporary data for(int i=0; i< Estimators.size(); i++) Estimators[i]->startAccumulate(); typedef MCWalkerConfiguration::Walker_t Walker_t; if(W.updatePbyP()) { while(wit != wit_end) { Walker_t& thisWalker(**wit); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); w_buffer.rewind(); W.copyFromBuffer(w_buffer); for(int i=0; i< Estimators.size(); i++) Estimators[i]->accumulate(W); ++wit; } } else { while(wit != wit_end) { Walker_t& thisWalker(**wit); W.R=thisWalker.R; W.update(); for(int i=0; i< Estimators.size(); i++) Estimators[i]->accumulate(W); ++wit; } } for(int i=0; i< Estimators.size(); i++) Estimators[i]->stopAccumulate(wgtnorm); //curSteps++; }
bool DummyQMC::run() { m_oneover2tau = 0.5/Tau; m_sqrttau = sqrt(Tau); cout << "Lattice of ParticleSet " << endl; W.Lattice.print(cout); //property container to hold temporary properties, such as a local energy //MCWalkerConfiguration::PropertyContainer_t Properties; MCWalkerConfiguration::Walker_t& thisWalker(**W.begin()); //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); //new poosition W.R = m_sqrttau*deltaR + thisWalker.R + thisWalker.Drift; //apply boundary condition: put everything back to a unit cell W.applyBC(W.R); //update the distance table associated with W W.update(); //evaluate wave function //update the properties: note that we are getting \f$\sum_i \ln(|psi_i|)\f$ and catching the sign separately ValueType logpsi(Psi.evaluateLog(W)); RealType eloc=H.evaluate(W); return true; }
bool nImO::Array::deeplyEqualTo (const nImO::Value & other) const { ODL_OBJENTER(); //#### ODL_P1("other = ", &other); //#### bool result = (&other == this); if (! result) { const Array * otherPtr = other.asArray(); if (otherPtr && (size() == otherPtr->size())) { const_iterator thisWalker(inherited2::begin()); const_iterator otherWalker(otherPtr->inherited2::begin()); for (result = true; result && (thisWalker != inherited2::end()); ++thisWalker, ++otherWalker) { SpValue thisValue(*thisWalker); SpValue otherValue(*otherWalker); if ((nullptr != thisValue) && (nullptr != otherValue)) { result = thisValue->deeplyEqualTo(*otherValue); } else { result = false; } } } } ODL_OBJEXIT_B(result); //#### return result; } // nImO::Array::deeplyEqualTo
void VMCParticleByParticle::advanceWalkerByWalker() { MCWalkerConfiguration::iterator it(W.begin()),it_end(W.end()); while(it != it_end) { //MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]); Walker_t& thisWalker(**it); Buffer_t& w_buffer(thisWalker.DataSet); W.R = thisWalker.R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); ValueType psi_old = thisWalker.Properties(SIGN); ValueType psi = psi_old; //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); bool moved = false; for(int iat=0; iat<W.getTotalNum(); iat++) { PosType dr = m_sqrttau*deltaR[iat]+thisWalker.Drift[iat]; PosType newpos = W.makeMove(iat,dr); //RealType ratio = Psi.ratio(W,iat); RealType ratio = Psi.ratio(W,iat,dG,dL); G = W.G+dG; //RealType forwardGF = exp(-0.5*dot(deltaR[iat],deltaR[iat])); //dr = (*it)->R[iat]-newpos-Tau*G[iat]; //RealType backwardGF = exp(-oneover2tau*dot(dr,dr)); RealType logGf = -0.5e0*dot(deltaR[iat],deltaR[iat]); ValueType vsq = Dot(G,G); ValueType scale = ((-1.0e0+sqrt(1.0e0+2.0e0*Tau*vsq))/vsq); dr = thisWalker.R[iat]-newpos-scale*G[iat]; //dr = (*it)->R[iat]-newpos-Tau*G[iat]; RealType logGb = -m_oneover2tau*dot(dr,dr); RealType prob = std::min(1.0e0,ratio*ratio*exp(logGb-logGf)); //alternatively if(Random() < prob) { moved = true; ++nAccept; W.acceptMove(iat); //Psi.update(W,iat); Psi.update2(W,iat); W.G = G; W.L += dL; //(*it)->Drift = Tau*G; thisWalker.Drift = scale*G; } else { ++nReject; Psi.restore(iat); } } if(moved) { w_buffer.rewind(); W.copyToBuffer(w_buffer); psi = Psi.evaluate(W,w_buffer); thisWalker.R = W.R; RealType eloc=H.evaluate(W); thisWalker.resetProperty(log(abs(psi)),psi,eloc); H.saveProperty(thisWalker.getPropertyBase()); } //Keep until everything is tested: debug routine // if(moved) { // //(*it)->Data.rewind(); // //W.copyToBuffer((*it)->Data); // //psi = Psi.evaluate(W,(*it)->Data); // DataSet[iwalker]->rewind(); // W.copyToBuffer(*DataSet[iwalker]); // psi = Psi.evaluate(W,*DataSet[iwalker]); // cout << "What is the ratio " << psi/psi_old << endl; // // std::cout << "Are they the same ratio=" << psi << endl; // RealType please = H.evaluate(W); // /**@note Debug the particle-by-particle move */ // G = W.G; // L = W.L; // DistanceTable::update(W); // ValueType psinew = Psi.evaluate(W); // ValueType dsum=pow(psi-psinew,2); // std::cout<< "Diff of updated and calculated gradients/laplacians" << endl; // for(int iat=0; iat<W.getTotalNum(); iat++) { // dsum += pow(G[iat][0]-W.G[iat][0],2)+pow(G[iat][1]-W.G[iat][1],2) // +pow(G[iat][2]-W.G[iat][2],2)+pow(L[iat]-W.L[iat],2); // std::cout << G[iat]-W.G[iat] << " " << L[iat]-W.L[iat] <<endl; // } // std::cout << "Are they the same ratio=" << psi << " eval=" << psinew << " " << sqrt(dsum) << endl; // std::cout << "============================ " << endl; // for(int i=0; i<W.getLocalNum(); i++) { // cout << W.G[i] << " " << W.L[i] << endl; // } // (*it)->Properties(PSISQ) = psi*psi; // (*it)->Properties(PSI) = psi; // (*it)->Properties(LOCALENERGY) = H.evaluate(W); // std::cout << "Energy " << please << " " << (*it)->Properties(LOCALENERGY) // << endl; // H.copy((*it)->getEnergyBase()); // ValueType vsq = Dot(W.G,W.G); // ValueType scale = ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq); // (*it)->Drift = scale*W.G; // (*it)->R =W.R; // } else { ++nAllRejected; } ++it; } }
void RQMCEstimator ::initialize(MCWalkerConfiguration& W, vector<ParticleSet*>& WW, SpaceWarp& Warp, vector<QMCHamiltonian*>& h, vector<TrialWaveFunction*>& psi, RealType tau,vector<RealType>& Norm, bool require_register) { NumWalkers = W.getActiveWalkers(); int numPtcls(W.getTotalNum()); RatioIJ.resize(NumWalkers,NumCopies*(NumCopies-1)/2); vector<RealType> invsumratio(NumCopies); MCWalkerConfiguration::ParticlePos_t drift(numPtcls); MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); vector<RealType> sumratio(NumCopies), logpsi(NumCopies); vector<RealType> Jacobian(NumCopies); int jindex=W.addProperty("Jacobian"); int iw(0); int DataSetSize((*it)->DataSet.size()); while(it != it_end) { Walker_t& thisWalker(**it); (*it)->DataSet.rewind(); //NECESSARY SINCE THE DISTANCE TABLE OF W ARE USED TO WARP if(require_register) { W.registerData(thisWalker,(*it)->DataSet); } else { W.R = thisWalker.R; W.update(); if(DataSetSize) W.updateBuffer((*it)->DataSet); } for(int ipsi=0; ipsi<NumCopies; ipsi++) Jacobian[ipsi]=1.e0; for(int iptcl=0; iptcl< numPtcls; iptcl++){ Warp.warp_one(iptcl,0); for(int ipsi=0; ipsi<NumCopies; ipsi++){ WW[ipsi]->R[iptcl]=W.R[iptcl]+Warp.get_displacement(iptcl,ipsi); Jacobian[ipsi]*=Warp.get_Jacobian(iptcl,ipsi); } if(require_register || DataSetSize) Warp.update_one_ptcl_Jacob(iptcl); } for(int ipsi=0; ipsi<NumCopies; ipsi++){ thisWalker.Properties(ipsi,jindex)=Jacobian[ipsi]; } //update distance table and bufferize it if necessary if(require_register) { for(int ipsi=0; ipsi<NumCopies; ipsi++){ WW[ipsi]->registerData((*it)->DataSet); } Warp.registerData(WW,(*it)->DataSet); } else { for(int ipsi=0; ipsi<NumCopies; ipsi++){ WW[ipsi]->update(); if(DataSetSize) WW[ipsi]->updateBuffer((*it)->DataSet); } if(DataSetSize) Warp.updateBuffer((*it)->DataSet); } //evalaute the wavefunction and hamiltonian for(int ipsi=0; ipsi< NumCopies;ipsi++) { psi[ipsi]->G.resize(numPtcls); psi[ipsi]->L.resize(numPtcls); //Need to modify the return value of OrbitalBase::registerData if(require_register) { logpsi[ipsi]=psi[ipsi]->registerData(*WW[ipsi],(*it)->DataSet); }else{ if(DataSetSize)logpsi[ipsi]=psi[ipsi]->updateBuffer(*WW[ipsi],(*it)->DataSet); else logpsi[ipsi]=psi[ipsi]->evaluateLog(*WW[ipsi]); } psi[ipsi]->G=WW[ipsi]->G; thisWalker.Properties(ipsi,LOGPSI)=logpsi[ipsi]; thisWalker.Properties(ipsi,LOCALENERGY)=h[ipsi]->evaluate(*WW[ipsi]); h[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi)); sumratio[ipsi]=1.0; } //Check SIMONE's note //Compute the sum over j of Psi^2[j]/Psi^2[i] for each i int indexij(0); RealType *rPtr=RatioIJ[iw]; for(int ipsi=0; ipsi< NumCopies-1; ipsi++) { for(int jpsi=ipsi+1; jpsi< NumCopies; jpsi++){ RealType r= std::exp(2.0*(logpsi[jpsi]-logpsi[ipsi]))*Norm[ipsi]/Norm[jpsi]; //BEWARE: RatioIJ DOES NOT INCLUDE THE JACOBIANS! rPtr[indexij++]=r; r*=(Jacobian[jpsi]/Jacobian[ipsi]); sumratio[ipsi] += r; sumratio[jpsi] += 1.0/r; } } //Re-use Multiplicity as the sumratio thisWalker.Multiplicity=sumratio[0]; /*START COMMENT QMCTraits::PosType WarpDrift; RealType denom(0.e0),wgtpsi; thisWalker.Drift=0.e0; for(int ipsi=0; ipsi< NumCopies; ipsi++) { wgtpsi=1.e0/sumratio[ipsi]; thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=wgtpsi; denom += wgtpsi; for(int iptcl=0; iptcl< numPtcls; iptcl++){ WarpDrift=dot( psi[ipsi]->G[iptcl], Warp.get_Jacob_matrix(iptcl,ipsi) ) +5.0e-1*Warp.get_grad_ln_Jacob(iptcl,ipsi) ; thisWalker.Drift[iptcl] += (wgtpsi*WarpDrift); } } //Drift = denom*Drift; thisWalker.Drift *= (tau/denom); END COMMENT*/ for(int ipsi=0; ipsi< NumCopies ;ipsi++){ invsumratio[ipsi]=1.0/sumratio[ipsi]; thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=invsumratio[ipsi]; } setScaledDrift(tau,psi[0]->G,drift); thisWalker.Drift=invsumratio[0]*drift; for(int ipsi=1; ipsi< NumCopies ;ipsi++) { setScaledDrift(tau,psi[ipsi]->G,drift); thisWalker.Drift += (invsumratio[ipsi]*drift); } ++it;++iw; } }
void CSVMCUpdatePbyP::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool measure) { int iwalker=0; //only used locally vector<RealType> ratio(nPsi), uw(nPsi); while(it != it_end) { //Walkers loop Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); W.R = thisWalker.R; w_buffer.rewind(); // Copy walker info in W W.copyFromBuffer(w_buffer); for(int ipsi=0; ipsi<nPsi; ipsi++){ // Copy wave function info in W and Psi1 Psi1[ipsi]->copyFromBuffer(W,w_buffer); Psi1[ipsi]->G=W.G; Psi1[ipsi]->L=W.L; } makeGaussRandomWithEngine(deltaR,RandomGen); for(int ipsi=0; ipsi<nPsi; ipsi++) { uw[ipsi]= thisWalker.Properties(ipsi,UMBRELLAWEIGHT); } // Point to the correct walker in the ratioij buffer RealType* restrict ratioijPtr=ratioIJ[iwalker]; bool moved = false; for(int iat=0; iat<W.getTotalNum(); iat++) { //Particles loop PosType dr = m_sqrttau*deltaR[iat]; PosType newpos = W.makeMove(iat,dr); RealType ratio_check=1.0; for(int ipsi=0; ipsi<nPsi; ipsi++) { // Compute ratios before and after the move ratio_check *= ratio[ipsi] = Psi1[ipsi]->ratio(W,iat,*G1[ipsi],*L1[ipsi]); logpsi[ipsi]=std::log(ratio[ipsi]*ratio[ipsi]); // Compute Gradient in new position //*G1[ipsi]=Psi1[ipsi]->G + dG; // Initialize: sumratio[i]=(Psi[i]/Psi[i])^2=1.0 sumratio[ipsi]=1.0; } bool accept_move=false; if(ratio_check>1e-12)//if any ratio is too small, reject the move automatically { int indexij(0); // Compute new (Psi[i]/Psi[j])^2 and their sum for(int ipsi=0; ipsi< nPsi-1; ipsi++) { for(int jpsi=ipsi+1; jpsi < nPsi; jpsi++, indexij++) { // Ratio between norms is already included in ratioijPtr from initialize. RealType rji=std::exp(logpsi[jpsi]-logpsi[ipsi])*ratioijPtr[indexij]; instRij[indexij]=rji; //ratioij[indexij]=rji; sumratio[ipsi] += rji; sumratio[jpsi] += 1.0/rji; } } // Evaluate new Umbrella Weight for(int ipsi=0; ipsi< nPsi ;ipsi++) invsumratio[ipsi]=1.0/sumratio[ipsi]; RealType td=ratio[0]*ratio[0]*sumratio[0]/(*it)->Multiplicity; accept_move=Random()<std::min(1.0,td); } //RealType prob = std::min(1.0,td); //if(Random() < prob) if(accept_move) { /* Electron move is accepted. Update: -ratio (Psi[i]/Psi[j])^2 for this walker -Gradient and laplacian for each Psi1[i] -Drift -buffered info for each Psi1[i]*/ moved = true; ++nAccept; W.acceptMove(iat); // Update Buffer for (Psi[i]/Psi[j])^2 std::copy(instRij.begin(),instRij.end(),ratioijPtr); // copy new Umbrella weight for averages uw=invsumratio; // Store sumratio for next Accept/Reject step to Multiplicity //thisWalker.Properties(SUMRATIO)=sumratio[0]; thisWalker.Multiplicity=sumratio[0]; for(int ipsi=0; ipsi< nPsi; ipsi++) { //Update local Psi1[i] buffer for the next move Psi1[ipsi]->acceptMove(W,iat); //Update G and L in Psi1[i] //Psi1[ipsi]->G = *G1[ipsi]; Psi1[ipsi]->G += *G1[ipsi]; Psi1[ipsi]->L += *L1[ipsi]; thisWalker.Properties(ipsi,LOGPSI)+=std::log(abs(ratio[ipsi])); } } else { ++nReject; W.rejectMove(iat); for(int ipsi=0; ipsi< nPsi; ipsi++) Psi1[ipsi]->rejectMove(iat); } } if(moved) { /* The walker moved: Info are copied back to buffers: -copy (Psi[i]/Psi[j])^2 to ratioijBuffer -Gradient and laplacian for each Psi1[i] -Drift -buffered info for each Psi1[i] Physical properties are updated */ (*it)->Age=0; (*it)->R = W.R; w_buffer.rewind(); W.copyToBuffer(w_buffer); for(int ipsi=0; ipsi< nPsi; ipsi++){ W.G=Psi1[ipsi]->G; W.L=Psi1[ipsi]->L; //ValueType psi = Psi1[ipsi]->evaluate(W,w_buffer); ValueType logpsi = Psi1[ipsi]->evaluateLog(W,w_buffer); RealType et = H1[ipsi]->evaluate(W); //multiEstimator->updateSample(iwalker,ipsi,et,UmbrellaWeight[ipsi]); //Properties is used for UmbrellaWeight and UmbrellaEnergy thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=uw[ipsi]; thisWalker.Properties(ipsi,LOCALENERGY)=et; H1[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi)); } } else { ++nAllRejected; } ++it; ++iwalker; } }
bool DMCOMPOPT::run() { bool variablePop = (Reconfiguration == "no"); resetUpdateEngines(); //estimator does not need to collect data Estimators->setCollectionMode(true); Estimators->start(nBlocks); for(int ip=0; ip<NumThreads; ip++) Movers[ip]->startRun(nBlocks,false); Timer myclock; IndexType block = 0; IndexType updatePeriod=(QMCDriverMode[QMC_UPDATE_MODE])?Period4CheckProperties:(nBlocks+1)*nSteps; int nsampls(0); int g_nsampls(0); do // block { Estimators->startBlock(nSteps); for(int ip=0; ip<NumThreads; ip++) Movers[ip]->startBlock(nSteps); IndexType step = 0; for(IndexType step=0; step< nSteps; ++step, CurrentStep+=BranchInterval) { #pragma omp parallel { int ip=omp_get_thread_num(); int now=CurrentStep; MCWalkerConfiguration::iterator wit(W.begin()+wPerNode[ip]), wit_first(W.begin()+wPerNode[ip]), wit2(W.begin()+wPerNode[ip]), wit_end(W.begin()+wPerNode[ip+1]); for(int interval = 0; interval<BranchInterval-1; ++interval,++now) { Movers[ip]->advanceWalkers(wit,wit_end,false); while(wit2!=wit_end) { (**wit2).addPropertyHistoryPoint(Eindx,(**wit2).getPropertyBase()[LOCALENERGY]); wit2++; } wit2=wit_first; if (Period4WalkerDump&&((now+1)%myPeriod4WalkerDump==0)) { wClones[ip]->saveEnsemble(wit2,wit_end); #pragma omp master nsampls+=W.getActiveWalkers(); } } wClones[ip]->resetCollectables(); Movers[ip]->advanceWalkers(wit,wit_end,false); wit2=wit_first; while(wit2!=wit_end) { (**wit2).addPropertyHistoryPoint(Eindx,(**wit2).getPropertyBase()[LOCALENERGY]); wit2++; } wit2=wit_first; if (myPeriod4WalkerDump&&((now+1)%myPeriod4WalkerDump==0)) { wClones[ip]->saveEnsemble(wit2,wit_end); #pragma omp master nsampls+=W.getActiveWalkers(); } Movers[ip]->setMultiplicity(wit,wit_end); if(QMCDriverMode[QMC_UPDATE_MODE] && now%updatePeriod == 0) Movers[ip]->updateWalkers(wit, wit_end); }//#pragma omp parallel } // branchEngine->debugFWconfig(); #pragma omp parallel for for (int ip=0; ip<NumThreads; ++ip) { MCWalkerConfiguration::iterator wit(W.begin()+wPerNode[ip]), wit_end(W.begin()+wPerNode[ip+1]); while (wit!=wit_end) { Walker_t& thisWalker(**wit); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); wClones[ip]->loadWalker(thisWalker,true); psiClones[ip]->copyFromBuffer(*wClones[ip],w_buffer); vector<RealType> Dsaved(NumOptimizables,0); vector<RealType> HDsaved(NumOptimizables,0); psiClones[ip]->evaluateDerivatives(*wClones[ip],dummyOptVars[ip],Dsaved,HDsaved,true);//SH like deriv style #pragma omp critical fillComponentMatrices(Dsaved,HDsaved,thisWalker); wit++; } } branchEngine->branch(CurrentStep,W, branchClones); if(variablePop) FairDivideLow(W.getActiveWalkers(),NumThreads,wPerNode); Estimators->stopBlock(acceptRatio()); block++; recordBlock(block); g_nsampls=nsampls; myComm->allreduce(g_nsampls); } while(((block<nBlocks) || (g_nsampls<nTargetSamples)) && myclock.elapsed()<MaxCPUSecs); //for(int ip=0; ip<NumThreads; ip++) Movers[ip]->stopRun(); for(int ip=0; ip<NumThreads; ip++) *(RandomNumberControl::Children[ip])=*(Rng[ip]); // adding weight index MCWalkerConfiguration::iterator wit(W.begin()), wit_end(W.end()); while(wit!=wit_end) { (**wit).deletePropertyHistory(); wit++; } Estimators->stop(); return finalize(block); }
void VMCUpdatePbyPWithDrift::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end) { while(it != it_end) { Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); W.R = thisWalker.R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); RealType psi_old = thisWalker.Properties(SIGN); RealType psi = psi_old; //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandomWithEngine(deltaR,RandomGen); bool moved = false; for(int iat=0; iat<W.getTotalNum(); iat++) { PosType dr = m_sqrttau*deltaR[iat]+thisWalker.Drift[iat]; PosType newpos = W.makeMove(iat,dr); //RealType ratio = Psi.ratio(W,iat); RealType ratio = Psi.ratio(W,iat,dG,dL); G = W.G+dG; //RealType forwardGF = exp(-0.5*dot(deltaR[iat],deltaR[iat])); //dr = (*it)->R[iat]-newpos-Tau*G[iat]; //RealType backwardGF = exp(-oneover2tau*dot(dr,dr)); RealType logGf = -0.5e0*dot(deltaR[iat],deltaR[iat]); RealType scale=getDriftScale(Tau,G); //COMPLEX WARNING //dr = thisWalker.R[iat]-newpos-scale*G[iat]; dr = thisWalker.R[iat]-newpos-scale*real(G[iat]); RealType logGb = -m_oneover2tau*dot(dr,dr); RealType prob = std::min(1.0e0,ratio*ratio*exp(logGb-logGf)); //alternatively if(RandomGen() < prob) { moved = true; ++nAccept; W.acceptMove(iat); Psi.acceptMove(W,iat); W.G = G; W.L += dL; //thisWalker.Drift = scale*G; assignDrift(scale,G,thisWalker.Drift); } else { ++nReject; W.rejectMove(iat); Psi.rejectMove(iat); } } if(moved) { w_buffer.rewind(); W.copyToBuffer(w_buffer); psi = Psi.evaluate(W,w_buffer); thisWalker.R = W.R; RealType eloc=H.evaluate(W); thisWalker.resetProperty(log(abs(psi)), psi,eloc); H.saveProperty(thisWalker.getPropertyBase()); } else { ++nAllRejected; } ++it; } }
void CSUpdateBase::initCSWalkers(WalkerIter_t it, WalkerIter_t it_end, bool resetNorms) { nPsi=Psi1.size(); useDrift=(useDriftOption=="yes"); if(nPsi ==0) { app_error() << " CSUpdateBase::initCSWalkers fails. Empyty Psi/H pairs" << endl; abort();//FIX_ABORT } int nw = it_end-it;//W.getActiveWalkers(); resizeWorkSpace(nw,W.getTotalNum()); if(resetNorms) logNorm.resize(nPsi,0.0); for(int ipsi=0; ipsi< nPsi; ipsi++) avgNorm[ipsi]=std::exp(logNorm[ipsi]); int iw(0); while(it != it_end) { Walker_t& thisWalker(**it); W.R = thisWalker.R; W.update(); //evalaute the wavefunction and hamiltonian for(int ipsi=0; ipsi< nPsi; ipsi++) { logpsi[ipsi]=Psi1[ipsi]->evaluateLog(W); Psi1[ipsi]->G=W.G; thisWalker.Properties(ipsi,LOGPSI)=logpsi[ipsi]; RealType e=thisWalker.Properties(ipsi,LOCALENERGY)=H1[ipsi]->evaluate(W); H1[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi)); sumratio[ipsi]=1.0; } //Check SIMONE's note //Compute the sum over j of Psi^2[j]/Psi^2[i] for each i int indexij(0); RealType* restrict rPtr=ratioIJ[iw]; for(int ipsi=0; ipsi< nPsi-1; ipsi++) { for(int jpsi=ipsi+1; jpsi< nPsi; jpsi++) { RealType r=std::exp(2.0*(logpsi[jpsi]-logpsi[ipsi])); rPtr[indexij++]=r*avgNorm[ipsi]/avgNorm[jpsi]; sumratio[ipsi] += r; sumratio[jpsi] += 1.0/r; } } //Re-use Multiplicity as the sumratio thisWalker.Multiplicity=sumratio[0]; for(int ipsi=0; ipsi< nPsi; ipsi++) { thisWalker.Properties(ipsi,UMBRELLAWEIGHT) = invsumratio[ipsi] =1.0/sumratio[ipsi]; } //DON't forget DRIFT!!! thisWalker.Drift=0.0; if(useDrift) { for(int ipsi=0; ipsi< nPsi; ipsi++) PAOps<RealType,DIM>::axpy(invsumratio[ipsi],Psi1[ipsi]->G,thisWalker.Drift); setScaledDrift(Tau,thisWalker.Drift); } ++it; ++iw; } }
// old ones void RQMCEstimator ::initialize(MCWalkerConfiguration& W, vector<QMCHamiltonian*>& h, vector<TrialWaveFunction*>& psi, RealType tau,vector<RealType>& Norm, bool require_register) { NumWalkers = W.getActiveWalkers(); //allocate UmbrellaEnergy int numPtcls(W.getTotalNum()); RatioIJ.resize(NumWalkers,NumCopies*(NumCopies-1)/2); MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); vector<RealType> sumratio(NumCopies), logpsi(NumCopies); int iw(0); int DataSetSize((*it)->DataSet.size()); while(it != it_end) { Walker_t& thisWalker(**it); (*it)->DataSet.rewind(); if(require_register) { W.registerData(thisWalker,(*it)->DataSet); } else { W.R = thisWalker.R; W.update(); if(DataSetSize) W.updateBuffer((*it)->DataSet); } //evalaute the wavefunction and hamiltonian for(int ipsi=0; ipsi< NumCopies;ipsi++) { psi[ipsi]->G.resize(numPtcls); psi[ipsi]->L.resize(numPtcls); //Need to modify the return value of OrbitalBase::registerData if(require_register) { logpsi[ipsi]=psi[ipsi]->registerData(W,(*it)->DataSet); } else { if(DataSetSize)logpsi[ipsi]=psi[ipsi]->updateBuffer(W,(*it)->DataSet); else logpsi[ipsi]=psi[ipsi]->evaluateLog(W); } psi[ipsi]->G=W.G; thisWalker.Properties(ipsi,LOGPSI)=logpsi[ipsi]; thisWalker.Properties(ipsi,LOCALENERGY)=h[ipsi]->evaluate(W); h[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi)); sumratio[ipsi]=1.0; } //Check SIMONE's note //Compute the sum over j of Psi^2[j]/Psi^2[i] for each i int indexij(0); RealType *rPtr=RatioIJ[iw]; for(int ipsi=0; ipsi< NumCopies-1; ipsi++) { for(int jpsi=ipsi+1; jpsi< NumCopies; jpsi++){ RealType r= std::exp(2.0*(logpsi[jpsi]-logpsi[ipsi])); rPtr[indexij++]=r*Norm[ipsi]/Norm[jpsi]; sumratio[ipsi] += r; sumratio[jpsi] += 1.0/r; } } //Re-use Multiplicity as the sumratio thisWalker.Multiplicity=sumratio[0]; //DON't forget DRIFT!!! thisWalker.Drift=0.0; for(int ipsi=0; ipsi< NumCopies; ipsi++) { RealType wgt=1.0/sumratio[ipsi]; thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=wgt; //thisWalker.Drift += wgt*psi[ipsi]->G; PAOps<RealType,DIM>::axpy(wgt,psi[ipsi]->G,thisWalker.Drift); } thisWalker.Drift *= tau; ++it;++iw; } }
QMCCostFunctionOMP::Return_t QMCCostFunctionOMP::correlatedSampling(bool needGrad) { for(int ip=0; ip<NumThreads; ++ip) { // synchronize the random number generator with the node (*MoverRng[ip]) = (*RngSaved[ip]); hClones[ip]->setRandomGenerator(MoverRng[ip]); } Return_t wgt_tot=0.0; Return_t wgt_tot2=0.0; Return_t NSm1 = 1.0/NumSamples; Return_t inv_n_samples=1.0/NumSamples; typedef MCWalkerConfiguration::Walker_t Walker_t; #pragma omp parallel reduction(+:wgt_tot,wgt_tot2) { int ip = omp_get_thread_num(); MCWalkerConfiguration& wRef(*wClones[ip]); Return_t wgt_node=0.0, wgt_node2=0.0; //int totalElements=W.getTotalNum()*OHMMS_DIM; MCWalkerConfiguration::iterator it(wRef.begin()); MCWalkerConfiguration::iterator it_end(wRef.end()); int iw=0,iwg=wPerNode[ip]; for (; it!= it_end; ++it,++iw,++iwg) { ParticleSet::Walker_t& thisWalker(**it); wRef.R=thisWalker.R; wRef.update(); Return_t* restrict saved = (*RecordsOnNode[ip])[iw]; // buffer for MultiSlaterDet data Return_t logpsi; // Return_t logpsi_old = thisWalker.getPropertyBase()[LOGPSI]; // if((usebuffer=="yes")||(includeNonlocalH=="yes")) if(StoreDerivInfo) { Walker_t::Buffer_t& tbuffer=thisWalker.DataSetForDerivatives; logpsi=psiClones[ip]->evaluateDeltaLog(wRef,tbuffer); wRef.G += *dLogPsi[iwg]; wRef.L += *d2LogPsi[iwg]; } else { logpsi=psiClones[ip]->evaluateDeltaLog(wRef); wRef.G += *dLogPsi[iwg]; wRef.L += *d2LogPsi[iwg]; // logpsi=psiClones[ip]->evaluateLog(wRef); } // Return_t weight = std::exp(2.0*(logpsi-saved[LOGPSI_FREE])); Return_t weight = saved[REWEIGHT] = vmc_or_dmc*(logpsi-saved[LOGPSI_FREE])+std::log(thisWalker.Weight); // if(std::isnan(weight)||std::isinf(weight)) weight=0; saved[ENERGY_NEW] = H_KE_Node[ip]->evaluate(wRef) + saved[ENERGY_FIXED]; if (needGrad) { vector<Return_t> Dsaved(NumOptimizables,0); vector<Return_t> HDsaved(NumOptimizables,0); psiClones[ip]->evaluateDerivatives(wRef, OptVariablesForPsi, Dsaved, HDsaved); for( int i=0; i<NumOptimizables; i++) if(OptVariablesForPsi.recompute(i)) { (*DerivRecords[ip])(iw,i) = Dsaved[i]; (*HDerivRecords[ip])(iw,i) = HDsaved[i]; } } wgt_node+=inv_n_samples*weight; wgt_node2+=inv_n_samples*weight*weight; } wgt_tot += wgt_node; wgt_tot2 += wgt_node2; } //this is MPI barrier OHMMS::Controller->barrier(); //collect the total weight for normalization and apply maximum weight myComm->allreduce(wgt_tot); myComm->allreduce(wgt_tot2); // app_log()<<"Before Purge"<<wgt_tot<<" "<<wgt_tot2<<endl; Return_t wgtnorm = (wgt_tot==0)?0:wgt_tot; wgt_tot=0.0; for (int ip=0; ip<NumThreads; ip++) { int nw=wClones[ip]->getActiveWalkers(); for (int iw=0; iw<nw; iw++) { Return_t* restrict saved = (*RecordsOnNode[ip])[iw]; saved[REWEIGHT] = std::min(std::exp(saved[REWEIGHT]-wgtnorm), numeric_limits<Return_t>::max()*0.1 ); wgt_tot+= inv_n_samples*saved[REWEIGHT]; } } myComm->allreduce(wgt_tot); // app_log()<<"During Purge"<<wgt_tot<<" "<<endl; wgtnorm =(wgt_tot==0)?1:1.0/wgt_tot; wgt_tot=0.0; for (int ip=0; ip<NumThreads; ip++) { int nw=wClones[ip]->getActiveWalkers(); for (int iw=0; iw<nw; iw++) { Return_t* restrict saved = (*RecordsOnNode[ip])[iw]; saved[REWEIGHT] = std::min(saved[REWEIGHT]*wgtnorm,MaxWeight); wgt_tot+= inv_n_samples*saved[REWEIGHT]; } } myComm->allreduce(wgt_tot); // app_log()<<"After Purge"<<wgt_tot<<" "<<endl; for (int i=0; i<SumValue.size(); i++) SumValue[i]=0.0; CSWeight=wgt_tot=(wgt_tot==0)?1:1.0/wgt_tot; for (int ip=0; ip<NumThreads; ip++) { int nw=wClones[ip]->getActiveWalkers(); for (int iw=0; iw<nw; iw++) { const Return_t* restrict saved = (*RecordsOnNode[ip])[iw]; Return_t weight=saved[REWEIGHT]*wgt_tot; Return_t eloc_new=saved[ENERGY_NEW]; Return_t delE=std::pow(abs(eloc_new-EtargetEff),PowerE); SumValue[SUM_E_BARE] += eloc_new; SumValue[SUM_ESQ_BARE] += eloc_new*eloc_new; SumValue[SUM_ABSE_BARE] += delE; SumValue[SUM_E_WGT] += eloc_new*saved[REWEIGHT]; SumValue[SUM_ESQ_WGT] += eloc_new*eloc_new*saved[REWEIGHT]; SumValue[SUM_ABSE_WGT] += delE*saved[REWEIGHT]; SumValue[SUM_WGT] += saved[REWEIGHT]; SumValue[SUM_WGTSQ] += saved[REWEIGHT]*saved[REWEIGHT]; } } //collect everything myComm->allreduce(SumValue); // for (int i=0; i<SumValue.size(); i++) cerr<<SumValue[i]<<" "; // cerr<<endl; // app_log()<<"After purge Energy Variance Weight " // << SumValue[SUM_E_WGT]/SumValue[SUM_WGT] << " " // << SumValue[SUM_ESQ_WGT]/SumValue[SUM_WGT] -(SumValue[SUM_E_WGT]/SumValue[SUM_WGT])*(SumValue[SUM_E_WGT]/SumValue[SUM_WGT]) << " " // << SumValue[SUM_WGT]*SumValue[SUM_WGT]/SumValue[SUM_WGTSQ] << endl; return SumValue[SUM_WGT]*SumValue[SUM_WGT]/SumValue[SUM_WGTSQ]; }
/** advance all the walkers with killnode==no * @param nat number of particles to move * * When killnode==no, any move resulting in node-crossing is treated * as a normal rejection. */ void DMCUpdatePbyPWithRejection::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool measure) { myTimers[0]->start(); for(;it != it_end;++it) { //MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]); Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); W.loadWalker(thisWalker,true); //W.R = thisWalker.R; //w_buffer.rewind(); //W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandomWithEngine(deltaR,RandomGen); int nAcceptTemp(0); int nRejectTemp(0); //copy the old energy and scale factor of drift RealType eold(thisWalker.Properties(LOCALENERGY)); RealType vqold(thisWalker.Properties(DRIFTSCALE)); RealType enew(eold); RealType rr_proposed=0.0; RealType rr_accepted=0.0; RealType gf_acc=1.0; myTimers[1]->start(); for(int iat=0; iat<NumPtcl; ++iat) { PosType dr; //get the displacement //RealType sc=getDriftScale(m_tauovermass,W.G[iat]); //PosType dr(m_sqrttau*deltaR[iat]+sc*real(W.G[iat])); getScaledDrift(m_tauovermass,W.G[iat],dr); dr += m_sqrttau*deltaR[iat]; //RealType rr=dot(dr,dr); RealType rr=m_tauovermass*dot(deltaR[iat],deltaR[iat]); rr_proposed+=rr; if(rr>m_r2max) { ++nRejectTemp; continue; } //PosType newpos(W.makeMove(iat,dr)); if(!W.makeMoveAndCheck(iat,dr)) continue; PosType newpos(W.R[iat]); RealType ratio=Psi.ratio(W,iat,dG,dL); bool valid_move=false; //node is crossed reject the move //if(Psi.getPhase() > numeric_limits<RealType>::epsilon()) if(branchEngine->phaseChanged(Psi.getPhaseDiff())) { ++nRejectTemp; ++nNodeCrossing; W.rejectMove(iat); Psi.rejectMove(iat); } else { G = W.G+dG; RealType logGf = -0.5*dot(deltaR[iat],deltaR[iat]); //Use the force of the particle iat //RealType scale=getDriftScale(m_tauovermass,G[iat]); //dr = thisWalker.R[iat]-newpos-scale*real(G[iat]); getScaledDrift(m_tauovermass, G[iat], dr); dr = thisWalker.R[iat] - newpos - dr; RealType logGb = -m_oneover2tau*dot(dr,dr); RealType prob = ratio*ratio*std::exp(logGb-logGf); //this is useless //RealType prob = std::min(1.0,ratio*ratio*std::exp(logGb-logGf)); if(RandomGen() < prob) { valid_move=true; ++nAcceptTemp; W.acceptMove(iat); Psi.acceptMove(W,iat); W.G = G; W.L += dL; rr_accepted+=rr; gf_acc *=prob;//accumulate the ratio } else { ++nRejectTemp; W.rejectMove(iat); Psi.rejectMove(iat); } } } myTimers[1]->stop(); RealType nodecorr_old=thisWalker.Properties(DRIFTSCALE); RealType nodecorr=nodecorr_old; bool advanced=true; if(UseTMove) nonLocalOps.reset(); if(nAcceptTemp>0) {//need to overwrite the walker properties myTimers[2]->start(); thisWalker.Age=0; thisWalker.R = W.R; nodecorr=getNodeCorrection(W.G,drift); //w_buffer.rewind(); //W.copyToBuffer(w_buffer); RealType logpsi = Psi.evaluateLog(W,w_buffer); W.saveWalker(thisWalker); myTimers[2]->stop(); myTimers[3]->start(); if(UseTMove) enew= H.evaluate(W,nonLocalOps.Txy); else enew= H.evaluate(W); myTimers[3]->stop(); //thisWalker.resetProperty(std::log(abs(psi)),psi,enew,rr_accepted,rr_proposed,nodecorr); thisWalker.resetProperty(logpsi,Psi.getPhase(),enew,rr_accepted,rr_proposed,nodecorr ); H.auxHevaluate(W,thisWalker); H.saveProperty(thisWalker.getPropertyBase()); } else {//all moves are rejected: does not happen normally with reasonable wavefunctions advanced=false; H.rejectedMove(W,thisWalker); thisWalker.Age++; thisWalker.Properties(R2ACCEPTED)=0.0; ++nAllRejected; enew=eold;//copy back old energy gf_acc=1.0; } if(UseTMove) { //make a non-local move int ibar=nonLocalOps.selectMove(RandomGen()); if(ibar) { myTimers[2]->start(); int iat=nonLocalOps.id(ibar); PosType newpos(W.makeMove(iat, nonLocalOps.delta(ibar))); RealType ratio=Psi.ratio(W,iat,dG,dL); W.acceptMove(iat); Psi.acceptMove(W,iat); W.G += dG; W.L += dL; //PAOps<RealType,OHMMS_DIM>::copy(W.G,thisWalker.Drift); //thisWalker.R[iat]=W.R[iat]; //w_buffer.rewind(); //W.copyToBuffer(w_buffer); RealType logpsi = Psi.evaluateLog(W,w_buffer); W.saveWalker(thisWalker); ++NonLocalMoveAccepted; myTimers[2]->stop(); } } //2008-06-26: select any //bare green function by setting nodecorr=nodecorr_old=1.0 thisWalker.Weight *= branchEngine->branchWeight(enew,eold); //Filtering extreme energies //thisWalker.Weight *= branchEngine->branchWeight(eold,enew); //using the corrections: see QMCUpdateBase::getNodeCorrection //thisWalker.Weight *= branchEngine->branchWeight(enew,eold,nodecorr,nodecorr_old); //using the corrections: see QMCUpdateBase::getNodeCorrection including gf_acc //RealType odd=std::min(gf_acc,1.0) //thisWalker.Weight *= branchEngine->branchWeight(enew,eold,nodecorr,nodecorr_oldi,odd); nAccept += nAcceptTemp; nReject += nRejectTemp; } myTimers[0]->stop(); }
void VMCParticleByParticle::runBlockWithoutDrift() { IndexType step = 0; MCWalkerConfiguration::iterator it_end(W.end()); do { //advanceWalkerByWalker(); MCWalkerConfiguration::iterator it(W.begin()); while(it != it_end) { //MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]); Walker_t& thisWalker(**it); Buffer_t& w_buffer(thisWalker.DataSet); W.R = thisWalker.R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); RealType psi_old = thisWalker.Properties(SIGN); RealType psi = psi_old; for(int iter=0; iter<nSubSteps; iter++) { makeGaussRandom(deltaR); bool stucked=true; for(int iat=0; iat<W.getTotalNum(); iat++) { PosType dr = m_sqrttau*deltaR[iat]; PosType newpos = W.makeMove(iat,dr); RealType ratio = Psi.ratio(W,iat); //RealType ratio = Psi.ratio(W,iat,dG,dL); RealType prob = std::min(1.0e0,ratio*ratio); //alternatively if(Random() < prob) { stucked=false; ++nAccept; W.acceptMove(iat); Psi.acceptMove(W,iat); //W.G+=dG; //W.L+=dL; } else { ++nReject; W.rejectMove(iat); Psi.rejectMove(iat); } } if(stucked) { ++nAllRejected; } } thisWalker.R = W.R; w_buffer.rewind(); W.updateBuffer(w_buffer); RealType logpsi = Psi.updateBuffer(W,w_buffer); //W.copyToBuffer(w_buffer); //RealType logpsi = Psi.evaluate(W,w_buffer); RealType eloc=H.evaluate(W); thisWalker.resetProperty(logpsi,Psi.getPhase(),eloc); H.saveProperty(thisWalker.getPropertyBase()); ++it; } ++step;++CurrentStep; Estimators->accumulate(W); } while(step<nSteps); }
void VMCUpdateRenyiWithDriftFast::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool measure) { myTimers[0]->start(); WalkerIter_t begin(it); for (; it != it_end; ++it) { Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); W.loadWalker(thisWalker,true); Psi.copyFromBuffer(W,w_buffer); myTimers[1]->start(); bool moved = false; for (int iter=0; iter<nSubSteps; ++iter) { //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandomWithEngine(deltaR,RandomGen); moved = false; for(int ig=0; ig<W.groups(); ++ig) //loop over species { RealType tauovermass = Tau*MassInvS[ig]; RealType oneover2tau = 0.5/(tauovermass); RealType sqrttau = std::sqrt(tauovermass); for (int iat=W.first(ig); iat<W.last(ig); ++iat) { GradType grad_now=Psi.evalGrad(W,iat), grad_new; PosType dr; getScaledDrift(tauovermass,grad_now,dr); dr += sqrttau*deltaR[iat]; if (!W.makeMoveAndCheck(iat,dr)) { ++nReject; continue; } //PosType newpos = W.makeMove(iat,dr); RealType ratio = Psi.ratioGrad(W,iat,grad_new); RealType prob = ratio*ratio; //zero is always rejected if (prob<numeric_limits<RealType>::epsilon()) { ++nReject; W.rejectMove(iat); Psi.rejectMove(iat); continue; } RealType logGf = -0.5e0*dot(deltaR[iat],deltaR[iat]); getScaledDrift(tauovermass,grad_new,dr); dr = thisWalker.R[iat]-W.R[iat]-dr; RealType logGb = -oneover2tau*dot(dr,dr); if (RandomGen() < prob*std::exp(logGb-logGf)) { moved = true; ++nAccept; W.acceptMove(iat); Psi.acceptMove(W,iat); } else { ++nReject; W.rejectMove(iat); Psi.rejectMove(iat); } } } //for subSteps must update thiswalker thisWalker.R=W.R; thisWalker.G=W.G; thisWalker.L=W.L; } myTimers[1]->stop(); //Always compute the energy //if(moved) { myTimers[2]->start(); //thisWalker.R = W.R; //w_buffer.rewind(); //W.updateBuffer(w_buffer); RealType logpsi = Psi.updateBuffer(W,w_buffer,false); W.saveWalker(thisWalker); myTimers[2]->stop(); myTimers[3]->start(); RealType eloc=H.evaluate(W); myTimers[3]->stop(); //thisWalker.resetProperty(std::log(abs(psi)), psi,eloc); thisWalker.resetProperty(logpsi,Psi.getPhase(), eloc); H.auxHevaluate(W,thisWalker); H.saveProperty(thisWalker.getPropertyBase()); } if(!moved) ++nAllRejected; //else //{ // ++nAllRejected; // H.rejectedMove(W,thisWalker); //} } myTimers[0]->stop(); }
bool DMCPeta::run() { resetUpdateEngine(); //estimator is ready to collect data Estimators->setCollectionMode(true); Estimators->start(nBlocks,true); Timer myclock; IndexType block = 0; IndexType numPtcls=W.getTotalNum(); RealType oneover2tau = 0.5/Tau; RealType sqrttau = std::sqrt(Tau); //temporary data to store differences ParticleSet::ParticlePos_t deltaR(numPtcls); ParticleSet::ParticleGradient_t G(numPtcls), dG(numPtcls); ParticleSet::ParticleLaplacian_t L(numPtcls), dL(numPtcls); CurrentStep = 0; typedef MCWalkerConfiguration::iterator WalkerIter_t; do // block { Mover->startBlock(nSteps); for(IndexType step=0; step< nSteps; step++, CurrentStep+=BranchInterval) { for(IndexType interval=0; interval<BranchInterval; ++interval) { for(WalkerIter_t it=W.begin();it != W.end(); ++it) { //MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]); Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); W.R = thisWalker.R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandomWithEngine(deltaR,Random); int nAcceptTemp(0); int nRejectTemp(0); RealType eold(thisWalker.Properties(LOCALENERGY)); RealType enew(eold); RealType rr_proposed=0.0; RealType rr_accepted=0.0; //loop over particles for(int iat=0; iat<numPtcls; iat++) { PosType dr(sqrttau*deltaR[iat]+thisWalker.Drift[iat]); PosType newpos(W.makeMove(iat,dr)); RealType ratio=Psi.ratio(W,iat,dG,dL); RealType rr=dot(dr,dr); rr_proposed+=rr; if(branchEngine->phaseChanged(Psi.getPhaseDiff())) {//node crossing detected ++nRejectTemp; W.rejectMove(iat); Psi.rejectMove(iat); } else { G = W.G+dG; RealType logGf = -0.5*dot(deltaR[iat],deltaR[iat]); RealType scale=getDriftScale(Tau,G); dr = thisWalker.R[iat]-newpos-scale*real(G[iat]); RealType logGb = -oneover2tau*dot(dr,dr); RealType prob = std::min(1.0,ratio*ratio*std::exp(logGb-logGf)); if(Random() < prob) {//move is accepted ++nAcceptTemp; W.acceptMove(iat); Psi.acceptMove(W,iat); W.G = G; W.L += dL; assignDrift(scale,G,thisWalker.Drift); rr_accepted+=rr; } else { ++nRejectTemp; W.rejectMove(iat); Psi.rejectMove(iat); } } }//for(int iat=0; iat<NumPtcl; iat++) if(nAcceptTemp>0) {//need to overwrite the walker properties thisWalker.R = W.R; w_buffer.rewind(); W.copyToBuffer(w_buffer); //RealType psi = Psi.evaluate(W,w_buffer); RealType logpsi = Psi.evaluateLog(W,w_buffer); enew= H.evaluate(W); //thisWalker.resetProperty(std::log(abs(psi)),psi,enew,rr_accepted,rr_proposed,1.0); thisWalker.resetProperty(logpsi,Psi.getPhase(),enew,rr_accepted,rr_proposed,1.0 ); H.auxHevaluate(W,thisWalker); H.saveProperty(thisWalker.getPropertyBase()); } else { thisWalker.rejectedMove(); thisWalker.Age++; rr_accepted=0.0; enew=eold;//copy back old energy } thisWalker.Weight *= branchEngine->branchWeight(eold,enew); nAccept += nAcceptTemp; nReject += nRejectTemp; }//for(WalkerIter_t it=W.begin();it != W.end(); ++it) }//interval //calculate multiplicity based on the weights: see QMCUpdateBase::setMultiplicity Mover->setMultiplicity(W.begin(),W.end()); //time to branch: see SimpleFixedNodeBranch::branch branchEngine->branch(CurrentStep,W); if(storeConfigs && (CurrentStep%storeConfigs == 0)) { ForwardWalkingHistory.storeConfigsForForwardWalking(W); W.resetWalkerParents(); } }//steps ++block; Estimators->stopBlock(static_cast<RealType>(nAccept)/static_cast<RealType>(nAccept+nReject)); recordBlock(block); } while(block<nBlocks && myclock.elapsed()<MaxCPUSecs); Estimators->stop(); return finalize(block); }
/** Advance all the walkers one timstep. */ void VMCMultiple::advanceWalkerByWalker() { m_oneover2tau = 0.5/Tau; m_sqrttau = std::sqrt(Tau); //MCWalkerConfiguration::PropertyContainer_t Properties; MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); int iwlk(0); int nPsi_minus_one(nPsi-1); while(it != it_end) { MCWalkerConfiguration::Walker_t &thisWalker(**it); //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); W.R = m_sqrttau*deltaR + thisWalker.R + thisWalker.Drift; //update the distance table associated with W //DistanceTable::update(W); W.update(); //Evaluate Psi and graidients and laplacians //\f$\sum_i \ln(|psi_i|)\f$ and catching the sign separately for(int ipsi=0; ipsi< nPsi; ipsi++) { logpsi[ipsi]=Psi1[ipsi]->evaluateLog(W); Psi1[ipsi]->L=W.L; Psi1[ipsi]->G=W.G; sumratio[ipsi]=1.0; } // Compute the sum over j of Psi^2[j]/Psi^2[i] for each i for(int ipsi=0; ipsi< nPsi_minus_one; ipsi++) { for(int jpsi=ipsi+1; jpsi< nPsi; jpsi++) { RealType ratioij=Norm[ipsi]/Norm[jpsi]*std::exp(2.0*(logpsi[jpsi]-logpsi[ipsi])); sumratio[ipsi] += ratioij; sumratio[jpsi] += 1.0/ratioij; } } for(int ipsi=0; ipsi< nPsi; ipsi++) invsumratio[ipsi]=1.0/sumratio[ipsi]; // Only these properties need to be updated // Using the sum of the ratio Psi^2[j]/Psi^2[iwref] // because these are number of order 1. Potentially // the sum of Psi^2[j] can get very big //Properties(LOGPSI) =logpsi[0]; //Properties(SUMRATIO) = sumratio[0]; RealType logGf = -0.5*Dot(deltaR,deltaR); //RealType scale = Tau; // ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq); //accumulate the weighted drift: using operators in ParticleBase/ParticleAttribOps.h //to handle complex-to-real assignment and axpy operations. //drift = invsumratio[0]*Psi1[0]->G; //for(int ipsi=1; ipsi< nPsi ;ipsi++) { // drift += invsumratio[ipsi]*Psi1[ipsi]->G; //} PAOps<RealType,DIM>::scale(invsumratio[0],Psi1[0]->G,drift); for(int ipsi=1; ipsi< nPsi ; ipsi++) { PAOps<RealType,DIM>::axpy(invsumratio[ipsi],Psi1[ipsi]->G,drift); } //drift *= scale; setScaledDrift(Tau,drift); deltaR = thisWalker.R - W.R - drift; RealType logGb = -m_oneover2tau*Dot(deltaR,deltaR); //Original //RealType g = Properties(SUMRATIO)/thisWalker.Properties(SUMRATIO)* // exp(logGb-logGf+2.0*(Properties(LOGPSI)-thisWalker.Properties(LOGPSI))); //Reuse Multiplicity to store the sumratio[0] RealType g = sumratio[0]/thisWalker.Multiplicity* std::exp(logGb-logGf+2.0*(logpsi[0]-thisWalker.Properties(LOGPSI))); if(Random() > g) { thisWalker.Age++; ++nReject; } else { thisWalker.Age=0; thisWalker.Multiplicity=sumratio[0]; thisWalker.R = W.R; thisWalker.Drift = drift; for(int ipsi=0; ipsi<nPsi; ipsi++) { W.L=Psi1[ipsi]->L; W.G=Psi1[ipsi]->G; RealType et = H1[ipsi]->evaluate(W); thisWalker.Properties(ipsi,LOGPSI)=logpsi[ipsi]; thisWalker.Properties(ipsi,SIGN) =Psi1[ipsi]->getPhase(); thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=invsumratio[ipsi]; thisWalker.Properties(ipsi,LOCALENERGY)=et; //multiEstimator->updateSample(iwlk,ipsi,et,invsumratio[ipsi]); H1[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi)); } ++nAccept; } ++it; ++iwlk; } }
bool VMCPbyPMultiple::run() { useDrift = (useDriftOpt=="yes"); if(useDrift) app_log() << " VMCPbyPMultiple::run useDrift=yes" << endl; else app_log() << " VMCPbyPMultiple::run useDrift=no" << endl; //TEST CACHE //Estimators->reportHeader(AppendRun); //going to add routines to calculate how much we need bool require_register = W.createAuxDataSet(); vector<RealType>Norm(nPsi),tmpNorm(nPsi); if(equilBlocks > 0) { for(int ipsi=0; ipsi< nPsi; ipsi++) { Norm[ipsi]=1.0; tmpNorm[ipsi]=0.0; } } else { for(int ipsi=0; ipsi< nPsi; ipsi++) Norm[ipsi]=std::exp(branchEngine->LogNorm[ipsi]); } multiEstimator->initialize(W,H1,Psi1,Tau,Norm,require_register); //TEST CACHE //Estimators->reset(); Estimators->start(nBlocks); //TEST CACHE IndexType block = 0; m_oneover2tau = 0.5/Tau; m_sqrttau = std::sqrt(Tau); RealType nPsi_minus_one = nPsi-1; ParticleSet::ParticleGradient_t dG(W.getTotalNum()); IndexType nAcceptTot = 0; IndexType nRejectTot = 0; MCWalkerConfiguration::iterator it; MCWalkerConfiguration::iterator it_end(W.end()); do //Blocks loop { IndexType step = 0; nAccept = 0; nReject=0; IndexType nAllRejected = 0; Estimators->startBlock(nSteps); do //Steps loop { it = W.begin(); int iwalker=0; while(it != it_end) //Walkers loop { Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); W.R = thisWalker.R; w_buffer.rewind(); // Copy walker info in W W.copyFromBuffer(w_buffer); for(int ipsi=0; ipsi<nPsi; ipsi++) { // Copy wave function info in W and Psi1 Psi1[ipsi]->copyFromBuffer(W,w_buffer); Psi1[ipsi]->G=W.G; Psi1[ipsi]->L=W.L; } // Point to the correct walker in the ratioij buffer RealType *ratioijPtr=multiEstimator->RatioIJ[iwalker]; //This is not used //ValueType psi_old = thisWalker.Properties(SIGN); //ValueType psi = psi_old; //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); bool moved = false; for(int iat=0; iat<W.getTotalNum(); iat++) //Particles loop { PosType dr = m_sqrttau*deltaR[iat]; if(useDrift) dr += thisWalker.Drift[iat]; PosType newpos = W.makeMove(iat,dr); for(int ipsi=0; ipsi<nPsi; ipsi++) { // Compute ratios before and after the move ratio[ipsi] = Psi1[ipsi]->ratio(W,iat,dG,*dL[ipsi]); logpsi2[ipsi]=std::log(ratio[ipsi]*ratio[ipsi]); // Compute Gradient in new position *G[ipsi]=Psi1[ipsi]->G + dG; // Initialize: sumratio[i]=(Psi[i]/Psi[i])^2=1.0 sumratio[ipsi]=1.0; } // Compute new (Psi[i]/Psi[j])^2 and their sum int indexij(0); for(int ipsi=0; ipsi< nPsi_minus_one; ipsi++) { for(int jpsi=ipsi+1; jpsi < nPsi; jpsi++, indexij++) { // Ratio between norms is already included in ratioijPtr from initialize. RealType rji=std::exp(logpsi2[jpsi]-logpsi2[ipsi])*ratioijPtr[indexij]; ratioij[indexij]=rji; sumratio[ipsi] += rji; sumratio[jpsi] += 1.0/rji; } } // Evaluate new Umbrella Weight for(int ipsi=0; ipsi< nPsi ; ipsi++) { invsumratio[ipsi]=1.0/sumratio[ipsi]; } RealType td=ratio[0]*ratio[0]*sumratio[0]/(*it)->Multiplicity; if(useDrift) { // Evaluate new drift PAOps<RealType,DIM>::scale(invsumratio[0],Psi1[0]->G,drift); for(int ipsi=1; ipsi< nPsi ; ipsi++) { PAOps<RealType,DIM>::axpy(invsumratio[ipsi],Psi1[ipsi]->G,drift); } setScaledDrift(Tau,drift); RealType logGf = -0.5*dot(deltaR[iat],deltaR[iat]); dr = thisWalker.R[iat]-newpos-drift[iat]; RealType logGb = -m_oneover2tau*dot(dr,dr); td *=std::exp(logGb-logGf); } // td = Target Density ratio //RealType td=pow(ratio[0],2)*sumratio[0]/(*it)->Properties(SUMRATIO); //td=ratio[0]*ratio[0]*sumratio[0]/(*it)->Multiplicity; //RealType prob = std::min(1.0,td*exp(logGb-logGf)); RealType prob = std::min(1.0,td); if(Random() < prob) { /* Electron move is accepted. Update: -ratio (Psi[i]/Psi[j])^2 for this walker -Gradient and laplacian for each Psi1[i] -Drift -buffered info for each Psi1[i]*/ moved = true; ++nAccept; W.acceptMove(iat); // Update Buffer for (Psi[i]/Psi[j])^2 std::copy(ratioij.begin(),ratioij.end(),ratioijPtr); // Update Umbrella weight UmbrellaWeight=invsumratio; // Store sumratio for next Accept/Reject step to Multiplicity //thisWalker.Properties(SUMRATIO)=sumratio[0]; thisWalker.Multiplicity=sumratio[0]; for(int ipsi=0; ipsi< nPsi; ipsi++) { //Update local Psi1[i] buffer for the next move Psi1[ipsi]->acceptMove(W,iat); //Update G and L in Psi1[i] Psi1[ipsi]->G = *G[ipsi]; Psi1[ipsi]->L += *dL[ipsi]; thisWalker.Properties(ipsi,LOGPSI)+=std::log(abs(ratio[ipsi])); } // Update Drift if(useDrift) (*it)->Drift = drift; } else { ++nReject; W.rejectMove(iat); for(int ipsi=0; ipsi< nPsi; ipsi++) Psi1[ipsi]->rejectMove(iat); } } if(moved) { /* The walker moved: Info are copied back to buffers: -copy (Psi[i]/Psi[j])^2 to ratioijBuffer -Gradient and laplacian for each Psi1[i] -Drift -buffered info for each Psi1[i] Physical properties are updated */ (*it)->Age=0; (*it)->R = W.R; w_buffer.rewind(); W.copyToBuffer(w_buffer); for(int ipsi=0; ipsi< nPsi; ipsi++) { W.G=Psi1[ipsi]->G; W.L=Psi1[ipsi]->L; ValueType psi = Psi1[ipsi]->evaluate(W,w_buffer); RealType et = H1[ipsi]->evaluate(W); //multiEstimator->updateSample(iwalker,ipsi,et,UmbrellaWeight[ipsi]); //Properties is used for UmbrellaWeight and UmbrellaEnergy thisWalker.Properties(ipsi,UMBRELLAWEIGHT)=UmbrellaWeight[ipsi]; thisWalker.Properties(ipsi,LOCALENERGY)=et; H1[ipsi]->auxHevaluate(W); H1[ipsi]->saveProperty(thisWalker.getPropertyBase(ipsi)); } } else { ++nAllRejected; } ++it; ++iwalker; } ++step; ++CurrentStep; Estimators->accumulate(W); } while(step<nSteps); //Modify Norm. if(block < equilBlocks) { for(int ipsi=0; ipsi< nPsi; ipsi++) { tmpNorm[ipsi]+=multiEstimator->esum(ipsi,MultipleEnergyEstimator::WEIGHT_INDEX); } if(block==(equilBlocks-1) || block==(nBlocks-1)) { RealType SumNorm(0.e0); for(int ipsi=0; ipsi< nPsi; ipsi++) SumNorm+=tmpNorm[ipsi]; for(int ipsi=0; ipsi< nPsi; ipsi++) { Norm[ipsi]=tmpNorm[ipsi]/SumNorm; branchEngine->LogNorm[ipsi]=std::log(Norm[ipsi]); } } } Estimators->stopBlock(static_cast<RealType>(nAccept)/static_cast<RealType>(nAccept+nReject)); nAcceptTot += nAccept; nRejectTot += nReject; nAccept = 0; nReject = 0; ++block; //record the current configuration recordBlock(block); //re-evaluate the ratio and update the Norm multiEstimator->initialize(W,H1,Psi1,Tau,Norm,false); } while(block<nBlocks); ////Need MPI-IO //app_log() // << "Ratio = " // << static_cast<RealType>(nAcceptTot)/static_cast<RealType>(nAcceptTot+nRejectTot) // << endl; return finalize(block); }
/** advance all the walkers with killnode==no * @param nat number of particles to move * * When killnode==no, any move resulting in node-crossing is treated * as a normal rejection. */ void DMCNonLocalUpdatePbyP::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool measure) { for(; it!=it_end; ++it) { Walker_t& thisWalker(**it); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); RealType eold(thisWalker.Properties(LOCALENERGY)); RealType vqold(thisWalker.Properties(DRIFTSCALE)); //RealType emixed(eold), enew(eold); RealType enew(eold); W.R = thisWalker.R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); bool notcrossed(true); int nAcceptTemp(0); int nRejectTemp(0); RealType rr_proposed=0.0; RealType rr_accepted=0.0; for(int iat=0; iat<NumPtcl; ++iat) { //PosType dr(m_sqrttau*deltaR[iat]+thisWalker.Drift[iat]); RealType sc=getDriftScale(Tau,W.G[iat]); PosType dr(m_sqrttau*deltaR[iat]+sc*real(W.G[iat])); //RealType rr=dot(dr,dr); RealType rr=Tau*dot(deltaR[iat],deltaR[iat]); rr_proposed+=rr; if(rr>m_r2max)//too big move { ++nRejectTemp; continue; } PosType newpos(W.makeMove(iat,dr)); RealType ratio=Psi.ratio(W,iat,dG,dL); //node is crossed reject the move if(Psi.getPhase() > numeric_limits<RealType>::epsilon()) { ++nRejectTemp; ++nNodeCrossing; W.rejectMove(iat); Psi.rejectMove(iat); } else { G = W.G+dG; RealType logGf = -0.5*dot(deltaR[iat],deltaR[iat]); //RealType scale=getDriftScale(Tau,G); RealType scale=getDriftScale(Tau,G[iat]); dr = thisWalker.R[iat]-newpos-scale*real(G[iat]); RealType logGb = -m_oneover2tau*dot(dr,dr); RealType prob = std::min(1.0,ratio*ratio*std::exp(logGb-logGf)); if(RandomGen() < prob) { ++nAcceptTemp; W.acceptMove(iat); Psi.acceptMove(W,iat); W.G = G; W.L += dL; //assignDrift(scale,G,thisWalker.Drift); rr_accepted+=rr; } else { ++nRejectTemp; W.rejectMove(iat); Psi.rejectMove(iat); } } }//end of drift+diffusion for all the particles of a walker nonLocalOps.reset(); if(nAcceptTemp>0) {//need to overwrite the walker properties thisWalker.R = W.R; w_buffer.rewind(); W.copyToBuffer(w_buffer); RealType psi = Psi.evaluate(W,w_buffer); enew= H.evaluate(W,nonLocalOps.Txy); thisWalker.resetProperty(std::log(abs(psi)),psi,enew,rr_accepted,rr_proposed,1.0); H.saveProperty(thisWalker.getPropertyBase()); thisWalker.Drift=W.G; } else { thisWalker.Age++; thisWalker.Properties(R2ACCEPTED)=0.0; ++nAllRejected; enew=eold;//copy back old energy } int ibar = nonLocalOps.selectMove(RandomGen()); //make a non-local move if(ibar) { int iat=nonLocalOps.id(ibar); PosType newpos(W.makeMove(iat, nonLocalOps.delta(ibar))); RealType ratio=Psi.ratio(W,iat,dG,dL); W.acceptMove(iat); Psi.acceptMove(W,iat); W.G += dG; W.L += dL; PAOps<RealType,OHMMS_DIM>::copy(W.G,thisWalker.Drift); thisWalker.R[iat]=W.R[iat]; w_buffer.rewind(); W.copyToBuffer(w_buffer); RealType psi = Psi.evaluate(W,w_buffer); ++NonLocalMoveAccepted; } thisWalker.Weight *= branchEngine->branchWeight(eold,enew); nAccept += nAcceptTemp; nReject += nRejectTemp; } }
/** advance all the walkers with killnode==no * @param nat number of particles to move * * When killnode==no, any move resulting in node-crossing is treated * as a normal rejection. */ void DMCNonLocalUpdate::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool measure) { //RealType plusFactor(Tau*Gamma); //RealType minusFactor(-Tau*(1.0-Alpha*(1.0+Gamma))); for(; it!=it_end; ++it) { Walker_t& thisWalker(**it); //save old local energy RealType eold = thisWalker.Properties(LOCALENERGY); RealType signold = thisWalker.Properties(SIGN); RealType enew = eold; //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandomWithEngine(deltaR,RandomGen); W.R = m_sqrttau*deltaR + thisWalker.R + thisWalker.Drift; //update the distance table associated with W //DistanceTable::update(W); W.update(); //evaluate wave function RealType logpsi(Psi.evaluateLog(W)); nonLocalOps.reset(); bool accepted=false; if(branchEngine->phaseChanged(Psi.getPhase(),thisWalker.Properties(SIGN))) { thisWalker.Age++; ++nReject; } else { //RealType enew(H.evaluate(W,nonLocalOps.Txy)); enew=H.evaluate(W,nonLocalOps.Txy); RealType logGf = -0.5*Dot(deltaR,deltaR); setScaledDrift(Tau,W.G,drift); deltaR = (*it)->R - W.R - drift; RealType logGb = -m_oneover2tau*Dot(deltaR,deltaR); RealType prob= std::min(std::exp(logGb-logGf +2.0*(logpsi-thisWalker.Properties(LOGPSI))),1.0); if(RandomGen() > prob){ thisWalker.Age++; ++nReject; enew=eold; } else { accepted=true; thisWalker.R = W.R; thisWalker.Drift = drift; thisWalker.resetProperty(logpsi,Psi.getPhase(),enew); H.saveProperty(thisWalker.getPropertyBase()); //emixed = (emixed+enew)*0.5; //eold=enew; ++nAccept; } } int ibar=nonLocalOps.selectMove(RandomGen()); //make a non-local move if(ibar) { int iat=nonLocalOps.id(ibar); W.R[iat] += nonLocalOps.delta(ibar); W.update(); logpsi=Psi.evaluateLog(W); setScaledDrift(Tau,W.G,thisWalker.Drift); thisWalker.resetProperty(logpsi,Psi.getPhase(),eold); thisWalker.R[iat] = W.R[iat]; ++NonLocalMoveAccepted; } thisWalker.Weight *= branchEngine->branchWeight(eold,enew); //branchEngine->accumulate(eold,1); } }
/** Perform the correlated sampling algorthim. */ QMCCostFunctionSingle::Return_t QMCCostFunctionSingle::correlatedSampling() { typedef MCWalkerConfiguration::Walker_t Walker_t; MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); Return_t eloc_new; int iw=0; int totalElements=W.getTotalNum()*OHMMS_DIM; Return_t wgt_tot=0.0; while(it != it_end) { Walker_t& thisWalker(**it); Return_t* restrict saved = Records[iw]; //rewind the buffer to get the data from buffer thisWalker.DataSet.rewind(); //W is updated by thisWalker W.copyFromBuffer(thisWalker.DataSet); Return_t logpsi=0.0; //copy dL from Buffer #if defined(QMC_COMPLEX) thisWalker.DataSet.get(&(dG[0][0]),&(dG[0][0])+totalElements); thisWalker.DataSet.get(dL.begin(),dL.end()); logpsi=Psi.evaluateDeltaLog(W); W.G += dG; #else thisWalker.DataSet.get(dL.begin(),dL.end()); logpsi=Psi.evaluateDeltaLog(W); W.G += thisWalker.Drift; #endif W.L += dL; eloc_new=H_KE.evaluate(W)+saved[ENERGY_FIXED]; Return_t weight = UseWeight?std::exp(2.0*(logpsi-saved[LOGPSI_FREE])):1.0; saved[ENERGY_NEW]=eloc_new; saved[REWEIGHT]=weight; wgt_tot+=weight; ++it; ++iw; } //collect the total weight for normalization and apply maximum weight myComm->allreduce(wgt_tot); for(int i=0; i<SumValue.size(); i++) SumValue[i]=0.0; wgt_tot=1.0/wgt_tot; Return_t wgt_max=MaxWeight*wgt_tot; int nw=W.getActiveWalkers(); for(iw=0; iw<nw;iw++) { Return_t* restrict saved = Records[iw]; Return_t weight=saved[REWEIGHT]*wgt_tot; Return_t eloc_new=saved[ENERGY_NEW]; weight = (weight>wgt_max)? wgt_max:weight; Return_t delE=std::pow(abs(eloc_new-EtargetEff),PowerE); SumValue[SUM_E_BARE] += eloc_new; SumValue[SUM_ESQ_BARE] += eloc_new*eloc_new; SumValue[SUM_ABSE_BARE] += delE; SumValue[SUM_E_WGT] += eloc_new*weight; SumValue[SUM_ESQ_WGT] += eloc_new*eloc_new*weight; SumValue[SUM_ABSE_WGT] += delE*weight; SumValue[SUM_WGT] += weight; SumValue[SUM_WGTSQ] += weight*weight; } //collect everything myComm->allreduce(SumValue); return SumValue[SUM_WGT]*SumValue[SUM_WGT]/SumValue[SUM_WGTSQ]; }
/** evaluate everything before optimization */ void QMCCostFunctionOMP::checkConfigurations() { /* mmorales: Since there are cases when memory is an issue (too many dets), the use of a buffer is decoupled from the use of includeNonlocalH in the cost function. Without a buffer, everything is recalculated. Options: - "yes" or "all" : store everything - "minimum" : store orbitals and inverses only, recalculate dets FIX FIX FIX: right now, there is no way to include the nonlocalH in the cost function without using a buffer because evaluateLog needs to be called to get the inverse of psiM This implies that isOptimizable must be set to true, which is risky. Fix this somehow */ StoreDerivInfo=false; DerivStorageLevel=-1; if(usebuffer == "yes" || usebuffer == "all") { StoreDerivInfo=true; if(includeNonlocalH!="no") DerivStorageLevel=0; else DerivStorageLevel=1; app_log() <<"Using buffers for temporary storage in QMCCostFunction.\n" <<endl; } else if (usebuffer == "minimum") { StoreDerivInfo=true; // in this case the use of nonlocalH is irrelevant, since the same inf is enough for both cases DerivStorageLevel=2; app_log() <<"Using minimum storage for determinant evaluation. \n"; } else { if(includeNonlocalH!="no") { APP_ABORT("Need to enable the use of includeNonlocalH=='name' without a buffer."); } } int numW = 0; for(int i=0; i<wClones.size(); i++) numW += wClones[i]->getActiveWalkers(); app_log() <<"Memory usage: " <<endl; app_log() <<"Linear method (approx matrix usage: 4*N^2): " <<NumParams()*NumParams()*sizeof(QMCTraits::RealType)*4.0/1.0e6 <<" MB" <<endl; // assuming 4 matrices app_log() <<"Deriv,HDerivRecord: " <<numW*NumOptimizables*sizeof(QMCTraits::RealType)*3.0/1.0e6 <<" MB" <<endl; if(StoreDerivInfo) { MCWalkerConfiguration& dummy(*wClones[0]); long memorb=0,meminv=0,memdets=0,memorbs_only=0; Psi.memoryUsage_DataForDerivatives(dummy,memorbs_only,memorb,meminv,memdets); memorbs_only*=sizeof(QMCTraits::RealType); memorb*=sizeof(QMCTraits::RealType); meminv*=sizeof(QMCTraits::RealType); memdets*=sizeof(QMCTraits::RealType); app_log() <<"Buffer memory cost: MB/walker MB/total " <<endl; app_log() <<"Orbitals only: " <<memorbs_only/1.0e6 <<" " <<memorbs_only*numW/1.0e6 <<endl; app_log() <<"Orbitals + dervs: " <<memorb/1.0e6 <<" " <<memorb*numW/1.0e6 <<endl; app_log() <<"Inverse: " <<meminv/1.0e6 <<" " <<meminv*numW/1.0e6 <<endl; app_log() <<"Determinants: " <<memdets/1.0e6 <<" " <<memdets*numW/1.0e6 <<endl; } app_log().flush(); RealType et_tot=0.0; RealType e2_tot=0.0; #pragma omp parallel reduction(+:et_tot,e2_tot) { int ip = omp_get_thread_num(); MCWalkerConfiguration& wRef(*wClones[ip]); if (RecordsOnNode[ip] ==0) { RecordsOnNode[ip]=new Matrix<Return_t>; RecordsOnNode[ip]->resize(wRef.getActiveWalkers(),SUM_INDEX_SIZE); if (needGrads) { DerivRecords[ip]=new Matrix<Return_t>; DerivRecords[ip]->resize(wRef.getActiveWalkers(),NumOptimizables); HDerivRecords[ip]=new Matrix<Return_t>; HDerivRecords[ip]->resize(wRef.getActiveWalkers(),NumOptimizables); } } else if (RecordsOnNode[ip]->size1()!=wRef.getActiveWalkers()) { RecordsOnNode[ip]->resize(wRef.getActiveWalkers(),SUM_INDEX_SIZE); if (needGrads) { DerivRecords[ip]->resize(wRef.getActiveWalkers(),NumOptimizables); HDerivRecords[ip]->resize(wRef.getActiveWalkers(),NumOptimizables); } } QMCHamiltonianBase* nlpp = (includeNonlocalH =="no")? 0: hClones[ip]->getHamiltonian(includeNonlocalH.c_str()); //set the optimization mode for the trial wavefunction psiClones[ip]->startOptimization(); // synchronize the random number generator with the node (*MoverRng[ip]) = (*RngSaved[ip]); hClones[ip]->setRandomGenerator(MoverRng[ip]); //int nat = wRef.getTotalNum(); //int totalElements=W.getTotalNum()*OHMMS_DIM; typedef MCWalkerConfiguration::Walker_t Walker_t; Return_t e0=0.0; // Return_t ef=0.0; Return_t e2=0.0; for (int iw=0, iwg=wPerNode[ip]; iw<wRef.getActiveWalkers(); ++iw,++iwg) { ParticleSet::Walker_t& thisWalker(*wRef[iw]); wRef.R=thisWalker.R; wRef.update(); Return_t* restrict saved=(*RecordsOnNode[ip])[iw]; // Return_t logpsi(0); // psiClones[ip]->evaluateDeltaLog(wRef, saved[LOGPSI_FIXED], saved[LOGPSI_FREE], *dLogPsi[iwg],*d2LogPsi[iwg]); // buffer for MultiSlaterDet data // if((usebuffer=="yes")||(includeNonlocalH=="yes")) if(StoreDerivInfo) { psiClones[ip]->registerDataForDerivatives(wRef, thisWalker.DataSetForDerivatives,DerivStorageLevel); psiClones[ip]->evaluateDeltaLog(wRef, saved[LOGPSI_FIXED], saved[LOGPSI_FREE], *dLogPsi[iwg], *d2LogPsi[iwg], thisWalker.DataSetForDerivatives); // logpsi = saved[LOGPSI_FIXED] + saved[LOGPSI_FREE]; } else { psiClones[ip]->evaluateDeltaLog(wRef, saved[LOGPSI_FIXED], saved[LOGPSI_FREE], *dLogPsi[iwg], *d2LogPsi[iwg]); // logpsi = psiClones[ip]->evaluateLog(wRef); } // if(includeNonlocalH!="no") logpsi = saved[LOGPSI_FIXED] + saved[LOGPSI_FREE]; Return_t x= hClones[ip]->evaluate(wRef); e0 += saved[ENERGY_TOT] = x; e2 += x*x; saved[ENERGY_FIXED] = hClones[ip]->getLocalPotential(); if(nlpp) saved[ENERGY_FIXED] -= nlpp->Value; //if (includeNonlocalH!="no") // saved[ENERGY_FIXED] = hClones[ip]->getLocalPotential() - (*(hClones[ip]->getHamiltonian(includeNonlocalH.c_str()))).Value; //else // saved[ENERGY_FIXED] = hClones[ip]->getLocalPotential(); // ef += saved[ENERGY_FIXED]; saved[REWEIGHT]=thisWalker.Weight=1.0; // thisWalker.resetProperty(logpsi,psiClones[ip]->getPhase(),x); if (needGrads) { //allocate vector vector<Return_t> Dsaved(NumOptimizables,0.0); vector<Return_t> HDsaved(NumOptimizables,0.0); psiClones[ip]->evaluateDerivatives(wRef, OptVariablesForPsi, Dsaved, HDsaved); std::copy(Dsaved.begin(),Dsaved.end(),(*DerivRecords[ip])[iw]); std::copy(HDsaved.begin(),HDsaved.end(),(*HDerivRecords[ip])[iw]); } } //add them all using reduction et_tot+=e0; e2_tot+=e2; // #pragma omp atomic // eft_tot+=ef; } OptVariablesForPsi.setComputed(); // app_log() << " VMC Efavg = " << eft_tot/static_cast<Return_t>(wPerNode[NumThreads]) << endl; //Need to sum over the processors vector<Return_t> etemp(3); etemp[0]=et_tot; etemp[1]=static_cast<Return_t>(wPerNode[NumThreads]); etemp[2]=e2_tot; myComm->allreduce(etemp); Etarget = static_cast<Return_t>(etemp[0]/etemp[1]); NumSamples = static_cast<int>(etemp[1]); app_log() << " VMC Eavg = " << Etarget << endl; app_log() << " VMC Evar = " << etemp[2]/etemp[1]-Etarget*Etarget << endl; app_log() << " Total weights = " << etemp[1] << endl; app_log().flush(); setTargetEnergy(Etarget); ReportCounter=0; }
void VMCParticleByParticle::runBlockWithDrift() { IndexType step = 0; MCWalkerConfiguration::iterator it_end(W.end()); do { //advanceWalkerByWalker(); MCWalkerConfiguration::iterator it(W.begin()); while(it != it_end) { //MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]); Walker_t& thisWalker(**it); Buffer_t& w_buffer(thisWalker.DataSet); W.R = thisWalker.R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); RealType psi_old = thisWalker.Properties(SIGN); RealType psi = psi_old; //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); bool moved = false; for(int iat=0; iat<W.getTotalNum(); iat++) { PosType dr = m_sqrttau*deltaR[iat]+thisWalker.Drift[iat]; PosType newpos = W.makeMove(iat,dr); //RealType ratio = Psi.ratio(W,iat); RealType ratio = Psi.ratio(W,iat,dG,dL); G = W.G+dG; //RealType forwardGF = exp(-0.5*dot(deltaR[iat],deltaR[iat])); //dr = (*it)->R[iat]-newpos-Tau*G[iat]; //RealType backwardGF = exp(-oneover2tau*dot(dr,dr)); RealType logGf = -0.5e0*dot(deltaR[iat],deltaR[iat]); RealType scale=getDriftScale(Tau,G); //COMPLEX WARNING //dr = thisWalker.R[iat]-newpos-scale*G[iat]; dr = thisWalker.R[iat]-newpos-scale*real(G[iat]); RealType logGb = -m_oneover2tau*dot(dr,dr); RealType prob = std::min(1.0e0,ratio*ratio*exp(logGb-logGf)); //alternatively if(Random() < prob) { moved = true; ++nAccept; W.acceptMove(iat); Psi.acceptMove(W,iat); W.G = G; W.L += dL; //thisWalker.Drift = scale*G; assignDrift(scale,G,thisWalker.Drift); } else { ++nReject; W.rejectMove(iat); Psi.rejectMove(iat); } } if(moved) { w_buffer.rewind(); W.copyToBuffer(w_buffer); psi = Psi.evaluate(W,w_buffer); thisWalker.R = W.R; RealType eloc=H.evaluate(W); thisWalker.resetProperty(log(abs(psi)), psi,eloc); H.saveProperty(thisWalker.getPropertyBase()); } else { ++nAllRejected; } ++it; } ++step;++CurrentStep; Estimators->accumulate(W); //if(CurrentStep%100 == 0) updateWalkers(); } while(step<nSteps); }
void VMCUpdatePbyP::advanceWalkers(WalkerIter_t it, WalkerIter_t it_end, bool measure) { myTimers[0]->start(); for (; it != it_end; ++it) { Walker_t& thisWalker(**it); W.loadWalker(thisWalker,true); Walker_t::Buffer_t& w_buffer(thisWalker.DataSet); Psi.copyFromBuffer(W,w_buffer); myTimers[1]->start(); for (int iter=0; iter<nSubSteps; ++iter) { makeGaussRandomWithEngine(deltaR,RandomGen); bool stucked=true; for(int ig=0; ig<W.groups(); ++ig) //loop over species { RealType sqrttau = std::sqrt(Tau*MassInvS[ig]); for (int iat=W.first(ig); iat<W.last(ig); ++iat) { PosType dr = sqrttau*deltaR[iat]; //replace makeMove by makeMoveAndCheck //PosType newpos = W.makeMove(iat,dr); if (W.makeMoveAndCheck(iat,dr)) { RealType ratio = Psi.ratio(W,iat); RealType prob = ratio*ratio; //RealType prob = std::min(1.0e0,ratio*ratio); if (RandomGen() < prob) { stucked=false; ++nAccept; W.acceptMove(iat); Psi.acceptMove(W,iat); } else { ++nReject; W.rejectMove(iat); Psi.rejectMove(iat); } } else //reject illegal moves ++nReject; } //iat }//ig for the species if (stucked) { ++nAllRejected; //H.rejectedMove(W,thisWalker); } thisWalker.R=W.R; } myTimers[1]->stop(); myTimers[2]->start(); //thisWalker.R = W.R; //PAOps<RealType,OHMMS_DIM>::copy(W.G,thisWalker.Drift); //w_buffer.rewind(); //W.updateBuffer(w_buffer); RealType logpsi = Psi.updateBuffer(W,w_buffer,false); W.saveWalker(thisWalker); //W.copyToBuffer(w_buffer); //RealType logpsi = Psi.evaluate(W,w_buffer); myTimers[2]->stop(); myTimers[3]->start(); RealType eloc=H.evaluate(W); myTimers[3]->stop(); thisWalker.resetProperty(logpsi,Psi.getPhase(),eloc); H.auxHevaluate(W,thisWalker); H.saveProperty(thisWalker.getPropertyBase()); } myTimers[0]->stop(); }