Source code for qmpy.analysis.vasp.potential

from django.db import models
import logging

import qmpy
import qmpy.materials.element as elt

logger = logging.getLogger(__name__)


[docs]class Potential(models.Model): """ Class for storing a VASP potential. Relationships: | calculation | element Attributes: | name | date | electrons: Electrons in potential. | enmax | enmin | gw | id | paw | potcar | us | xc """ potcar = models.TextField() element = models.ForeignKey(elt.Element, on_delete=models.PROTECT) name = models.CharField(max_length=10) xc = models.CharField(max_length=3) gw = models.BooleanField(default=False) paw = models.BooleanField(default=False) us = models.BooleanField(default=False) enmax = models.FloatField() enmin = models.FloatField() date = models.CharField(max_length=20) electrons = models.TextField(blank=True, null=True) class Meta: app_label = "qmpy" db_table = "vasp_potentials" def __str__(self): ident = "%s %s" % (self.name, self.xc) if self.paw: ident += " PAW" if self.us: ident += " US" if self.gw: ident += " GW" return ident
[docs] @classmethod def read_potcar(cls, potfile): """ Import pseudopotential(s) from VASP POTCAR. Make sure to save each of them after importing in order to store in them in the OQMD Arguments: potfile - string, Path to POTCAR file Output: List of Potential objects """ # Read entire POTCAR file pots = open(potfile).read() # Split into the component POTCARs pots = pots.strip().split("End of Dataset") # Parse each file potobjs = [] for pot in pots: if not pot: continue # Get key information from POTCAR potcar = {} for line in pot.split("\n"): # Get element name if "TITEL" in line: potcar["name"] = line.split()[3] telt = potcar["name"].split("_")[0] date = potcar["name"].split("_")[-1] try: potcar["element"] = elt.Element.objects.get(symbol=telt) except: print("Unknown element in potcar", telt) raise if "GW" in line: potcar["gw"] = True if "PAW" in line: potcar["paw"] = True if "US" in line: potcar["us"] = True if "ENMAX" in line: data = line.split() potcar["enmax"] = float(data[2].rstrip(";")) potcar["enmin"] = float(data[5]) if "VRHFIN" in line: potcar["electrons"] = line.split(":")[1] if "LEXCH" in line: key = line.split()[-1] if key == "91": potcar["xc"] = "GGA" elif key == "CA": potcar["xc"] = "LDA" elif key == "PE": potcar["xc"] = "PBE" potobj, created = cls.objects.get_or_create(**potcar) if created: potobj.potcar = pot potobjs.append(potobj) return potobjs
[docs]class Hubbard(models.Model): """ Base class for a hubbard correction parameterization. Attributes: | calculation | convention | correction | element | id | l | ligand | ox | u """ element = models.ForeignKey( elt.Element, related_name="hubbards", on_delete=models.CASCADE ) convention = models.CharField(max_length=20) ox = models.FloatField(default=None, null=True) ligand = models.ForeignKey( elt.Element, related_name="+", on_delete=models.CASCADE, null=True, blank=True ) u = models.FloatField(default=0) l = models.IntegerField(default=-1) class Meta: app_label = "qmpy" db_table = "hubbards" def __bool__(self): if self.u > 0 and self.l != -1: return True else: return False def __eq__(self, other): if self.element != other.element: return False elif self.ligand != other.ligand: return False elif self.u != other.u: return False elif self.l != other.l: return False return True def __str__(self): retval = self.element_id if self.ox: retval += "+%d" % (self.ox) if self.ligand: retval += "-" + self.ligand_id retval += ", U=%0.2f, L=%d" % (self.u, self.l) return retval def __hash__(self): return hash(self.__str__()) @property def key(self): return "%s_%s" % (self.element_id, self.u) @classmethod def get(cls, elt, ox=None, u=0, l=-1, lig=None): hub, new = Hubbard.objects.get_or_create( element_id=elt, ligand=lig, ox=ox, l=l, u=u ) if new: hub.save() return hub