00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "cluster.h"
00019
00020 #include <iomanip>
00021 using std::ios;
00022 using std::scientific;
00023 using std::showpos;
00024
00025
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
00085 double sqrAtomDistance=0.0, sr2=0.0, sr6=0.0, sr12=0.0;
00086
00087 double atomPotentialEnergy=0.0;
00088
00089 double potentialEnergyPart=0.0;
00090
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());
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;
00147 string positionFilename, velocityFilename;
00148 Atom newAtom;
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;
00172 string filename;
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 }