Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

mdljsimulation.cpp

Go to the documentation of this file.
00001 /***************************************************************************************************
00002 *****           Copyright (C) 2005 John Schneiderman <JohnMS@member.fsf.org>                   *****
00003 *****                                                                                          *****
00004 *****           This program is free software; you can redistribute it and/or modify           *****
00005 *****           it under the terms of the GNU General Public License as published by           *****
00006 *****           the Free Software Foundation; either version 2 of the License, or              *****
00007 *****           (at your option) any later version.                                            *****
00008 *****                                                                                          *****
00009 *****           This program is distributed in the hope that it will be useful,                *****
00010 *****           but WITHOUT ANY WARRANTY; without even the implied warranty of                 *****
00011 *****           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                  *****
00012 *****           GNU General Public License for more details.                                   *****
00013 *****                                                                                          *****
00014 *****           You should have received a copy of the GNU General Public License              *****
00015 *****           along with this program; if not, write to the Free Software                    *****
00016 *****           Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA     *****
00017 ***************************************************************************************************/
00018 #include "mdljsimulation.h"
00019 #include "configurationdatabase.h"
00020 
00021 #include <fstream>
00022 using std::ifstream;
00023 using std::ofstream;
00024 using std::cout;
00025 using std::endl;
00026 
00027 #include <iomanip>
00028 using std::ios;
00029 using std::scientific;
00030 using std::showpos;
00031 using std::setw;
00032 
00033 MDLJ_Simulation::MDLJ_Simulation(const ConfigurationDatabase &conf):MD_Simulation(conf)
00034 {
00035     m_reducedPotentialEnergy = 0.0, m_reducedKineticEnergy = 0.0, m_reducedEnergyTotal = 0.0;
00036 }
00037 
00038 double MDLJ_Simulation::reducedPotentialEnergy() const
00039 {
00040     return m_reducedPotentialEnergy;
00041 }
00042 
00043 double MDLJ_Simulation::reducedKineticEnergy() const
00044 {
00045     return m_reducedKineticEnergy;
00046 }
00047 
00048 double MDLJ_Simulation::reducedTotalEnergy() const
00049 {
00050     return m_reducedEnergyTotal;
00051 }
00052 
00053 void MDLJ_Simulation::run(Cluster &cluster, string currentRun, string prevRun)
00054 {
00055     ofstream runFile;//This is the run file output.
00056     ofstream mscFile;//The name of the current miscellaneous file.
00057     string runFilename = currentRun + ".run";//This is the name of the run file.
00058     string mscFilename = currentRun + ".mis";//This is the miscellaneous file.
00059 
00060     m_stepStart = findLastStep(prevRun);//This is the starting time.
00061     //Write initial informaion to the miscellaneous file.
00062     mscFile.open(mscFilename.c_str());
00063     mscFile.precision(Cluster::PRECISION);
00064     mscFile.setf(ios::scientific);
00065     mscFile.setf(ios::showpos);
00066     mscFile << "    Number of steps: " << m_runSteps << endl;
00067     mscFile << "Change in time step: " << m_changeInStep << endl;
00068     mscFile << "     Print Interval: " << m_printInterval << endl;
00069     mscFile << "Number of particles: " << cluster.size() << endl;
00070 
00071     //Calculate Cluster information
00072     cluster.calculateCentreMass();
00073     cluster.calculatePotentialEnergy();
00074     cluster.calculateKineticEnergy();
00075     m_reducedEnergyTotal = (cluster.kineticEnergyTotal() + cluster.potentialEnergyTotal())/cluster.size();
00076     m_reducedPotentialEnergy = cluster.potentialEnergyTotal()/cluster.size();
00077     m_reducedKineticEnergy = cluster.kineticEnergyTotal()/cluster.size();
00078     m_temperature = m_reducedKineticEnergy * (2.0 * cluster.size())/(3.0 * cluster.size() - 6.0);
00079 
00080     //Write Cluster information to the miscellaneous file.
00081     mscFile << "Energies (over epsilon, per particle): \n";
00082     mscFile << "     Initial reduced potential energy: " << m_reducedPotentialEnergy << endl;
00083     mscFile << "       Initial reduced kinetic energy: " << m_reducedKineticEnergy << endl;
00084     mscFile << "         Initial reduced total energy: " << m_reducedEnergyTotal << endl;
00085     mscFile << "                  Initial temperature: " << m_temperature << endl;
00086 
00087     //Start run
00088     runFile.open(runFilename.c_str());
00089     runFile.precision(Cluster::PRECISION);
00090     runFile.setf(ios::scientific);
00091     runFile.setf(ios::showpos);
00092     m_timeStep = m_stepStart;
00093     calculateAccelerations(cluster);
00094     cout << "Time Step" << " " << setw(Cluster::WIDTH) << "Potential" << setw(Cluster::WIDTH) << "Kinetic" << setw(Cluster::WIDTH) << "Energy" << setw(Cluster::WIDTH) << "Temp" << endl;
00095     for (int intervalStep=0; intervalStep < m_runSteps; intervalStep++)
00096     {
00097         m_timeStep = intervalStep * m_changeInStep + m_stepStart;
00098         if ((intervalStep%m_printInterval)==0)
00099         {
00100             runFile << m_timeStep << " " << setw(Cluster::WIDTH) << m_reducedPotentialEnergy << setw(Cluster::WIDTH)<< m_reducedKineticEnergy <<  setw(Cluster::WIDTH) << m_reducedEnergyTotal << setw(Cluster::WIDTH)  << m_temperature << endl;
00101             cout<< m_timeStep << " " << setw(Cluster::WIDTH) << m_reducedPotentialEnergy << setw(Cluster::WIDTH)<< m_reducedKineticEnergy <<  setw(Cluster::WIDTH) << m_reducedEnergyTotal << setw(Cluster::WIDTH)  << m_temperature << endl;
00102         }
00103         calculatePositions(cluster);
00104         calculateAccelerations(cluster);
00105         calculateVelocities(cluster);
00106         m_reducedEnergyTotal = (cluster.kineticEnergyTotal() + cluster.potentialEnergyTotal())/cluster.size();
00107         m_reducedPotentialEnergy = cluster.potentialEnergyTotal()/cluster.size();
00108         m_reducedKineticEnergy = cluster.kineticEnergyTotal()/cluster.size();
00109         m_temperature = m_reducedKineticEnergy * (2.0 * cluster.size())/(3.0 * cluster.size() - 6.0);
00110         m_accumPotentialTotal += m_reducedPotentialEnergy;
00111         m_accumKineticTotal += m_reducedKineticEnergy;
00112         m_accumEnergyTotal += m_reducedEnergyTotal;
00113         m_accumPotentialSQ += (m_reducedPotentialEnergy*m_reducedPotentialEnergy);
00114         m_accumKineticSQ += (m_reducedKineticEnergy*m_reducedKineticEnergy);
00115         m_accumEnergySQ += (m_reducedEnergyTotal*m_reducedEnergyTotal);
00116         if ((intervalStep % m_radialDensityHistogram.pullingInterval()) == 0)
00117             m_radialDensityHistogram.acquire(cluster);
00118         if ((intervalStep % m_radialDistributionFunction.pullingInterval()) == 0)
00119             m_radialDistributionFunction.acquire(cluster);
00120         if ((intervalStep % m_potentialEnergyHistogram.pullingInterval()) == 0)
00121         {
00122             cluster.calculatePotentialEnergy();
00123             m_potentialEnergyHistogram.acquire(cluster);
00124         }
00125         if ((intervalStep % m_kineticEnergyHistogram.pullingInterval()) == 0)
00126         {
00127             cluster.calculateKineticEnergy();
00128             m_kineticEnergyHistogram.acquire(cluster);
00129         }
00130     }
00131     m_timeStep = m_runSteps * m_changeInStep + m_stepStart;
00132     runFile << m_timeStep << " " << setw(Cluster::WIDTH) << m_reducedPotentialEnergy << setw(Cluster::WIDTH) << m_reducedKineticEnergy <<  setw(Cluster::WIDTH) << m_reducedEnergyTotal << setw(Cluster::WIDTH)  << m_temperature << endl;
00133     cout << m_timeStep << " " << setw(Cluster::WIDTH) << m_reducedPotentialEnergy << setw(Cluster::WIDTH) << m_reducedKineticEnergy <<  setw(Cluster::WIDTH) << m_reducedEnergyTotal << setw(Cluster::WIDTH)  << m_temperature << endl;
00134     runFile.close();
00135 
00136     //Write out average energies
00137     writeAverages(mscFile, cluster);
00138     mscFile.close();
00139 
00140     //Write out histograms
00141     m_radialDensityHistogram.write(cluster.size(), currentRun);
00142     m_radialDistributionFunction.write(cluster.size(), currentRun);
00143     m_kineticEnergyHistogram.write(cluster.size(), currentRun);
00144     m_potentialEnergyHistogram.write(cluster.size(), currentRun);
00145 }
00146 
00147 void MDLJ_Simulation::clear()
00148 {
00149     MD_Simulation::clear();
00150     m_reducedPotentialEnergy = 0.0, m_reducedKineticEnergy = 0.0, m_reducedEnergyTotal = 0.0;
00151 }
00152 
00153 void MDLJ_Simulation::calculatePositions(Cluster &cluster) const
00154 {
00155     double changeInTimeSquared = 0.0;//The change in the time squared.
00156 
00157     changeInTimeSquared = m_changeInStep*m_changeInStep;
00158     for(int i = 0; i < cluster.size(); i++)
00159     {
00160         cluster[i].properties.position.x += (m_changeInStep * cluster[i].properties.velocity.x + 0.5 * changeInTimeSquared * cluster[i].properties.acceleration.x);
00161         cluster[i].properties.position.y += (m_changeInStep * cluster[i].properties.velocity.y + 0.5 * changeInTimeSquared * cluster[i].properties.acceleration.y);
00162         cluster[i].properties.position.z += (m_changeInStep * cluster[i].properties.velocity.z + 0.5 * changeInTimeSquared * cluster[i].properties.acceleration.z);
00163         cluster[i].properties.velocity.x += (0.5 * m_changeInStep * cluster[i].properties.acceleration.x);
00164         cluster[i].properties.velocity.y += (0.5 * m_changeInStep * cluster[i].properties.acceleration.y);
00165         cluster[i].properties.velocity.z += (0.5 * m_changeInStep * cluster[i].properties.acceleration.z);
00166     }
00167 }
00168 
00169 void MDLJ_Simulation::calculateVelocities(Cluster &cluster) const
00170 {
00171     double sumPotentialSQ = 0.0;//The sum of the potential energy squared.
00172     int size = cluster.size();//The size of the Cluster.
00173 
00174     cluster.setKineticEnergyTotal(0.5 * sumPotentialSQ);
00175     for (int i = 0; i < size; i++)
00176     {
00177         cluster[i].properties.velocity.x += (0.5 * m_changeInStep * cluster[i].properties.acceleration.x);
00178         cluster[i].properties.velocity.y += (0.5 * m_changeInStep * cluster[i].properties.acceleration.y);
00179         cluster[i].properties.velocity.z += (0.5 * m_changeInStep * cluster[i].properties.acceleration.z);
00180         sumPotentialSQ += (cluster[i].properties.velocity.x * cluster[i].properties.velocity.x +  cluster[i].properties.velocity.y * cluster[i].properties.velocity.y + cluster[i].properties.velocity.z * cluster[i].properties.velocity.z);
00181     }
00182     cluster.setKineticEnergyTotal(0.5 * sumPotentialSQ);
00183 }
00184 
00185 void MDLJ_Simulation::calculateAccelerations(Cluster &cluster) const
00186 {
00187     Coordinate examAtomPos, examAtomAcc, neighbourAtomAcc, adjustedAccAtom;
00188     int size = cluster.size();//The size of the Cluster.
00189     //Lennard-Jones modelling numbers.
00190     double sr2 = 0.0, sr6 = 0.0, sr12 = 0.0, fij = 0.0;
00191     double rijsq = 0.0, atomPotentialEnergy = 0.0, wij = 0.0;
00192 
00193     cluster.setPotentialEnergyTotal(0.0);
00194     for(int i = 0; i < size; i++)
00195         cluster[i].properties.acceleration=0.0;
00196     for(int i=0; i < size-1; i++)
00197     {
00198         examAtomPos = cluster[i].properties.position;
00199         examAtomAcc = cluster[i].properties.acceleration;
00200         for(int j = i+1; j < size; j++)
00201         {
00202             neighbourAtomAcc = examAtomPos - cluster[j].properties.position;
00203             rijsq = (neighbourAtomAcc.x * neighbourAtomAcc.x) + (neighbourAtomAcc.y * neighbourAtomAcc.y) + (neighbourAtomAcc.z * neighbourAtomAcc.z);
00204             sr2 = 1.0/rijsq;
00205             sr6 = sr2*sr2*sr2;
00206             sr12 = sr6*sr6;
00207             atomPotentialEnergy = sr12-sr6;
00208             cluster.setPotentialEnergyTotal(cluster.potentialEnergyTotal() + atomPotentialEnergy);
00209             wij = atomPotentialEnergy + sr12;
00210             fij = wij * sr2;
00211             adjustedAccAtom = Coordinate(fij) * neighbourAtomAcc;
00212             examAtomAcc += adjustedAccAtom;
00213             cluster[j].properties.acceleration -= adjustedAccAtom;
00214         }
00215         cluster[i].properties.acceleration = examAtomAcc;
00216     }
00217     cluster.setPotentialEnergyTotal(cluster.potentialEnergyTotal()*4.0);
00218     for (int i = 0; i < size; i++)
00219         cluster[i].properties.acceleration *= 24.0;
00220 }
00221 
00222 void MDLJ_Simulation::adjustPosCenMass(Cluster& cluster) const
00223 {
00224     Coordinate centre = 0.0;//The positions of the centre of mass.
00225 
00226     for (int i = 0; i < cluster.size(); i++)
00227         centre += cluster[i].properties.position;
00228     centre /= cluster.size();
00229     for (int i = 0; i < cluster.size(); i++)
00230         cluster[i].properties.position -= (centre + cluster.positionCentreMass());
00231 }
00232 
00233 double MDLJ_Simulation::findLastStep(string prevRun) const
00234 {
00235     double timeTemp=0.0, temp=0.0, temp0=0.0, temp1=0.0, temp2=0.0;//Temperary values of time.
00236     ifstream inputFile;//The input run file.
00237     string filename = "";//The name of the last run file.
00238 
00239     filename = prevRun + ".run";
00240     inputFile.open(filename.c_str());
00241     while(!inputFile.fail())
00242         inputFile >> timeTemp >> temp >> temp0 >> temp1 >> temp2;
00243     inputFile.close();
00244     return timeTemp;
00245 }

Generated on Tue Mar 28 23:28:03 2006 for ClusterSim by  doxygen 1.4.4