/* * GaussianThermostat.cpp * * Created on: Aug 18, 2010 * Author: crueger */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "GaussianThermostat.hpp" #include "LinearAlgebra/Vector.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Verbose.hpp" #include "AtomSet.hpp" #include "element.hpp" #include "config.hpp" #include "World.hpp" #include GaussianThermostat::GaussianThermostat(int _ScaleTempStep) : E(0),G(0), ScaleTempStep(_ScaleTempStep) {} GaussianThermostat::GaussianThermostat() : E(0),G(0), ScaleTempStep(25) {} GaussianThermostat::~GaussianThermostat() {} const char *ThermostatTraits::name = "Gaussian"; std::string ThermostatTraits::getName(){ return ThermostatTraits::name; } Thermostat *ThermostatTraits::make(class ConfigFileBuffer * const fb){ int ScaleTempStep; const int verbose = 0; ParseForParameter(verbose,fb,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read collision rate return new class GaussianThermostat(ScaleTempStep); } double GaussianThermostat::scaleAtoms(unsigned int step,double ActualTemp,ATOMSET(std::list) atoms){ return doScaleAtoms(step,ActualTemp,atoms.begin(),atoms.end()); } double GaussianThermostat::scaleAtoms(unsigned int step,double ActualTemp,ATOMSET(std::vector) atoms){ return doScaleAtoms(step,ActualTemp,atoms.begin(),atoms.end()); } double GaussianThermostat::scaleAtoms(unsigned int step,double ActualTemp,ATOMSET(std::set) atoms){ return doScaleAtoms(step,ActualTemp,atoms.begin(),atoms.end()); } template double GaussianThermostat::doScaleAtoms(unsigned int step,double ActualTemp,ForwardIterator begin, ForwardIterator end){ DoLog(2) && (Log() << Verbose(2) << "Applying Gaussian thermostat..." << endl); init(step,begin,end); double G_over_E = G/E; DoLog(1) && (Log() << Verbose(1) << "Gaussian Least Constraint constant is " << G_over_E << "." << endl); double ekin =0; for(ForwardIterator iter=begin;iter!=end;++iter){ Vector &U = (*iter)->Trajectory.U.at(step); if ((*iter)->FixedIon == 0) {// even FixedIon moves, only not by other's forces U += World::getInstance().getConfig()->Deltat * G_over_E * U; ekin += (*iter)->getType()->getMass() * U.NormSquared(); } } return ekin; } template void GaussianThermostat::init(unsigned int step,ForwardIterator begin, ForwardIterator end){ E=0; G=0; for(ForwardIterator iter=begin;iter!=end;++iter){ Vector &U = (*iter)->Trajectory.U.at(step); Vector &F = (*iter)->Trajectory.F.at(step); if ((*iter)->FixedIon == 0){ // even FixedIon moves, only not by other's forces G += U.ScalarProduct(F); E += U.NormSquared()*(*iter)->getType()->getMass(); } } } double GaussianThermostat::getE() const{ return E; } double GaussianThermostat::getG() const{ return G; } std::string GaussianThermostat::name(){ return ThermostatTraits::name; } std::string GaussianThermostat::writeParams(){ std::stringstream sstr; sstr << ScaleTempStep; return sstr.str(); }