def lecturePointsK(self): """ lit les informations sur les point K du calcul """ # lecture des points k fxml = open(self.xmlFile, "r") kpoints = myxml.getBlocs("kpoints", fxml, onlyfirst=True) fxml.close() # grille de points K generation = myxml.getBlocs("generation", kpoints, onlyfirst=True) if generation == None: self.typePointsK = "explicit" else: att = myxml.getClefs(generation[0], ["param"]) self.typePointsK = att["param"] if self.typePointsK == "listgenerated": ndir = 0 liste = list() for ligne in generation: nom = myxml.getNodeName(ligne) if nom == "i": self.Ndivision = int(myxml.getNodeData(ligne)[0]) if nom == "v": valeurs = [float(val) for val in myxml.getNodeData(ligne)] liste.append(valeurs) ndir += 1 # liste des directions self.directionsPointsK = list() for d in range(ndir - 1): self.directionsPointsK.append(liste[d] + liste[d + 1]) else: print("Explicit K points grid") # kpointlist varray = myxml.getBlocs("varray", kpoints, {"name": "kpointlist"}, True) self.listePointsK = list() for ligne in varray[1:-1]: valeurs = [float(val) for val in myxml.getNodeData(ligne)] self.listePointsK.append(valeurs) if self.typePointsK == "listgenerated": if len(self.directionsPointsK) * self.Ndivision != len( self.listePointsK): raise ValueError("k-points number unconsistent") else: self.directionsPointsK = [ self.listePointsK[0] + self.listePointsK[-1] ] self.Ndivision = len(self.listePointsK) # controle de lecture self.pointsKLues = True return self.pointsKLues
def lecturePointsK(self): """ lit les informations sur les point K du calcul """ # lecture des points k fxml = open(self.xmlFile, "r") kpoints = myxml.getBlocs("kpoints", fxml, onlyfirst = True ) fxml.close() # grille de points K generation = myxml.getBlocs("generation", kpoints, onlyfirst = True) if generation == None: self.typePointsK = "explicit" else: att = myxml.getClefs(generation[0], ["param"]) self.typePointsK = att["param"] if self.typePointsK == "listgenerated": ndir = 0 liste = list() for ligne in generation: nom = myxml.getNodeName(ligne) if nom == "i": self.Ndivision = int(myxml.getNodeData(ligne)[0]) if nom == "v": valeurs = [float(val) for val in myxml.getNodeData(ligne)] liste.append(valeurs) ndir += 1 # liste des directions self.directionsPointsK = list() for d in range(ndir - 1): self.directionsPointsK.append(liste[d] + liste[d + 1]) else: print("Explicit K points grid") # kpointlist varray = myxml.getBlocs( "varray", kpoints, {"name" : "kpointlist"}, True) self.listePointsK = list() for ligne in varray[1:-1]: valeurs = [float(val) for val in myxml.getNodeData(ligne)] self.listePointsK.append(valeurs) if self.typePointsK == "listgenerated": if len(self.directionsPointsK) * self.Ndivision != len(self.listePointsK): raise ValueError("k-points number unconsistent") else: self.directionsPointsK = [self.listePointsK[0] + self.listePointsK[-1]] self.Ndivision = len(self.listePointsK) # controle de lecture self.pointsKLues = True return self.pointsKLues
def __readKeywords(self): """ read xmlFile and store all keywords and their values """ if self.verbose: print("\t* Read keywords of the run") # # # parameters keywords # bloc parameters fxml = open( self.xmlFile, "r") parameters = myxml.getBlocs("parameters", fxml, onlyfirst = True) fxml.close() # dictionnary des parametres du calcul self.allMotsClefs = {} for ligne in parameters: if "<i" in ligne: nomFlag, valeurFlag = self.__lectureFlag(ligne) self.allMotsClefs[nomFlag] = valeurFlag elif "<v" in ligne: nomFlag, valeurFlag = self.__lectureFlag(ligne, vecteur=True) self.allMotsClefs[nomFlag] = valeurFlag else: continue # # # mots clefs du bloc incar # bloc incar fxml = open(self.xmlFile, "r") incar = myxml.getBlocs("incar", fxml, onlyfirst = True) fxml.close() # dictionnaire INCAR self.INCAR = {} for ligne in incar[1:-1]: if "<i" in ligne: nomFlag, valeurFlag = self.__lectureFlag(ligne) self.INCAR[ nomFlag ] = valeurFlag elif "<v" in ligne: nomFlag, valeurFlag = self.__lectureFlag(ligne, vecteur=True) self.INCAR[ nomFlag ] = valeurFlag else: continue self.allMotsClefs = dict(self.allMotsClefs.items() + self.INCAR.items())
def __readKeywords(self): """ read xmlFile and store all keywords and their values """ if self.verbose: print("\t* Read keywords of the run") # # # parameters keywords # bloc parameters fxml = open(self.xmlFile, "r") parameters = myxml.getBlocs("parameters", fxml, onlyfirst=True) fxml.close() # dictionnary des parametres du calcul self.allMotsClefs = {} for ligne in parameters: if "<i" in ligne: nomFlag, valeurFlag = self.__lectureFlag(ligne) self.allMotsClefs[nomFlag] = valeurFlag elif "<v" in ligne: nomFlag, valeurFlag = self.__lectureFlag(ligne, vecteur=True) self.allMotsClefs[nomFlag] = valeurFlag else: continue # # # mots clefs du bloc incar # bloc incar fxml = open(self.xmlFile, "r") incar = myxml.getBlocs("incar", fxml, onlyfirst=True) fxml.close() # dictionnaire INCAR self.INCAR = {} for ligne in incar[1:-1]: if "<i" in ligne: nomFlag, valeurFlag = self.__lectureFlag(ligne) self.INCAR[nomFlag] = valeurFlag elif "<v" in ligne: nomFlag, valeurFlag = self.__lectureFlag(ligne, vecteur=True) self.INCAR[nomFlag] = valeurFlag else: continue self.allMotsClefs = dict(self.allMotsClefs.items() + self.INCAR.items())
def getInitialStructure(self, verbose=True): """ read initial structure """ # read initial pos fxml = open(self.xmlFile, "r") structure = myxml.getBlocs("structure", fxml, {"name": "initialpos"}, True) fxml.close() # read lattice vectors latticeParam = myxml.getBlocs("varray", structure, {"name": "basis"}, True) veca = [float(val) for val in myxml.getNodeData(latticeParam[1])] vecb = [float(val) for val in myxml.getNodeData(latticeParam[2])] vecc = [float(val) for val in myxml.getNodeData(latticeParam[3])] # crystal object self.initialStructure = Crystal(veca = veca, vecb = vecb, vecc = vecc, \ name = "Initial structure : {0}".format(self.xmlFile)) # print lattice parameters if verbose: print("\t* a = %10.5f \t* alpha = %10.3f" % \ (self.initialStructure.a, self.initialStructure.alpha)) print("\t* b = %10.5f \t* beta = %10.3f" % \ (self.initialStructure.b, self.initialStructure.beta) ) print("\t* c = %10.5f \t* gamma = %10.3f" % \ (self.initialStructure.c, self.initialStructure.gamma)) # read reduce coordinates and compute cartesian coordinates positions = myxml.getBlocs("varray", structure, {"name": "positions"}, True) self.initialStructure.Natoms = 0 for ligne in positions[1:-1]: pos = [float(val) for val in myxml.getNodeData(ligne)] self.initialStructure.redCoord.append(pos) self.initialStructure.Natoms += 1 self.initialStructure.computeXYZCoord() if self.initialStructure.Natoms != self.Natomes: print("Natoms : {0}".format(self.Natomes)) print("Structure : {0}".format(self.initialStructure.Natoms)) print("Error : atom number") exit(1) # atom names for iat in range(self.Natomes): self.initialStructure.atomNames.append(self.atoms[iat].name) return self.initialStructure
def getInitialStructure(self,verbose=True): """ read initial structure """ # read initial pos fxml = open(self.xmlFile, "r") structure = myxml.getBlocs("structure", fxml, {"name":"initialpos"}, True) fxml.close() # read lattice vectors latticeParam = myxml.getBlocs("varray", structure, {"name":"basis"}, True) veca = [ float(val) for val in myxml.getNodeData(latticeParam[1]) ] vecb = [ float(val) for val in myxml.getNodeData(latticeParam[2]) ] vecc = [ float(val) for val in myxml.getNodeData(latticeParam[3]) ] # crystal object self.initialStructure = Crystal(veca = veca, vecb = vecb, vecc = vecc, \ name = "Initial structure : {0}".format(self.xmlFile)) # print lattice parameters if verbose: print("\t* a = %10.5f \t* alpha = %10.3f" % \ (self.initialStructure.a, self.initialStructure.alpha)) print("\t* b = %10.5f \t* beta = %10.3f" % \ (self.initialStructure.b, self.initialStructure.beta) ) print("\t* c = %10.5f \t* gamma = %10.3f" % \ (self.initialStructure.c, self.initialStructure.gamma)) # read reduce coordinates and compute cartesian coordinates positions = myxml.getBlocs("varray", structure, {"name":"positions"}, True) self.initialStructure.Natoms = 0 for ligne in positions[1:-1]: pos = [float(val) for val in myxml.getNodeData(ligne)] self.initialStructure.redCoord.append(pos) self.initialStructure.Natoms += 1 self.initialStructure.computeXYZCoord() if self.initialStructure.Natoms != self.Natomes: print("Natoms : {0}".format(self.Natomes)) print("Structure : {0}".format(self.initialStructure.Natoms)) print("Error : atom number") exit(1) # atom names for iat in range(self.Natomes): self.initialStructure.atomNames.append(self.atoms[iat].name) return self.initialStructure
def __readAtomsData( self ) : """ Read bloc 'atominfo'. It contains the atom list and their description. """ if self.verbose: print("\t* Read atom data") # on recupere le bloc atominfo fxml = open(self.xmlFile, "r") atominfo = myxml.getBlocs("atominfo", fxml, onlyfirst = True) fxml.close() # nombre d'atomes et nombre de types i = 0 for ligne in atominfo: if "<atoms>" in ligne : self.Natomes = int(myxml.getNodeData(ligne)[0]) i += 1 if "<types>" in ligne : self.Ntypes = int(myxml.getNodeData(ligne)[0]) i += 1 if i == 2 : break # atom list self.atoms = list() # read atom type lignesArrayTypes = myxml.getBlocs("array", atominfo, {"name":"atomtypes"}, True) self.typesAtomes = list() debutListe = False for ligne in lignesArrayTypes: if "<set>" in ligne: debutListe = True continue if "</set>" in ligne: break if debutListe: ligne = ligne.replace("<rc><c>", "") ligne = ligne.replace("</c></rc>", "") valeurs = ligne.split("</c><c>") tmpdic = {"nom":valeurs[1].strip(), "masse":float(valeurs[2]), \ "valence":float(valeurs[3]), "pseudo":valeurs[4] } self.typesAtomes.append(tmpdic) # lecture des atomes lignesArrayAtomes = myxml.getBlocs("array", atominfo, {"name":"atoms"}, True) debutListe = False for ligne in lignesArrayAtomes: if "<set>" in ligne: debutListe = True continue if "</set>" in ligne: break if debutListe : ligne = ligne.replace("<rc><c>", "") ligne = ligne.replace("</c></rc>", "") valeurs = ligne.split("</c><c>") nom = valeurs[0].strip() typ = int(valeurs[1]) if nom != self.typesAtomes[typ-1]["nom"]: print("non concordance nom / type ") exit(1) atom = Atom(name = self.typesAtomes[typ-1]["nom"], \ atomType = typ, \ Ne = self.typesAtomes[typ-1]["valence"], \ w = self.typesAtomes[typ-1]["masse"], \ pseudo = self.typesAtomes[typ-1]["pseudo"] ) self.atoms.append(atom)
def getFinalStructure(self,verbose=True): """ read final structure """ # read final pos fxml = open(self.xmlFile, "r") structure = myxml.getBlocs("structure", fxml, {"name":"finalpos"}, True) fxml.close() if self.verbose: print("\n# Read final structure") if structure == None: # there is not final structure (run not terminated) # <structure>...</structure> print("\t* Warning: final structure not found, read last one instead") fxml = open(self.xmlFile, "r") blocsStructures = myxml.getBlocs("structure", fxml) fxml.close() Nstructures = len(blocsStructures) if Nstructures == 0: # aucune structure ? print("\nError : there is not any structure in this xml file!\n") exit(1) elif Nstructures == 1: # only one structure => the initial one ligne = blocsStructures[0][0] att = myxml.getClefs(ligne, ["name"]) if att["name"] != None and att["name"] == "initialpos": print("\t* Warning : I found only the initial structure") else: print("\t* Warning : I found only one structure which is not the initial one ??") structure = blocsStructures[0] else: structure = blocsStructures[Nstructures-1] # read lattice vectors latticeParam = myxml.getBlocs("varray", structure, {"name":"basis"}, True) veca = [ float(val) for val in myxml.getNodeData(latticeParam[1]) ] vecb = [ float(val) for val in myxml.getNodeData(latticeParam[2]) ] vecc = [ float(val) for val in myxml.getNodeData(latticeParam[3]) ] # definition du cristal self.finalStructure = Crystal(veca = veca, vecb = vecb, vecc = vecc, \ name = "Final structure : {0}".format(self.xmlFile)) # print lattice parameters if verbose: print("\t* a = %10.5f \t* alpha = %10.3f" % (self.finalStructure.a, self.finalStructure.alpha)) print("\t* b = %10.5f \t* beta = %10.3f" % (self.finalStructure.b, self.finalStructure.beta) ) print("\t* c = %10.5f \t* gamma = %10.3f" % (self.finalStructure.c, self.finalStructure.gamma)) # read reduce coordinates and compute cartesian coordinates positions = myxml.getBlocs( "varray", structure, {"name":"positions"}, True) self.finalStructure.Natoms = 0 for ligne in positions[1:-1]: pos = [ float(val) for val in myxml.getNodeData(ligne) ] self.finalStructure.redCoord.append(pos) self.finalStructure.Natoms += 1 self.finalStructure.computeXYZCoord() if self.finalStructure.Natoms != self.Natomes: print("Natomes : {0}".format(self.Natomes)) print("Structure : {0}".format(self.finalStructure.Natomes)) print("Error : atomic number unconsistant") exit(1) # atom names for iat in range(self.Natomes): self.finalStructure.atomNames.append(self.atoms[iat].name) return self.finalStructure
def lectureBandes(self): """ Méthode permettant de lire les bandes d'énergie sur le fichier xml du calcul. Après exécution de cette méthode, on dispose des bandes d'énergie dans la liste Bandes sous la forme : <VaspRun>.bandes[ spin ][ point k ][ bandes ][ i ] spin : 0 ou 1, seule la valeur 0 est disponnible pour les calculs avec spin non polarisé (ISPIN = 1). Pour les calculs spin polarisé (ISPIN = 2), spin = 0 donne les bandes pour les spin alpha et spin = 1 pour les spin beta. point k : 0 -> nombre de point K le nombre de point k est calcul.nbrePointsK calcul.nbreLignesPointsK : nombre de directions de points k calcul.Ndivision : nombre de points k par direction Les points k sont listés direction après direction en donnant l'ensemble des points k sur chaque direction bandes : 0 -> NBANDS-1 i : 0 ou 1 i = 0 -> valeurs de l'énergie i = 1 -> occupation de la bande """ # lecture du niveau de fermi fxml = open(self.xmlFile, "r") dos = myxml.getBlocs("dos", fxml, onlyfirst = True) fxml.close() # test presence de la dos if dos == None: print("Density of state and fermi level not found in xml file") self.eFermi = 0.0 else: # niveau de Fermi for ligne in dos: att = myxml.getClefs(ligne, ["name"]) if att["name"] != None and att["name"] == "efermi": self.eFermi = float(myxml.getNodeData(ligne)[0]) break # bloc eigenvalues = bandes d'energie fxml = open(self.xmlFile, "r") eigenvalues = myxml.getBlocs("eigenvalues", fxml, onlyfirst = True) fxml.close() if eigenvalues == None: print("\nerreur : bandes d'énergie introuvable\n") exit(1) # infos sur le calcul NBANDS = self.allMotsClefs["NBANDS"] ISPIN = self.allMotsClefs["ISPIN"] # lecuture des points K self.lecturePointsK() nbreKpoints = len(self.listePointsK) if self.verbose: print("# Lecture des bandes d'énergies") print("\t* Fermi level = {0} eV (warning accuracy depend on k-points grid)".format(self.eFermi)) print("\t* ISPIN = {0}".format(ISPIN)) print("\t* nombre de bandes = {0}".format(NBANDS)) print("\t* nombre de points K = {0}".format(nbreKpoints)) setMain = myxml.getBlocs("set", eigenvalues, onlyfirst = True) blocSpin = list() blocSpin.append( myxml.getBlocs("set", setMain, {"comment":"spin 1"}, True)) if ISPIN == 2: blocSpin.append( myxml.getBlocs("set", setMain, {"comment":"spin 2"}, True)) # lecture des bandes self.bands = list() for spin in range(ISPIN): self.bands.append( list() ) # boucle sur les points k pour un spin for k in range(nbreKpoints): self.bands[spin].append( list() ) kpoint = "kpoint " + str(k+1) block = myxml.getBlocs("set", blocSpin[spin], {"comment":kpoint }, True) # boucle sur les valeurs des bandes sur un points k for ligne in block: nom = myxml.getNodeName(ligne) if nom == "r": valeurs = [float(val) for val in myxml.getNodeData(ligne) ] self.bands[spin][k].append( valeurs ) if len(self.bands[spin][k]) != NBANDS: print("\nerreur nombre de bandes incorrect\n") exit(1) # controle de lecture self.bandesLues = True return self.bandesLues
def lectureDOS( self ): """ Lecture de la densité d'états totale et des densités d'états partielles sur le fichier xml du calcul. Après exécution de cette méthode, on dispose de la densité d'états totale dans la liste dosTotale et des densités d'états partielles dans la liste dosPartielles. Les valeurs d'énergies pour lesquelles on dispose des valeurs de la DOS sont dans la liste energiesDOS. Ici <VaspRun> désigne un objet de type VaspRun, les listes crées sont de la forme : <VaspRun>.nptsDos => nombre de valeurs pour la DOS <VaspRun>.energiesDOS[i] i : 0 -> calcul.nptsDos-1 valeurs d'énergies pour lesquelles les DOS sont connues. <VaspRun>.dosTotale[ spin ][ E ][ i ] spin : 0 ou 1, seule la valeur 0 est disponnible pour les calculs avec spin non polarisé (ISPIN = 1). Pour les calculs spin polarisé (ISPIN = 2), spin = 0 donne la DOS pour le spin alpha et spin = 1 pour le spin beta. E : indice de parcours de la DOS pour un spin (valeurs de l'énergie) i : 0 -> 1 i = 0 -> densité d'états i = 1 -> intégrale de la DOS <VaspRun>.dosPartielles[ iat ][ spin ][ E ][ i ] iat : numéro de l'atome spin : 0 ou 1, seule la valeur 0 est disponnible pour les calculs avec spin non polarisé (ISPIN = 1). Pour les calculs spin polarisé (ISPIN = 2), spin = 0 donne la DOS pour le spin alpha et spin = 1 pour le spin beta. E : indice de parcours de la DOS pour un spin (valeurs de l'énergie) i : 0 -> 2 ou 8 valeurs de la DOS sur chaque sous couche ou OA 0 s, 1 p, 2 d 0 s, 1 py, 2 pz, 3 px, 4 dxy, 5 dyz, 6 dz2, 7 dxz, 8 dx2-y2 """ # spin polarise ? ISPIN = self.allMotsClefs["ISPIN"] if self.verbose: print("# Lecture de la densité d'états") # calcul spin polarisé ? print("\t* ISPIN = {0}".format(ISPIN)) # bloc dos fxml = open(self.xmlFile, "r") dos = myxml.getBlocs("dos", fxml, onlyfirst = True) fxml.close() # test presence de la dos if dos == None: print("Pas de densité d'états dans ce calcul") else: if self.verbose: print("\t* densité d'états totale") # niveau de Fermi for ligne in dos: att = myxml.getClefs(ligne, ["name"]) if att["name"] != None and att["name"] == "efermi": self.eFermi = float(myxml.getNodeData(ligne)[0]) print("\t* Fermi level = {0} eV (warning : accuracy depend on k-points grid)".format(self.eFermi)) break # DOS TOTALE # lecture de la dos totale blocDosTotale = myxml.getBlocs("total", dos, onlyfirst = True) self.dosTotale = list() self.energiesDOS = list() # cas spin non polarise blocDosTotaleSpin1 = myxml.getBlocs("set", blocDosTotale[1:-1], {"comment":"spin 1"}, True) self.dosTotale.append(list()) for ligne in blocDosTotaleSpin1[1:-1]: valeurs = [float(val) for val in myxml.getNodeData(ligne)] # valeurs[0] est l'energie self.energiesDOS.append(valeurs[0]) self.dosTotale[0].append(valeurs[1:]) if ISPIN == 2: # cas spin polarise blocDosTotaleSpin2 = myxml.getBlocs("set", blocDosTotale[1:-1], {"comment":"spin 2"}, True) self.dosTotale.append(list()) for ligne in blocDosTotaleSpin2[1:-1]: valeurs = [float(val) for val in myxml.getNodeData(ligne)] # valeurs[0] est l'energie self.dosTotale[1].append(valeurs[1:]) self.DOSTotaleLue = True # # DOS PARTIELLES # blocDosPartielle = myxml.getBlocs("partial", dos, onlyfirst = True ) if blocDosPartielle == None: print("\t ! pas de densité d'états partielles !") else: if self.verbose: print("\t* densités d'états partielles") self.dosPartielles = list() # boucle sur les atomes du calcul for iat in range(self.Natomes): ion = "ion " + str(iat+1) blocDosIon = myxml.getBlocs("set", blocDosPartielle, {"comment":ion}, True) self.dosPartielles.append( list() ) blocDosIonSpin1 = myxml.getBlocs( "set", blocDosIon[1:-1], {"comment":"spin 1"}, True) self.dosPartielles[iat].append( list() ) # lecture des dos projetees spin 1 for ligne in blocDosIonSpin1[1:-1]: valeurs = [ float(val) for val in myxml.getNodeData( ligne ) ] # valeurs[0] est l'energie self.dosPartielles[iat][0].append( valeurs[1:] ) if ISPIN == 2: self.dosPartielles[iat].append( list() ) blocDosIonSpin2 = myxml.getBlocs( "set", blocDosIon[1:-1], {"comment":"spin 2"}, True) # lecture des dos projetees spin 2 for ligne in blocDosIonSpin2[1:-1]: valeurs = [ float(val) for val in myxml.getNodeData( ligne ) ] # valeurs[0] est l'energie self.dosPartielles[iat][1].append( valeurs[1:] ) self.DOSPartiellesLues = True return [self.DOSTotaleLue, self.DOSPartiellesLues]
def __readAtomsData(self): """ Read bloc 'atominfo'. It contains the atom list and their description. """ if self.verbose: print("\t* Read atom data") # on recupere le bloc atominfo fxml = open(self.xmlFile, "r") atominfo = myxml.getBlocs("atominfo", fxml, onlyfirst=True) fxml.close() # nombre d'atomes et nombre de types i = 0 for ligne in atominfo: if "<atoms>" in ligne: self.Natomes = int(myxml.getNodeData(ligne)[0]) i += 1 if "<types>" in ligne: self.Ntypes = int(myxml.getNodeData(ligne)[0]) i += 1 if i == 2: break # atom list self.atoms = list() # read atom type lignesArrayTypes = myxml.getBlocs("array", atominfo, {"name": "atomtypes"}, True) self.typesAtomes = list() debutListe = False for ligne in lignesArrayTypes: if "<set>" in ligne: debutListe = True continue if "</set>" in ligne: break if debutListe: ligne = ligne.replace("<rc><c>", "") ligne = ligne.replace("</c></rc>", "") valeurs = ligne.split("</c><c>") tmpdic = {"nom":valeurs[1].strip(), "masse":float(valeurs[2]), \ "valence":float(valeurs[3]), "pseudo":valeurs[4] } self.typesAtomes.append(tmpdic) # lecture des atomes lignesArrayAtomes = myxml.getBlocs("array", atominfo, {"name": "atoms"}, True) debutListe = False for ligne in lignesArrayAtomes: if "<set>" in ligne: debutListe = True continue if "</set>" in ligne: break if debutListe: ligne = ligne.replace("<rc><c>", "") ligne = ligne.replace("</c></rc>", "") valeurs = ligne.split("</c><c>") nom = valeurs[0].strip() typ = int(valeurs[1]) if nom != self.typesAtomes[typ - 1]["nom"]: print("non concordance nom / type ") exit(1) atom = Atom(name = self.typesAtomes[typ-1]["nom"], \ atomType = typ, \ Ne = self.typesAtomes[typ-1]["valence"], \ w = self.typesAtomes[typ-1]["masse"], \ pseudo = self.typesAtomes[typ-1]["pseudo"] ) self.atoms.append(atom)
def getFinalStructure(self, verbose=True): """ read final structure """ # read final pos fxml = open(self.xmlFile, "r") structure = myxml.getBlocs("structure", fxml, {"name": "finalpos"}, True) fxml.close() if self.verbose: print("\n# Read final structure") if structure == None: # there is not final structure (run not terminated) # <structure>...</structure> print( "\t* Warning: final structure not found, read last one instead" ) fxml = open(self.xmlFile, "r") blocsStructures = myxml.getBlocs("structure", fxml) fxml.close() Nstructures = len(blocsStructures) if Nstructures == 0: # aucune structure ? print( "\nError : there is not any structure in this xml file!\n") exit(1) elif Nstructures == 1: # only one structure => the initial one ligne = blocsStructures[0][0] att = myxml.getClefs(ligne, ["name"]) if att["name"] != None and att["name"] == "initialpos": print("\t* Warning : I found only the initial structure") else: print( "\t* Warning : I found only one structure which is not the initial one ??" ) structure = blocsStructures[0] else: structure = blocsStructures[Nstructures - 1] # read lattice vectors latticeParam = myxml.getBlocs("varray", structure, {"name": "basis"}, True) veca = [float(val) for val in myxml.getNodeData(latticeParam[1])] vecb = [float(val) for val in myxml.getNodeData(latticeParam[2])] vecc = [float(val) for val in myxml.getNodeData(latticeParam[3])] # definition du cristal self.finalStructure = Crystal(veca = veca, vecb = vecb, vecc = vecc, \ name = "Final structure : {0}".format(self.xmlFile)) # print lattice parameters if verbose: print("\t* a = %10.5f \t* alpha = %10.3f" % (self.finalStructure.a, self.finalStructure.alpha)) print("\t* b = %10.5f \t* beta = %10.3f" % (self.finalStructure.b, self.finalStructure.beta)) print("\t* c = %10.5f \t* gamma = %10.3f" % (self.finalStructure.c, self.finalStructure.gamma)) # read reduce coordinates and compute cartesian coordinates positions = myxml.getBlocs("varray", structure, {"name": "positions"}, True) self.finalStructure.Natoms = 0 for ligne in positions[1:-1]: pos = [float(val) for val in myxml.getNodeData(ligne)] self.finalStructure.redCoord.append(pos) self.finalStructure.Natoms += 1 self.finalStructure.computeXYZCoord() if self.finalStructure.Natoms != self.Natomes: print("Natomes : {0}".format(self.Natomes)) print("Structure : {0}".format(self.finalStructure.Natomes)) print("Error : atomic number unconsistant") exit(1) # atom names for iat in range(self.Natomes): self.finalStructure.atomNames.append(self.atoms[iat].name) return self.finalStructure
def lectureBandes(self): """ Méthode permettant de lire les bandes d'énergie sur le fichier xml du calcul. Après exécution de cette méthode, on dispose des bandes d'énergie dans la liste Bandes sous la forme : <VaspRun>.bandes[ spin ][ point k ][ bandes ][ i ] spin : 0 ou 1, seule la valeur 0 est disponnible pour les calculs avec spin non polarisé (ISPIN = 1). Pour les calculs spin polarisé (ISPIN = 2), spin = 0 donne les bandes pour les spin alpha et spin = 1 pour les spin beta. point k : 0 -> nombre de point K le nombre de point k est calcul.nbrePointsK calcul.nbreLignesPointsK : nombre de directions de points k calcul.Ndivision : nombre de points k par direction Les points k sont listés direction après direction en donnant l'ensemble des points k sur chaque direction bandes : 0 -> NBANDS-1 i : 0 ou 1 i = 0 -> valeurs de l'énergie i = 1 -> occupation de la bande """ # lecture du niveau de fermi fxml = open(self.xmlFile, "r") dos = myxml.getBlocs("dos", fxml, onlyfirst=True) fxml.close() # test presence de la dos if dos == None: print("Density of state and fermi level not found in xml file") self.eFermi = 0.0 else: # niveau de Fermi for ligne in dos: att = myxml.getClefs(ligne, ["name"]) if att["name"] != None and att["name"] == "efermi": self.eFermi = float(myxml.getNodeData(ligne)[0]) break # bloc eigenvalues = bandes d'energie fxml = open(self.xmlFile, "r") eigenvalues = myxml.getBlocs("eigenvalues", fxml, onlyfirst=True) fxml.close() if eigenvalues == None: print("\nerreur : bandes d'énergie introuvable\n") exit(1) # infos sur le calcul NBANDS = self.allMotsClefs["NBANDS"] ISPIN = self.allMotsClefs["ISPIN"] # lecuture des points K self.lecturePointsK() nbreKpoints = len(self.listePointsK) if self.verbose: print("# Lecture des bandes d'énergies") print( "\t* Fermi level = {0} eV (warning accuracy depend on k-points grid)" .format(self.eFermi)) print("\t* ISPIN = {0}".format(ISPIN)) print("\t* nombre de bandes = {0}".format(NBANDS)) print("\t* nombre de points K = {0}".format(nbreKpoints)) setMain = myxml.getBlocs("set", eigenvalues, onlyfirst=True) blocSpin = list() blocSpin.append( myxml.getBlocs("set", setMain, {"comment": "spin 1"}, True)) if ISPIN == 2: blocSpin.append( myxml.getBlocs("set", setMain, {"comment": "spin 2"}, True)) # lecture des bandes self.bands = list() for spin in range(ISPIN): self.bands.append(list()) # boucle sur les points k pour un spin for k in range(nbreKpoints): self.bands[spin].append(list()) kpoint = "kpoint " + str(k + 1) block = myxml.getBlocs("set", blocSpin[spin], {"comment": kpoint}, True) # boucle sur les valeurs des bandes sur un points k for ligne in block: nom = myxml.getNodeName(ligne) if nom == "r": valeurs = [ float(val) for val in myxml.getNodeData(ligne) ] self.bands[spin][k].append(valeurs) if len(self.bands[spin][k]) != NBANDS: print("\nerreur nombre de bandes incorrect\n") exit(1) # controle de lecture self.bandesLues = True return self.bandesLues
def lectureDOS(self): """ Lecture de la densité d'états totale et des densités d'états partielles sur le fichier xml du calcul. Après exécution de cette méthode, on dispose de la densité d'états totale dans la liste dosTotale et des densités d'états partielles dans la liste dosPartielles. Les valeurs d'énergies pour lesquelles on dispose des valeurs de la DOS sont dans la liste energiesDOS. Ici <VaspRun> désigne un objet de type VaspRun, les listes crées sont de la forme : <VaspRun>.nptsDos => nombre de valeurs pour la DOS <VaspRun>.energiesDOS[i] i : 0 -> calcul.nptsDos-1 valeurs d'énergies pour lesquelles les DOS sont connues. <VaspRun>.dosTotale[ spin ][ E ][ i ] spin : 0 ou 1, seule la valeur 0 est disponnible pour les calculs avec spin non polarisé (ISPIN = 1). Pour les calculs spin polarisé (ISPIN = 2), spin = 0 donne la DOS pour le spin alpha et spin = 1 pour le spin beta. E : indice de parcours de la DOS pour un spin (valeurs de l'énergie) i : 0 -> 1 i = 0 -> densité d'états i = 1 -> intégrale de la DOS <VaspRun>.dosPartielles[ iat ][ spin ][ E ][ i ] iat : numéro de l'atome spin : 0 ou 1, seule la valeur 0 est disponnible pour les calculs avec spin non polarisé (ISPIN = 1). Pour les calculs spin polarisé (ISPIN = 2), spin = 0 donne la DOS pour le spin alpha et spin = 1 pour le spin beta. E : indice de parcours de la DOS pour un spin (valeurs de l'énergie) i : 0 -> 2 ou 8 valeurs de la DOS sur chaque sous couche ou OA 0 s, 1 p, 2 d 0 s, 1 py, 2 pz, 3 px, 4 dxy, 5 dyz, 6 dz2, 7 dxz, 8 dx2-y2 """ # spin polarise ? ISPIN = self.allMotsClefs["ISPIN"] if self.verbose: print("# Lecture de la densité d'états") # calcul spin polarisé ? print("\t* ISPIN = {0}".format(ISPIN)) # bloc dos fxml = open(self.xmlFile, "r") dos = myxml.getBlocs("dos", fxml, onlyfirst=True) fxml.close() # test presence de la dos if dos == None: print("Pas de densité d'états dans ce calcul") else: if self.verbose: print("\t* densité d'états totale") # niveau de Fermi for ligne in dos: att = myxml.getClefs(ligne, ["name"]) if att["name"] != None and att["name"] == "efermi": self.eFermi = float(myxml.getNodeData(ligne)[0]) print( "\t* Fermi level = {0} eV (warning : accuracy depend on k-points grid)" .format(self.eFermi)) break # DOS TOTALE # lecture de la dos totale blocDosTotale = myxml.getBlocs("total", dos, onlyfirst=True) self.dosTotale = list() self.energiesDOS = list() # cas spin non polarise blocDosTotaleSpin1 = myxml.getBlocs("set", blocDosTotale[1:-1], {"comment": "spin 1"}, True) self.dosTotale.append(list()) for ligne in blocDosTotaleSpin1[1:-1]: valeurs = [float(val) for val in myxml.getNodeData(ligne)] # valeurs[0] est l'energie self.energiesDOS.append(valeurs[0]) self.dosTotale[0].append(valeurs[1:]) if ISPIN == 2: # cas spin polarise blocDosTotaleSpin2 = myxml.getBlocs("set", blocDosTotale[1:-1], {"comment": "spin 2"}, True) self.dosTotale.append(list()) for ligne in blocDosTotaleSpin2[1:-1]: valeurs = [float(val) for val in myxml.getNodeData(ligne)] # valeurs[0] est l'energie self.dosTotale[1].append(valeurs[1:]) self.DOSTotaleLue = True # # DOS PARTIELLES # blocDosPartielle = myxml.getBlocs("partial", dos, onlyfirst=True) if blocDosPartielle == None: print("\t ! pas de densité d'états partielles !") else: if self.verbose: print("\t* densités d'états partielles") self.dosPartielles = list() # boucle sur les atomes du calcul for iat in range(self.Natomes): ion = "ion " + str(iat + 1) blocDosIon = myxml.getBlocs("set", blocDosPartielle, {"comment": ion}, True) self.dosPartielles.append(list()) blocDosIonSpin1 = myxml.getBlocs("set", blocDosIon[1:-1], {"comment": "spin 1"}, True) self.dosPartielles[iat].append(list()) # lecture des dos projetees spin 1 for ligne in blocDosIonSpin1[1:-1]: valeurs = [ float(val) for val in myxml.getNodeData(ligne) ] # valeurs[0] est l'energie self.dosPartielles[iat][0].append(valeurs[1:]) if ISPIN == 2: self.dosPartielles[iat].append(list()) blocDosIonSpin2 = myxml.getBlocs( "set", blocDosIon[1:-1], {"comment": "spin 2"}, True) # lecture des dos projetees spin 2 for ligne in blocDosIonSpin2[1:-1]: valeurs = [ float(val) for val in myxml.getNodeData(ligne) ] # valeurs[0] est l'energie self.dosPartielles[iat][1].append(valeurs[1:]) self.DOSPartiellesLues = True return [self.DOSTotaleLue, self.DOSPartiellesLues]