def _checkExpectedDistanceBetweenImages(self): noVacSupercell = supCell.superCellFromUCell( self.testCellA, [1,1,2] ) noVacDist = self._getDistTwoPoints(noVacSupercell.cartCoords[0][:3] ,noVacSupercell.cartCoords[1][:3]) expDistance = self.lenVac + noVacDist tCode.addVacuumToUnitCellAlongC(self.testCellA,self.lenVac) doubleCell = supCell.superCellFromUCell( self.testCellA, [1,1,2] ) posA, posB = doubleCell.cartCoords[0][:3], doubleCell.cartCoords[1][:3] actDistance = self._getDistTwoPoints(posA,posB) self.assertAlmostEqual(expDistance,actDistance)
def getVacancyPlaneWaveStruct(structType, relaxType, cellSize): baseUCell = getPlaneWaveGeom(structType) cellDims = [int(x) for x in cellSize.split("_")] if relaxType == "unrelaxed": vacCell = supCell.superCellFromUCell(baseUCell, cellDims) defects.makeVacancyUnitCell(vacCell) return vacCell elif relaxType == "novac": return supCell.superCellFromUCell(baseUCell, cellDims) elif relaxType == "relaxed_constant_pressure": return _getVacancyHcpPlaneWaveStruct_relaxedConstantPressure() else: raise NotImplementedError("relaxType = {} not currently implemented".format(relaxType))
def createTestObjs(self): self.singleCellA = uCellHelp.UnitCell(lattParams=self.lattParamsA, lattAngles=self.lattAnglesA) self.singleCellA.cartCoords = self.cartCoordsA self.adsObjsA = [self.adsObjA] self.testObjA = tCode.GetWaterBoxForMDFromEmptyBoxStandard(self.singleCellA, self.adsObjsA,waterAdsGap=self.waterAdsGapA) self.emptyCellA = supCellHelp.superCellFromUCell(self.singleCellA,[2,1,1]) self.emptyCellA.cartCoords = list()
def __call__(self, nSites, primCell, inpCell): allPossible = self._getPossibleCombinations(nSites, primCell) allObjVals = list() #1) Figure out the objective function for EACH possible supercell targParams = inpCell.getLattParamsList() objVals = list() for combo in allPossible: currCell = supCellHelp.superCellFromUCell(primCell, combo) currLattParams = currCell.getLattParamsList() currObjVals = sum([ abs(targParam - actParam) / actParam for targParam, actParam in zip(targParams, currLattParams) ]) objVals.append(currObjVals) #2) Figure out the best supercell parameters from the objective functions minVal = min(objVals) diffFromMinVals = [x - minVal for x in objVals] paramsWithinTolerance = [ x for x, diffFromMin in zip(allPossible, diffFromMinVals) if diffFromMin < self.diffTol ] #If some are tied, favor the one with highest c, then b then a outVal = sorted(paramsWithinTolerance)[0] return outVal
def _createWorkFlowCoordinator(self): allObjs = list() for x in self.interObjs: cellDims = x.cellDims interStruct = x.getInterStructFromRefDataStruct(self.refData) refStruct = self._getRefGeom(x) #Should be the same for all really refStruct = supCell.superCellFromUCell(refStruct, cellDims) startFolder = self.workFolder modOptDict = self.optDict platoComm = self.platoComm relaxed = x.relaxed interType = x.interstitType runCalcs = x.runCalcs currObj = createWFlows.CreateInterstitialWorkFlow( refStruct, interStruct, startFolder, modOptDict, platoComm, relaxed=relaxed, cellDims=cellDims, interType=interType, genPreShellComms=runCalcs, eType=self.eType)() allObjs.append(currObj) workFlowCoord = wFlowCoordinator.WorkFlowCoordinator( allObjs, nCores=self.nCores, quietPreShellComms=False) return workFlowCoord
def testExpectedCoordsForSimpleCell(self): outCell = supCellHelp.superCellFromUCell(self.primCellA, [2, 2, 2]) expCartCoords = outCell.cartCoords actCartCoords = self.testObjA(self.targNAtoms, self.inpCellA) for exp, act in it.zip_longest(expCartCoords, actCartCoords): self.assertEqual(len(exp), len(act)) [self.assertAlmostEqual(e, a) for e, a in zip(exp[:3], act[:3])] self.assertEqual(exp[-1], act[-1])
def getCartCoordsToFillUpCell(self, nAtoms, inpCell): self._checkAnglesSimilarEnough(self.primCell, inpCell) nLayersC = self._getNLayersInC(nAtoms, inpCell) nA, nB = self._getNumbImagesAB(nAtoms, nLayersC, inpCell) outCell = supCellHelp.superCellFromUCell(self.primCell, [nA, nB, nLayersC]) outCell.lattParams = inpCell.lattParams #Fractional co-ordinates dont move; but cartesian will. return outCell.cartCoords
def _getNearestOutOfPlaneCoordsToPointForInpCell(inpCell, pointCoords, zCartTol=1e-2): #Step 1 = create the relevant supercell superCell = supCellHelp.superCellFromUCell(inpCell, [3, 3, 3]) otherPoints = [x[:3] for x in superCell.cartCoords] filteredCoords = _getAllCoordsInDiffZPlaneAsInpCartCoord( pointCoords[:3], otherPoints) nearestPointIdx = cartCoordUtils.getIdxOfNearestPointToInputPoint( pointCoords[:3], filteredCoords) return filteredCoords[nearestPointIdx]
def _getNearestNebCoordsInPlane(inpCell, atomIdx, zCartTol=1e-1, inclImages=True): #Step 1 = create the relevant supercell inpCartCoord = inpCell.cartCoords[atomIdx][0:3] if inclImages: superCell = supCellHelp.superCellFromUCell(inpCell, [3, 3, 3]) else: superCell = supCellHelp.superCellFromUCell(inpCell, [1, 1, 1]) newCartCoords = superCell.cartCoords[atomIdx][0:3] coordDiffs = [ abs(x - y) for x, y in it.zip_longest(inpCartCoord, newCartCoords) ] assert all([x < 1e-5 for x in coordDiffs]) #Step 2 = figure out the index (within the NEW supercell) filteredCoords = _getAllNeighbourCoordsInSameZPlane( superCell.cartCoords, atomIdx, zCartTol) idxInFilteredList = cartCoordUtils.getIdxOfNearestPointToInputPoint( inpCartCoord, filteredCoords) #Step 3 = return the co-ordinates for that index return filteredCoords[idxInFilteredList]
def testCellA_2x2x1(self): #These are values from platos build (the fractCoords were reordered) lattVects_221 = [[12.12, 0.00, 0.00], [6.06, 10.4962278819, 0.00], [0.00, 0.00, 9.839043529]] fractCoords_221 = [[0, 0.000000000, 0.0, "Mg"], [0.166666665, 0.166666665, 0.5, "Mg"], [0.5, 0.0, 0, "Mg"], [0.666666665, 0.166666665, 0.5, "Mg"], [0.00, 0.5, 0.00, "Mg"], [0.166666665, 0.666666665, 0.5, "Mg"], [0.5, 0.5, 0.0, "Mg"], [0.666666665, 0.666666665, 0.5, "Mg"]] expectedUCell = UCell.UnitCell.fromLattVects(lattVects_221, fractCoords_221) supCell = tCode.superCellFromUCell(self.startUCellA, [2, 2, 1]) self.assertTrue(expectedUCell == supCell)
def testCellB_3x1x2(self): lattVects_312 = [[18.18, 0.0, 0], [3.0300000097, 5.248113941, 0], [0.00, 0.0, 19.67808706]] fractCoords_312 = [[0, 0, 0, "Mg"], [0.11111111, 0.3333333, 0.25, "Mg"], [0.33333333, 0, 0, "Mg"], [0.66666667, 0, 0, "Mg"], [0.44444444, 0.3333333, 0.25, "Mg"], [0.77777778, 0.3333333, 0.25, "Mg"], [0, 0, 0.5, "Mg"], [0.11111111, 0.3333333, 0.75, "Mg"], [0.33333333, 0, 0.5, "Mg"], [0.66666667, 0, 0.5, "Mg"], [0.44444444, 0.3333333, 0.75, "Mg"], [0.77777778, 0.3333333, 0.75, "Mg"]] expectedUCell = UCell.UnitCell.fromLattVects(lattVects_312, fractCoords_312) supCell = tCode.superCellFromUCell(self.startUCellA, [3, 1, 2]) self.assertTrue(expectedUCell == supCell)
def _getNearestNebCoordsOutOfZPlane(inpCell, atomIdx, zCartTol=1e-2): #Step 1 = create the relevant supercell inpCartCoord = inpCell.cartCoords[atomIdx][0:3] superCell = supCellHelp.superCellFromUCell(inpCell, [3, 3, 4]) newCartCoords = superCell.cartCoords[atomIdx][0:3] coordDiffs = [ abs(x - y) for x, y in it.zip_longest(inpCartCoord, newCartCoords) ] assert all([x < 1e-5 for x in coordDiffs]) #Step 2 = figure out the index (within the NEW supercell) filteredIndices = _getAllIndicesForNeighboursInDiffZPlane( inpCell.cartCoords, atomIdx, zCartTol) #TODO: Not actually needed filteredCoords = _getAllNeighbourCoordsInDiffZPlane( inpCell.cartCoords, atomIdx, zCartTol) idxInFilteredList = cartCoordUtils.getIdxOfNearestPointToInputPoint( inpCartCoord, filteredCoords) #Step 3 = return the co-ordinates for that index return filteredCoords[idxInFilteredList]
def _getNearestNebDistanceForAtomInUcell(inpCell, atomIdx): """ Returns the nearest neighbour distance for a given atom in a unit cell (including periodic images by default) Args: inpCell: plato_pylib UnitCell object atomIdx: int, index of the atom you want to look for nearest neighboru distances for. 0 means the 1st atom in the list from inpCell.fractCoords (or inpCell.cartCoords) """ #Create a 2x2x2 supercell and check the atom indices havent been rearanged cartCoords = inpCell.cartCoords[atomIdx][0:3] superCell = supCellHelp.superCellFromUCell(inpCell, [2, 2, 2]) newCartCoords = superCell.cartCoords[atomIdx][0:3] coordDiffs = [ abs(x - y) for x, y in it.zip_longest(cartCoords, newCartCoords) ] assert all([x < 1e-5 for x in coordDiffs]) #Figure out all distances otherAtomCoords = [ superCell.cartCoords[x][0:3] for x in range(len(superCell.cartCoords)) if x != atomIdx ] return cartCoordUtils.getNearestDistanceToInputPoint( cartCoords, otherAtomCoords)
def unitCell(self): superCell = supCell.superCellFromUCell(self._singleLayerCell, [1, 1, self._nLayers]) vacToAdd = self._getAmountOfVacuumToAddAlongC() addVacuumToUnitCellAlongC(superCell, vacToAdd) return superCell
def getCartCoordsToFillUpCell(self, nSites, inpCell): self._checkAnglesSimilarEnough(self.primCell, inpCell) nA, nB, nC = self._getNumbImagesEachDim(nSites, inpCell) outCell = supCellHelp.superCellFromUCell(self.primCell, [nA, nB, nC]) outCell.lattParams = inpCell.lattParams #Fractional co-ordinates dont move; but cartesian will. return outCell.cartCoords
def _bulkCellNoSurfaceLayers(self): return supCell.superCellFromUCell(self.baseGeom, self.cellDims)