Ejemplo n.º 1
0
 def update_atom_indices_from_structure(self,
                                        mystr,
                                        ing_label="",
                                        manname=""):
     """Add new information to each atom index
         Args:
             mystr <pymatgen Structure object>
             ing_label <str>: Ingredient name
             manname <str>: Manifest name
     """
     self.logger.debug("Update atom indices from structure %s" % mystr)
     self.logger.debug("Manifest name %s" % manname)
     self.logger.debug("Current ingredient %s" % ing_label)
     self.logger.debug("Structure index directory %s" % self.sdir)
     mlist = list(self.read_manifest_file("%s/%s" % (self.sdir, manname)))
     self.logger.debug("MLIST %s" % mlist)
     for midx in range(0, len(mlist)):
         msplit = mlist[midx].split(";")
         ameta = Metadata(metafile="%s/atom_index_%s" %
                          (self.sdir, msplit[0]))
         ameta.write_data("%s_frac_coords" % ing_label,
                          mystr.sites[midx].frac_coords)
         if len(msplit) > 1 and not (msplit[1] == "int"):
             ameta = Metadata(metafile="%s/atom_index_%s" %
                              (self.sdir, msplit[1]))
             ameta.write_data("%s_frac_coords" % ing_label,
                              mystr.sites[midx].frac_coords)
     return
Ejemplo n.º 2
0
 def make_coordinate_and_element_list_from_manifest(self,
                                                    manname,
                                                    ing_label=""):
     """
         Args:
             ing_label <str>: If blank, use orig_frac_coords.
                             Otherwise, use <ing_label>_frac_coords
     """
     if ing_label == "":
         ing_label = "original"
     coordlist = list()
     elemlist = list()
     mlist = list(self.read_manifest_file("%s/%s" % (self.sdir, manname)))
     for aidxline in mlist:
         aidxsplit = aidxline.split(";")
         aidx = aidxsplit[0]
         idxtorepl = ""
         if len(aidxsplit) > 1:
             idxtorepl = aidxsplit[1]
         ameta = Metadata(metafile="%s/atom_index_%s" % (self.sdir, aidx))
         if idxtorepl == "":
             frac_coords = ameta.read_data("%s_frac_coords" % ing_label)
             if frac_coords == None:
                 raise MASTError(
                     self.__class__.__name__,
                     "No coordinates for %s_frac_coords building from manifest %s/%s using atom index %s"
                     % (ing_label, self.sdir, manname, aidx))
         elif idxtorepl == "int":  #interstitial
             frac_coords = ameta.read_data("original_frac_coords")
             if frac_coords == None:
                 raise MASTError(
                     self.__class__.__name__,
                     "No coordinates for %s_frac_coords building from manifest %s/%s using atom index %s"
                     % (ing_label, self.sdir, manname, aidx))
         else:  #substitution
             replmeta = Metadata(metafile="%s/atom_index_%s" %
                                 (self.sdir, idxtorepl))
             frac_coords = replmeta.read_data("%s_frac_coords" % ing_label)
             if frac_coords == None:
                 raise MASTError(
                     self.__class__.__name__,
                     "No coordinates for %s_frac_coords building from manifest %s/%s using atom index %s for coordinates and atom index %s for element"
                     % (ing_label, self.sdir, manname, idxtorepl, aidx))
         frac_coords = frac_coords.split("[")[1]
         frac_coords = frac_coords.split("]")[0]
         frac_array = np.array(frac_coords.split(), 'float')
         elem = ameta.read_data("element")
         coordlist.append(frac_array)
         elemlist.append(elem)
     return [coordlist, elemlist]
Ejemplo n.º 3
0
    def make_temp_manifest_from_scrambled_structure(self, ingdir, mystr,
                                                    scrambledman):
        """Make a temporary manifest from a scrambled structure.
            Args:
                ingdir <str>: Ingredient directory (need scaling label)
                mystr <pymatgen Structure>: Scrambled structure that does not match a manifest
                scrambledman <str>: Scrambled manifest list that the structure does match
                namelabel <str>: Parent label of frac coords to find
            Returns:
                writes to scrambledman
        """
        mymeta = Metadata(metafile="%s/metadata.txt" % ingdir)
        scaling_label = mymeta.read_data("scaling_label")
        if scaling_label == None:
            scaling_label = ""

        scrambledlist = list()
        for site in mystr.sites:
            fidx = self.find_any_frac_coord_in_atom_indices(
                site.frac_coords, site.species_string, scaling_label, False,
                0.002)
            scrambledlist.append(fidx)

        self.write_manifest_file(scrambledlist, scrambledman)

        return
Ejemplo n.º 4
0
def main(ingname=""):
    """Get the U value from an ingredient.
        Args:
            ingname <str>: Ingredient name, full path
        Returns:
            <string>: "LDAUU, LDAUJ (eV);x x x, x x x", ex:
                "LDAUU, LDAUJ (eV); 0 5 0, 0 1 0"
    """
    trymeta = "%s/metadata.txt" % ingname
    frontstr = "LDAUU, LDAUJ (eV);"
    if os.path.isfile(trymeta):
        mymeta = Metadata(metafile=trymeta)
        myprogram = mymeta.read_data("program")
    else:
        myprogram = "None"
    if myprogram in ['vasp', 'vasp_neb']:
        if os.path.isdir("%s/01" % ingname):
            tryfile = "%s/01/OUTCAR" % ingname
        else:
            tryfile = "%s/OUTCAR" % ingname
        grepldauu = fileutil.grepme(tryfile, "LDAUU")
        if grepldauu == []:
            return "%s N/A" % frontstr
        ldauuparse = grepldauu[0].split("=")[1].strip()
        grepldauj = fileutil.grepme(tryfile, "LDAUJ")
        ldaujparse = grepldauj[0].split("=")[1].strip()
        return "%s %s, %s" % (frontstr, ldauuparse, ldaujparse)
    else:
        return "%s N/A" % frontstr
Ejemplo n.º 5
0
def main(ingname=""):
    """Get the last pressure value from an ingredient.
        Args:
            ingname <str>: Ingredient name, full path
        Returns:
            <string>: "Last pressure (kbar);0.00", ex:
                "Last pressure (kbar);-23.55"
    """
    trymeta = "%s/metadata.txt" % ingname
    frontstr = "Last pressure (kbar);"
    if os.path.isfile(trymeta):
        mymeta = Metadata(metafile=trymeta)
        myprogram = mymeta.read_data("program")
    else:
        myprogram = "None"
    if myprogram in ['vasp', 'vasp_neb']:
        if os.path.isdir("%s/01" % ingname):
            tryfile = "%s/01/OUTCAR" % ingname
        else:
            tryfile = "%s/OUTCAR" % ingname
        greppress = fileutil.grepme(tryfile, "external pressure")
        #"external pressure = -1.97 kB Pullay stress = 0.00 kB"
        if greppress == []:
            return "%s N/A" % frontstr
        mypress = greppress[-1].strip().split()[3]
        return "%s %s" % (frontstr, mypress)
    else:
        return "%s N/A" % frontstr
Ejemplo n.º 6
0
def main(ingname=""):
    """Get the last volume value from an ingredient.
        Args:
            ingname <str>: Ingredient name, full path
        Returns:
            <string>: "Last volume (Angstroms^3);0.000", ex:
                "Last volume (Angstroms^3); 324.456"
    """
    trymeta = "%s/metadata.txt" % ingname
    frontstr = "Last volume (Angstroms^3);"
    if os.path.isfile(trymeta):
        mymeta = Metadata(metafile=trymeta)
        myprogram = mymeta.read_data("program")
    else:
        myprogram = "None"
    if myprogram in ['vasp', 'vasp_neb']:
        if os.path.isdir("%s/01" % ingname):
            tryfile = "%s/01/OUTCAR" % ingname
        else:
            tryfile = "%s/OUTCAR" % ingname
        grepvol = fileutil.grepme(tryfile, "volume of cell")
        if grepvol == []:
            return "%s N/A" % frontstr
        myvol = grepvol[-1].split(":")[1].strip()
        return "%s %s" % (frontstr, myvol)
    else:
        return "%s N/A" % frontstr
Ejemplo n.º 7
0
 def guess_manifest_from_ingredient_metadata(self, ingdir, nebpc=0):
     """Guess the manifest name from the ingredient.
         Not for phonon manifests.
         Args:
             ingdir <str>: ingredient name, full path
             nebpc <int>: 0 for first endpoint (default)
                             1 for final endpoint
         Returns:
             manname <str>: manifest name guess; returns None if errors
     """
     mymeta = Metadata(metafile="%s/metadata.txt" % (ingdir))
     #phonon_label = mymeta.read_data("phonon_label")
     scaling_label = mymeta.read_data("scaling_label")
     neb_label = mymeta.read_data("neb_label")
     defect_label = mymeta.read_data("defect_label")
     if scaling_label == None:
         scaling_label = ""
     if defect_label == None:
         if neb_label == None:
             defect_label = ""
         else:
             if nebpc == 0:
                 defect_label = neb_label.split("-")[0].strip()
             else:
                 defect_label = neb_label.split("-")[1].strip()
     manname = "%s/manifest_%s_%s_%s" % (self.sdir, scaling_label,
                                         defect_label, neb_label)
     return manname
Ejemplo n.º 8
0
def main(ingname=""):
    """Get the last lattice from an ingredient.
        Args:
            ingname <str>: Ingredient name, full path
        Returns:
            <string>: "Last lattice (Angstroms);scale, a, b, c", ex:
                "Last lattice (Angstroms); scale 1, 4.01 0.2 0, 0 4.01 0, 
                        0.1 0.1 4.01"
    """
    trymeta = "%s/metadata.txt" % ingname
    frontstr = "Last lattice (Angstroms);"
    if os.path.isfile(trymeta):
        mymeta = Metadata(metafile=trymeta)
        myprogram = mymeta.read_data("program")
    else:
        myprogram = "None"
    if myprogram in ['vasp', 'vasp_neb']:
        if os.path.isdir("%s/01" % ingname):
            tryfile = "%s/01/CONTCAR" % ingname
        else:
            tryfile = "%s/CONTCAR" % ingname
        cfile = MASTFile(tryfile)
        if len(cfile.data) == 0:
            return "%s N/A" % frontstr
        scale = cfile.data[1].strip()
        avec = cfile.data[2].strip()
        bvec = cfile.data[3].strip()
        cvec = cfile.data[4].strip()
        return "%s scale %s, %s, %s, %s" % (frontstr, scale, avec, bvec, cvec)
    else:
        return "%s N/A" % frontstr
Ejemplo n.º 9
0
def main(ingname=""):
    """Get the energy from an ingredient.
        Args:
            ingname <str>: Ingredient name, full path
        Returns:
            <string>: "energy (eV);<energy as a string>", ex:
                "energy (eV); 3.0"
                Returns last E0 energy for a VASP run.
                Returns last E0 energy for all images for a VASP neb.
                Returns "N/A" otherwise.
    """
    trymeta = "%s/metadata.txt" % ingname
    if os.path.isfile(trymeta):
        mymeta = Metadata(metafile=trymeta)
        myprogram = mymeta.read_data("program")
    else:
        myprogram = "None"
    if 'induce' in ingname:  #skip inducedefect ingredients
        myprogram = "None"
    if 'vasp' in myprogram:
        if os.path.isdir("%s/01" % ingname):
            estr = "energies (eV)"
            for subdir in dirutil.immediate_subdirs(ingname):
                mychecker = VaspChecker(name="%s/%s" % (ingname, subdir))
                estr = estr + ";%3.3f" % mychecker.get_energy_from_energy_file(
                )
            return estr
        else:
            mychecker = VaspChecker(name=ingname)
            return "energy (eV);%3.3f" % mychecker.get_energy_from_energy_file(
            )
    else:
        return "energy (eV);N/A"
Ejemplo n.º 10
0
 def write_undefected_atom_indices(self):
     """Write undefected atom indices, including scaled indices.
         Also write an undefected manifest file.
     """
     scales = self.scaling.keys()
     scales.append("")
     for scaling_label in scales:
         if scaling_label == "":
             mySE = SE(struc_work1=self.startstr.copy())
             mystruc = mySE.keywords['struc_work1']
         else:
             mySE = SE(
                 struc_work1=self.startstr.copy(),
                 scaling_size=self.scaling[scaling_label]["mast_size"])
             mystruc = mySE.scale_structure()
         alist = list()
         manname = os.path.join(self.sdir, "manifest_%s__" % scaling_label)
         for site in mystruc:
             akey = self.get_new_key()
             aname = "atom_index_%s" % akey
             aname = os.path.join(self.sdir, aname)
             ameta = Metadata(metafile=aname)
             ameta.write_data("atom_index", akey)
             ameta.write_data("original_frac_coords", site.frac_coords)
             ameta.write_data("element", site.species_string)
             ameta.write_data("scaling_label", scaling_label)
             alist.append(akey)
         self.write_manifest_file(alist, manname)
     return
Ejemplo n.º 11
0
    def __init__(self, **kwargs):
        MASTObj.__init__(self, ALLOWED_KEYS, **kwargs)
        self.input_options = self.keywords['inputOptions']
        self.template_file = self.keywords['templateFile']
        self.personal_recipe = self.keywords['personalRecipe']
        self.ingredient_list = list()

        self.metafile = Metadata(metafile='%s/metadata.txt' %
                                 self.keywords['working_directory'])
        self.chunks = list()
Ejemplo n.º 12
0
    def __init__(self, **kwargs):
        MASTObj.__init__(self, ALLOWED_KEYS, **kwargs)
        self.recipe_file = self.keywords['recipeFile']
        self.input_options = self.keywords['inputOptions']
        self.structure = self.keywords['structure']
        self.work_dir = self.keywords['workingDirectory']
        self.logger = loggerutils.get_mast_logger("recipe setup %s" %
                                                  self.work_dir)

        self.metafile = Metadata(metafile='%s/metadata.txt' % self.work_dir)
        self.logger.debug(
            'Setting up the recipe based on the personal recipe contents passed in self.recipe_file'
        )
Ejemplo n.º 13
0
 def get_my_label(self, label):
     """Get the value of a label in the metadata file.
         Args:
             label <str>: Label to search for.
         Returns:
             <str>: Value of the label as a string, stripped.
     """
     myname = self.keywords['name']
     mymeta = Metadata(metafile=os.path.join(myname, "metadata.txt"))
     mylabel = mymeta.search_data(label)
     if mylabel == "":
         raise MASTError(self.__class__.__name__,
                         "No metadata for tag %s" % label)
     return mylabel[1]
Ejemplo n.º 14
0
 def get_sd_array(self, ing_label, multiple=False):
     """Get a selective dynamics array.
         Args:
             ing_label <str>: Ingredient name (fullpath)
             multiple <bool>: Multiple (T F F, F T F, etc. for each atom and direction) or 
                 single (T T T for all indicated atoms) array
     """
     mymeta = Metadata(metafile="%s/metadata.txt" % (ing_label))
     phonon_label = mymeta.read_data("phonon_label")
     scaling_label = mymeta.read_data("scaling_label")
     if scaling_label == None:
         scaling_label = ""
     nord_label = phonon_label.split("_")[0]
     if "-" in nord_label:
         neb_label = nord_label
         defect_label = neb_label.split('-')[0]  #always parse from first ep
     else:
         neb_label = ""
         defect_label = nord_label
     phonon_only_label = phonon_label.split("_")[-1]
     phononman = "%s/manifest_phonon_sd_%s_%s_%s" % (
         self.sdir, nord_label, phonon_only_label, scaling_label)
     structureman = "%s/manifest_%s_%s_%s" % (self.sdir, scaling_label,
                                              defect_label, neb_label)
     phononlist = self.read_manifest_file(phononman)
     structurelist = self.read_manifest_file(structureman)
     lensites = len(structurelist)
     if not multiple:
         mysd = np.zeros([lensites, 3], bool)
         for lidx in range(0, lensites):
             if structurelist[lidx] in phononlist:
                 mysd[lidx] = np.ones(3, bool)
         return mysd
     elif multiple:
         mysdlist = list()
         for lidx in range(0, lensites):
             for myct in range(0, 3):
                 mysd = np.zeros([lensites, 3], bool)
                 mysd[lidx] = np.zeros(3, bool)
                 if structurelist[lidx] in phononlist:
                     mysd[lidx][myct] = 1
                     mysdlist.append(mysd)
         return mysdlist
     return
Ejemplo n.º 15
0
    def parse_structure_section(self, section_name, section_content, options):
        """Parses the structure section and populate the options.
            Does not create the structure.

            Format is along the lines of:
                coord_type fractional

                begin coordinates
                Ga 0.000000 0.000000 0.000000
                Ga 0.500000 0.500000 0.000000
                Ga 0.000000 0.500000 0.500000
                Ga 0.500000 0.000000 0.500000
                As 0.250000 0.250000 0.250000
                As 0.750000 0.750000 0.250000
                As 0.250000 0.750000 0.750000
                As 0.750000 0.250000 0.750000
                end

                begin lattice
                2.0 0.0 0.0
                0.0 2.0 0.0
                0.0 0.0 2.0
                end

            Note that coord_type will default to "cartesian" if not specified.

        """
        # Initialize with default values
        structure_dict = STRUCTURE_KEYWORDS.copy()

        subsection_dict = dict()
        for myline in section_content:
            line = myline.split()

            if (line[0] in structure_dict):
                structure_dict[line[0]] = line[1]
            elif ('begin' in line[0]):
                subsection = line[1]
                subsection_list = list()
            elif ('end' not in line):
                lsplit = myline.split()
                lineval = list()
                for lval in lsplit:
                    lval.strip()
                    if len(lval) > 0:
                        lineval.append(lval)
                subsection_list.append(lineval)
            elif ('end' in line):
                subsection_dict[subsection] = subsection_list

        # GRJ: Since we lowercase the whole input file, and filenames may not
        # conform to this, we examine the current directory for any files that
        # may match and use that.  If there are multiple matches, we'll throw
        # an error.
        if (structure_dict['posfile']
                is not None):  # Do we have a geometry file?
            # TTM for issue #423
            posfiletry = os.path.join(os.getcwd(), structure_dict['posfile'])
            if os.path.isfile(posfiletry):
                self.logger.info("Using posfile %s in directory %s" %
                                 (structure_dict['posfile'], os.getcwd()))
            else:
                # First build a list of likely files
                origindir = os.path.dirname(self.keywords['inputfile'])
                if origindir == "":
                    origindir = os.getcwd()
                metatry = os.path.join(os.getcwd(), 'metadata.txt')
                if os.path.isfile(metatry):
                    myrecipemeta = Metadata(metafile=metatry)
                    origindir = myrecipemeta.search_data('origin_dir')[1]
                myfiles = dirutil.walkfiles(origindir)
                file_list = list()
                for myfile in myfiles:
                    if structure_dict['posfile'] in myfile:
                        file_list.append(myfile)
                if (len(file_list) > 1):
                    # If we have multiple files with the same name, but different capitalization, throw an error here
                    self.logger.warning(
                        'Found multiple files with the name %s' %
                        structure_dict['posfile'])
                    self.logger.warning('Found the files:')
                    for file in file_list:
                        self.logger.warning(file)
                    error = 'Found ambiguous file names'
                    raise MASTError(self.__class__.__name__, error)
                elif len(file_list) == 0:
                    raise MASTError(
                        self.__class__.__name__,
                        "No structure file %s found in %s" %
                        (structure_dict['posfile'], origindir))
                else:
                    structure_dict['posfile'] = file_list[0]
        # print 'in InputParser.parse_structure_section:', subsection_dict
        # TM
        element_map = dict()
        atom_list = list()
        for key, value in subsection_dict.items():
            if (key == 'coordinates'):
                value = np.array(value)
                # Here we use .title() to re-capitalize the first letter of all
                # the atomic symbols to comply with what
                # pymatgen needs
                atom_list = [val.title() for val in value[:, 0]]
                structure_dict['atom_list'] = atom_list
                coordinates = np.array(value[:, 1:], dtype='float')
                structure_dict['coordinates'] = coordinates
            if (key == 'lattice'):
                #print "VALUE: ", value
                lattice = np.array(value, dtype='float')
                structure_dict['lattice'] = lattice
            if (key == 'elementmap'):
                for elline in value:
                    elkey = elline[0].strip().upper()  #all caps
                    elname = elline[1].strip().title()  #Title case
                    element_map[elkey] = elname
                structure_dict['element_map'] = element_map
        if len(element_map) > 0 and len(atom_list) > 0:
            new_atom_list = list()
            for atomval in atom_list:
                if atomval.upper() in element_map.keys():
                    new_atom_list.append(element_map[atomval])
                else:
                    new_atom_list.append(atomval)
            structure_dict['atom_list'] = new_atom_list

        for key, value in structure_dict.items():
            options.set_item(section_name, key, value)
Ejemplo n.º 16
0
    def write_defected_atom_indices(self):
        """Write any additional defect atom indices and make manifests.
        """
        defect_dict = self.input_options.get_item('defects', 'defects')
        if defect_dict == None:
            return None
        dlabels = defect_dict.keys()

        scales = self.scaling.keys()
        scales.append("")
        for scaling_label in scales:
            alist = list(
                self.read_manifest_file("%s/manifest_%s__" %
                                        (self.sdir, scaling_label)))
            if scaling_label == "":
                mySE = SE(struc_work1=self.startstr.copy())
            else:
                mySE = SE(
                    struc_work1=self.startstr.copy(),
                    scaling_size=self.scaling[scaling_label]["mast_size"])
            for dlabel in dlabels:
                dlist = list(alist)
                manname = os.path.join(
                    self.sdir, "manifest_%s_%s_" % (scaling_label, dlabel))
                dsubkeys = defect_dict[dlabel].keys()
                for dsubkey in dsubkeys:
                    if "subdefect_" in dsubkey:
                        dtype = defect_dict[dlabel][dsubkey]['type']
                        dcoords = defect_dict[dlabel][dsubkey]['coordinates']
                        delement = defect_dict[dlabel][dsubkey]['symbol']
                        if not (scaling_label == ""):
                            dcoords = mySE.get_scaled_coordinates(dcoords)
                        if dtype == "interstitial":
                            didx = self.find_orig_frac_coord_in_atom_indices(
                                dcoords, delement, scaling_label, False, 0.001)
                            if didx == None:
                                akey = self.get_new_key()
                                aname = "atom_index_%s" % akey
                                aname = os.path.join(self.sdir, aname)
                                ameta = Metadata(metafile=aname)
                                ameta.write_data("atom_index", akey)
                                ameta.write_data("original_frac_coords",
                                                 dcoords)
                                ameta.write_data("element", delement)
                                ameta.write_data("scaling_label",
                                                 scaling_label)
                                dlist.append("%s;int" %
                                             akey)  #interstitial label
                            else:
                                dlist.append("%s;int" % didx)
                        elif dtype == "vacancy":
                            didx = self.find_orig_frac_coord_in_atom_indices(
                                dcoords, delement, scaling_label, False, 0.001)
                            try:
                                dlist.remove(didx)
                            except ValueError:
                                raise MASTError(
                                    self.__class__.__name__,
                                    "For defect %s, cannot remove atom index %s from list: %s"
                                    % (dlabel, didx, dlist))
                        elif dtype in ["substitution", "antisite"]:
                            didxlist = self.find_orig_frac_coord_in_atom_indices(
                                dcoords, "", scaling_label, True, 0.001
                            )  #leave element empty; just search coords
                            idxtorepl = list()
                            for didx in didxlist:
                                dmeta = Metadata(metafile="%s/atom_index_%s" %
                                                 (self.sdir, didx))
                                dmetaelem = dmeta.read_data("element")
                                if not (delement == dmetaelem):
                                    if didx in dlist:
                                        dlist.remove(didx)
                                        idxtorepl.append(didx)
                            if len(idxtorepl) > 1:
                                raise MASTError(
                                    self.__class__.__name__,
                                    "Interstitial %s is attempting to replace more than one atom: %s"
                                    % (dlabel, idxtorepl))
                            didxsub = self.find_orig_frac_coord_in_atom_indices(
                                dcoords, delement, scaling_label, False, 0.001
                            )  #leave element empty; just search coords
                            if didxsub == None:
                                akey = self.get_new_key()
                                aname = "atom_index_%s" % akey
                                aname = os.path.join(self.sdir, aname)
                                ameta = Metadata(metafile=aname)
                                ameta.write_data("atom_index", akey)
                                ameta.write_data("original_frac_coords",
                                                 dcoords)
                                ameta.write_data("element",
                                                 delement)  #sub element here
                                ameta.write_data("scaling_label",
                                                 scaling_label)
                                dlist.append("%s;%s" % (akey, idxtorepl[0]))
                            else:
                                dlist.append("%s;%s" % (didxsub, idxtorepl[0]))
                self.write_manifest_file(dlist, manname)
        return
Ejemplo n.º 17
0
 def find_any_frac_coord_in_atom_indices(self,
                                         coord,
                                         element="",
                                         scaling_label="",
                                         find_multiple=False,
                                         tol=0.0001):
     """Find the atomic index of any FRACTIONAL coordinate in the 
         structure dictionary.
         Args:
             coord <numpy array of float>: coordinate to find
             element <str>: element symbol to match
                             If blank, matches any element.
             scaling_label <str>: scaling label
                                 If blank, must match NO scaling (blank)
             find_multiple <boolean>: allow multiple matches. Default False.
             tol <float>: tolerance
         Returns:
             atomic index <hex string>: atomic index of match, 
                 if find_multiple is false
             list of atomic indices of matches, if find_multiple is true
             Returns None if no match is found
     """
     import glob
     matchstring = "%s/atom_index_*" % self.sdir
     idxnames = glob.glob(matchstring)
     rtol = tol * 100
     coord_matches = list()
     elem_matches = list()
     scaling_matches = list()
     namelist = list()
     allfolders = immediate_subdirs(os.path.dirname(self.sdir))  #ing dirs
     for folder in allfolders:
         namelist.append("%s_frac_coords" % folder)
     for nametofind in namelist:
         for aname in idxnames:
             ameta = Metadata(metafile=aname)
             aidx = ameta.read_data("atom_index")
             atom_ofc = ameta.read_data(nametofind)
             if atom_ofc == None:
                 continue
             if ";" in atom_ofc:
                 atom_ofc = atom_ofc.split(
                     ';')[-1].strip()  # get most updated
             atom_ofc_arr = np.array(atom_ofc[1:-1].split(), 'float')
             if np.allclose(atom_ofc_arr, coord, rtol, tol):
                 coord_matches.append(aidx)
     if element == "":
         elem_matches = list(coord_matches)
     else:
         for aidx in coord_matches:
             ameta = Metadata(metafile="%s/atom_index_%s" %
                              (self.sdir, aidx))
             atom_elem = ameta.read_data("element")
             if (element == atom_elem):
                 elem_matches.append(aidx)
     for aidx in elem_matches:
         ameta = Metadata(metafile="%s/atom_index_%s" % (self.sdir, aidx))
         ascale = ameta.read_data("scaling_label")
         if (scaling_label == ascale):
             scaling_matches.append(aidx)
     allmatches = list(scaling_matches)
     allmatches = list(set(allmatches))  # get unique values
     if len(allmatches) == 0:
         return None
     if len(allmatches) > 1:
         if not find_multiple:
             raise MASTError(
                 self.__class__.__name__,
                 "Multiple matches found for coordinate %s: %s" %
                 (coord, allmatches))
         else:
             return allmatches
     if len(allmatches) == 1:
         if not find_multiple:
             return allmatches[0]
         else:
             return allmatches
     return None
Ejemplo n.º 18
0
    def __init__(self, allowed_keys, **kwargs):
        allowed_keys_base = dict()
        allowed_keys_base.update(allowed_keys)
        MASTObj.__init__(self, allowed_keys_base, **kwargs)

        work_dir = '/'.join(self.keywords['name'].split('/')[:-1])
        topmeta = Metadata(metafile='%s/metadata.txt' % work_dir)
        data = topmeta.read_data(self.keywords['name'].split('/')[-1])

        self.meta_dict = dict()
        if data:
            for datum in data.split(';'):
                self.meta_dict[datum.split(':')[0]] = datum.split(
                    ':')[1].strip()

        self.metafile = Metadata(metafile='%s/metadata.txt' %
                                 self.keywords['name'])

        self.program = self.keywords['program_keys']['mast_program'].lower()

        self.logger = loggerutils.get_mast_logger(self.keywords['name'])

        sdir = os.path.join(os.path.dirname(self.keywords['name']),
                            "structure_index_files")
        if os.path.exists(sdir):
            self.atomindex = AtomIndex(structure_index_directory=sdir)
        else:
            self.atomindex = None

        if self.program == 'vasp':
            self.checker = VaspChecker(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
            self.errhandler = VaspError(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
        elif self.program == 'vasp_neb':
            self.checker = VaspNEBChecker(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
            self.errhandler = VaspNEBError(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
        elif self.program == 'phon':
            self.checker = PhonChecker(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
            self.errhandler = PhonError(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
        elif self.program == 'lammps':
            self.checker = LammpsChecker(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
            self.errhandler = GenericError(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
        elif self.program == 'structopt':
            self.checker = StructoptChecker(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
            self.errhandler = GenericError(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
        else:
            allowed_keys = {'name', 'program_keys', 'structure'}
            self.checker = GenericChecker(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
            self.errhandler = GenericError(
                name=self.keywords['name'],
                program_keys=self.keywords['program_keys'],
                structure=self.keywords['structure'])
Ejemplo n.º 19
0
    def calculate_single_defect_formation_energy(self, mylabel, conditions,
                                                 potentials):
        """Calculate one defect formation energy.
            Args:
                mylabel <str>: Defect label
                conditions <str>: Environment condition, e.g. "As-rich"
                potentials <dict of float>: Dictionary of chemical potentials,
                    e.g.:
                    potentials['As']=-6.0383
                    potentials['Ga']=-3.6080
                    potentials['Bi']=-4.5650
            Returns:
                <float>: Defect formation energy
        """
        pdir = self.dirs[mylabel]['perfect']
        ddir = self.dirs[mylabel]['defected']
        #Get perfect data
        perf_meta = Metadata(metafile='%s/%s/metadata.txt' %
                             (self.recdir, pdir))
        e_perf = self.get_total_energy(pdir)
        #e_perf = float(perf_meta.read_data('energy').split(',')[-1]) #Sometimes the energy is listed more than once.
        efermi = self.get_fermi_energy(pdir)
        struct_perf = self.get_structure(pdir)
        perf_species = dict()
        for site in struct_perf:
            if (str(site.specie) not in perf_species):
                perf_species[str(site.specie)] = 1
            else:
                perf_species[str(site.specie)] += 1

        #print 'Perfect composition: ', perf_species

        #Get defected data
        def_meta = Metadata(metafile='%s/%s/metadata.txt' %
                            (self.recdir, ddir))
        #print def_meta
        label = def_meta.read_data('defect_label')
        charge = int(def_meta.read_data('charge'))
        energy = self.get_total_energy(ddir)
        #energy = float(def_meta.read_data('energy').split(',')[-1])
        structure = self.get_structure(ddir)
        if (label not in self.e_defects[conditions]):
            self.e_defects[conditions][label] = list()
        print 'Calculating DFEs for defect %s with charge %3i.' % (label,
                                                                   charge)
        def_species = dict()
        for site in structure.sites:
            if (site.specie not in def_species):
                def_species[site.specie] = 1
            else:
                def_species[site.specie] += 1

        # Find the differences in the number of each atom type
        # between the perfect and the defect
        struct_diff = dict()
        for specie, number in def_species.items():
            try:
                nperf = perf_species[str(specie)]
            except KeyError:
                nperf = 0
            struct_diff[str(specie)] = number - nperf

        # Get the potential alignment correction
        alignment = self.get_potential_alignment(pdir, ddir)

        # Calculate the base DFE energy
        e_def = energy - e_perf  # E_defect - E_perf
        print "TTM DEBUG: e_def: ", e_def
        for specie, number in struct_diff.items():
            mu = potentials[str(specie)]
            #print str(specie), mu, number
            e_def -= (number * mu)
            print "TTM DEBUG: number: ", number
            print "TTM DEBUG: mu: ", mu
            print "TTM DEBUG: e_def -= number*mu: ", e_def
        print "TTM DEBUG: charge: ", charge
        print "TTM DEBUG: alignment: ", alignment
        print "TTM DEBUG: efermi: ", efermi
        e_def += charge * (efermi + alignment)  # Add in the shift here!
        print "TTM DEBUG: e_def += charge*(efermi + alignment): ", e_def
        #print '%-15s%-5i%12.5f%12.5f%12.5f%12.5f' % (label.split('_')[1], charge, energy, e_perf, efermi, alignment)
        print 'DFE = %f' % e_def
        self.e_defects[conditions][label].append((charge, e_def))
        return
Ejemplo n.º 20
0
    def parse_ingredients_section(self, section_name, section_content,
                                  options):
        """Parses the ingredients section and populates the options.
            Section takes the form of:
                $ingredients
                begin ingredients_global
                mast_kpoints 3x3x3
                mast_xc pbe
                end

                begin singlepoint
                encut 400
                end

                begin optimize
                encut 300
                ibrion 2
                end

                $end

            mast_kpoints are parsed out as a 3 index list of integers. 
            Everything else is parsed out as a string.

            Anything in ingredients_global is then appended onto each 
            individual ingredient.
        """

        global_dict = dict()
        ingredients_dict = dict()

        for line in section_content:
            if (line.startswith('begin')):
                # Each ingredient section starts with "begin".
                # Check for this line, and initialize the individual
                # ingredient dictionary
                ingredient_name = line.split()[1]
                ingredient_dict = dict()
            elif (not (line == 'end')):
                opt = line.split()
                # print opt
                if (opt[0] == 'mast_kpoints'):
                    try:
                        kpts = map(int, opt[1].split('x'))
                        if len(opt) > 2:
                            kpts.append(opt[2])
                    except ValueError:
                        kpts = opt[1:]
                    # Second option after mast_kpoints tells where to
                    # center the k-point mesh.
                    # If it's there, we append it onto the k-point grid list.
                    ingredient_dict[opt[0]] = kpts
                elif (opt[0] == 'mast_pp_setup'):
                    psp_dict = dict()
                    for key in opt[1:]:
                        key = key.split('=')
                        ref = key[0].title()
                        val = str().join(key[1][0].upper() + key[1][1:])
                        psp_dict[ref] = val
                    ingredient_dict[opt[0]] = psp_dict
                #elif (opt[0] == 'mast_exec'):
                #    ingredient_dict[opt[0]] = ' '.join(opt[1:]) #preserve whole line
                #elif (opt[0] == 'mast_strain'):
                #    ingredient_dict[opt[0]] = ' '.join(opt[1:]) #preserve whole line
                #elif (opt[0] == 'ptemp'):
                #    ingredient_dict[opt[0]] = ' '.join(opt[1:]) #preserve whole line
                #elif (opt[0] == 'rwigs'):
                #    ingredient_dict[opt[0]] = ' '.join(opt[1:]) #preserve whole line
                #elif (opt[0] == 'mast_setmagmom'):
                #    ingredient_dict[opt[0]] = ' '.join(opt[1:]) #preserve whole line
                elif (opt[0] == 'mast_coordinates'):
                    shortsplit = opt[1].split(",")
                    filesplit = list()
                    origindir = os.getcwd()
                    metatry = os.path.join(os.getcwd(), 'metadata.txt')
                    if os.path.isfile(metatry):
                        myrecipemeta = Metadata(metafile=metatry)
                        origindir = myrecipemeta.search_data('origin_dir')[1]
                    myfiles = dirutil.walkfiles(origindir)
                    for shortname in shortsplit:
                        for fullfile in myfiles:
                            if shortname.strip() in os.path.basename(fullfile):
                                filesplit.append(fullfile)
                    if not (len(filesplit) == len(shortsplit)):
                        raise MASTError(
                            self.__class__.__name__,
                            "Not all files given by %s were found in %s." %
                            (shortsplit, origindir))
                    ingredient_dict[opt[0]] = filesplit
                else:
                    ingredient_dict[opt[0]] = ' '.join(
                        opt[1:])  #preserve whole line
                    #ingredient_dict[opt[0]] = opt[1] #old behavior took only the first part
                if (opt[0] == 'mast_program') and (opt[1] == 'vasp'
                                                   or opt[1] == 'vasp_neb'):
                    if os.getenv('VASP_PSP_DIR') == None:
                        raise MASTError(
                            self.__class__.__name__,
                            "Input file specifies program vasp, but no POTCAR directory is set in environment variable VASP_PSP_DIR"
                        )
            elif ('end' in line):
                # Each ingredient section ends with "end", if present finish
                # that current section and assign
                # the neccessary element in the ingredients dictionary and
                # create the global dictionary
                if (ingredient_name == 'ingredients_global'):
                    global_dict = ingredient_dict
                else:
                    ingredients_dict[ingredient_name] = ingredient_dict

        # Each value in ingredients_dict is a dictionary containing the relevant
        # ingredient and option(s).
        for ing_key, ing_value in ingredients_dict.items():
            options.set_item(section_name, ing_key, ing_value)

        options.set_item(section_name, 'global', global_dict)
Ejemplo n.º 21
0
    def _calculate_defect_formation_energies(self, scsize):
        perf_dirs = []
        ingredients = self.recipe_plan.ingredients.keys()
        for i in range(len(ingredients)):
            if 'perfect' in ingredients[i]:
                perf_dirs.append(ingredients[i])
        if len(perf_dirs) == 0:
            raise MASTError(
                self.__class__.__name__,
                "A perfect final directory (has no children and has the word 'perfect' in its name) could not be found. Check recipe %s for a perfect directory."
                % self.directory)

        def_dir = ru.read_recipe(
            self.input_options.get_item(
                "personal_recipe",
                "personal_recipe_list"))[1]['madelung_utility']
        defects = self.input_options.get_item('defects', 'defects')
        chempot = self.input_options.get_item('chemical_potentials')
        for i in range(len(perf_dirs)):
            perf_meta = Metadata(metafile='%s/%s/metadata.txt' %
                                 (self.directory, perf_dirs[i]))
            if scsize == perf_meta.read_data('scaling_size'):
                perf_dir = perf_dirs[i]

        perfpath = os.path.join(self.directory, perf_dir)
        if os.path.isfile(os.path.join(perfpath, "vasprun.xml")):
            e_perf = pmg.io.vaspio.vasp_output.Vasprun(
                os.path.join(perfpath, "vasprun.xml")).final_energy
        else:
            e_perf = float(
                open(os.path.join(
                    perfpath,
                    "OSZICAR")).readlines()[-1].split('E0=')[1].split()[0])
        efermi = self.get_fermi_energy(perf_dir)
        struct_perf = self.get_structure(perf_dir)

        perf_species = dict()
        for site in struct_perf:
            if (str(site.specie) not in perf_species):
                perf_species[str(site.specie)] = 1
            else:
                perf_species[str(site.specie)] += 1

        #print 'Perfect composition: ', perf_species
        #First Loop through the conditions for the defects
        for conditions, potentials in chempot.items():
            self.e_defects[conditions] = dict()
            # Loop through each defect
            for ddir in sorted(def_dir):
                def_meta = Metadata(metafile='%s/%s/metadata.txt' %
                                    (self.directory, ddir))
                if scsize == def_meta.read_data('scaling_size'):
                    label = def_meta.read_data(
                        'defect_label') + '_q=' + def_meta.read_data('charge')
                    charge = int(def_meta.read_data('charge'))
                    if os.path.isfile(
                            os.path.join(self.directory, ddir, "vasprun.xml")):
                        energy = pmg.io.vaspio.vasp_output.Vasprun(
                            self.directory + '/' + ddir +
                            '/vasprun.xml').final_energy
                    else:
                        energy = float(
                            open(self.directory + '/' + ddir +
                                 '/OSZICAR').readlines()[-1].split('E0=')
                            [1].split()[0])
                    structure = self.get_structure(ddir)
                    #if (label not in self.e_defects[conditions]):
                    #    self.e_defects[conditions][label] = list()
                    # Find out how many atoms of each type are in the defects
                    def_species = dict()
                    for site in structure.sites:
                        if (site.specie not in def_species):
                            def_species[site.specie] = 1
                        else:
                            def_species[site.specie] += 1
                    # Find the differences in the number of each atom type
                    # between the perfect and the defect
                    struct_diff = dict()
                    for specie, number in def_species.items():
                        try:
                            nperf = perf_species[str(specie)]
                        except KeyError:
                            nperf = 0
                        struct_diff[str(specie)] = number - nperf

                    # Get the potential alignment correction
                    alignment = self.get_potential_alignment(perf_dir, ddir)
                    # Calculate the base DFE energy
                    e_def = energy - e_perf  # E_defect - E_perf
                    for specie, number in struct_diff.items():
                        mu = potentials[str(specie)]
                        e_def -= (number * mu)
                    e_def += charge * (efermi + alignment
                                       )  # Add in the shift here!
                    #print '%-15s%-5i%12.5f%12.5f%12.5f%12.5f' % (label.split('_')[1], charge, energy, e_perf, efermi, alignment)
                    #print 'DFE = %f' % e_def
                    self.e_defects[conditions][label] = e_def