Show
Ignore:
Timestamp:
04/20/12 11:08:47 (13 months ago)
Author:
David C. Lonie <loniedavid@…>
Children:
036c828437ec98a9c38307ff8c60226a84bd6ccc
Parents:
bea169516b1c2a35f2b8a030fa4d731c09e954ec
git-author:
David C. Lonie <loniedavid@…> (10/27/11 13:43:46)
git-committer:
David C. Lonie <loniedavid@…> (04/20/12 11:08:47)
Message:

Add XtalOpt::generateNewMXtal().

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/xtalopt/xtalopt.cpp

    rbea16951 ra426e387  
    2626#include <xtalopt/ui/dialog.h> 
    2727#include <xtalopt/genetic.h> 
     28 
     29#include <xtalopt/mxtaloptgenetic.h> 
    2830 
    2931#include <globalsearch/optbase.h> 
     
    767769  void XtalOpt::generateNewStructure_() 
    768770  { 
    769     Xtal *newXtal = generateNewXtal(); 
    770     initializeAndAddXtal(newXtal, newXtal->getGeneration(), 
    771                          newXtal->getParents()); 
     771    if (this->isMolecularXtalSearch()) { 
     772      MolecularXtal *newMXtal = generateNewMXtal(); 
     773      initializeAndAddXtal(newMXtal, newMXtal->getGeneration(), 
     774                           newMXtal->getParents()); 
     775    } 
     776    else { 
     777      Xtal *newXtal = generateNewXtal(); 
     778      initializeAndAddXtal(newXtal, newXtal->getGeneration(), 
     779                           newXtal->getParents()); 
     780    } 
    772781  } 
    773782 
     
    975984    xtal->setParents(parents); 
    976985    return xtal; 
     986  } 
     987 
     988  MolecularXtal* XtalOpt::generateNewMXtal() 
     989  { 
     990    // Get all optimized structures 
     991    QList<Structure*> structures = m_queue->getAllOptimizedStructures(); 
     992 
     993    // Check to see if there are enough optimized structure to perform 
     994    // genetic operations 
     995    if (structures.size() < 3) { 
     996      MolecularXtal *mxtal = 0; 
     997      while (!checkXtal(mxtal)) { 
     998        if (mxtal) { 
     999          mxtal->deleteLater(); 
     1000          mxtal = NULL; 
     1001        } 
     1002        mxtal = generateRandomMXtal(1, 0); 
     1003      } 
     1004      mxtal->setParents(mxtal->getParents() + " (too few optimized structures " 
     1005                       "to generate offspring)"); 
     1006      return mxtal; 
     1007    } 
     1008 
     1009#warning Remove when operator GUI is setup // TODO 
     1010    mga_p_cross = 34; 
     1011    mga_cross_minimumContribution = .25; 
     1012    // - Reconf 
     1013    mga_p_reconf = 33; 
     1014    mga_reconf_minSubMolsToReplace = 1; 
     1015    mga_reconf_maxSubMolsToReplace = 3; 
     1016    mga_reconf_minStrain = 0.0; 
     1017    mga_reconf_maxStrain = 0.5; 
     1018    // - Swirl 
     1019    mga_p_swirl = 33; 
     1020    mga_swirl_minSubMolsToRotate = 1; 
     1021    mga_swirl_maxSubMolsToRotate = 3; 
     1022    mga_swirl_minRotationDegree = 30; 
     1023    mga_swirl_fracInPlane = 0.5; 
     1024    mga_swirl_minStrain = 0.0; 
     1025    mga_swirl_maxStrain = 0.5; 
     1026 
     1027    // Sort structure list 
     1028    Structure::sortByEnthalpy(&structures); 
     1029 
     1030    // Trim list 
     1031    // Remove all but (popSize + 1). The "+ 1" will be removed 
     1032    // during probability generation. 
     1033    while ( static_cast<uint>(structures.size()) > popSize + 1 ) { 
     1034      structures.removeLast(); 
     1035    } 
     1036 
     1037    // Make list of weighted probabilities based on enthalpy values 
     1038    QList<double> probs = getProbabilityList(structures); 
     1039 
     1040    // Cast Structures into MXtals 
     1041    QList<MolecularXtal*> mxtals; 
     1042#if QT_VERSION >= 0x040700 
     1043    mxtals.reserve(structures.size()); 
     1044#endif // QT_VERSION 
     1045    for (int i = 0; i < structures.size(); ++i) { 
     1046      mxtals.append(qobject_cast<MolecularXtal*>(structures.at(i))); 
     1047    } 
     1048 
     1049    // Initialize loop vars 
     1050    double r; 
     1051    unsigned int gen; 
     1052    MolecularXtal *mxtal = NULL; 
     1053 
     1054    // Perform operation until xtal is valid: 
     1055    while (!checkXtal(mxtal)) { 
     1056      // First delete any previous failed structure in xtal 
     1057      if (mxtal) { 
     1058        mxtal->deleteLater(); 
     1059        mxtal = NULL; 
     1060      } 
     1061 
     1062      // Decide operator: 
     1063      r = RANDDOUBLE(); 
     1064      MXtalOperator op; 
     1065      if (r < mga_p_cross/100.0) 
     1066        op = MXOP_Crossover; 
     1067      else if (r < (mga_p_cross + mga_p_reconf)/100.0) 
     1068        op = MXOP_Reconf; 
     1069      else // if (r < (mga_p_cross + mga_p_reconf + mga_p_swirl)/100.0 
     1070        op = MXOP_Swirl; 
     1071 
     1072      // Try 1000 times to get a good structure from the selected 
     1073      // operation. If not possible, send a warning to the log and 
     1074      // start anew. 
     1075      int attemptCount = 0; 
     1076      while (attemptCount < 1000 && !checkXtal(mxtal)) { 
     1077        attemptCount++; 
     1078        if (mxtal) { 
     1079          delete mxtal; 
     1080          mxtal = NULL; 
     1081        } 
     1082 
     1083        // Select two potential parents 
     1084        int ind1, ind2; 
     1085        MolecularXtal *parent1=0, *parent2=0; 
     1086        // Select structures 
     1087        double r1 = RANDDOUBLE(); 
     1088        double r2 = RANDDOUBLE(); 
     1089        for (ind1 = 0; ind1 < probs.size(); ind1++) 
     1090          if (r1 < probs.at(ind1)) break; 
     1091        for (ind2 = 0; ind2 < probs.size(); ind2++) 
     1092          if (r2 < probs.at(ind2)) break; 
     1093 
     1094        parent1 = mxtals.at(ind1); 
     1095        parent2 = mxtals.at(ind2); 
     1096 
     1097        // Operation specific set up: 
     1098        switch (op) { 
     1099        case MXOP_Crossover: 
     1100          mxtal = MXtalOptGenetic::crossover(parent1, parent2, this); 
     1101          break; 
     1102        case MXOP_Reconf: 
     1103          mxtal = MXtalOptGenetic::reconf(parent1, this); 
     1104          break; 
     1105        case MXOP_Swirl: 
     1106          mxtal = MXtalOptGenetic::swirl(parent1, this); 
     1107          break; 
     1108        default: 
     1109          qWarning() << "Unknown genetic operation, enum code:" << op; 
     1110          mxtal = NULL; 
     1111          continue; 
     1112        } 
     1113 
     1114        // Assign id 
     1115        int gen = mxtal->getGeneration(); 
     1116        int id = 0; 
     1117        for (QList<MolecularXtal*>::const_iterator it = mxtals.constBegin(), 
     1118             it_end = mxtals.constEnd(); it != it_end; ++it) { 
     1119          (*it)->lock()->lockForRead(); 
     1120          const int curGen = (*it)->getGeneration(); 
     1121          const int curId = (*it)->getIDNumber(); 
     1122          (*it)->lock()->unlock(); 
     1123          if (curGen == gen && 
     1124              curId  >= id) { 
     1125            id = curId + 1; 
     1126          } 
     1127        } 
     1128        mxtal->setIDNumber(id); 
     1129 
     1130      } 
     1131      if (attemptCount >= 1000) { 
     1132        QString opStr; 
     1133        switch (op) { 
     1134        case MXOP_Crossover: opStr = "crossover"; break; 
     1135        case MXOP_Reconf:    opStr = "reconf"; break; 
     1136        case MXOP_Swirl:     opStr = "swirl"; break; 
     1137        default:             opStr = "(unknown)"; break; 
     1138        } 
     1139        warning(tr("Unable to perform operation %1 after 1000 tries. " 
     1140                   "Reselecting operator...").arg(opStr)); 
     1141      } 
     1142    } 
     1143 
     1144    return mxtal; 
    9771145  } 
    9781146