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); }
int main(int argc, char** argv) { NcError error(NcError::silent_nonfatal); try { // Input filename std::string strInputFile; // Output mesh filename std::string strOutputMesh; // Output connectivity filename std::string strOutputConnectivity; // Number of elements in mesh int nP; // Use uniformly spaced sub-volumes bool fUniformSpacing = false; // Do not merge faces bool fNoMergeFaces = false; // Nodes appear at GLL nodes bool fCGLL = true; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputMesh, "out", ""); CommandLineString(strOutputConnectivity, "out_connect", ""); CommandLineInt(nP, "np", 2); CommandLineBool(fUniformSpacing, "uniform"); //CommandLineBool(fNoMergeFaces, "no-merge-face"); //CommandLineBool(fCGLL, "cgll"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check file names if (strInputFile == "") { _EXCEPTIONT("No input file specified"); } if (nP < 2) { _EXCEPTIONT("--np must be >= 2"); } if ((fNoMergeFaces) && (strOutputConnectivity != "")) { _EXCEPTIONT("--out_connect and --no-merge-face not implemented"); } // Load input mesh std::cout << std::endl; std::cout << "..Loading input mesh" << std::endl; Mesh meshIn(strInputFile); meshIn.RemoveZeroEdges(); // Number of elements int nElements = meshIn.faces.size(); // Gauss-Lobatto quadrature nodes and weights std::cout << "..Computing sub-volume boundaries" << std::endl; DataArray1D<double> dG(nP); DataArray1D<double> dW(nP); // Uniformly spaced nodes if (fUniformSpacing) { for (int i = 0; i < nP; i++) { dG[i] = (2.0 * static_cast<double>(i) + 1.0) / (2.0 * nP); dW[i] = 1.0 / nP; } dG[0] = 0.0; dG[1] = 1.0; // Get Gauss-Lobatto Weights } else { GaussLobattoQuadrature::GetPoints(nP, 0.0, 1.0, dG, dW); } // Accumulated weight vector DataArray1D<double> dAccumW(nP+1); dAccumW[0] = 0.0; for (int i = 1; i < nP+1; i++) { dAccumW[i] = dAccumW[i-1] + dW[i-1]; } if (fabs(dAccumW[dAccumW.GetRows()-1] - 1.0) > 1.0e-14) { _EXCEPTIONT("Logic error in accumulated weight"); } // Data structures used for generating connectivity DataArray3D<int> dataGLLnodes(nP, nP, nElements); std::vector<Node> vecNodes; std::map<Node, int> mapFaces; // Data structure for // Data structure used for avoiding coincident nodes on the fly std::map<Node, int> mapNewNodes; // Generate new mesh std::cout << "..Generating sub-volumes" << std::endl; Mesh meshOut; for (size_t f = 0; f < nElements; f++) { const Face & face = meshIn.faces[f]; if (face.edges.size() != 4) { _EXCEPTIONT("Input mesh must only contain quadrilaterals"); } const Node & node0 = meshIn.nodes[face[0]]; const Node & node1 = meshIn.nodes[face[1]]; const Node & node2 = meshIn.nodes[face[2]]; const Node & node3 = meshIn.nodes[face[3]]; for (int q = 0; q < nP; q++) { for (int p = 0; p < nP; p++) { bool fNewFace = true; // Build unique node array if CGLL if (fCGLL) { // Get local nodal location Node nodeGLL; Node dDx1G; Node dDx2G; ApplyLocalMap( face, meshIn.nodes, dG[p], dG[q], nodeGLL, dDx1G, dDx2G); // Determine if this is a unique Node std::map<Node, int>::const_iterator iter = mapFaces.find(nodeGLL); if (iter == mapFaces.end()) { // Insert new unique node into map int ixNode = static_cast<int>(mapFaces.size()); mapFaces.insert(std::pair<Node, int>(nodeGLL, ixNode)); dataGLLnodes[q][p][f] = ixNode + 1; vecNodes.push_back(nodeGLL); } else { dataGLLnodes[q][p][f] = iter->second + 1; fNewFace = false; } // Non-unique node array if DGLL } else { dataGLLnodes[q][p][f] = nP * nP * f + q * nP + p; } // Get volumetric region Face faceNew(4); for (int i = 0; i < 4; i++) { int px = p+((i+1)/2)%2; // p,p+1,p+1,p int qx = q+(i/2); // q,q,q+1,q+1 Node nodeOut = InterpolateQuadrilateralNode( node0, node1, node2, node3, dAccumW[px], dAccumW[qx]); std::map<Node, int>::const_iterator iterNode = mapNewNodes.find(nodeOut); if (iterNode == mapNewNodes.end()) { mapNewNodes.insert( std::pair<Node, int>(nodeOut, meshOut.nodes.size())); faceNew.SetNode(i, meshOut.nodes.size()); meshOut.nodes.push_back(nodeOut); } else { faceNew.SetNode(i, iterNode->second); } } // Insert new Face or merge with existing Face meshOut.faces.push_back(faceNew); /* if ((fNoMergeFaces) || (fNewFace)) { } else { std::cout << dataGLLnodes[q][p][f]-1 << " " << mapFaces.size()-1 << std::endl; meshOut.faces[dataGLLnodes[q][p][f]-1].Merge(faceNew); } */ } } } meshOut.RemoveCoincidentNodes(); // Build connectivity and write to file if (strOutputConnectivity != "") { std::cout << "..Constructing connectivity file" << std::endl; std::vector< std::set<int> > vecConnectivity; vecConnectivity.resize(mapFaces.size()); for (size_t f = 0; f < nElements; f++) { for (int q = 0; q < nP; q++) { for (int p = 0; p < nP; p++) { std::set<int> & setLocalConnectivity = vecConnectivity[dataGLLnodes[q][p][f]-1]; // Connect in all directions if (p != 0) { setLocalConnectivity.insert( dataGLLnodes[q][p-1][f]); } if (p != (nP-1)) { setLocalConnectivity.insert( dataGLLnodes[q][p+1][f]); } if (q != 0) { setLocalConnectivity.insert( dataGLLnodes[q-1][p][f]); } if (q != (nP-1)) { setLocalConnectivity.insert( dataGLLnodes[q+1][p][f]); } } } } // Open output file FILE * fp = fopen(strOutputConnectivity.c_str(), "w"); fprintf(fp, "%lu\n", vecConnectivity.size()); for (size_t f = 0; f < vecConnectivity.size(); f++) { const Node & node = vecNodes[f]; double dLon = atan2(node.y, node.x); double dLat = asin(node.z); if (dLon < 0.0) { dLon += 2.0 * M_PI; } fprintf(fp, "%1.14f,", dLon / M_PI * 180.0); fprintf(fp, "%1.14f,", dLat / M_PI * 180.0); fprintf(fp, "%lu", vecConnectivity[f].size()); std::set<int>::const_iterator iter = vecConnectivity[f].begin(); for (; iter != vecConnectivity[f].end(); iter++) { fprintf(fp, ",%i", *iter); } if (f != vecConnectivity.size()-1) { fprintf(fp,"\n"); } } fclose(fp); } // Remove coincident nodes //std::cout << "..Removing coincident nodes" << std::endl; //meshOut.RemoveCoincidentNodes(); // Write the mesh if (strOutputMesh != "") { std::cout << "..Writing mesh" << std::endl; meshOut.Write(strOutputMesh); } // Announce std::cout << "..Mesh generator exited successfully" << std::endl; std::cout << "========================================================="; std::cout << std::endl; return (0); } catch(Exception & e) { Announce(e.ToString().c_str()); return (-1); } catch(...) { return (-2); } }
SolutionInfo Alignment::align(bool n) { // create initial solution SolutionInfo si; si.volume = -1000.0; si.iterations = 0; si.center1 = _refCenter; si.center2 = _dbCenter; si.rotation1 = _refRotMat; si.rotation2 = _dbRotMat; // scaling of the exclusion spheres double scale(1.0); if (_nbrExcl != 0) { scale /= _nbrExcl; } // try 4 different start orientations for (unsigned int _call(0); _call < 4; ++_call ) { // create initial rotation quaternion SiMath::Vector rotor(4,0.0); rotor[_call] = 1.0; double volume(0.0), oldVolume(-999.99), v(0.0); SiMath::Vector dG(4,0.0); // gradient update SiMath::Matrix hessian(4,4,0.0), dH(4,4,0.0); // hessian and hessian update unsigned int ii(0); for ( ; ii < 100; ++ii) { // compute gradient of volume _grad = 0.0; volume = 0.0; hessian = 0.0; for (unsigned int i(0); i < _refMap.size(); ++i) { // compute the volume overlap of the two pharmacophore points SiMath::Vector Aq(4,0.0); SiMath::Matrix * AkA = _AkA[i]; Aq[0] = (*AkA)[0][0] * rotor[0] + (*AkA)[0][1] * rotor[1] + (*AkA)[0][2] * rotor[2] + (*AkA)[0][3] * rotor[3]; Aq[1] = (*AkA)[1][0] * rotor[0] + (*AkA)[1][1] * rotor[1] + (*AkA)[1][2] * rotor[2] + (*AkA)[1][3] * rotor[3]; Aq[2] = (*AkA)[2][0] * rotor[0] + (*AkA)[2][1] * rotor[1] + (*AkA)[2][2] * rotor[2] + (*AkA)[2][3] * rotor[3]; Aq[3] = (*AkA)[3][0] * rotor[0] + (*AkA)[3][1] * rotor[1] + (*AkA)[3][2] * rotor[2] + (*AkA)[3][3] * rotor[3]; double qAq = Aq[0] * rotor[0] + Aq[1] * rotor[1] + Aq[2] * rotor[2] +Aq[3] * rotor[3]; v = GCI2 * pow(PI/(_refMap[i].alpha+_dbMap[i].alpha),1.5) * exp(-qAq); double c(1.0); // add normal if AROM-AROM // in this case the absolute value of the angle is needed if (n && (_refMap[i].func == AROM) && (_dbMap[i].func == AROM) && (_refMap[i].hasNormal) && (_dbMap[i].hasNormal)) { // for aromatic rings only the planar directions count // therefore the absolute value of the cosine is taken c = _normalContribution(_refMap[i].normal, _dbMap[i].normal, rotor); // update based on the sign of the cosine if (c < 0) { c *= -1.0; _dCdq *= -1.0; _d2Cdq2 *= -1.0; } for (unsigned int hi(0); hi < 4; hi++) { _grad[hi] += v * ( _dCdq[hi] - 2.0 * c * Aq[hi] ); for (unsigned int hj(0); hj < 4; hj++) { hessian[hi][hj] += v * (_d2Cdq2[hi][hj] - 2.0 * _dCdq[hi]*Aq[hj] + 2.0 * c * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj])); } } v *= c; } else if (n && ((_refMap[i].func == HACC) || (_refMap[i].func == HDON) || (_refMap[i].func == HYBH)) && ((_dbMap[i].func == HYBH) || (_dbMap[i].func == HACC) || (_dbMap[i].func == HDON)) && (_refMap[i].hasNormal) && (_dbMap[i].hasNormal)) { // hydrogen donors and acceptor also have a direction // in this case opposite directions have negative impact c = _normalContribution(_refMap[i].normal, _dbMap[i].normal, rotor); for (unsigned int hi(0); hi < 4; hi++) { _grad[hi] += v * ( _dCdq[hi] - 2.0 * c * Aq[hi] ); for (unsigned int hj(0); hj < 4; hj++) { hessian[hi][hj] += v * (_d2Cdq2[hi][hj] - 2.0 * _dCdq[hi]*Aq[hj] + 2.0 * c * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj])); } } v *= c; } else if (_refMap[i].func == EXCL) { // scale volume overlap of exclusion sphere with a negative scaling factor // => exclusion spheres have a negative impact v *= -scale; // update gradient and hessian directions for (unsigned int hi=0; hi < 4; hi++) { _grad[hi] -= 2.0 * v * Aq[hi]; for (unsigned int hj(0); hj < 4; hj++) { hessian[hi][hj] += 2.0 * v * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj]); } } } else { // update gradient and hessian directions for (unsigned int hi(0); hi < 4; hi++) { _grad[hi] -= 2.0 * v * Aq[hi]; for (unsigned int hj(0); hj < 4; hj++) { hessian[hi][hj] += 2.0 * v * (2.0*Aq[hi]*Aq[hj] - (*AkA)[hi][hj]); } } } volume += v; } // stop iterations if the increase in volume overlap is too small (gradient ascent) // or if the volume is not defined if (std::isnan(volume) || (volume - oldVolume < 1e-5)) { break; } // reset old volume oldVolume = volume; inverseHessian(hessian); // update gradient based on inverse hessian _grad = rowProduct(hessian,_grad); // small scaling of the gradient _grad *= 0.9; // update rotor based on gradient information rotor += _grad; // normalise rotor such that it has unit norm normalise(rotor); } // save result in info structure if (oldVolume > si.volume) { si.rotor = rotor; si.volume = oldVolume; si.iterations = ii; } } return si; }
bool VMCPbyPMultiple::run() { Estimators->reportHeader(); //going to add routines to calculate how much we need bool require_register = W.createAuxDataSet(); multiEstimator->initialize(W,H1,Psi1,Tau,require_register); Estimators->reset(); //create an output engine HDFWalkerOutput WO(RootName); IndexType block = 0; Pooma::Clock timer; RealType oneovertau = 1.0/Tau; RealType oneover2tau = 0.5*oneovertau; RealType g = sqrt(Tau); RealType nPsi_minus_one = nPsi-1; MCWalkerConfiguration::iterator it; MCWalkerConfiguration::iterator it_end(W.end()); MCWalkerConfiguration::PropertyContainer_t Properties; ParticleSet::ParticleGradient_t dG(W.getTotalNum()); IndexType accstep=0; IndexType nAcceptTot = 0; IndexType nRejectTot = 0; do { //Blocks loop IndexType step = 0; timer.start(); nAccept = 0; nReject=0; IndexType nAllRejected = 0; do { //Steps loop it = W.begin(); int iwalker=0; while(it != it_end) { //Walkers loop MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]); W.R = (*it)->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]; ValueType psi_old = (*it)->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 = g*deltaR[iat]+(*it)->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]); // 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++){ RealType rji=ratio[jpsi]/ratio[ipsi]; rji = rji*rji*ratioijPtr[indexij]; ratioij[indexij++]=rji; sumratio[ipsi] += rji; sumratio[jpsi] += 1.0/rji; } } RealType logGf = -0.5*dot(deltaR[iat],deltaR[iat]); ValueType scale = Tau; drift=0.0; // Evaluate new Umbrella Weight and new drift for(int ipsi=0; ipsi< nPsi; ipsi++){ invsumratio[ipsi]=1.0/sumratio[ipsi]; drift += invsumratio[ipsi]*(*G[ipsi]); } drift *= scale; dr = (*it)->R[iat]-newpos-drift[iat]; RealType logGb = -oneover2tau*dot(dr,dr); // td = Target Density ratio RealType td=pow(ratio[0],2) *sumratio[0]/(*it)->Properties(SUMRATIO); RealType prob = std::min(1.0,td*exp(logGb-logGf)); 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 (*it)->Properties(SUMRATIO)=sumratio[0]; for(int ipsi=0; ipsi< nPsi; ipsi++){ ////Update local Psi1[i] buffer for the next move Psi1[ipsi]->update2(W,iat); // Update G and L in Psi1[i] Psi1[ipsi]->G = *G[ipsi]; Psi1[ipsi]->L += *dL[ipsi]; } // Update Drift (*it)->Drift = drift; } else { ++nReject; for(int ipsi=0; ipsi< nPsi; ipsi++) Psi1[ipsi]->restore(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)->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; psi = Psi1[ipsi]->evaluate(W,w_buffer); RealType et = H1[ipsi]->evaluate(W); H1[ipsi]->copy((*it)->getEnergyBase(ipsi)); multiEstimator->updateSample(iwalker,ipsi,et,UmbrellaWeight[ipsi]); } } else { ++nAllRejected; } ++it; ++iwalker; } ++step;++accstep; Estimators->accumulate(W); } while(step<nSteps); timer.stop(); nAcceptTot += nAccept; nRejectTot += nReject; Estimators->flush(); Estimators->setColumn(AcceptIndex, static_cast<RealType>(nAccept)/static_cast<RealType>(nAccept+nReject)); Estimators->report(accstep); LogOut->getStream() << "Block " << block << " " << timer.cpu_time() << " Fixed_configs " << static_cast<RealType>(nAllRejected)/static_cast<RealType>(step*W.getActiveWalkers()) << " nPsi " << nPsi << endl; if(pStride) WO.get(W); nAccept = 0; nReject = 0; ++block; } while(block<nBlocks); LogOut->getStream() << "Ratio = " << static_cast<RealType>(nAcceptTot)/static_cast<RealType>(nAcceptTot+nRejectTot) << endl; if(!pStride) WO.get(W); Estimators->finalize(); return true; }
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); }
bool DMCParticleByParticle::run() { //add columns IndexType PopIndex = Estimators->addColumn("Population"); IndexType EtrialIndex = Estimators->addColumn("E_T"); //write the header Estimators->reportHeader(); MolecuFixedNodeBranch<RealType> brancher(Tau,W.getActiveWalkers()); //initialize parameters for fixed-node branching brancher.put(qmcNode,LogOut); if(BranchInfo != "default") brancher.read(BranchInfo); else { /*if VMC/DMC directly preceded DMC (Counter > 0) then use the average value of the energy estimator for the reference energy of the brancher*/ if(Counter) { RealType e_ref = W.getLocalEnergy(); LOGMSG("Overwriting the reference energy by the local energy " << e_ref) brancher.setEguess(e_ref); } } MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); while(it!=it_end) { (*it)->Properties(WEIGHT) = 1.0; (*it)->Properties(MULTIPLICITY) = 1.0; ++it; } //going to add routines to calculate how much we need bool require_register = W.createAuxDataSet(); int iwalker=0; it = W.begin(); it_end = W.end(); if(require_register) { while(it != it_end) { W.DataSet[iwalker]->rewind(); W.registerData(**it,*(W.DataSet[iwalker])); Psi.registerData(W,*(W.DataSet[iwalker])); ++it;++iwalker; } } Estimators->reset(); IndexType block = 0; Pooma::Clock timer; int Population = W.getActiveWalkers(); int tPopulation = W.getActiveWalkers(); RealType Eest = brancher.E_T; RealType E_T = Eest; RealType oneovertau = 1.0/Tau; RealType oneover2tau = 0.5*oneovertau; RealType g = sqrt(Tau); MCWalkerConfiguration::PropertyContainer_t Properties; ParticleSet::ParticlePos_t deltaR(W.getTotalNum()); ParticleSet::ParticleGradient_t G(W.getTotalNum()), dG(W.getTotalNum()); ParticleSet::ParticleLaplacian_t L(W.getTotalNum()), dL(W.getTotalNum()); IndexType accstep=0; IndexType nAcceptTot = 0; IndexType nRejectTot = 0; IndexType nat = W.getTotalNum(); int ncross = 0; do { IndexType step = 0; timer.start(); nAccept = 0; nReject=0; IndexType nAllRejected = 0; do { Population = W.getActiveWalkers(); it = W.begin(); it_end = W.end(); iwalker=0; while(it != it_end) { MCWalkerConfiguration::WalkerData_t& w_buffer = *(W.DataSet[iwalker]); (*it)->Properties(WEIGHT) = 1.0; (*it)->Properties(MULTIPLICITY) = 1.0; //save old local energy ValueType eold((*it)->Properties(LOCALENERGY)); ValueType emixed(eold); W.R = (*it)->R; w_buffer.rewind(); W.copyFromBuffer(w_buffer); Psi.copyFromBuffer(W,w_buffer); ValueType psi_old((*it)->Properties(SIGN)); ValueType psi(psi_old); //create a 3N-Dimensional Gaussian with variance=1 makeGaussRandom(deltaR); bool notcrossed(true); int nAcceptTemp(0); int nRejectTemp(0); int iat=0; while(notcrossed && iat<nat){ PosType dr(g*deltaR[iat]+(*it)->Drift[iat]); PosType newpos(W.makeMove(iat,dr)); RealType ratio(Psi.ratio(W,iat,dG,dL)); if(ratio < 0.0) {//node is crossed, stop here notcrossed = false; } else { G = W.G+dG; RealType logGf = -0.5*dot(deltaR[iat],deltaR[iat]); ValueType vsq = Dot(G,G); ValueType scale = ((-1.0+sqrt(1.0+2.0*Tau*vsq))/vsq); dr = (*it)->R[iat]-newpos-scale*G[iat]; //dr = (*it)->R[iat]-newpos-Tau*G[iat]; RealType logGb = -oneover2tau*dot(dr,dr); //RealType ratio2 = pow(ratio,2) RealType prob = std::min(1.0,pow(ratio,2)*exp(logGb-logGf)); if(Random() < prob) { ++nAcceptTemp; W.acceptMove(iat); Psi.update2(W,iat); W.G = G; W.L += dL; // (*it)->Drift = Tau*G; (*it)->Drift = scale*G; } else { ++nRejectTemp; Psi.restore(iat); } } ++iat; } if(notcrossed) { if(nAcceptTemp) {//need to overwrite the walker properties w_buffer.rewind(); W.copyToBuffer(w_buffer); psi = Psi.evaluate(W,w_buffer); (*it)->R = W.R; (*it)->Properties(AGE) = 0; //This is not so useful: allow overflow/underflow (*it)->Properties(LOGPSI) = log(fabs(psi)); (*it)->Properties(SIGN) = psi; (*it)->Properties(LOCALENERGY) = H.evaluate(W); H.copy((*it)->getEnergyBase()); (*it)->Properties(LOCALPOTENTIAL) = H.getLocalPotential(); emixed += (*it)->Properties(LOCALENERGY); } else { //WARNMSG("All the particle moves are rejected.") (*it)->Properties(AGE)++; ++nAllRejected; emixed += eold; } ValueType M = brancher.branchGF(Tau,emixed*0.5,0.0); // if((*it)->Properties(AGE) > 3.0) M = min(0.5,M); //persistent configurations if((*it)->Properties(AGE) > 1.9) M = std::min(0.5,M); if((*it)->Properties(AGE) > 0.9) M = std::min(1.0,M); (*it)->Properties(WEIGHT) = M; (*it)->Properties(MULTIPLICITY) = M + Random(); nAccept += nAcceptTemp; nReject += nRejectTemp; } else {//set the weight and multiplicity to zero (*it)->Properties(WEIGHT) = 0.0; (*it)->Properties(MULTIPLICITY) = 0.0; nReject += W.getTotalNum();//not make sense } ++it; ++iwalker; } ++step;++accstep; Estimators->accumulate(W); Eest = brancher.update(Population,Eest); //E_T = brancher.update(Population,Eest); brancher.branch(accstep,W); } while(step<nSteps); //WARNMSG("The number of a complete rejectoin " << nAllRejected) timer.stop(); nAcceptTot += nAccept; nRejectTot += nReject; Estimators->flush(); Estimators->setColumn(PopIndex,static_cast<RealType>(Population)); Estimators->setColumn(EtrialIndex,Eest); //E_T); Estimators->setColumn(AcceptIndex, static_cast<RealType>(nAccept)/static_cast<RealType>(nAccept+nReject)); Estimators->report(accstep); Eest = Estimators->average(0); LogOut->getStream() << "Block " << block << " " << timer.cpu_time() << " Fixed_configs " << static_cast<RealType>(nAllRejected)/static_cast<RealType>(step*W.getActiveWalkers()) << endl; if(pStride) { //create an output engine HDFWalkerOutput WO(RootName); WO.get(W); brancher.write(WO.getGroupID()); } nAccept = 0; nReject = 0; block++; } while(block<nBlocks); LogOut->getStream() << "Ratio = " << static_cast<double>(nAcceptTot)/static_cast<double>(nAcceptTot+nRejectTot) << endl; if(!pStride) { //create an output engine HDFWalkerOutput WO(RootName); WO.get(W); brancher.write(WO.getGroupID()); } Estimators->finalize(); return true; }