00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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;
00056 ofstream mscFile;
00057 string runFilename = currentRun + ".run";
00058 string mscFilename = currentRun + ".mis";
00059
00060 m_stepStart = findLastStep(prevRun);
00061
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
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
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
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
00137 writeAverages(mscFile, cluster);
00138 mscFile.close();
00139
00140
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;
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;
00172 int size = cluster.size();
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();
00189
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;
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;
00236 ifstream inputFile;
00237 string filename = "";
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 }