Ejemplo n.º 1
0
  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);
}
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
  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;
  }
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
  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;
  }