コード例 #1
0
   /* 
   * Evaluate pressure, and add to accumulator.
   */
   void McStressAutoCorrelation::sample(long iStep)
   {
      double pressure;
      double temperature;
      McSystem& sys=system(); 
      sys.computeStress(pressure);

      DArray<double> elements;
      elements.allocate(9);

      Tensor total;

      if (isAtInterval(iStep)){
         sys.computeVirialStress(total);
         temperature = sys.energyEnsemble().temperature();

         elements[0] = (total(0,0) - pressure / 3.0) / (10.0 * temperature);
         elements[1] = (total(0,1) + total(1,0)) / 2.0 / (10.0 * temperature);
         elements[2] = (total(0,2) + total(2,0)) / 2.0 / (10.0 * temperature);
         elements[3] = elements[1];
         elements[4] = (total(1,1) - pressure / 3.0) / (10.0 * temperature);
         elements[5] = (total(1,2) + total(2,1)) / 2.0 / (10.0 * temperature);
         elements[6] = elements[2];
         elements[7] = elements[5];
         elements[8] = (total(2,2) - pressure / 3.0) / (10.0 * temperature);

         accumulator_.sample(elements);
     }
   }
コード例 #2
0
void RingMaker::readParam(std::istream& in)
{
   //bondPotential_.setBoundary(boundary_);
   bondPotential_.setNBondType(1);

   read<Boundary>(in, "boundary", boundary_);
   readParamComposite(in, bondPotential_);
   readParamComposite(in, random_);
   read<int>(in, "nMolecule", nMolecule_);
   read<int>(in, "nAtomPerMolecule", nAtom_);

   if (nAtom_ < 2) UTIL_THROW("No. of atoms too small");
   v_.allocate(nAtom_);
}
コード例 #3
0
ファイル: ReplicaMove.cpp プロジェクト: jglaser/simpatico
   /*
   * Perform replica exchange move.
   */
   bool ReplicaMove::move()
   {
      MPI::Request request[4];
      MPI::Status  status;
      System::MoleculeIterator molIter;
      Molecule::AtomIterator   atomIter;
      int iA;
      int recvPt, sendPt;
  
      DArray<int> permutation;
      permutation.allocate(nProcs_);

      // Gather all derivatives of the perturbation Hamiltonians and parameters on processor with rank 0
      DArray<double> myDerivatives;
      myDerivatives.allocate(nParameters_);
      DArray<double> myParameters;
      myParameters.allocate(nParameters_);

      for (int i=0; i< nParameters_; i++) {
         myDerivatives[i] = system().perturbation().derivative(i);
         myParameters[i] = system().perturbation().parameter(i);
      }

      int size = 0;
      size += memorySize(myDerivatives);
      size += memorySize(myParameters);

      if (myId_ != 0) {

         MemoryOArchive sendCurrent;
         sendCurrent.allocate(size);

         sendCurrent << myDerivatives;
         sendCurrent << myParameters;

         sendCurrent.send(*communicatorPtr_, 0);
      } else {
         DArray< DArray<double> > allDerivatives;
         DArray< DArray<double> > allParameters;
         allDerivatives.allocate(nProcs_);
         allParameters.allocate(nProcs_);
   
         allDerivatives[0].allocate(nParameters_);
         allDerivatives[0] = myDerivatives;
         allParameters[0].allocate(nParameters_);
         allParameters[0] = myParameters;

         for (int i = 1; i<nProcs_; i++) {
            MemoryIArchive recvPartner;
            recvPartner.allocate(size);
            recvPartner.recv(*communicatorPtr_, i);
            allDerivatives[i].allocate(nParameters_);
            allParameters[i].allocate(nParameters_);
            recvPartner >> allDerivatives[i];
            recvPartner >> allParameters[i];
         }

         // Now we have the complete matrix U_ij = u_i(x_j), permutate nsampling steps according
         // to acceptance criterium
  
         // start with identity permutation
         for (int i = 0; i < nProcs_; i++)
            permutation[i] = i;

         for (int n =0; n < nSampling_; n++) {
            swapAttempt_++;
            // choose a pair i,j, i!= j at random
            int i = system().simulation().random().uniformInt(0,nProcs_);
            int j = system().simulation().random().uniformInt(0,nProcs_-1);
            if (i<=j) j++;

            // apply acceptance criterium
            double weight = 0;
            for (int k = 0; k < nParameters_; k++) {
               double deltaDerivative = allDerivatives[i][k] - allDerivatives[j][k];
               // the permutations operate on the states (the perturbation parameters)
               weight += (allParameters[permutation[j]][k] - allParameters[permutation[i]][k])*deltaDerivative;
             }
            double exponential = exp(-weight);
            int accept = system().simulation().random(). metropolis(exponential) ? 1 : 0;
   
            if (accept) {
               swapAccept_++;
               // swap states of pair i,j
               int tmp = permutation[i];
               permutation[i] = permutation[j];
               permutation[j] = tmp;
               }
         }
    
         // send exchange partner information to all other processors
         for (int i = 0; i < nProcs_; i++) {
            if (i != 0)
                communicatorPtr_->Send(&permutation[i], 1, MPI::INT, i, 0);
            else
                sendPt = permutation[i];

            if (permutation[i] != 0)
               communicatorPtr_->Send(&i, 1, MPI::INT, permutation[i], 1);
            else
               recvPt = i;
         }
      }

      
      if (myId_ != 0) {
         // partner id to receive from
         communicatorPtr_->Recv(&sendPt, 1, MPI::INT, 0, 0);
         // partner id to send to
         communicatorPtr_->Recv(&recvPt, 1, MPI::INT, 0, 1);
      }

      if (recvPt == myId_ || sendPt == myId_) {
         // no exchange necessary
         outputFile_ << sendPt << std::endl;
         return true;
      }

      assert(recvPt != myId_ && sendPt != myId_);

      Vector myBoundary;
      myBoundary = system().boundary().lengths();
            
      Vector ptBoundary;
            
      // Accomodate new boundary dimensions.
      request[0] = communicatorPtr_->Irecv(&ptBoundary, 1,
                                           MpiTraits<Vector>::type, recvPt, 1);

      // Send old boundary dimensions.
      request[1] = communicatorPtr_->Isend(&myBoundary, 1,
                                            MpiTraits<Vector>::type, sendPt, 1);

      request[0].Wait();
      request[1].Wait();
             
      system().boundary().setOrthorhombic(ptBoundary);

      // Pack atomic positions and types.
      iA = 0;
      for (int iSpec=0; iSpec < system().simulation().nSpecies(); ++iSpec){
         for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter){
            for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
               myPositionPtr_[iA] = atomIter->position();
               iA++;
            }
         }
      }
      
      // Accomodate new configuration.
      request[2] = communicatorPtr_->Irecv(ptPositionPtr_, iA,
                       MpiTraits<Vector>::type, recvPt, 2); 

      // Send old configuration.
      request[3] = communicatorPtr_->Isend(myPositionPtr_, iA,
                       MpiTraits<Vector>::type, sendPt, 2);

      request[2].Wait();
      request[3].Wait();
      
      // Adopt the new atomic positions.
      iA = 0;
      for (int iSpec=0; iSpec < system().simulation().nSpecies(); ++iSpec){
         for (system().begin(iSpec, molIter); molIter.notEnd(); ++molIter){
            for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter){
               atomIter->position() = ptPositionPtr_[iA];
               ++iA;
            }
         }
      }
      

      // Notify component observers.
      sendRecvPair partners;
      partners[0] = sendPt;
      partners[1] = recvPt;
      Notifier<sendRecvPair>::notifyObservers(partners);

      // Log information about exchange partner to file
      outputFile_ << sendPt << std::endl;

      return true;

   }