| | 814 | } |
| | 815 | |
| | 816 | void XtalOpt::preoptimizeStructure(Structure *s) |
| | 817 | { |
| | 818 | if (s == NULL) { |
| | 819 | qWarning() << Q_FUNC_INFO << "NULL argument."; |
| | 820 | return; |
| | 821 | } |
| | 822 | |
| | 823 | MolecularXtal *mxtal = qobject_cast<MolecularXtal*>(s); |
| | 824 | if (mxtal == NULL) { |
| | 825 | qWarning() << "No preoptimization method implemented for" |
| | 826 | << s->metaObject()->className(); |
| | 827 | return; |
| | 828 | } |
| | 829 | |
| | 830 | QtConcurrent::run(this, &XtalOpt::preoptimizeMXtal, mxtal); |
| | 831 | } |
| | 832 | |
| | 833 | void XtalOpt::preoptimizeMXtal(MolecularXtal *mxtal) |
| | 834 | { |
| | 835 | QWriteLocker locker (mxtal->lock()); |
| | 836 | |
| | 837 | if (!mxtal->needsPreoptimization()) |
| | 838 | return; |
| | 839 | |
| | 840 | mxtal->emitPreoptimizationStarted(); |
| | 841 | |
| | 842 | mxtal->setNeedsPreoptimization(false); |
| | 843 | |
| | 844 | mxtal->wrapAtomsToCell(); |
| | 845 | |
| | 846 | // Rough preoptimization |
| | 847 | MolecularXtalOptimizer mxtalOpt (this, sOBMutex); |
| | 848 | mxtalOpt.setDebug(this->mpo_debug); |
| | 849 | mxtalOpt.setMXtal(mxtal); |
| | 850 | mxtalOpt.setEnergyConvergence(this->mpo_econv); |
| | 851 | mxtalOpt.setNumberOfGeometrySteps(this->mpo_maxSteps); |
| | 852 | mxtalOpt.setSuperCellUpdateInterval(this->mpo_sCUpdateInterval); |
| | 853 | mxtalOpt.setVDWCutoff(this->mpo_vdwCut); |
| | 854 | mxtalOpt.setElectrostaticCutoff(this->mpo_eleCut); |
| | 855 | mxtalOpt.setCutoffUpdateInterval(this->mpo_cutoffUpdateInterval); |
| | 856 | mxtalOpt.setup(); |
| | 857 | |
| | 858 | mxtal->startOptTimer(); |
| | 859 | locker.unlock(); |
| | 860 | mxtalOpt.run(); |
| | 861 | locker.relock(); |
| | 862 | mxtal->stopOptTimer(); |
| | 863 | |
| | 864 | mxtal->setStatus(MolecularXtal::Updating); |
| | 865 | |
| | 866 | if (mxtalOpt.isConverged() || mxtalOpt.reachedStepLimit()) { |
| | 867 | mxtalOpt.updateMXtalCoords(); |
| | 868 | mxtal->wrapAtomsToCell(); |
| | 869 | } |
| | 870 | else { |
| | 871 | qWarning() << "Preoptimization failed for" << mxtal->getIDString() |
| | 872 | << ". Continuing with full optimization."; |
| | 873 | } |
| | 874 | |
| | 875 | mxtalOpt.releaseMXtal(); // Under writelock on mxtal->lock(), ok to call |
| | 876 | |
| | 877 | mxtal->emitPreoptimizationFinished(); |