void transformation_update() { if (enigma::transform_needs_update == true) { //Recalculate matrices enigma::mv_matrix = enigma::view_matrix * enigma::model_matrix; enigma::mvp_matrix = enigma::projection_matrix * enigma::mv_matrix; //normal_matrix = invert(transpose(mv_submatrix)), where mv_submatrix is modelview top-left 3x3 matrix enigma::Matrix4 tmpNorm = enigma::mv_matrix.Transpose().Inverse(); enigma::normal_matrix = enigma::Matrix3(tmpNorm(0,0),tmpNorm(0,1),tmpNorm(0,2), tmpNorm(1,0),tmpNorm(1,1),tmpNorm(1,2), tmpNorm(2,0),tmpNorm(2,1),tmpNorm(2,2)); enigma::transform_needs_update = false; } }
/** Run the VMCMultiple algorithm. * * Similar to VMC::run */ bool VMCMultiple::run() { //TEST CACHE //Estimators->reportHeader(AppendRun); bool require_register=false; //Check if we need to update the norm of the wave functions vector<RealType> 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]); } //this is where the first values are evaulated multiEstimator->initialize(W,H1,Psi1,Tau,Norm,require_register); //TEST CACHE //Estimators->reset(); Estimators->start(nBlocks); //TEST CACHE IndexType block = 0; double wh=0.0; IndexType nAcceptTot = 0; IndexType nRejectTot = 0; do { IndexType step = 0; nAccept = 0; nReject=0; Estimators->startBlock(nSteps); do { advanceWalkerByWalker(); 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(nAccept/static_cast<RealType>(nAccept+nReject)); nAcceptTot += nAccept; nRejectTot += nReject; nAccept = 0; nReject = 0; block++; //record the current configuration recordBlock(block); } while(block<nBlocks); //Need MPI-IO app_log() << "Ratio = " << static_cast<double>(nAcceptTot)/static_cast<double>(nAcceptTot+nRejectTot) << endl; //finalize a qmc section return finalize(block); }
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); }