Ejemplo n.º 1
0
   /*
   * Verlet MD NVE integrator step
   *
   * This method implements the algorithm:
   *
   *        vm(n)  = v(n) + 0.5*a(n)*dt
   *        x(n+1) = x(n) + vm(n)*dt
   *
   *        calculate acceleration a(n+1)
   *
   *        v(n+1) = vm(n) + 0.5*a(n+1)*dt
   *
   * where x is position, v is velocity, and a is acceleration.
   */
   void NveVvIntegrator::step() 
   {
      Vector dv;
      Vector dr;
      System::MoleculeIterator molIter;
      double prefactor;
      int iSpecies, nSpecies;

      nSpecies = simulation().nSpecies();

      // 1st half velocity Verlet, loop over atoms 
      #if USE_ITERATOR
      Molecule::AtomIterator atomIter;
      for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
         system().begin(iSpecies, molIter); 
         for ( ; molIter.notEnd(); ++molIter) {
            for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {

               prefactor = prefactors_[atomIter->typeId()];

               dv.multiply(atomIter->force(), prefactor);
               atomIter->velocity() += dv;

               dr.multiply(atomIter->velocity(), dt_);
               atomIter->position() += dr;

            }
         }
      }
      #else 
      Atom* atomPtr;
      int   ia;
      for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
         system().begin(iSpecies, molIter); 
         for ( ; molIter.notEnd(); ++molIter) {
            for (ia=0; ia < molIter->nAtom(); ++ia) {
               atomPtr = &molIter->atom(ia);
               prefactor = prefactors_[atomPtr->typeId()];

               dv.multiply(atomPtr->force(), prefactor);
               atomPtr->velocity() += dv;
               dr.multiply(atomPtr->velocity(), dt_);
               
               atomPtr->position() += dr;

            }
         }
      }
      #endif

      system().calculateForces();

      // 2nd half velocity Verlet, loop over atoms
      #if USE_ITERATOR
      for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
         system().begin(iSpecies, molIter); 
         for ( ; molIter.notEnd(); ++molIter) {
            for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
               prefactor = prefactors_[atomIter->typeId()];
               dv.multiply(atomIter->force(), prefactor);
               atomIter->velocity() += dv;
            }
         }
      }
      #else
      for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
         system().begin(iSpecies, molIter); 
         for ( ; molIter.notEnd(); ++molIter)
         {
            for (ia=0; ia < molIter->nAtom(); ++ia) {
               atomPtr = &molIter->atom(ia);
               prefactor = prefactors_[atomPtr->typeId()];
               dv.multiply(atomPtr->force(), prefactor);
               atomPtr->velocity() += dv;
            }
         }
      }
      #endif

      #ifndef INTER_NOPAIR
      if (!system().pairPotential().isPairListCurrent()) {
         system().pairPotential().buildPairList();
      }
      #endif

   }
   /*
   * Nose-Hoover integrator step.
   *
   * This implements a reversible Velocity-Verlet MD NVT integrator step.
   *
   * Reference: Winkler, Kraus, and Reineker, J. Chem. Phys. 102, 9018 (1995).
   */
   void NvtNhIntegrator::step() 
   {
      Vector  dv;
      Vector  dr;
      System::MoleculeIterator molIter;
      double  dtHalf = 0.5*dt_;
      double  prefactor;
      double  factor;
      Molecule::AtomIterator atomIter;
      int  iSpecies, nSpecies;
      int  nAtom;

      T_target_ = energyEnsemblePtr_->temperature();
      nSpecies  = simulation().nSpecies();
      nAtom     = system().nAtom();

      factor = exp(-dtHalf*(xi_ + xiDot_*dtHalf));

      // 1st half velocity Verlet, loop over atoms 
      for (iSpecies = 0; iSpecies < nSpecies; ++iSpecies) {
         system().begin(iSpecies, molIter); 
         for ( ; molIter.notEnd(); ++molIter) {

            molIter->begin(atomIter); 
            for ( ; atomIter.notEnd(); ++atomIter) {

               atomIter->velocity() *= factor;

               prefactor = prefactors_[atomIter->typeId()];
               dv.multiply(atomIter->force(), prefactor);
               //dv.multiply(atomIter->force(), dtHalf);

               atomIter->velocity() += dv;
               dr.multiply(atomIter->velocity(), dt_);

               atomIter->position() += dr;

            }

         }
      }

      // First half of update of xi_
      xi_ += xiDot_*dtHalf;

      #ifndef INTER_NOPAIR
      // Rebuild the pair list if necessary
      if (!system().pairPotential().isPairListCurrent()) {
         system().pairPotential().buildPairList();
      }
      #endif

      system().calculateForces();

      // 2nd half velocity Verlet, loop over atoms
      for (iSpecies=0; iSpecies < nSpecies; ++iSpecies) {
         system().begin(iSpecies, molIter); 
         for ( ; molIter.notEnd(); ++molIter) {
            for (molIter->begin(atomIter); atomIter.notEnd(); ++atomIter) {
               prefactor = prefactors_[atomIter->typeId()];
               dv.multiply(atomIter->force(), prefactor);
               atomIter->velocity() += dv;
               atomIter->velocity() *=factor;
            }
         }
      }

      // Update xiDot and complete update of xi_
      T_kinetic_ = system().kineticEnergy()*2.0/double(3*nAtom);
      xiDot_ = (T_kinetic_/T_target_ -1.0)*nuT_*nuT_;
      xi_ += xiDot_*dtHalf;

   }