def getCastepSurfaceEnergyFromSurfAndBulkFilePaths(surfPath, bulkPath, surfClass): bulkModFile = bulkPath surfFile = surfPath #Parse both files and get energy and energy per atom from them. We can create a surf-energies object for each #That simply returns this info parsedBulkModFile = parseCastep.parseCastepOutfile(bulkModFile) parsedSurfFile = parseCastep.parseCastepOutfile(surfFile) surfUCell = parsedSurfFile["unitCell"] surfUCell.convAngToBohr() lenVac, nLayer = 0, 1 #Irrelevant for getting surface area surfObj = surfClass( surfUCell, nLayer, lenVac ) surfArea = surfObj.surfaceArea #Create the objects for the workflow surfEPerAtom = parsedSurfFile["energies"].electronicTotalE / parsedSurfFile["numbAtoms"] bulkEPerAtom = parsedBulkModFile["energies"].electronicTotalE / parsedBulkModFile["numbAtoms"] surfRunner = SurfaceRunnerForExtractingRefData(surfEPerAtom, parsedSurfFile["numbAtoms"], surfArea) bulkRunner = SurfaceRunnerForExtractingRefData(bulkEPerAtom, parsedBulkModFile["numbAtoms"], surfArea) #Run the workflow and extract the values wFlow = surfFlow.SurfaceEnergiesWorkFlow(surfRunner,bulkRunner) wFlow.run() surfEnergy = wFlow.output.surfaceEnergy return surfEnergy
def getDefectEnergyFromCastepNoDefectAndDefectFiles(noDefectPath, defectPath): parsedNoDefect = parseCastep.parseCastepOutfile(noDefectPath) parsedDefect = parseCastep.parseCastepOutfile(defectPath) nAtomsNoDefect, energyNoDefect = parsedNoDefect["numbAtoms"], parsedNoDefect["energies"].electronicTotalE nAtomsDefect, energyDefect = parsedDefect["numbAtoms"], parsedDefect["energies"].electronicTotalE ePerAtomNoDefect = energyNoDefect / nAtomsNoDefect ePerAtomDefect = energyDefect / nAtomsDefect return nAtomsDefect * (ePerAtomDefect - ePerAtomNoDefect)
def getUCellsAndEnergiesForBulkModCalcs(structType,perAtom=True, eUnits="eV"): refFolder = os.path.join(BASE_FOLDER, "eos", structType) parsedFiles = [parseCastep.parseCastepOutfile(x) for x in helpers.getCastepOutPathsForFolder(refFolder)] allUCells = [x["unitCell"] for x in parsedFiles] [x.convAngToBohr() for x in allUCells] allEnergies = [x["energies"].electronicTotalE for x in parsedFiles] if perAtom: allEnergies = [ energy/parsed["numbAtoms"] for energy,parsed in it.zip_longest(allEnergies, parsedFiles) ] outObjs = list() for cell,energy in it.zip_longest(allUCells,allEnergies): currObj = types.SimpleNamespace(uCell=cell, energy=energy) outObjs.append(currObj) #Do any energy conversions needed if eUnits.lower()=="ev": pass elif eUnits.lower()=="ryd": print("Converting to Rydberg units") convUnits = unitConvs.EV_TO_RYD for x in outObjs: x.energy *= convUnits else: raise AttributeError("{} is an invalid value for eUnits".format(eUnits)) return outObjs
def _getMgAtomGeomAsUCell(): inpFolder = os.path.join(BASE_FOLDER,"atom_calc") inpFiles = helpers.getCastepOutPathsForFolder(inpFolder) assert len(inpFiles)==1 outCell = parseCastep.parseCastepOutfile(inpFiles[0])["unitCell"] outCell.convAngToBohr() return outCell
def getPlaneWaveGeom(structType:str): refFolder = os.path.join(BASE_FOLDER, "opt_geoms", structType) structTypeToFileName = {"hcp": "Zr_hcp_opt.castep", "bcc": "Zr_bcc_opt.castep", "fcc": "Zr_fcc_opt.castep"} refPath = os.path.join(refFolder, structTypeToFileName[structType]) uCell = parseCastep.parseCastepOutfile(refPath)["unitCell"] uCell.convAngToBohr() return uCell
def parseOutputFile(outPath): if outPath.endswith('.castep'): outParsed = parseCastep.parseCastepOutfile(outPath) elif outPath.endswith('.out'): outParsed = parsePlatoOut.parsePlatoOutFile(outPath) else: raise ValueError("{} is an invalid file extension") return outParsed
def getPlaneWaveDissocSepVsTotalE(inBohr=True): outFolder = os.path.join(BASE_FOLDER,"dissoc_curve") outFiles = helpers.getCastepOutPathsForFolder(outFolder) outEnergies = [parseCastep.parseCastepOutfile(x)["energies"].electronicTotalE for x in outFiles] outSeps = [helpers.getDimerSepFromCastepOutFile(x,inBohr=True) for x in outFiles] outList = list() for sep,e in it.zip_longest(outSeps,outEnergies): outList.append( [sep,e] ) return outList
def _createWaterMonomerCastep(): structName = "monomer" outPath = os.path.join(CASTEP_DB_BASE_FOLDER, "monomer", "geom", "h2o_monomer_opt.castep") geom = helpers.getUCellInBohrFromCastepOutFile(outPath) label = labelObjs.StandardLabel(eleKey="h20", methodKey="castep", structKey="monomer") parsedFile = parseCastep.parseCastepOutfile(outPath) outEnergy = parsedFile["energies"].electronicTotalE nMolecules = 1 return WaterClusterData(label, geom, nMolecules, outEnergy)
def getPlaneWaveAtomTotalEnergy(self, charge=0): if charge==0: return _getMgAtomPlaneWaveTotalEnergy() elif charge==2: return _getMg2PlusIonPlaneWaveTotalEnergy() else: raise ValueError("charge = {} is an invalid value".format(charge)) inpFolder = os.path.join(BASE_FOLDER,"atom_calc") inpFiles = helpers.getCastepOutPathsForFolder(inpFolder) assert len(inpFiles)==1 outEnergy = parseCastep.parseCastepOutfile(inpFiles[0])["energies"].electronicTotalE return outEnergy
def getDimerSepFromCastepOutFile(inpFile,inBohr=True): """ Gets separation Args: inpFile(str): Path to *.castep output file inBohr(opt, bool): If true convert distance from angstrom to bohr; if False use angstrom Returns dimerSep: Separation between the two atoms in the castep file Raises: AssertionError: If the last unit-cell in the input file doesnt have exactly 2 atoms """ parsedUCell = parseCastep.parseCastepOutfile(inpFile)["unitCell"] if inBohr: parsedUCell.convAngToBohr() return getDimerSepFromUCellObj(parsedUCell)
def _getUpdatedOptDictFromCastepOutFile(casFile,outDict): parsedFile = parseCastep.parseCastepOutfile(casFile) outDict["natom"] = parsedFile["numbAtoms"] #Get parameters from unitcell uCell = parsedFile["unitCell"] uCell.convAngToBohr() outDict["cellsize"] = uCell.getLattParamsList() lattVects = uCell.getLattVects() for idx,lVect in enumerate(lattVects): lattVects[idx] = [x/outDict["cellsize"][idx] for x in lVect] outDict["cellvec"] = lattVects outDict["format"] = 0 #The fractional co-ordinations - Not really checked up on this yet outDict["atoms"] = list() for fCoord in uCell.fractCoords: outDict["atoms"].append( " ".join([str(x) for x in fCoord]) ) return outDict
def getDispsAndStackFaultEnergiesFromCastepFilesInFolder(inpFolder): outFiles = [os.path.join(inpFolder,x) for x in os.listdir(inpFolder) if x.endswith(".castep")] dispVals = list() stackFaultValsTotal = list() stackFaultValsRelative = list() refStackFaultValTotal = None #Get individual energies for x in outFiles: parsedFile = types.SimpleNamespace(**parseCastep.parseCastepOutfile(x)) baseFileName = os.path.splitext( os.path.split(x)[-1] )[0] if baseFileName.startswith("disp_val"): dispVal = float( baseFileName.replace("disp_val_","").replace("pt",".") ) currStackFaultTotal = _getAbsoluteStackFaultValueFromParsedFile(parsedFile) stackFaultValsTotal.append(currStackFaultTotal) dispVals.append(dispVal) elif baseFileName.startswith("perfect_cell"): refStackFaultValTotal = _getAbsoluteStackFaultValueFromParsedFile(parsedFile) else: pass #Convert to relative energies stackFaultValsRelative = [x-refStackFaultValTotal for x in stackFaultValsTotal] return dispVals, stackFaultValsRelative
def getPlaneWaveAtomTotalEnergy(self): inpFolder = os.path.join(BASE_FOLDER,"atom_calc") inpFiles = helpers.getCastepOutPathsForFolder(inpFolder) assert len(inpFiles)==1 outEnergy = parseCastep.parseCastepOutfile(inpFiles[0])["energies"].electronicTotalE return outEnergy
def getHcpComprStructAsUCell(): refPath = os.path.join(BASE_FOLDER,"eos", "hcp", "Mg_hcp_SPE_otf_10el_usp_PP_5pt81.castep") initUCell = parseCastep.parseCastepOutfile(refPath)["unitCell"] initUCell.convAngToBohr() return initUCell
def getEnergyFromCastepOutFile(outFile, eType="electronicTotalE"): parsedFile = parseCastep.parseCastepOutfile(outFile) return getattr(parsedFile["energies"],eType)
def _getMg2PlusIonPlaneWaveTotalEnergy(): inpFolder = os.path.join(BASE_FOLDER,"atom_calc","ion_calcs") inpFiles = helpers.getCastepOutPathsForFolder(inpFolder) assert len(inpFiles)==1 outEnergy = parseCastep.parseCastepOutfile(inpFiles[0])["energies"].electronicTotalE return outEnergy
def getBccComprStructAsUCell(): refPath = os.path.join(BASE_FOLDER,"eos", "bcc", "Mg_bcc_opt_otf_10el_usp_PP_10_5pt592.castep") initUCell = parseCastep.parseCastepOutfile(refPath)["unitCell"] initUCell.convAngToBohr() return initUCell
def _getHcpPlaneWaveStruct_interTetraRelaxedConstantPressure332(): refFile = os.path.join(BASE_FOLDER, "interstitial", "relaxed", "constant_p", "Zr_hcp_strain6_0-Tinterstitial.castep") parsedUCell = parseCastep.parseCastepOutfile(refFile)["unitCell"] parsedUCell.convAngToBohr() return parsedUCell
def getUCellsFromCastepBulkModFolder(refFolder): casOutFiles = getCastepOutPathsForFolder(refFolder) parsedUCells = [parseCastep.parseCastepOutfile(x)["unitCell"] for x in casOutFiles] [x.convAngToBohr() for x in parsedUCells] return parsedUCells
def getUCellInBohrFromCastepOutFile(outFilePath): uCell = parseCastep.parseCastepOutfile(outFilePath)["unitCell"] uCell.convAngToBohr() return uCell
def getParsedFileObjFromCastepOutputFile(outFilePath): parsedDict = parseCastep.parseCastepOutfile(outFilePath) outObj = baseObjs.StandardParsedOutputFile.fromKwargDict(**parsedDict) outObj.unitCell.convAngToBohr() return outObj