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

cluster.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 "cluster.h"
00019 
00020 #include <iomanip>
00021 using std::ios;
00022 using std::scientific;
00023 using std::showpos;
00024 
00025 //Output file includes
00026 using std::ifstream;
00027 using std::ofstream;
00028 using std::endl;
00029 
00030 Cluster::Cluster():m_atoms(), m_positionCentreMass(), m_velocityCentreMass()
00031 {
00032     m_potentialEnergyTotal = 0.0, m_kineticEnergyTotal = 0.0;
00033 }
00034 
00035 Cluster::Cluster(const Cluster &cluster)
00036 {
00037     *this = cluster;
00038 }
00039 
00040 double Cluster::potentialEnergyTotal() const
00041 {
00042     return m_potentialEnergyTotal;
00043 }
00044 
00045 double Cluster::kineticEnergyTotal() const
00046 {
00047     return m_kineticEnergyTotal;
00048 }
00049 
00050 Coordinate Cluster::positionCentreMass() const
00051 {
00052     return m_positionCentreMass;
00053 }
00054 
00055 Coordinate Cluster::velocityCentreMass() const
00056 {
00057     return m_velocityCentreMass;
00058 }
00059 
00060 void Cluster::setPotentialEnergyTotal(double potentialEnergyTotal)
00061 {
00062     m_potentialEnergyTotal = potentialEnergyTotal;
00063 }
00064 
00065 void Cluster::setKineticEnergyTotal(double kineticEnergyTotal)
00066 {
00067     m_kineticEnergyTotal = kineticEnergyTotal;
00068 }
00069 
00070 void Cluster::setPositionCentreMass(Coordinate positionCentreMass)
00071 {
00072     m_positionCentreMass = positionCentreMass;
00073 }
00074 
00075 void Cluster::setVelocityCentreMass(Coordinate velocityCentreMass)
00076 {
00077     m_velocityCentreMass = velocityCentreMass;
00078 }
00079 
00080 void Cluster::calculatePotentialEnergy()
00081 {
00082     Coordinate examAtomPos;
00083     Coordinate examAtomsDistance;
00084     //Parts of calculating the Lennard-Jones energies.
00085     double sqrAtomDistance=0.0, sr2=0.0, sr6=0.0, sr12=0.0;
00086     //The potential energy between two m_atoms.
00087     double atomPotentialEnergy=0.0;
00088     //The partial sums of the potential energy.
00089     double potentialEnergyPart=0.0;
00090     //The average of the potential energy.
00091     double potentialEnergyAverage=0.0;
00092 
00093     for (int i = 0; i < int(m_atoms.size()); i++)
00094         m_atoms[i].properties.potentialEnergy=0.0;
00095     for (int i = 0; i < int(m_atoms.size()); i++)
00096     {
00097         potentialEnergyPart = 0.0;
00098         examAtomPos = m_atoms[i].properties.position;
00099         for (int j = 0; j < int(m_atoms.size()); j++)
00100             if (j != i)
00101             {
00102                 examAtomsDistance = examAtomPos-m_atoms[j].properties.position;
00103                 sqrAtomDistance = (examAtomsDistance.x * examAtomsDistance.x) + (examAtomsDistance.y * examAtomsDistance.y) + (examAtomsDistance.z * examAtomsDistance.z);
00104                 sr2 = 1.0/sqrAtomDistance;
00105                 sr6 = sr2*sr2*sr2;
00106                 sr12 = sr6*sr6;
00107                 atomPotentialEnergy = sr12-sr6;
00108                 potentialEnergyPart += (4.0*atomPotentialEnergy);
00109             }
00110         m_atoms[i].properties.potentialEnergy = potentialEnergyPart/2;
00111         potentialEnergyAverage += m_atoms[i].properties.potentialEnergy;
00112     }
00113     m_potentialEnergyTotal = potentialEnergyAverage;
00114 }
00115 
00116 void Cluster::calculateKineticEnergy()
00117 {
00118     double kineticEnergyAverage=0.0, kineticEnergyPart=0.0;
00119 
00120     for (int i = 0; i < int(m_atoms.size()); i++)
00121     {
00122         kineticEnergyPart = 0.5*((m_atoms[i].properties.velocity.x * m_atoms[i].properties.velocity.x) + (m_atoms[i].properties.velocity.y * m_atoms[i].properties.velocity.y) + (m_atoms[i].properties.velocity.z * m_atoms[i].properties.velocity.z));
00123         m_atoms[i].properties.kineticEnergy = kineticEnergyPart;
00124         kineticEnergyAverage += kineticEnergyPart;
00125     }
00126     m_kineticEnergyTotal = kineticEnergyAverage;
00127 }
00128 
00129 void Cluster::calculateCentreMass()
00130 {
00131     int size = int(m_atoms.size());//The size of the Cluster.
00132 
00133     m_positionCentreMass=0.0;
00134     m_velocityCentreMass=0.0;
00135     for (int i = 0; i < size; i++)
00136     {
00137         m_positionCentreMass += m_atoms[i].properties.position;
00138         m_velocityCentreMass += m_atoms[i].properties.velocity;
00139     }
00140     m_positionCentreMass /= size;
00141     m_velocityCentreMass /= size;
00142 }
00143 
00144 void Cluster::read(string baseName)
00145 {
00146     ifstream positionFile, velocityFile;//The position and velocity files.
00147     string positionFilename, velocityFilename;//The names of the position and velocity files.
00148     Atom newAtom;//The values of the atom to placed into the Cluster.
00149 
00150     positionFilename = baseName + ".pos";
00151     velocityFilename = baseName + ".vel";
00152     positionFile.open(positionFilename.c_str());
00153     velocityFile.open(velocityFilename.c_str());
00154     if (positionFile.fail() || velocityFile.fail())
00155         throw("position or velocity file not found!");
00156     m_atoms.clear();
00157     positionFile >> newAtom.properties.position;
00158     velocityFile >> newAtom.properties.velocity;
00159     while((!positionFile.fail()) && (!velocityFile.fail()))
00160     {
00161         m_atoms.push_back(newAtom);
00162         positionFile >> newAtom.properties.position;
00163         velocityFile >> newAtom.properties.velocity;
00164     }
00165     positionFile.close();
00166     velocityFile.close();
00167 }
00168 
00169 void Cluster::write(string baseName)
00170 {
00171     ofstream outputFile;//This is the file to write to.
00172     string filename;//This is the name of the position and velocity files.
00173 
00174     filename = baseName + ".pos";
00175     outputFile.open(filename.c_str());
00176     outputFile.precision(PRECISION);
00177     outputFile.setf(ios::scientific);
00178     outputFile.setf(ios::showpos);
00179     for (int i = 0; i < int(m_atoms.size()); i++)
00180         outputFile << m_atoms[i].properties.position << endl;
00181     if (outputFile.fail())
00182         throw("Could not write position file.");
00183     outputFile.close();
00184     outputFile.clear();
00185     filename = baseName + ".vel";
00186     outputFile.open(filename.c_str());
00187     outputFile.precision(PRECISION);
00188     outputFile.setf(ios::scientific);
00189     outputFile.setf(ios::showpos);
00190     for (int i = 0; i < int(m_atoms.size()); i++)
00191         outputFile << m_atoms[i].properties.velocity << endl;
00192     if (outputFile.fail())
00193         throw("Could not write velocity file.");
00194     outputFile.close();
00195 }
00196 
00197 void Cluster::clear()
00198 {
00199     m_atoms.clear();
00200     m_positionCentreMass = 0.0, m_velocityCentreMass= 0.0, m_potentialEnergyTotal = 0.0, m_kineticEnergyTotal = 0.0;
00201 }
00202 
00203 int Cluster::size() const
00204 {
00205     return int(m_atoms.size());
00206 }
00207 
00208 Cluster& Cluster::operator=(const Cluster &rhs)
00209 {
00210     if (this != &rhs)
00211     {
00212         this->clear();
00213         for (int i = 0; i < rhs.size(); i++)
00214             m_atoms.push_back(rhs[i]);
00215         m_positionCentreMass = rhs.positionCentreMass();
00216         m_velocityCentreMass = rhs.velocityCentreMass();
00217         m_potentialEnergyTotal = rhs.potentialEnergyTotal();
00218         m_kineticEnergyTotal = rhs.kineticEnergyTotal();
00219     }
00220     return *this;
00221 }
00222 
00223 Atom& Cluster::operator[](int i)
00224 {
00225     return m_atoms[i];
00226 }
00227 
00228 const Atom& Cluster::operator[](int i) const
00229 {
00230     return m_atoms[i];
00231 }
00232 
00233 void Cluster::addAtom(const Atom &atom)
00234 {
00235     m_atoms.push_back(atom);
00236 }
00237 
00238 ostream& operator<<(ostream &outStream, const Cluster &cluster)
00239 {
00240     outStream.precision(Cluster::PRECISION);
00241     outStream.setf(ios::scientific);
00242     outStream.setf(ios::showpos);
00243     outStream << "Positions:" << endl;
00244     for (int i = 0; i < cluster.size(); i++)
00245         outStream << cluster[i].properties.position << endl;
00246     outStream << "Velocities:" << endl;
00247     for (int i = 0; i < cluster.size(); i++)
00248         outStream << cluster[i].properties.velocity << endl;
00249     outStream << "Acceleration:" << endl;
00250     for (int i = 0; i < cluster.size(); i++)
00251         outStream << cluster[i].properties.acceleration << endl;
00252     outStream << "Potential Energies:" << endl;
00253     for (int i = 0; i < cluster.size(); i++)
00254         outStream << cluster[i].properties.potentialEnergy << endl;
00255     outStream << "Kinetic Energies:" << endl;
00256     for (int i = 0; i < cluster.size(); i++)
00257         outStream << cluster[i].properties.kineticEnergy;
00258     return outStream;
00259 }
00260 
00261 bool operator==(const Cluster &lhs, const Cluster &rhs)
00262 {
00263     if (lhs.size() != rhs.size())
00264         return false;
00265     if (lhs.m_potentialEnergyTotal != rhs.m_potentialEnergyTotal)
00266         return false;
00267     if (lhs.m_kineticEnergyTotal != rhs.m_kineticEnergyTotal)
00268         return false;
00269     if (lhs.m_positionCentreMass != rhs.m_positionCentreMass)
00270         return false;
00271     if (lhs.m_velocityCentreMass != rhs.m_velocityCentreMass)
00272         return false;
00273     for (int i = 0; i < lhs.size(); i++)
00274     {
00275         if (lhs[i].properties.position != rhs[i].properties.position)
00276             return false;
00277         else if (lhs[i].properties.velocity != rhs[i].properties.velocity)
00278             return false;
00279         else if (lhs[i].properties.acceleration != rhs[i].properties.acceleration)
00280             return false;
00281         else if (lhs[i].properties.kineticEnergy != rhs[i].properties.kineticEnergy)
00282             return false;
00283         else if (lhs[i].properties.potentialEnergy != rhs[i].properties.potentialEnergy)
00284             return false;
00285     }
00286     return true;
00287 }

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