/* * NoseHoover.cpp * * Created on: Aug 20, 2010 * Author: crueger */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "NoseHoover.hpp" #include "element.hpp" #include "config.hpp" #include "CodePatterns/Verbose.hpp" #include "CodePatterns/Log.hpp" #include "ThermoStatContainer.hpp" #include "World.hpp" NoseHoover::NoseHoover(double _HooverMass) : HooverMass(_HooverMass), alpha(0) {} NoseHoover::NoseHoover() : HooverMass(0.) {} NoseHoover::~NoseHoover() {} const char *ThermostatTraits::name = "NoseHoover"; std::string ThermostatTraits::getName(){ return ThermostatTraits::name; } Thermostat *ThermostatTraits::make(class ConfigFileBuffer * const fb){ double HooverMass; const int verbose = 0; ParseForParameter(verbose,fb,"Thermostat", 0, 2, 1, double_type, &HooverMass, 1, critical); // read Hoovermass return new NoseHoover(HooverMass); } double NoseHoover::scaleAtoms(unsigned int step,double ActualTemp,ATOMSET(std::list) atoms){ return doScaleAtoms(step,ActualTemp,atoms.begin(),atoms.end()); } double NoseHoover::scaleAtoms(unsigned int step,double ActualTemp,ATOMSET(std::vector) atoms){ return doScaleAtoms(step,ActualTemp,atoms.begin(),atoms.end()); } double NoseHoover::scaleAtoms(unsigned int step,double ActualTemp,ATOMSET(std::set) atoms){ return doScaleAtoms(step,ActualTemp,atoms.begin(),atoms.end()); } template double NoseHoover::doScaleAtoms(unsigned int step,double ActualTemp,ForwardIterator begin, ForwardIterator end){ DoLog(2) && (Log() << Verbose(2) << "Applying Nose-Hoover thermostat..." << endl); init(step,begin,end); delta_alpha = (delta_alpha - (3.*count+1.) * getContainer().TargetTemp)/(HooverMass*Units2Electronmass); alpha += delta_alpha*World::getInstance().getConfig()->Deltat; DoLog(3) && (Log() << Verbose(3) << "alpha = " << delta_alpha << " * " << World::getInstance().getConfig()->Deltat << " = " << alpha << "." << endl); double ekin =0; for(ForwardIterator iter=begin;iter!=end;++iter){ Vector U = (*iter)->getAtomicVelocityAtStep(step); if ((*iter)->getFixedIon() == 0) { // even FixedIon moves, only not by other's forces U += World::getInstance().getConfig()->Deltat/(*iter)->getType()->getMass() * (alpha * (U * (*iter)->getType()->getMass())); ekin += (0.5*(*iter)->getType()->getMass()) * U.NormSquared(); } (*iter)->setAtomicVelocityAtStep(step, U); } return ekin; } template void NoseHoover::init(unsigned int step,ForwardIterator begin, ForwardIterator end){ delta_alpha=0; count=0; for(ForwardIterator iter = begin;iter!=end;++iter){ const Vector &U = (*iter)->getAtomicVelocityAtStep(step); if ((*iter)->getFixedIon() == 0) { // even FixedIon moves, only not by other's forces delta_alpha += U.NormSquared()*(*iter)->getType()->getMass(); } ++count; } } std::string NoseHoover::name(){ return ThermostatTraits::name; } std::string NoseHoover::writeParams(){ std::stringstream sstr; sstr << HooverMass; return sstr.str(); }