00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef STRUCTURE_H
00017 #define STRUCTURE_H
00018
00019 #include <avogadro/molecule.h>
00020 #include <avogadro/atom.h>
00021
00022 #include <openbabel/math/vector3.h>
00023 #include <openbabel/mol.h>
00024 #include <openbabel/generic.h>
00025
00026 #include <QtCore/QDebug>
00027 #include <QtCore/QDateTime>
00028 #include <QtCore/QHash>
00029 #include <QtCore/QTextStream>
00030
00031 #include <vector>
00032
00033
00034 #define EV_TO_KJ_PER_MOL 96.4853365
00035 #define KJ_PER_MOL_TO_EV 0.0103642692
00036
00037 namespace GlobalSearch {
00038
00049 class Structure : public Avogadro::Molecule
00050 {
00051 Q_OBJECT
00052
00053 public:
00054
00060 Structure(QObject *parent = 0);
00061
00065 Structure(const Structure &other);
00066
00070 Structure(const Avogadro::Molecule &other);
00071
00075 virtual ~Structure();
00076
00082 Structure& operator=(const Structure& other);
00083
00089 Structure& operator=(const Avogadro::Molecule& other);
00090
00096 virtual Structure& copyStructure(const Structure &other);
00097
00103 enum State {
00105 Optimized = 0,
00109 StepOptimized,
00113 WaitingForOptimization,
00116 InProcess,
00119 Empty,
00123 Updating,
00125 Error,
00128 Submitted,
00131 Killed,
00134 Removed,
00138 Duplicate,
00141 Restart,
00143 Preoptimizing
00144 };
00145
00149 bool hasBestOffspring() const {return m_hasBestOffspring;}
00150
00160 bool hasEnthalpy() const {return m_hasEnthalpy;};
00161
00178 double getEnergy() const {return energy(0) * KJ_PER_MOL_TO_EV;};
00179
00194 double getEnthalpy()const {if (!m_hasEnthalpy) return getEnergy(); return m_enthalpy;};
00195
00207 double getPV() const {return m_PV;};
00208
00213 uint getRank() const {return m_rank;};
00214
00220 uint getJobID() const {return m_jobID;};
00221
00232 uint getGeneration() const {return m_generation;};
00233
00246 uint getIDNumber() const {return m_id;};
00247
00259 int getIndex() const {return m_index;};
00260
00265 QString getDuplicateString() const {return m_dupString;};
00266
00270 QString getParents() const {return m_parents;};
00271
00276 QString getRempath() const {return m_rempath;};
00277
00282 State getStatus() const {return m_status;};
00283
00287 uint getCurrentOptStep() {return m_currentOptStep;};
00288
00290 virtual bool isPreoptimizing() const {return false;}
00291
00295 virtual int getPreOptProgress() const {return -1;}
00296
00298 virtual bool needsPreoptimization() const {return false;}
00299
00306 uint getFailCount() { return m_failCount;};
00307
00316 QDateTime getOptTimerStart() const {return m_optStart;};
00317
00326 QDateTime getOptTimerEnd() const {return m_optEnd;};
00327
00338 QString getIDString() const {
00339 return tr("%1x%2").arg(getGeneration()).arg(getIDNumber());};
00340
00345 virtual QString getResultsHeader() const {
00346 return QString("%1 %2 %3 %4 %5")
00347 .arg("Rank", 6)
00348 .arg("Gen", 6)
00349 .arg("ID", 6)
00350 .arg("Enthalpy", 10)
00351 .arg("Status", 11);};
00352
00357 virtual QString getResultsEntry() const;
00358
00362 QHash<int, int> * getOptimizerLookupTable()
00363 {
00364 return &m_optimizerLookup;
00365 }
00366
00370 void resetOptimizerLookupTable()
00371 {
00372 m_optimizerLookup.clear();
00373 for (int i = 0; i < m_atomList.size(); ++i)
00374 m_optimizerLookup.insert(i,i);
00375 }
00376
00388 virtual bool getNearestNeighborDistances(QList<double> * list) const;
00389
00402 virtual bool getShortestInteratomicDistance(double & shortest) const;
00403
00422 virtual bool getNearestNeighborDistance(const double x,
00423 const double y,
00424 const double z,
00425 double & shortest) const;
00426
00439 virtual bool getNearestNeighborDistance(const Avogadro::Atom *atom,
00440 double & shortest) const;
00441
00446 QList<Avogadro::Atom*> getNeighbors (const double x,
00447 const double y,
00448 const double z,
00449 const double cutoff,
00450 QList<double> *distances = 0) const;
00451
00458 QList<Avogadro::Atom*> getNeighbors (const Avogadro::Atom *atom,
00459 const double cutoff,
00460 QList<double> *distances = 0) const;
00461
00464 virtual void getDefaultHistogram(QList<double> *dist, QList<double> *freq) const;
00465
00468 virtual void getDefaultHistogram(QList<QVariant> *dist, QList<QVariant> *freq) const;
00469
00473 virtual bool isHistogramGenerationPending() const {
00474 return m_histogramGenerationPending;};
00475
00508 virtual bool generateIADHistogram(QList<double> * distance,
00509 QList<double> * frequency,
00510 double min = 0.0,
00511 double max = 10.0,
00512 double step = 0.01,
00513 Avogadro::Atom *atom = 0) const;
00514
00547 virtual bool generateIADHistogram(QList<QVariant> * distance,
00548 QList<QVariant> * frequency,
00549 double min = 0.0,
00550 double max = 10.0,
00551 double step = 0.01,
00552 Avogadro::Atom *atom = 0) const;
00553
00573 virtual bool addAtomRandomly(uint atomicNumber,
00574 double minIAD = 0.0,
00575 double maxIAD = 0.0,
00576 int maxAttempts = 1000,
00577 Avogadro::Atom **atom = 0);
00578
00583 QList<QString> getSymbols() const;
00584
00589 QList<uint> getNumberOfAtomsAlpha() const;
00590
00601 QString getOptElapsed() const;
00602
00613 virtual QHash<QString, QVariant> getFingerprint() const;
00614
00623 bool hasChangedSinceDupChecked() {return m_updatedSinceDupChecked;};
00624
00631 static void sortByEnthalpy(QList<Structure*> *structures);
00632
00641 static void rankByEnthalpy(const QList<Structure*> &structures);
00642
00651 static void sortAndRankByEnthalpy(QList<Structure*> *structures);
00652
00653 signals:
00654 void preoptimizationStarted();
00655 void preoptimizationFinished();
00656
00657 public slots:
00658
00663 virtual void setupConnections();
00664
00669 virtual void enableAutoHistogramGeneration(bool);
00670
00677 virtual void requestHistogramGeneration();
00678
00684 virtual void generateDefaultHistogram();
00685
00690 virtual void structureChanged();
00691
00712 static bool compareIADDistributions(const std::vector<double> &d,
00713 const std::vector<double> &f1,
00714 const std::vector<double> &f2,
00715 double decay,
00716 double smear,
00717 double *error);
00738 static bool compareIADDistributions(const QList<double> &d,
00739 const QList<double> &f1,
00740 const QList<double> &f2,
00741 double decay,
00742 double smear,
00743 double *error);
00744
00765 static bool compareIADDistributions(const QList<QVariant> &d,
00766 const QList<QVariant> &f1,
00767 const QList<QVariant> &f2,
00768 double decay,
00769 double smear,
00770 double *error);
00771
00783 virtual void writeSettings(const QString &filename) {
00784 writeStructureSettings(filename);};
00785
00797 virtual void readSettings(const QString &filename) {
00798 readStructureSettings(filename);};
00799
00811 virtual void updateAndSkipHistory(const QList<unsigned int> &atomicNums,
00812 const QList<Eigen::Vector3d> &coords,
00813 const double energy = 0,
00814 const double enthalpy = 0,
00815 const Eigen::Matrix3d &cell = Eigen::Matrix3d::Zero());
00816
00828 virtual void updateAndAddToHistory(const QList<unsigned int> &atomicNums,
00829 const QList<Eigen::Vector3d> &coords,
00830 const double energy = 0,
00831 const double enthalpy = 0,
00832 const Eigen::Matrix3d &cell = Eigen::Matrix3d::Zero());
00833
00837 virtual void deleteFromHistory(unsigned int index);
00838
00866 virtual void retrieveHistoryEntry(unsigned int index,
00867 QList<unsigned int> *atomicNums,
00868 QList<Eigen::Vector3d> *coords,
00869 double *energy,
00870 double *enthalpy,
00871 Eigen::Matrix3d *cell);
00872
00876 virtual unsigned int sizeOfHistory() {return m_histEnergies.size();};
00877
00881 void setHasBestOffspring(bool b = true)
00882 {
00883 m_hasBestOffspring = b;
00884 }
00885
00890 void setEnthalpy(double enthalpy) {m_hasEnthalpy = true; m_enthalpy = enthalpy;};
00891
00896 void setPV(double pv) {m_PV = pv;};
00897
00906 void resetEnthalpy() {m_enthalpy=0; m_PV=0; m_hasEnthalpy=false;};
00907
00912 void resetEnergy() {std::vector<double> E; E.push_back(0); setEnergies(E);};
00913
00918 void setOBEnergy(const QString &ff = QString("UFF"));
00919
00924 void setRank(uint rank) {m_rank = rank;};
00925
00930 void setJobID(uint id) {m_jobID = id;};
00931
00942 void setGeneration(uint gen) {m_generation = gen;};
00943
00956 void setIDNumber(uint id) {m_id = id;};
00957
00971 void setIndex(int index) {m_index = index;};
00972
00976 void setParents(const QString & p) {m_parents = p;};
00977
00982 void setRempath(const QString & p) {m_rempath = p;};
00983
00988 void setStatus(State status) {m_status = status;};
00989
00993 void setCurrentOptStep(uint i) {m_currentOptStep = i;};
00994
01001 void setFailCount(uint count) {m_failCount = count;};
01002
01010 void resetFailCount() {setFailCount(0);};
01011
01019 void addFailure() {setFailCount(getFailCount() + 1);};
01020
01025 void setDuplicateString(const QString & s) {m_dupString = s;};
01026
01035 void setChangedSinceDupChecked(bool b) {m_updatedSinceDupChecked = b;};
01036
01047 void startOptTimer() {
01048 m_optStart = QDateTime::currentDateTime(); m_optEnd = QDateTime();};
01049
01060 void stopOptTimer() {
01061 if (m_optEnd.isNull()) m_optEnd = QDateTime::currentDateTime();};
01062
01073 void setOptTimerStart(const QDateTime &d) {m_optStart = d;};
01074
01085 void setOptTimerEnd(const QDateTime &d) {m_optEnd = d;};
01086
01087
01089 virtual void setNeedsPreoptimization(bool b)
01090 {
01091 Q_UNUSED(b);
01092 qWarning() << "Preoptimization is not implemented for all structure "
01093 "types. Call to Structure::setNeedsPreoptimization "
01094 "ignored.";
01095 }
01096
01098 virtual void abortPreoptimization() const {};
01099
01101 void emitPreoptimizationStarted()
01102 {
01103 emit preoptimizationStarted();
01104 }
01105
01107 void emitPreoptimizationFinished()
01108 {
01109 emit preoptimizationFinished();
01110 }
01111
01121 virtual void load(QTextStream &in);
01122
01123 protected slots:
01130 void writeStructureSettings(const QString &filename);
01131
01138 void readStructureSettings(const QString &filename);
01139
01140 protected:
01141
01143 bool m_hasEnthalpy, m_updatedSinceDupChecked;
01144 bool m_histogramGenerationPending;
01145 bool m_hasBestOffspring;
01146 uint m_generation, m_id, m_rank, m_jobID, m_currentOptStep, m_failCount;
01147 QString m_parents, m_dupString, m_rempath;
01148 double m_enthalpy, m_PV;
01149 State m_status;
01150 QDateTime m_optStart, m_optEnd;
01151 int m_index;
01152 QList<QVariant> m_histogramDist, m_histogramFreq;
01153
01154
01155 QList<QList<unsigned int> > m_histAtomicNums;
01156 QList<double> m_histEnthalpies;
01157 QList<double> m_histEnergies;
01158 QList<QList<Eigen::Vector3d> > m_histCoords;
01159 QList<Eigen::Matrix3d> m_histCells;
01160
01161
01162 QHash<int, int> m_optimizerLookup;
01163
01164
01166 };
01167
01168 }
01169
01170 #endif