diff --git a/gocia/ga/crossover.py b/gocia/ga/crossover.py index 87ac184..15341ac 100644 --- a/gocia/ga/crossover.py +++ b/gocia/ga/crossover.py @@ -100,7 +100,7 @@ def splice_2d_GC(surf1, badPos, goodPos, center, direction): tmpSurf.set_allPos(childPos) return tmpSurf -def crossover_snsSurf_2d_GC(surf1, surf2, tolerance=0.5): +def crossover_snsSurf_2d_GC(surf1, surf2, tolerance=0.5, keepCluster=''): matPos, patPos = surf1.get_fixBufPos(), surf2.get_fixBufPos() # positions of fixed and buffer atoms in substrate matAds, patAds = surf1.get_adsAtoms(), surf2.get_adsAtoms() # adsorbate atoms goodPos, badPos = [], [] @@ -164,6 +164,8 @@ def crossover_snsSurf_2d_GC(surf1, surf2, tolerance=0.5): newSurf.set_adsAtoms(Atoms(newAdsElem, newAdsPos)) newSurf.wrap() isBADSTRUCTURE = newSurf.has_badContact(tolerance=tolerance) + if newSurf.get_chemical_symbols().count(keepCluster) != surf1.get_chemical_symbols().count(keepCluster) or newSurf.get_chemical_symbols().count(keepCluster) != surf2.get_chemical_symbols().count(keepCluster): + isBADSTRUCTURE = True if n_trial > 1000: isBADSTRUCTURE = False newSurf = None @@ -172,7 +174,7 @@ def crossover_snsSurf_2d_GC(surf1, surf2, tolerance=0.5): (n_trial, tolerance)) return newSurf -def crossover_snsSurf_2d_GC_poly(surf1, surf2, tolerance=0.5): +def crossover_snsSurf_2d_GC_poly(surf1, surf2, tolerance=0.5, keepCluster=''): # Get relevant positions from mother and father surfaces matFixBufPos, patFixBufPos = surf1.get_fixBufPos(), surf2.get_fixBufPos() # positions of fixed and buffer atoms, or equivalently, substrate atoms with get_subPos() matBridPos, patBridPos = surf1.get_bridPos(), surf2.get_bridPos() # positions of bridle atoms @@ -280,6 +282,8 @@ def crossover_snsSurf_2d_GC_poly(surf1, surf2, tolerance=0.5): # Evaluate quality of kid structure isBADSTRUCTURE = childSurf.has_badContact(tolerance=tolerance) + if childSurf.get_chemical_symbols().count(keepCluster) != surf1.get_chemical_symbols().count(keepCluster) or childSurf.get_chemical_symbols().count(keepCluster) != surf2.get_chemical_symbols().count(keepCluster): + isBADSTRUCTURE = True if n_trial > 1000: isBADSTRUCTURE = False childSurf = None @@ -287,3 +291,4 @@ def crossover_snsSurf_2d_GC_poly(surf1, surf2, tolerance=0.5): print('\nOffspring is created at attempt #%i\t|Tolerance = %.3f'%\ (n_trial, tolerance)) return childSurf + \ No newline at end of file diff --git a/gocia/ga/popGrandCanon.py b/gocia/ga/popGrandCanon.py index 5805754..d473662 100644 --- a/gocia/ga/popGrandCanon.py +++ b/gocia/ga/popGrandCanon.py @@ -220,7 +220,7 @@ def is_uniqueInAll_geom(self, atoms): break return isUnique - def gen_offspring(self, mutRate=0.3, rattleOn=True, growOn=True, leachOn=True, permuteOn=True, transOn=True, transVec=[[-2, 2], [-2, 2]]): + def gen_offspring(self, mutRate=0.3, rattleOn=True, growOn=True, leachOn=True, permuteOn=True, transOn=True, transVec=[[-2, 2], [-2, 2]], keepCluster=''): kid, parent = None, None mater, pater = 0, 0 while kid is None: @@ -229,7 +229,7 @@ def gen_offspring(self, mutRate=0.3, rattleOn=True, growOn=True, leachOn=True, p a2 = self.gadb.get(id=pater).toatoms() surf1 = Interface(a1, self.substrate, zLim=self.zLim) surf2 = Interface(a2, self.substrate, zLim=self.zLim) - kid = crossover_snsSurf_2d_GC(surf1, surf2, tolerance=0.75) + kid = crossover_snsSurf_2d_GC(surf1, surf2, tolerance=0.75, keepCluster=keepCluster) parent = surf1.copy() print('PARENTS: %i and %i' % (mater, pater)) myMutate = '' @@ -268,7 +268,7 @@ def gen_offspring(self, mutRate=0.3, rattleOn=True, growOn=True, leachOn=True, p self.gadb.update(pater, mated=self.gadb.get(id=pater).mated+1) return kid - def gen_offspring_box(self, mutRate=0.3, xyzLims=[], bondRejList=None, constrainTop=False, rattleOn=True, growOn=True, leachOn=True, permuteOn=True, transOn=True, transVec=[[-2, 2], [-2, 2]]): + def gen_offspring_box(self, mutRate=0.3, xyzLims=[], bondRejList=None, constrainTop=False, rattleOn=True, growOn=True, leachOn=True, permuteOn=True, transOn=True, transVec=[[-2, 2], [-2, 2]], keepCluster=''): kid, parent = None, None mater, pater = 0, 0 while kid is None: @@ -277,7 +277,7 @@ def gen_offspring_box(self, mutRate=0.3, xyzLims=[], bondRejList=None, constrain a2 = self.gadb.get(id=pater).toatoms() surf1 = Interface(a1, self.substrate, zLim=self.zLim) surf2 = Interface(a2, self.substrate, zLim=self.zLim) - kid = crossover_snsSurf_2d_GC(surf1, surf2, tolerance=0.75) + kid = crossover_snsSurf_2d_GC(surf1, surf2, tolerance=0.75,keepCluster=keepCluster) parent = surf1.copy() print('PARENTS: %i and %i' % (mater, pater)) mutType = '' diff --git a/gocia/ga/popGrandCanonPoly.py b/gocia/ga/popGrandCanonPoly.py index c351620..2d9b9de 100644 --- a/gocia/ga/popGrandCanonPoly.py +++ b/gocia/ga/popGrandCanonPoly.py @@ -60,6 +60,7 @@ def __init__( self.simParam1 = simParam1 self.simParam2 = simParam2 + def __len__(self): return len(self.gadb) @@ -239,7 +240,7 @@ def convertFragListToInfo(self, fragList): info['adsorbate_fragments'] = [] return info - def gen_offspring(self, mutRate=0.3, rattleOn=True, growOn=True, leachOn=True, moveOn=True, permuteOn=True, transOn=True, transVec=[[-2, 2], [-2, 2]]): + def gen_offspring(self, mutRate=0.3, rattleOn=True, growOn=True, leachOn=True, moveOn=True, permuteOn=True, transOn=True, transVec=[[-2, 2], [-2, 2]], keepCluster=''): kid, parent = None, None mater, pater = 0, 0 while kid is None: @@ -252,7 +253,7 @@ def gen_offspring(self, mutRate=0.3, rattleOn=True, growOn=True, leachOn=True, m patInfo = self.convertFragStrToInfo(patFragStr) surf1 = Interface(matAtms, self.substrate, zLim=self.zLim, info=matInfo) surf2 = Interface(patAtms, self.substrate, zLim=self.zLim, info=patInfo) - kid = crossover_snsSurf_2d_GC_poly(surf1, surf2, tolerance=0.75) + kid = crossover_snsSurf_2d_GC_poly(surf1, surf2, tolerance=0.75, keepCore=keepCluster) parent = surf1.copy() print('PARENTS: %i and %i' % (mater, pater)) myMutate = '' @@ -294,7 +295,7 @@ def gen_offspring(self, mutRate=0.3, rattleOn=True, growOn=True, leachOn=True, m open('fragments', 'w').write('%s' % kid.get_fragList() ) return kid - def gen_offspring_box(self, mutRate=0.3, xyzLims=[], bondRejList=None, constrainTop=False, rattleOn=True, growOn=True, leachOn=True, moveOn=True, permuteOn=True, transOn=True, transVec=[[-2, 2], [-2, 2]]): + def gen_offspring_box(self, mutRate=0.3, xyzLims=[], bondRejList=None, constrainTop=False, rattleOn=True, growOn=True, leachOn=True, moveOn=True, permuteOn=True, transOn=True, transVec=[[-2, 2], [-2, 2]], keepCluster=''): kid, parent = None, None mater, pater = 0, 0 while kid is None: @@ -307,7 +308,7 @@ def gen_offspring_box(self, mutRate=0.3, xyzLims=[], bondRejList=None, constrain patInfo = self.convertFragStrToInfo(patFragStr) surf1 = Interface(matAtms, self.substrate, zLim=self.zLim, info=matInfo) surf2 = Interface(patAtms, self.substrate, zLim=self.zLim, info=patInfo) - kid = crossover_snsSurf_2d_GC_poly(surf1, surf2, tolerance=0.5) + kid = crossover_snsSurf_2d_GC_poly(surf1, surf2, tolerance=0.5, keepCluster=keepCluster) parent = random.choice([surf1, surf2]).copy() print('PARENTS: %i and %i' % (mater, pater)) print(matInfo['adsorbate_fragments'], [matAtms[l].get_chemical_formula() for l in matInfo['adsorbate_fragments']]) diff --git a/gocia/geom/build.py b/gocia/geom/build.py index d1090f7..a24d2b4 100644 --- a/gocia/geom/build.py +++ b/gocia/geom/build.py @@ -115,8 +115,16 @@ def grow_frag( frags_to_add.append(Atoms('CO',[(0, 0, 0),(0, 0, 1.15034)])) elif fragName == 'H': frags_to_add.append(Atoms('H',[(0,0,0)])) + elif fragName == 'O': + frags_to_add.append(Atoms('O',[(0,0,0)])) + elif fragName =='OH': + frags_to_add.append(Atoms('OH',[(0,0,0),(0,0,0.97)])) elif fragName =='H2O': frags_to_add.append(Atoms('OH2',[(0,0,0),(0.758602,0,0.504284),(-0.758602,0,0.504284)])) + #elif fragName =='C3H8': + #frags_to_add.append(Atoms('C3H8',[(0.000000,0.000000,0.000000),(0.000000,1.266857,0.847902),(0.000000,2.533714,0.000000),(-0.876898,1.266857,1.504899),(0.876898,1.266857,1.504899),(0.000000,3.433007,0.622252),(0.000000,-0.899293,0.622252),(0.883619,2.571091,-0.644219),(-0.883619,2.571091,-0.644219),(-0.883619,-0.037377,-0.644219),(0.883619,-0.037377,-0.644219)])) + elif fragName =='C3H8': + frags_to_add.append(Atoms('C3H8',[(0.00000000,0.00000000,0.00000000),(0.00000000,1.26685700,0.84790200),(0.00000000,-1.26685700,0.84790200),(-0.87689800,0.00000000,-0.65699700),(0.87689800,0.00000000,-0.65699700),(0.00000000,2.16615000,0.22565000),(0.00000000,-2.16615000,0.22565000),(0.88361900,1.30423400,1.49212100),(-0.88361900,1.30423400,1.49212100),(-0.88361900,-1.30423400,1.49212100),(0.88361900,-1.30423400,1.49212100)])) else: print('Unknown fragment: must add option to grow {} in grow_adFrag() in build.py'.format(fragName)) @@ -321,8 +329,16 @@ def boxSample_frag( frags_to_add.append(Atoms('CO',[(0, 0, 0),(0, 0, 1.15034)])) elif fragName == 'H': frags_to_add.append(Atoms('H',[(0,0,0)])) + elif fragName == 'O': + frags_to_add.append(Atoms('O',[(0,0,0)])) + elif fragName =='OH': + frags_to_add.append(Atoms('OH',[(0,0,0),(0,0,0.97)])) elif fragName =='H2O': frags_to_add.append(Atoms('OH2',[(0,0,0),(0.758602,0,0.504284),(-0.758602,0,0.504284)])) + #elif fragName =='C3H8': + #frags_to_add.append(Atoms('C3H8',[(0.000000,0.000000,0.000000),(0.000000,1.266857,0.847902),(0.000000,2.533714,0.000000),(-0.876898,1.266857,1.504899),(0.876898,1.266857,1.504899),(0.000000,3.433007,0.622252),(0.000000,-0.899293,0.622252),(0.883619,2.571091,-0.644219),(-0.883619,2.571091,-0.644219),(-0.883619,-0.037377,-0.644219),(0.883619,-0.037377,-0.644219)])) + elif fragName =='C3H8': + frags_to_add.append(Atoms('C3H8',[(0.00000000,0.00000000,0.00000000),(0.00000000,1.26685700,0.84790200),(0.00000000,-1.26685700,0.84790200),(-0.87689800,0.00000000,-0.65699700),(0.87689800,0.00000000,-0.65699700),(0.00000000,2.16615000,0.22565000),(0.00000000,-2.16615000,0.22565000),(0.88361900,1.30423400,1.49212100),(-0.88361900,1.30423400,1.49212100),(-0.88361900,-1.30423400,1.49212100),(0.88361900,-1.30423400,1.49212100)])) else: print('Unknown fragment: must add option to grow {} in grow_adFrag() in build.py'.format(fragName)) diff --git a/gocia/interface.py b/gocia/interface.py index 0070503..51579d2 100644 --- a/gocia/interface.py +++ b/gocia/interface.py @@ -825,7 +825,7 @@ def moveMut_frag(self, fragPool): tmpInterfc.growMut_frag([myFrag]) self.set_allAtoms(tmpInterfc.get_allAtoms()) - def growMut_box(self, elemList, xyzLims, bondRejList = None, constrainTop=False): + def growMut_box(self, elemList, xyzLims, bondRejList = None, bondMustList = None, constrainTop=False): print(' |- Growth mutation:', end = '\t') from gocia.geom.build import boxSample_adatom tmpInterfc = self.copy() @@ -836,6 +836,7 @@ def growMut_box(self, elemList, xyzLims, bondRejList = None, constrainTop=False) myElem, xyzLims=xyzLims, bondRejList=bondRejList, + bondMustList=bondMustList, constrainTop=constrainTop ) if tmpInterfc is not None: