/* * 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; }