示例#1
0
    def add_snl(self, snl, force_new=False, snlgroup_guess=None):
        try:
            self.lock_db()
            snl_id = self._get_next_snl_id()

            spstruc = snl.structure.copy()
            spstruc.remove_oxidation_states()
            sf = SymmetryFinder(spstruc, SPACEGROUP_TOLERANCE)
            sf.get_spacegroup()
            sgnum = sf.get_spacegroup_number() if sf.get_spacegroup_number() \
                else -1
            sgsym = sf.get_spacegroup_symbol() if sf.get_spacegroup_symbol() \
                else 'unknown'
            sghall = sf.get_hall() if sf.get_hall() else 'unknown'
            sgxtal = sf.get_crystal_system() if sf.get_crystal_system() \
                else 'unknown'
            sglatt = sf.get_lattice_type() if sf.get_lattice_type() else 'unknown'
            sgpoint = unicode(sf.get_point_group(), errors="ignore")

            mpsnl = MPStructureNL.from_snl(snl, snl_id, sgnum, sgsym, sghall,
                                           sgxtal, sglatt, sgpoint)
            snlgroup, add_new, spec_group = self.add_mpsnl(mpsnl, force_new, snlgroup_guess)
            self.release_lock()
            return mpsnl, snlgroup.snlgroup_id, spec_group
        except:
            self.release_lock()
            traceback.print_exc()
            raise ValueError("Error while adding SNL!")
示例#2
0
    def add_snl(self, snl, force_new=False, snlgroup_guess=None):
        try:
            self.lock_db()
            snl_id = self._get_next_snl_id()

            spstruc = snl.structure.copy()
            spstruc.remove_oxidation_states()
            sf = SymmetryFinder(spstruc, SPACEGROUP_TOLERANCE)
            sf.get_spacegroup()
            sgnum = sf.get_spacegroup_number() if sf.get_spacegroup_number() \
                else -1
            sgsym = sf.get_spacegroup_symbol() if sf.get_spacegroup_symbol() \
                else 'unknown'
            sghall = sf.get_hall() if sf.get_hall() else 'unknown'
            sgxtal = sf.get_crystal_system() if sf.get_crystal_system() \
                else 'unknown'
            sglatt = sf.get_lattice_type() if sf.get_lattice_type(
            ) else 'unknown'
            sgpoint = unicode(sf.get_point_group(), errors="ignore")

            mpsnl = MPStructureNL.from_snl(snl, snl_id, sgnum, sgsym, sghall,
                                           sgxtal, sglatt, sgpoint)
            snlgroup, add_new, spec_group = self.add_mpsnl(
                mpsnl, force_new, snlgroup_guess)
            self.release_lock()
            return mpsnl, snlgroup.snlgroup_id, spec_group
        except:
            self.release_lock()
            traceback.print_exc()
            raise ValueError("Error while adding SNL!")
示例#3
0
文件: db_manip.py 项目: muhrin/SPLpy
def _generate_entry(structure, params, name, energy, pressure):
    comp = structure.composition
    entry = {"structure": structure.to_dict, "name": name, "energy": energy, "energy_per_site": energy / comp.num_atoms,
             "pressure": pressure, "potential": {"name": "lennard_jones", "params": params.to_dict}}

    # Set the composition and formulas for the system
    el_amt = comp.get_el_amt_dict()
    entry.update({"unit_cell_formula": comp.to_dict,
                  "reduced_cell_formula": comp.to_reduced_dict,
                  "elements": list(el_amt.keys()),
                  "nelements": len(el_amt),
                  "pretty_formula": comp.reduced_formula,
                  "anonymous_formula": comp.anonymized_formula,
                  "nsites": comp.num_atoms,
                  "chemsys": "-".join(sorted(el_amt.keys()))})

    # Figure out the symmetry group
    sg = SymmetryFinder(structure, normalised_symmetry_precision(structure), -1)
    entry["spacegroup"] = {"symbol": unicode(sg.get_spacegroup_symbol(), errors="ignore"),
                           "number": sg.get_spacegroup_number(),
                           "point_group": unicode(sg.get_point_group(), errors="ignore"),
                           "source": "spglib",
                           "crystal_system": sg.get_crystal_system(),
                           "hall": sg.get_hall()}

    return entry
    def test_apply_transformation(self):
        trans = MagOrderingTransformation({"Fe": 5})
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR.LiFePO4'),
                             check_for_POTCAR=False)
        s = p.structure
        alls = trans.apply_transformation(s, 10)
        self.assertEqual(len(alls), 3)
        f = SymmetryFinder(alls[0]["structure"], 0.1)
        self.assertEqual(f.get_spacegroup_number(), 31)

        model = IsingModel(5, 5)
        trans = MagOrderingTransformation({"Fe": 5},
                                          energy_model=model)
        alls2 = trans.apply_transformation(s, 10)
        #Ising model with +J penalizes similar neighbor magmom.
        self.assertNotEqual(alls[0]["structure"], alls2[0]["structure"])
        self.assertEqual(alls[0]["structure"], alls2[2]["structure"])

        from pymatgen.io.smartio import read_structure
        s = read_structure(os.path.join(test_dir, 'Li2O.cif'))
        #Li2O doesn't have magnetism of course, but this is to test the
        # enumeration.
        trans = MagOrderingTransformation({"Li+": 1}, max_cell_size=3)
        alls = trans.apply_transformation(s, 100)
        self.assertEqual(len(alls), 10)
示例#5
0
    def process_res(cls, resfile):
        fullpath = os.path.abspath(resfile)
        res = Res.from_file(resfile)
        d = res.to_dict
        d["file_name"] = fullpath

        s = res.structure
        # Set the composition and formulas for the system
        comp = s.composition
        el_amt = s.composition.get_el_amt_dict()
        d.update({"unit_cell_formula": comp.to_dict,
                  "reduced_cell_formula": comp.to_reduced_dict,
                  "elements": list(el_amt.keys()),
                  "nelements": len(el_amt),
                  "pretty_formula": comp.reduced_formula,
                  "anonymous_formula": comp.anonymized_formula,
                  "nsites": comp.num_atoms,
                  "chemsys": "-".join(sorted(el_amt.keys()))})
        #d["density"] = s.density

        # Figure out the symmetry group
        sg = SymmetryFinder(s, util.normalised_symmetry_precision(s), -1)
        d["spacegroup"] = {"symbol": unicode(sg.get_spacegroup_symbol(),
                                             errors="ignore"),
                           "number": sg.get_spacegroup_number(),
                           "point_group": unicode(sg.get_point_group(),
                                                  errors="ignore"),
                           "source": "spglib",
                           "crystal_system": sg.get_crystal_system(),
                           "hall": sg.get_hall()}

        return d
示例#6
0
    def __init__(self, structures, spacegroup, symm_prec=0.1):
        """
        Args:
            structures:
                Sequence of structures to test.
            spacegroup:
                A spacegroup to test the structures.
            symm_prec:
                The symmetry precision to test with.
        """
        structure_symm = {}
        self.symm_prec = symm_prec
        self.spacegroup = spacegroup
        logger.debug("Computing spacegroups...")
        for i, s in enumerate(structures):
            finder = SymmetryFinder(s, symm_prec)
            structure_symm[s] = finder.get_spacegroup_number()
            logger.debug("Structure {} has spacegroup {}"
                         .format(i, structure_symm[s]))

        sorted_structures = sorted(structures,
                                   key=lambda s: -structure_symm[s])
        unique_groups = []
        for i, group in itertools.groupby(sorted_structures,
                                          key=lambda s: structure_symm[s]):
            logger.debug("Processing group of structures with sg number {}"
                         .format(i))
            subgroups = self._fit_group(group)
            unique_groups.extend(subgroups)
        self.unique_groups = unique_groups
示例#7
0
def get_primitive(fname):
    poscar = Poscar.from_file(fname)

    finder = SymmetryFinder(poscar.structure)
    spg_num = finder.get_spacegroup_number()

    primitive = finder.get_primitive_standard_structure()
    return spg_num, primitive
示例#8
0
    def add_snl(self, snl, force_new=False, snlgroup_guess=None):
        snl_id = self._get_next_snl_id()
        sf = SymmetryFinder(snl.structure, SPACEGROUP_TOLERANCE)
        sf.get_spacegroup()
        sgnum = sf.get_spacegroup_number() if sf.get_spacegroup_number() \
            else -1
        sgsym = sf.get_spacegroup_symbol() if sf.get_spacegroup_symbol() \
            else 'unknown'
        sghall = sf.get_hall() if sf.get_hall() else 'unknown'
        sgxtal = sf.get_crystal_system() if sf.get_crystal_system() \
            else 'unknown'
        sglatt = sf.get_lattice_type() if sf.get_lattice_type() else 'unknown'
        sgpoint = unicode(sf.get_point_group(), errors="ignore")

        mpsnl = MPStructureNL.from_snl(snl, snl_id, sgnum, sgsym, sghall,
                                       sgxtal, sglatt, sgpoint)
        snlgroup, add_new = self.add_mpsnl(mpsnl, force_new, snlgroup_guess)
        return mpsnl, snlgroup.snlgroup_id
示例#9
0
    def add_snl(self, snl, force_new=False, snlgroup_guess=None):
        snl_id = self._get_next_snl_id()
        sf = SymmetryFinder(snl.structure, SPACEGROUP_TOLERANCE)
        sf.get_spacegroup()
        sgnum = sf.get_spacegroup_number() if sf.get_spacegroup_number() \
            else -1
        sgsym = sf.get_spacegroup_symbol() if sf.get_spacegroup_symbol() \
            else 'unknown'
        sghall = sf.get_hall() if sf.get_hall() else 'unknown'
        sgxtal = sf.get_crystal_system() if sf.get_crystal_system() \
            else 'unknown'
        sglatt = sf.get_lattice_type() if sf.get_lattice_type() else 'unknown'
        sgpoint = unicode(sf.get_point_group(), errors="ignore")

        mpsnl = MPStructureNL.from_snl(snl, snl_id, sgnum, sgsym, sghall,
                                       sgxtal, sglatt, sgpoint)
        snlgroup, add_new = self.add_mpsnl(mpsnl, force_new, snlgroup_guess)
        return mpsnl, snlgroup.snlgroup_id
示例#10
0
 def add_snl(self, snl):
     snl_id = self._get_next_snl_id()
     sf = SymmetryFinder(snl.structure, SPACEGROUP_TOLERANCE)
     sf.get_spacegroup()
     mpsnl = MPStructureNL.from_snl(snl, snl_id, sf.get_spacegroup_number(),
                                    sf.get_spacegroup_symbol(), sf.get_hall(),
                                    sf.get_crystal_system(), sf.get_lattice_type())
     snlgroup, add_new = self.add_mpsnl(mpsnl)
     return mpsnl, snlgroup.snlgroup_id
    def get_structure_hash(self, structure):
        """
        Hash for structure.

        Args:
            structure: A structure

        Returns:
            Reduced formula for the structure is used as a hash for the
            SpeciesComparator.
        """
        f = SymmetryFinder(structure, 0.1)
        return "{} {}".format(f.get_spacegroup_number(), structure.composition.reduced_formula)
示例#12
0
    def get_structure_hash(self, structure):
        """
        Hash for structure.

        Args:
            structure: A structure

        Returns:
            Reduced formula for the structure is used as a hash for the
            SpeciesComparator.
        """
        f = SymmetryFinder(structure, 0.1)
        return "{} {}".format(f.get_spacegroup_number(),
                              structure.composition.reduced_formula)
示例#13
0
    def get_structure_hash(self, structure):
        """
        Hash for structure.

        Args:
            structure: A structure

        Returns:
            Reduced formula for the structure is used as a hash for the
            SpeciesComparator.
        """
        if not hasattr(structure, 'spacegroup'):
            sg = SymmetryFinder(structure, splpy.util.normalised_symmetry_precision(structure), -1)
            structure.spacegroup = {"symbol": unicode(sg.get_spacegroup_symbol(), errors="ignore"),
                                    "number": sg.get_spacegroup_number(),
                                    "point_group": unicode(sg.get_point_group(), errors="ignore"),
                                    "crystal_system": sg.get_crystal_system(),
                                    "hall": sg.get_hall()}

        return "{} {}".format(structure.spacegroup['number'], self._parent.get_structure_hash(structure))
示例#14
0
def produce(irreps):
    os.makedirs('irrep')
    for i, irrep in enumerate(irreps):
        poscar = Poscar(irrep)
        symbols = poscar.site_symbols
        natoms = poscar.natoms
        name_dict = {'Al': 'A', 'Ti': 'B'}
        tmp = ["{0}{1}".format(name_dict[x], y)
               for x, y in zip(symbols, natoms)]
        finder = SymmetryFinder(irrep)
        spg_num = finder.get_spacegroup_number()
        spg = "_".join(finder.get_spacegroup_symbol().split('/'))
        dirname = "No." + "{0:03d}".format(i) + "_" + spg + "_" + "".join(tmp)
        poscar.comment += "    (#" + str(spg_num) + ": " + spg + ")"

        standard = finder.get_conventional_standard_structure()
        stand_pos = Poscar(standard)
        stand_pos.comment += "    (#" + str(spg_num) + ": " + spg + ")"

        os.makedirs(os.path.join('irrep', dirname))
        poscar.write_file(os.path.join('irrep', dirname, 'POSCAR.prim'))
        stand_pos.write_file(os.path.join('irrep', dirname, 'POSCAR.std'))
    def test_apply_transformation(self):
        trans = MagOrderingTransformation({"Fe": 5})
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR.LiFePO4'),
                             check_for_POTCAR=False)
        s = p.structure
        alls = trans.apply_transformation(s, 10)
        self.assertEqual(len(alls), 3)
        f = SymmetryFinder(alls[0]["structure"], 0.1)
        self.assertEqual(f.get_spacegroup_number(), 31)

        model = IsingModel(5, 5)
        trans = MagOrderingTransformation({"Fe": 5}, energy_model=model)
        alls2 = trans.apply_transformation(s, 10)
        #Ising model with +J penalizes similar neighbor magmom.
        self.assertNotEqual(alls[0]["structure"], alls2[0]["structure"])
        self.assertEqual(alls[0]["structure"], alls2[2]["structure"])

        from pymatgen.io.smartio import read_structure
        s = read_structure(os.path.join(test_dir, 'Li2O.cif'))
        #Li2O doesn't have magnetism of course, but this is to test the
        # enumeration.
        trans = MagOrderingTransformation({"Li+": 1}, max_cell_size=3)
        alls = trans.apply_transformation(s, 100)
        self.assertEqual(len(alls), 10)
示例#16
0
precision = 0.01
same = 0
different = 0
for doc in structures.find({"prototype_id": {"$exists": True}, "spacegroup.number": {"$gt": 100}},
                           fields={"prototype_id": 1, "structure": 1}):
    proto_doc = prototypes.find({"_id": doc["prototype_id"]}, fields={"structure": 1, "wyckoff_sites": 1})[0]

    proto_pretidy = Structure.from_dict(proto_doc["structure"])
    sg = SymmetryFinder(proto_pretidy, precision, -1)
    proto = structure_tidy.structure_tidy(sg.get_primitive_standard_structure())
    sg_proto = SymmetryFinder(proto, precision, -1)
    proto_wyckoff = prototype.get_wyckoff_sites(sg_proto)

    str_pretidy = prototype.create_prototype(Structure.from_dict(doc["structure"]))
    sg = SymmetryFinder(str_pretidy, precision, -1)
    str = structure_tidy.structure_tidy(sg.get_primitive_standard_structure())
    sg_str = SymmetryFinder(str, precision, -1)
    str_wyckoff = prototype.get_wyckoff_sites(sg_str)
    # if str_wyckoff != proto_wyckoff:
    #     print("Wyckoff sites not equal!")
    #     print("proto: {}".format(proto_wyckoff))
    #     print("structure: {}".format(str_wyckoff))
    #     splpy.util.write_structures([proto, str], ['proto', 'str'])
    if str_wyckoff != proto_wyckoff:
        different += 1
        print("{} {}".format(str_wyckoff == proto_wyckoff, sg_str.get_spacegroup_number()))
    else:
        same += 1
    print("Same: {}, Different: {}, Percent: {}".format(same, different, float(different)/float(same+different)))
示例#17
0
    def _gen_input_file(self, working_dir):
        """
        Generate the necessary struct_enum.in file for enumlib. See enumlib
        documentation for details.
        """
        coord_format = "{:.6f} {:.6f} {:.6f}"

        # Using symmetry finder, get the symmetrically distinct sites.
        fitter = SymmetryFinder(self.structure, self.symm_prec)
        symmetrized_structure = fitter.get_symmetrized_structure()
        logger.debug("Spacegroup {} ({}) with {} distinct sites".format(
            fitter.get_spacegroup_symbol(),
            fitter.get_spacegroup_number(),
            len(symmetrized_structure.equivalent_sites))
        )

        """
        Enumlib doesn"t work when the number of species get too large. To
        simplify matters, we generate the input file only with disordered sites
        and exclude the ordered sites from the enumeration. The fact that
        different disordered sites with the exact same species may belong to
        different equivalent sites is dealt with by having determined the
        spacegroup earlier and labelling the species differently.
        """

        # index_species and index_amounts store mappings between the indices
        # used in the enum input file, and the actual species and amounts.
        index_species = []
        index_amounts = []

        #Let"s group and sort the sites by symmetry.
        site_symmetries = []
        for sites in symmetrized_structure.equivalent_sites:
            finder = SymmetryFinder(Structure.from_sites(sites),
                                    self.symm_prec)
            sgnum = finder.get_spacegroup_number()
            site_symmetries.append((sites, sgnum))

        site_symmetries = sorted(site_symmetries, key=lambda s: s[1])

        #Stores the ordered sites, which are not enumerated.
        min_sg_num = site_symmetries[0][1]
        ordered_sites = []
        disordered_sites = []
        coord_str = []
        min_disordered_sg = 300
        for (sites, sgnum) in site_symmetries:
            if sites[0].is_ordered:
                ordered_sites.append(sites)
            else:
                min_disordered_sg = min(min_disordered_sg, sgnum)
                sp_label = []
                species = {k: v for k, v in sites[0].species_and_occu.items()}
                if sum(species.values()) < 1 - EnumlibAdaptor.amount_tol:
                    #Let us first make add a dummy element for every single
                    #site whose total occupancies don't sum to 1.
                    species[DummySpecie("X")] = 1 - sum(species.values())
                for sp in species.keys():
                    if sp not in index_species:
                        index_species.append(sp)
                        sp_label.append(len(index_species) - 1)
                        index_amounts.append(species[sp] * len(sites))
                    else:
                        ind = index_species.index(sp)
                        sp_label.append(ind)
                        index_amounts[ind] += species[sp] * len(sites)
                sp_label = "/".join(["{}".format(i) for i in sorted(sp_label)])
                for site in sites:
                    coord_str.append("{} {}".format(
                        coord_format.format(*site.coords),
                        sp_label))
                disordered_sites.append(sites)

        #It could be that some of the ordered sites has a lower symmetry than
        #the disordered sites.  So we consider the lowest symmetry sites as
        #disordered in our enumeration.
        if min_disordered_sg > min_sg_num:
            logger.debug("Ordered sites have lower symmetry than disordered.")
            sites = ordered_sites.pop(0)
            index_species.append(sites[0].specie)
            index_amounts.append(len(sites))
            sp_label = len(index_species) - 1
            logger.debug("Lowest symmetry {} sites are included in enum."
                         .format(sites[0].specie))
            for site in sites:
                coord_str.append("{} {}".format(
                    coord_format.format(*site.coords),
                    sp_label))
            disordered_sites.append(sites)

        self.ordered_sites = []
        for sites in ordered_sites:
            self.ordered_sites.extend(sites)
        self.index_species = index_species

        lattice = self.structure.lattice

        output = [self.structure.formula, "bulk"]
        for vec in lattice.matrix:
            output.append(coord_format.format(*vec))
        output.append("{}".format(len(index_species)))
        output.append("{}".format(len(coord_str)))
        output.extend(coord_str)

        output.append("{} {}".format(self.min_cell_size, self.max_cell_size))
        output.append(str(self.enum_precision_parameter))
        output.append("partial")
        #To get a reasonable number of structures, we fix concentrations to the
        #range expected in the original structure.
        total_amounts = sum(index_amounts)
        for amt in index_amounts:
            conc = amt / total_amounts
            if abs(conc * 100 - round(conc * 100)) < 1e-5:
                output.append("{} {} {}".format(int(round(conc * 100)),
                                                int(round(conc * 100)), 100))
            else:
                min_conc = int(math.floor(conc * 100))
                output.append("{} {} {}".format(min_conc - 1, min_conc + 1,
                                                100))
        output.append("")
        logger.debug("Generated input file:\n{}".format("\n".join(output)))
        with open(os.path.join(working_dir, "struct_enum.in"), "w") as f:
            f.write("\n".join(output))
示例#18
0
 def get_sg_info(ss):
     finder = SymmetryFinder(Structure.from_sites(ss), self.symm_prec)
     sgnum = finder.get_spacegroup_number()
     return sgnum
示例#19
0
def inter_descript_gen(cif_file, collection, prune_args):
    """
    Generates the interstitial descriptor values for the structures 
    in input cif directory and store them into the database supplied
    Args:
        cif_file:
            cif File 
        collection:
            Mongo database collection
        prune_ars:
            List of keywords to prune the interstitials
            a) anion:
                Only the interstitial sites that can be occupied by the 
                anion are kept
            a) cation:
                Only the interstitial sites that can be occupied by the 
                smallest cation are kept
            c) [El, oxi_state]:
                Only the interstitial sites that can be occupied by the 
                input ion are kept
                Ex: ['Li', 1]
    """
    # Use the number as struct identifier
    # Store the remaining string as formula
    print cif_file
    dir, filen = os.path.split(cif_file)
    print filen
    name = os.path.splitext(filen)[0]
    item = name.split('--')
    key = item[0]
    inter_descript_dict = {'key': key, 'formula': ''.join(item[1].split())}
    FAIL = 0
    SUCC = 1

    #read the file to pymatgen struct
    try:
        struct = CifParser(cif_file).get_structures(False)[0]
    except:
        print 'reading ', cif_file, ' failed'
        return FAIL

    symm_finder = SymmetryFinder(struct)
    inter_descript_dict['structure'] = struct
    inter_descript_dict['crystal_system'] = symm_finder.get_crystal_system()
    inter_descript_dict['spacegroup_no'] = symm_finder.get_spacegroup_number()
    no_symmops = len(symm_finder.get_symmetry_operations())
    inter_descript_dict['no_symmops'] = no_symmops

    try:
        struct_val_rad = StructWithValenceIonicRadius(struct)
        valences = struct_val_rad.valences.values()
        valences.sort()
        anion_cation_charge_ratio = abs(valences[-1] / valences[0])
        radii = struct_val_rad.radii.values()
        radii.sort()
        anion_cation_radii_ratio = radii[-1] / radii[0]
    except:
        print inter_descript_dict['formula']
        print "Unable to identify radii and valences"
        return FAIL
    inter_descript_dict['charge_ratio'] = anion_cation_charge_ratio
    inter_descript_dict['radius_ratio'] = anion_cation_radii_ratio

    try:
        inter = Interstitial(struct_val_rad)
    except:
        print inter_descript_dict['formula']
        print 'interstitial not generated'
        return FAIL

    if prune_args[0] == "cation":
        inter.radius_prune_defectsites(
            radii[0])  #smallest element in the structure
    elif prune_args[0] == "anion":
        inter.radius_prune_defectsites(
            radii[-1])  #largest element in the structure
    else:
        el = prune_args[0]
        oxi_state = prune_args[1]
        inter.prune_defectsites(el, oxi_state)
    inter.prune_close_defectsites()

    if inter.defectsite_count() > 10:
        inter.reduce_defectsites()
    no_inter = inter.defectsite_count()
    inter_descript_dict['no_inter'] = no_inter
    #print >>sys.stderr, inter_descript_dict[key]['formula'], "No. of inter", no_inter

    #Create a list storing a dictionary of properties for each interstitial
    inter_list = []
    for i in range(no_inter):
        inter_dict = {}
        inter_dict['coord_no'] = inter.get_defectsite_coordination_number(i)
        inter_dict['coord_el'] = list(inter.get_coordinated_elements(i))
        inter_dict['radius'] = inter.get_radius(i)
        inter_dict['coord_chrg_sum'] = inter.get_coordsites_charge_sum(i)
        inter_list.append(inter_dict)
    inter_descript_dict['interstitials'] = inter_list
    descriptor_id = collection.insert(inter_descript_dict)
    return descriptor_id
示例#20
0
    def generate_doc(cls, dir_name, vasprun_files, parse_dos,
                     additional_fields):
        """Process aflow style and NEB runs."""
        print "TTM DEBUG: In generate_doc for NEB task drone."
        try:
            fullpath = os.path.abspath(dir_name)
            #Defensively copy the additional fields first.  This is a MUST.
            #Otherwise, parallel updates will see the same object and inserts
            #will be overridden!!
            d = {k: v for k, v in additional_fields.items()} \
                if additional_fields else {}
            d["dir_name"] = fullpath
            print "TTM DEBUG: fullpath: ", fullpath
            d["schema_version"] = NEBToDbTaskDrone.__version__
            d["calculations"] = [
                cls.process_vasprun(dir_name, taskname, filename, parse_dos)
                for taskname, filename in vasprun_files.items()]
            d1 = d["calculations"][0]
            d2 = d["calculations"][-1]

            #Now map some useful info to the root level.
            for root_key in ["completed_at", "nsites", "unit_cell_formula",
                             "reduced_cell_formula", "pretty_formula",
                             "elements", "nelements", "cif", "density",
                             "is_hubbard", "hubbards", "run_type"]:
                d[root_key] = d2[root_key]
            d["chemsys"] = "-".join(sorted(d2["elements"]))
            d["input"] = {"crystal": d1["input"]["crystal"]}
            vals = sorted(d2["reduced_cell_formula"].values())
            d["anonymous_formula"] = {string.ascii_uppercase[i]: float(vals[i])
                                      for i in xrange(len(vals))}
            d["output"] = {
                "crystal": d2["output"]["crystal"],
                "final_energy": d2["output"]["final_energy"],
                "final_energy_per_atom": d2["output"]["final_energy_per_atom"]}
            d["name"] = "aflow"
            d["pseudo_potential"] = {"functional": "pbe", "pot_type": "paw",
                                     "labels": d2["input"]["potcar"]}

            if len(d["calculations"]) == 2 or \
                    vasprun_files.keys()[0] != "relax1":
                d["state"] = "successful" if d2["has_vasp_completed"] \
                    else "unsuccessful"
            else:
                d["state"] = "stopped"

            s = Structure.from_dict(d2["output"]["crystal"])
            if not s.is_valid():
                d["state"] = "errored_bad_structure"

            d["analysis"] = get_basic_analysis_and_error_checks(d)

            sg = SymmetryFinder(Structure.from_dict(d["output"]["crystal"]),
                                0.1)
            d["spacegroup"] = {"symbol": sg.get_spacegroup_symbol(),
                               "number": sg.get_spacegroup_number(),
                               "point_group": unicode(sg.get_point_group(),
                                                      errors="ignore"),
                               "source": "spglib",
                               "crystal_system": sg.get_crystal_system(),
                               "hall": sg.get_hall()}
            d["last_updated"] = datetime.datetime.today()

            # Process NEB runs. The energy and magnetic moments for each image are listed.
            # Some useful values are calculated.

            # Number of NEB images
            print "TTM DEBUG: At NEB processing stage."
            image_list = []
            for i in xrange(0,9):
                append = "0"+str(i)
                newpath = os.path.join(fullpath,append)
                if os.path.exists(newpath):
                    image_list.append(newpath)
            d["num_images"] = len(image_list)
            print "TTM DEBUG: Image list:", image_list
            # Image energies and magnetic moments for specific folders
            list_image_energies = []
            list_image_mags = []
            for i in xrange(0,len(image_list)):
                append = "0"+str(i)
                oszicar = os.path.join(fullpath,append,"OSZICAR")
                if not os.path.isfile(oszicar):
                    return None
                val_energy = util2.getEnergy(oszicar)
                val_mag = util2.getMag(oszicar)
                d["E_"+append]= val_energy
                d["mag_"+append]= val_mag
                list_image_energies.append(val_energy)
                list_image_mags.append(val_mag)
            print "TTM DEBUG: first occurrence list_image_mags", list_image_mags
            # List of image energies and magnetic moments in order 
            image_energies = ' '.join(map(str,list_image_energies))
            d["image_energies"] = image_energies

            # An simple way to visualize relative image energies and magnetic moments
            energy_contour = "-x-"
            if len(image_list)==0:
                return None
            for i in xrange(1,len(image_list)):
                if(list_image_energies[i]>list_image_energies[i-1]):
                    energy_contour += "/-x-"
                elif list_image_energies[i]<list_image_energies[i-1]:
                    energy_contour += "\\-x-"
                else:
                    energy_contour += "=-x-"
            d["energy_contour"] = energy_contour
            print "TTM DEBUG: energy contour:", energy_contour

            # Difference between the first and maximum energies and magnetic moments
            deltaE_firstmax = max(list_image_energies) - list_image_energies[0] 
            d["deltaE_firstmax"] = deltaE_firstmax
            # Difference between the last and maximum energies and magnetic moments
            deltaE_lastmax = max(list_image_energies) - list_image_energies[-1]
            d["deltaE_lastmax"] = deltaE_lastmax

            # Difference between the endpoint energies and magnetic moments
            deltaE_endpoints = list_image_energies[-1] - list_image_energies[0]
            d["deltaE_endpoints"] = deltaE_endpoints

            # Difference between the minimum and maximum energies and magnetic moments
            deltaE_maxmin = max(list_image_energies) - min(list_image_energies)
            d["deltaE_maxmin"] = deltaE_maxmin            
        
#INDENT THE NEXT LINES:
            if not (list_image_mags[0] == None): #if ISPIN not 2, no mag info
                image_mags = ' '.join(map(str,list_image_mags))
                d["image_mags"] = image_mags
                mag_contour = "-o-"
                if len(image_list)==0:
                    return None
                for i in xrange(1,len(image_list)):
                    if(list_image_mags[i]>list_image_mags[i-1]):
                        mag_contour += "/-o-"
                    elif list_image_mags[i]<list_image_mags[i-1]:
                        mag_contour += "\\-o-"
                    else:
                        mag_contour += "=-o-"
                d["mag_contour"] = mag_contour
                deltaM_firstmax = max(list_image_mags) - list_image_mags[0]
                d["deltaM_firstmax"] = deltaM_firstmax
                deltaM_lastmax = max(list_image_mags) - list_image_mags[-1]
                d["deltaM_lastmax"] = deltaM_lastmax
                deltaM_endpoints = list_image_mags[-1] - list_image_mags[0]
                d["deltaM_endpoints"] = deltaM_endpoints
                deltaM_maxmin = max(list_image_mags) - min(list_image_mags)
                d["deltaM_maxmin"] = deltaM_maxmin


            d["type"] = "NEB"

            return d

        except Exception as ex:
            logger.error("Error in " + os.path.abspath(dir_name) +
                         ".\nError msg: " + str(ex))
            return None
示例#21
0
    def _gen_input_file(self, working_dir):
        """
        Generate the necessary struct_enum.in file for enumlib. See enumlib
        documentation for details.
        """
        coord_format = "{:.6f} {:.6f} {:.6f}"

        # Using symmetry finder, get the symmetrically distinct sites.
        fitter = SymmetryFinder(self.structure, self.symm_prec)
        symmetrized_structure = fitter.get_symmetrized_structure()
        logger.debug("Spacegroup {} ({}) with {} distinct sites".format(
            fitter.get_spacegroup_symbol(), fitter.get_spacegroup_number(),
            len(symmetrized_structure.equivalent_sites)))
        """
        Enumlib doesn"t work when the number of species get too large. To
        simplify matters, we generate the input file only with disordered sites
        and exclude the ordered sites from the enumeration. The fact that
        different disordered sites with the exact same species may belong to
        different equivalent sites is dealt with by having determined the
        spacegroup earlier and labelling the species differently.
        """

        # index_species and index_amounts store mappings between the indices
        # used in the enum input file, and the actual species and amounts.
        index_species = []
        index_amounts = []

        #Let"s group and sort the sites by symmetry.
        site_symmetries = []
        for sites in symmetrized_structure.equivalent_sites:
            finder = SymmetryFinder(Structure.from_sites(sites),
                                    self.symm_prec)
            sgnum = finder.get_spacegroup_number()
            site_symmetries.append((sites, sgnum))

        site_symmetries = sorted(site_symmetries, key=lambda s: s[1])

        #Stores the ordered sites, which are not enumerated.
        min_sg_num = site_symmetries[0][1]
        ordered_sites = []
        disordered_sites = []
        coord_str = []
        min_disordered_sg = 300
        for (sites, sgnum) in site_symmetries:
            if sites[0].is_ordered:
                ordered_sites.append(sites)
            else:
                min_disordered_sg = min(min_disordered_sg, sgnum)
                sp_label = []
                species = {k: v for k, v in sites[0].species_and_occu.items()}
                if sum(species.values()) < 1 - EnumlibAdaptor.amount_tol:
                    #Let us first make add a dummy element for every single
                    #site whose total occupancies don't sum to 1.
                    species[DummySpecie("X")] = 1 - sum(species.values())
                for sp in species.keys():
                    if sp not in index_species:
                        index_species.append(sp)
                        sp_label.append(len(index_species) - 1)
                        index_amounts.append(species[sp] * len(sites))
                    else:
                        ind = index_species.index(sp)
                        sp_label.append(ind)
                        index_amounts[ind] += species[sp] * len(sites)
                sp_label = "/".join(["{}".format(i) for i in sorted(sp_label)])
                for site in sites:
                    coord_str.append("{} {}".format(
                        coord_format.format(*site.coords), sp_label))
                disordered_sites.append(sites)

        #It could be that some of the ordered sites has a lower symmetry than
        #the disordered sites.  So we consider the lowest symmetry sites as
        #disordered in our enumeration.
        if min_disordered_sg > min_sg_num:
            logger.debug("Ordered sites have lower symmetry than disordered.")
            sites = ordered_sites.pop(0)
            index_species.append(sites[0].specie)
            index_amounts.append(len(sites))
            sp_label = len(index_species) - 1
            logger.debug(
                "Lowest symmetry {} sites are included in enum.".format(
                    sites[0].specie))
            for site in sites:
                coord_str.append("{} {}".format(
                    coord_format.format(*site.coords), sp_label))
            disordered_sites.append(sites)

        self.ordered_sites = []
        for sites in ordered_sites:
            self.ordered_sites.extend(sites)
        self.index_species = index_species

        lattice = self.structure.lattice

        output = [self.structure.formula, "bulk"]
        for vec in lattice.matrix:
            output.append(coord_format.format(*vec))
        output.append("{}".format(len(index_species)))
        output.append("{}".format(len(coord_str)))
        output.extend(coord_str)

        output.append("{} {}".format(self.min_cell_size, self.max_cell_size))
        output.append(str(self.enum_precision_parameter))
        output.append("partial")
        #To get a reasonable number of structures, we fix concentrations to the
        #range expected in the original structure.
        total_amounts = sum(index_amounts)
        for amt in index_amounts:
            conc = amt / total_amounts
            if abs(conc * 100 - round(conc * 100)) < 1e-5:
                output.append("{} {} {}".format(int(round(conc * 100)),
                                                int(round(conc * 100)), 100))
            else:
                min_conc = int(math.floor(conc * 100))
                output.append("{} {} {}".format(min_conc - 1, min_conc + 1,
                                                100))
        output.append("")
        logger.debug("Generated input file:\n{}".format("\n".join(output)))
        with open(os.path.join(working_dir, "struct_enum.in"), "w") as f:
            f.write("\n".join(output))
示例#22
0
    def generate_doc(cls, dir_name, vasprun_files, parse_dos,
                     additional_fields):
        """Process aflow style and NEB runs."""
        print "TTM DEBUG: In generate_doc for NEB task drone."
        try:
            fullpath = os.path.abspath(dir_name)
            #Defensively copy the additional fields first.  This is a MUST.
            #Otherwise, parallel updates will see the same object and inserts
            #will be overridden!!
            d = {k: v for k, v in additional_fields.items()} \
                if additional_fields else {}
            d["dir_name"] = fullpath
            print "TTM DEBUG: fullpath: ", fullpath
            d["schema_version"] = NEBToDbTaskDrone.__version__
            d["calculations"] = [
                cls.process_vasprun(dir_name, taskname, filename, parse_dos)
                for taskname, filename in vasprun_files.items()
            ]
            d1 = d["calculations"][0]
            d2 = d["calculations"][-1]

            #Now map some useful info to the root level.
            for root_key in [
                    "completed_at", "nsites", "unit_cell_formula",
                    "reduced_cell_formula", "pretty_formula", "elements",
                    "nelements", "cif", "density", "is_hubbard", "hubbards",
                    "run_type"
            ]:
                d[root_key] = d2[root_key]
            d["chemsys"] = "-".join(sorted(d2["elements"]))
            d["input"] = {"crystal": d1["input"]["crystal"]}
            vals = sorted(d2["reduced_cell_formula"].values())
            d["anonymous_formula"] = {
                string.ascii_uppercase[i]: float(vals[i])
                for i in xrange(len(vals))
            }
            d["output"] = {
                "crystal": d2["output"]["crystal"],
                "final_energy": d2["output"]["final_energy"],
                "final_energy_per_atom": d2["output"]["final_energy_per_atom"]
            }
            d["name"] = "aflow"
            d["pseudo_potential"] = {
                "functional": "pbe",
                "pot_type": "paw",
                "labels": d2["input"]["potcar"]
            }

            if len(d["calculations"]) == 2 or \
                    vasprun_files.keys()[0] != "relax1":
                d["state"] = "successful" if d2["has_vasp_completed"] \
                    else "unsuccessful"
            else:
                d["state"] = "stopped"

            s = Structure.from_dict(d2["output"]["crystal"])
            if not s.is_valid():
                d["state"] = "errored_bad_structure"

            d["analysis"] = get_basic_analysis_and_error_checks(d)

            sg = SymmetryFinder(Structure.from_dict(d["output"]["crystal"]),
                                0.1)
            d["spacegroup"] = {
                "symbol": sg.get_spacegroup_symbol(),
                "number": sg.get_spacegroup_number(),
                "point_group": unicode(sg.get_point_group(), errors="ignore"),
                "source": "spglib",
                "crystal_system": sg.get_crystal_system(),
                "hall": sg.get_hall()
            }
            d["last_updated"] = datetime.datetime.today()

            # Process NEB runs. The energy and magnetic moments for each image are listed.
            # Some useful values are calculated.

            # Number of NEB images
            print "TTM DEBUG: At NEB processing stage."
            image_list = []
            for i in xrange(0, 9):
                append = "0" + str(i)
                newpath = os.path.join(fullpath, append)
                if os.path.exists(newpath):
                    image_list.append(newpath)
            d["num_images"] = len(image_list)
            print "TTM DEBUG: Image list:", image_list
            # Image energies and magnetic moments for specific folders
            list_image_energies = []
            list_image_mags = []
            for i in xrange(0, len(image_list)):
                append = "0" + str(i)
                oszicar = os.path.join(fullpath, append, "OSZICAR")
                if not os.path.isfile(oszicar):
                    return None
                val_energy = util2.getEnergy(oszicar)
                val_mag = util2.getMag(oszicar)
                d["E_" + append] = val_energy
                d["mag_" + append] = val_mag
                list_image_energies.append(val_energy)
                list_image_mags.append(val_mag)
            print "TTM DEBUG: first occurrence list_image_mags", list_image_mags
            # List of image energies and magnetic moments in order
            image_energies = ' '.join(map(str, list_image_energies))
            d["image_energies"] = image_energies

            # An simple way to visualize relative image energies and magnetic moments
            energy_contour = "-x-"
            if len(image_list) == 0:
                return None
            for i in xrange(1, len(image_list)):
                if (list_image_energies[i] > list_image_energies[i - 1]):
                    energy_contour += "/-x-"
                elif list_image_energies[i] < list_image_energies[i - 1]:
                    energy_contour += "\\-x-"
                else:
                    energy_contour += "=-x-"
            d["energy_contour"] = energy_contour
            print "TTM DEBUG: energy contour:", energy_contour

            # Difference between the first and maximum energies and magnetic moments
            deltaE_firstmax = max(list_image_energies) - list_image_energies[0]
            d["deltaE_firstmax"] = deltaE_firstmax
            # Difference between the last and maximum energies and magnetic moments
            deltaE_lastmax = max(list_image_energies) - list_image_energies[-1]
            d["deltaE_lastmax"] = deltaE_lastmax

            # Difference between the endpoint energies and magnetic moments
            deltaE_endpoints = list_image_energies[-1] - list_image_energies[0]
            d["deltaE_endpoints"] = deltaE_endpoints

            # Difference between the minimum and maximum energies and magnetic moments
            deltaE_maxmin = max(list_image_energies) - min(list_image_energies)
            d["deltaE_maxmin"] = deltaE_maxmin

            #INDENT THE NEXT LINES:
            if not (list_image_mags[0] == None):  #if ISPIN not 2, no mag info
                image_mags = ' '.join(map(str, list_image_mags))
                d["image_mags"] = image_mags
                mag_contour = "-o-"
                if len(image_list) == 0:
                    return None
                for i in xrange(1, len(image_list)):
                    if (list_image_mags[i] > list_image_mags[i - 1]):
                        mag_contour += "/-o-"
                    elif list_image_mags[i] < list_image_mags[i - 1]:
                        mag_contour += "\\-o-"
                    else:
                        mag_contour += "=-o-"
                d["mag_contour"] = mag_contour
                deltaM_firstmax = max(list_image_mags) - list_image_mags[0]
                d["deltaM_firstmax"] = deltaM_firstmax
                deltaM_lastmax = max(list_image_mags) - list_image_mags[-1]
                d["deltaM_lastmax"] = deltaM_lastmax
                deltaM_endpoints = list_image_mags[-1] - list_image_mags[0]
                d["deltaM_endpoints"] = deltaM_endpoints
                deltaM_maxmin = max(list_image_mags) - min(list_image_mags)
                d["deltaM_maxmin"] = deltaM_maxmin

            d["type"] = "NEB"

            return d

        except Exception as ex:
            logger.error("Error in " + os.path.abspath(dir_name) +
                         ".\nError msg: " + str(ex))
            return None
 def get_energy(self, structure):
     f = SymmetryFinder(structure, symprec=self.symprec,
                        angle_tolerance=self.angle_tolerance)
     return -f.get_spacegroup_number()
示例#24
0
    def generate_doc(cls, dir_name, vasprun_files, parse_dos,
                     additional_fields):
        """
        Process aflow style runs, where each run is actually a combination of
        two vasp runs.
        """
        try:
            fullpath = os.path.abspath(dir_name)
            #Defensively copy the additional fields first.  This is a MUST.
            #Otherwise, parallel updates will see the same object and inserts
            #will be overridden!!
            d = {k: v for k, v in additional_fields.items()} \
                if additional_fields else {}
            d["dir_name"] = fullpath
            d["schema_version"] = VaspToDbTaskDrone.__version__
            d["calculations"] = [
                cls.process_vasprun(dir_name, taskname, filename, parse_dos)
                for taskname, filename in vasprun_files.items()
            ]
            d1 = d["calculations"][0]
            d2 = d["calculations"][-1]

            #Now map some useful info to the root level.
            for root_key in [
                    "completed_at", "nsites", "unit_cell_formula",
                    "reduced_cell_formula", "pretty_formula", "elements",
                    "nelements", "cif", "density", "is_hubbard", "hubbards",
                    "run_type"
            ]:
                d[root_key] = d2[root_key]
            d["chemsys"] = "-".join(sorted(d2["elements"]))
            d["input"] = {"crystal": d1["input"]["crystal"]}
            vals = sorted(d2["reduced_cell_formula"].values())
            d["anonymous_formula"] = {
                string.ascii_uppercase[i]: float(vals[i])
                for i in xrange(len(vals))
            }
            d["output"] = {
                "crystal": d2["output"]["crystal"],
                "final_energy": d2["output"]["final_energy"],
                "final_energy_per_atom": d2["output"]["final_energy_per_atom"]
            }
            d["name"] = "aflow"
            d["pseudo_potential"] = {
                "functional": "pbe",
                "pot_type": "paw",
                "labels": d2["input"]["potcar"]
            }

            if len(d["calculations"]) == 2 or \
                    vasprun_files.keys()[0] != "relax1":
                d["state"] = "successful" if d2["has_vasp_completed"] \
                    else "unsuccessful"
            else:
                d["state"] = "stopped"

            s = Structure.from_dict(d2["output"]["crystal"])
            if not s.is_valid():
                d["state"] = "errored_bad_structure"

            d["analysis"] = get_basic_analysis_and_error_checks(d)

            sg = SymmetryFinder(Structure.from_dict(d["output"]["crystal"]),
                                0.1)
            d["spacegroup"] = {
                "symbol": sg.get_spacegroup_symbol(),
                "number": sg.get_spacegroup_number(),
                "point_group": unicode(sg.get_point_group(), errors="ignore"),
                "source": "spglib",
                "crystal_system": sg.get_crystal_system(),
                "hall": sg.get_hall()
            }
            d["last_updated"] = datetime.datetime.today()
            d["type"] = "VASP"  #PS

            return d
        except Exception as ex:
            logger.error("Error in " + os.path.abspath(dir_name) +
                         ".\nError msg: " + str(ex))
            return None
示例#25
0
 def get_energy(self, structure):
     f = SymmetryFinder(structure,
                        symprec=self.symprec,
                        angle_tolerance=self.angle_tolerance)
     return -f.get_spacegroup_number()
示例#26
0
 def get_sg(s):
     finder = SymmetryFinder(s, symprec=self._symprec)
     return finder.get_spacegroup_number()
示例#27
0
 def get_sg(s):
     finder = SymmetryFinder(s, symprec=self._symprec)
     return finder.get_spacegroup_number()
示例#28
0
    def __init__(self, struct, find_spacegroup=False):
        block = CifFile.CifBlock()
        latt = struct.lattice
        comp = struct.composition
        no_oxi_comp = Composition(comp.formula)
        spacegroup = ("P 1", 1)
        if find_spacegroup:
            sf = SymmetryFinder(struct, 0.001)
            spacegroup = (sf.get_spacegroup_symbol(), sf.get_spacegroup_number())
        block["_symmetry_space_group_name_H-M"] = spacegroup[0]
        for cell_attr in ['a', 'b', 'c']:
            block["_cell_length_" + cell_attr] = str(getattr(latt, cell_attr))
        for cell_attr in ['alpha', 'beta', 'gamma']:
            block["_cell_angle_" + cell_attr] = float(getattr(latt, cell_attr))
        block["_chemical_name_systematic"] = "Generated by pymatgen"
        block["_symmetry_Int_Tables_number"] = spacegroup[1]
        block["_chemical_formula_structural"] = str(no_oxi_comp
                                                    .reduced_formula)
        block["_chemical_formula_sum"] = str(no_oxi_comp.formula)
        block["_cell_volume"] = str(latt.volume)

        reduced_comp = Composition.from_formula(no_oxi_comp.reduced_formula)
        el = no_oxi_comp.elements[0]
        amt = comp[el]
        fu = int(amt / reduced_comp[Element(el.symbol)])

        block["_cell_formula_units_Z"] = str(fu)
        block.AddCifItem(([["_symmetry_equiv_pos_site_id",
                            "_symmetry_equiv_pos_as_xyz"]],
                          [[["1"], ["x, y, z"]]]))

        contains_oxidation = True
        try:
            symbol_to_oxinum = {str(el): float(el.oxi_state)
                                for el in comp.elements}
        except AttributeError:
            symbol_to_oxinum = {el.symbol: 0 for el in comp.elements}
            contains_oxidation = False
        if contains_oxidation:
            block.AddCifItem(([["_atom_type_symbol",
                                "_atom_type_oxidation_number"]],
                              [[symbol_to_oxinum.keys(),
                                symbol_to_oxinum.values()]]))

        atom_site_type_symbol = []
        atom_site_symmetry_multiplicity = []
        atom_site_fract_x = []
        atom_site_fract_y = []
        atom_site_fract_z = []
        atom_site_attached_hydrogens = []
        atom_site_B_iso_or_equiv = []
        atom_site_label = []
        atom_site_occupancy = []
        count = 1
        for site in struct:
            for sp, occu in site.species_and_occu.items():
                atom_site_type_symbol.append(str(sp))
                atom_site_symmetry_multiplicity.append("1")
                atom_site_fract_x.append("{0:f}".format(site.a))
                atom_site_fract_y.append("{0:f}".format(site.b))
                atom_site_fract_z.append("{0:f}".format(site.c))
                atom_site_attached_hydrogens.append("0")
                atom_site_B_iso_or_equiv.append(".")
                atom_site_label.append("{}{}".format(sp.symbol, count))
                atom_site_occupancy.append(str(occu))
                count += 1

        block["_atom_site_type_symbol"] = atom_site_type_symbol
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_label": atom_site_label})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_symmetry_multiplicity":
                         atom_site_symmetry_multiplicity})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_fract_x": atom_site_fract_x})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_fract_y": atom_site_fract_y})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_fract_z": atom_site_fract_z})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_attached_hydrogens":
                         atom_site_attached_hydrogens})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_B_iso_or_equiv":
                         atom_site_B_iso_or_equiv})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_occupancy": atom_site_occupancy})

        self._cf = CifFile.CifFile()
        # AJ says: CIF Block names cannot be more than 75 characters or you
        # get an Exception
        self._cf[comp.reduced_formula[0:74]] = block
示例#29
0
    def generate_doc(cls, dir_name, vasprun_files, parse_dos, additional_fields):
        """
        Process aflow style runs, where each run is actually a combination of
        two vasp runs.
        """
        try:
            fullpath = os.path.abspath(dir_name)
            # Defensively copy the additional fields first.  This is a MUST.
            # Otherwise, parallel updates will see the same object and inserts
            # will be overridden!!
            d = {k: v for k, v in additional_fields.items()} if additional_fields else {}
            d["dir_name"] = fullpath
            d["schema_version"] = VaspToDbTaskDrone.__version__
            d["calculations"] = [
                cls.process_vasprun(dir_name, taskname, filename, parse_dos)
                for taskname, filename in vasprun_files.items()
            ]
            d1 = d["calculations"][0]
            d2 = d["calculations"][-1]

            # Now map some useful info to the root level.
            for root_key in [
                "completed_at",
                "nsites",
                "unit_cell_formula",
                "reduced_cell_formula",
                "pretty_formula",
                "elements",
                "nelements",
                "cif",
                "density",
                "is_hubbard",
                "hubbards",
                "run_type",
            ]:
                d[root_key] = d2[root_key]
            d["chemsys"] = "-".join(sorted(d2["elements"]))
            d["input"] = {"crystal": d1["input"]["crystal"]}
            vals = sorted(d2["reduced_cell_formula"].values())
            d["anonymous_formula"] = {string.ascii_uppercase[i]: float(vals[i]) for i in xrange(len(vals))}
            d["output"] = {
                "crystal": d2["output"]["crystal"],
                "final_energy": d2["output"]["final_energy"],
                "final_energy_per_atom": d2["output"]["final_energy_per_atom"],
            }
            d["name"] = "aflow"
            d["pseudo_potential"] = {"functional": "pbe", "pot_type": "paw", "labels": d2["input"]["potcar"]}

            if len(d["calculations"]) == 2 or vasprun_files.keys()[0] != "relax1":
                d["state"] = "successful" if d2["has_vasp_completed"] else "unsuccessful"
            else:
                d["state"] = "stopped"

            s = Structure.from_dict(d2["output"]["crystal"])
            if not s.is_valid():
                d["state"] = "errored_bad_structure"

            d["analysis"] = get_basic_analysis_and_error_checks(d)

            sg = SymmetryFinder(Structure.from_dict(d["output"]["crystal"]), 0.1)
            d["spacegroup"] = {
                "symbol": sg.get_spacegroup_symbol(),
                "number": sg.get_spacegroup_number(),
                "point_group": unicode(sg.get_point_group(), errors="ignore"),
                "source": "spglib",
                "crystal_system": sg.get_crystal_system(),
                "hall": sg.get_hall(),
            }
            d["last_updated"] = datetime.datetime.today()
            return d
        except Exception as ex:
            logger.error("Error in " + os.path.abspath(dir_name) + ".\nError msg: " + str(ex))
            return None
示例#30
0
class SymmetryFinderTest(unittest.TestCase):
    def setUp(self):
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR'))
        self.structure = p.structure
        self.sg = SymmetryFinder(self.structure, 0.001)
        parser = CifParser(os.path.join(test_dir, 'Li10GeP2S12.cif'))
        self.disordered_structure = parser.get_structures()[0]
        self.disordered_sg = SymmetryFinder(self.disordered_structure, 0.001)
        s = p.structure.copy()
        site = s[0]
        del s[0]
        s.append(site.species_and_occu, site.frac_coords)
        self.sg3 = SymmetryFinder(s, 0.001)
        parser = CifParser(os.path.join(test_dir, 'Graphite.cif'))
        graphite = parser.get_structures()[0]
        graphite.add_site_property("magmom", [0.1] * len(graphite))
        self.sg4 = SymmetryFinder(graphite, 0.001)

    def test_get_space_symbol(self):
        self.assertEqual(self.sg.get_spacegroup_symbol(), "Pnma")
        self.assertEqual(self.disordered_sg.get_spacegroup_symbol(),
                         "P4_2/nmc")
        self.assertEqual(self.sg3.get_spacegroup_symbol(), "Pnma")
        self.assertEqual(self.sg4.get_spacegroup_symbol(), "R-3m")

    def test_get_space_number(self):
        self.assertEqual(self.sg.get_spacegroup_number(), 62)
        self.assertEqual(self.disordered_sg.get_spacegroup_number(), 137)
        self.assertEqual(self.sg4.get_spacegroup_number(), 166)

    def test_get_hall(self):
        self.assertEqual(self.sg.get_hall(), '-P 2ac 2n')
        self.assertEqual(self.disordered_sg.get_hall(), 'P 4n 2n -1n')

    def test_get_pointgroup(self):
        self.assertEqual(self.sg.get_point_group(), 'mmm')
        self.assertEqual(self.disordered_sg.get_point_group(), '4/mmm')

    def test_get_symmetry_dataset(self):
        ds = self.sg.get_symmetry_dataset()
        self.assertEqual(ds['international'], 'Pnma')

    def test_get_crystal_system(self):
        crystal_system = self.sg.get_crystal_system()
        self.assertEqual('orthorhombic', crystal_system)
        self.assertEqual('tetragonal', self.disordered_sg.get_crystal_system())

    def test_get_symmetry_operations(self):
        fracsymmops = self.sg.get_symmetry_operations()
        symmops = self.sg.get_symmetry_operations(True)
        self.assertEqual(len(symmops), 8)
        latt = self.structure.lattice
        for fop, op in zip(fracsymmops, symmops):
            for site in self.structure:
                newfrac = fop.operate(site.frac_coords)
                newcart = op.operate(site.coords)
                self.assertTrue(
                    np.allclose(latt.get_fractional_coords(newcart), newfrac))
                found = False
                newsite = PeriodicSite(site.species_and_occu,
                                       newcart,
                                       latt,
                                       coords_are_cartesian=True)
                for testsite in self.structure:
                    if newsite.is_periodic_image(testsite, 1e-3):
                        found = True
                        break
                self.assertTrue(found)

    def test_get_refined_structure(self):
        for a in self.sg.get_refined_structure().lattice.angles:
            self.assertEqual(a, 90)
        refined = self.disordered_sg.get_refined_structure()
        for a in refined.lattice.angles:
            self.assertEqual(a, 90)
        self.assertEqual(refined.lattice.a, refined.lattice.b)
        parser = CifParser(os.path.join(test_dir, 'Li2O.cif'))
        s = parser.get_structures()[0]
        sg = SymmetryFinder(s, 0.001)
        self.assertEqual(sg.get_refined_structure().num_sites, 4 * s.num_sites)

    def test_get_symmetrized_structure(self):
        symm_struct = self.sg.get_symmetrized_structure()
        for a in symm_struct.lattice.angles:
            self.assertEqual(a, 90)
        self.assertEqual(len(symm_struct.equivalent_sites), 5)

        symm_struct = self.disordered_sg.get_symmetrized_structure()
        self.assertEqual(len(symm_struct.equivalent_sites), 8)
        self.assertEqual(map(len, symm_struct.equivalent_sites),
                         [16, 4, 8, 4, 2, 8, 8, 8])
        s1 = symm_struct.equivalent_sites[1][1]
        s2 = symm_struct[symm_struct.equivalent_indices[1][1]]
        self.assertEqual(s1, s2)
        self.assertEqual(self.sg4.get_symmetrized_structure()[0].magmom, 0.1)

    def test_find_primitive(self):
        """
        F m -3 m Li2O testing of converting to primitive cell
        """
        parser = CifParser(os.path.join(test_dir, 'Li2O.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure)
        primitive_structure = s.find_primitive()
        self.assertEqual(primitive_structure.formula, "Li2 O1")
        # This isn't what is expected. All the angles should be 60
        self.assertAlmostEqual(primitive_structure.lattice.alpha, 60)
        self.assertAlmostEqual(primitive_structure.lattice.beta, 60)
        self.assertAlmostEqual(primitive_structure.lattice.gamma, 60)
        self.assertAlmostEqual(primitive_structure.lattice.volume,
                               structure.lattice.volume / 4.0)

    def test_get_ir_reciprocal_mesh(self):
        grid = self.sg.get_ir_reciprocal_mesh()
        self.assertEquals(len(grid), 216)
        self.assertAlmostEquals(grid[1][0][0], 0.1)
        self.assertAlmostEquals(grid[1][0][1], 0.0)
        self.assertAlmostEquals(grid[1][0][2], 0.0)
        self.assertEquals(grid[1][1], 2)

    def test_get_conventional_standard_structure(self):
        parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.b, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.c, 9.1980270633769461)

        parser = CifParser(os.path.join(test_dir, 'btet_1915.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.b, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.c, 4.2327080177761687)

        parser = CifParser(os.path.join(test_dir, 'orci_1010.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 2.9542233922299999)
        self.assertAlmostEqual(conv.lattice.b, 4.6330325651443296)
        self.assertAlmostEqual(conv.lattice.c, 5.373703587040775)

        parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 4.1430033493799998)
        self.assertAlmostEqual(conv.lattice.b, 31.437979757624728)
        self.assertAlmostEqual(conv.lattice.c, 3.99648651)

        parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 117.53832420192903)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 14.033435583000625)
        self.assertAlmostEqual(conv.lattice.b, 3.96052850731)
        self.assertAlmostEqual(conv.lattice.c, 6.8743926325200002)

        parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 120)
        self.assertAlmostEqual(conv.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.c, 6.9779585500000003)

    def test_get_primitive_standard_structure(self):
        parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.beta, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.gamma, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.a, 7.9657251015812145)
        self.assertAlmostEqual(prim.lattice.b, 7.9657251015812145)
        self.assertAlmostEqual(prim.lattice.c, 7.9657251015812145)

        parser = CifParser(os.path.join(test_dir, 'btet_1915.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 105.015053349)
        self.assertAlmostEqual(prim.lattice.beta, 105.015053349)
        self.assertAlmostEqual(prim.lattice.gamma, 118.80658411899999)
        self.assertAlmostEqual(prim.lattice.a, 4.1579321075608791)
        self.assertAlmostEqual(prim.lattice.b, 4.1579321075608791)
        self.assertAlmostEqual(prim.lattice.c, 4.1579321075608791)

        parser = CifParser(os.path.join(test_dir, 'orci_1010.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 134.78923546600001)
        self.assertAlmostEqual(prim.lattice.beta, 105.856239333)
        self.assertAlmostEqual(prim.lattice.gamma, 91.276341676000001)
        self.assertAlmostEqual(prim.lattice.a, 3.8428217771014852)
        self.assertAlmostEqual(prim.lattice.b, 3.8428217771014852)
        self.assertAlmostEqual(prim.lattice.c, 3.8428217771014852)

        parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 90)
        self.assertAlmostEqual(prim.lattice.beta, 90)
        self.assertAlmostEqual(prim.lattice.gamma, 164.985257335)
        self.assertAlmostEqual(prim.lattice.a, 15.854897098324196)
        self.assertAlmostEqual(prim.lattice.b, 15.854897098324196)
        self.assertAlmostEqual(prim.lattice.c, 3.99648651)

        parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 63.579155761999999)
        self.assertAlmostEqual(prim.lattice.beta, 116.42084423747779)
        self.assertAlmostEqual(prim.lattice.gamma, 148.47965136208569)
        self.assertAlmostEqual(prim.lattice.a, 7.2908007159612325)
        self.assertAlmostEqual(prim.lattice.b, 7.2908007159612325)
        self.assertAlmostEqual(prim.lattice.c, 6.8743926325200002)

        parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 90)
        self.assertAlmostEqual(prim.lattice.beta, 90)
        self.assertAlmostEqual(prim.lattice.gamma, 120)
        self.assertAlmostEqual(prim.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(prim.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(prim.lattice.c, 6.9779585500000003)
示例#31
0
        except ValueError, IndexError:
            print("-d must be followed by an integer")
            exit(1)

# read structure
if os.path.exists(fstruct):
    struct = mg.read_structure(fstruct)
else:
    print("File %s does not exist" % fstruct)
    exit(1)

# symmetry information
struct_sym = SymmetryFinder(struct)
print("lattice type : {0}".format(struct_sym.get_lattice_type()))
print("space group  : {0} ({1})".format(struct_sym.get_spacegroup_symbol(),
                                     struct_sym.get_spacegroup_number()))

# Compute first brillouin zone
ibz = HighSymmKpath(struct)
ibz.get_kpath_plot(savefig="path.png")
print("ibz type     : {0}".format(ibz.name))

# print specific kpoints in the first brillouin zone
for key, val in ibz.kpath["kpoints"].items():
    print("%8s %s" % (key, str(val)))
 
# suggested path for the band structure
print("paths in first brillouin zone :")
for path in ibz.kpath["path"]:
    print(path)
示例#32
0
class SymmetryFinderTest(unittest.TestCase):

    def setUp(self):
        p = Poscar.from_file(os.path.join(test_dir, 'POSCAR'))
        self.structure = p.structure
        self.sg = SymmetryFinder(self.structure, 0.001)
        parser = CifParser(os.path.join(test_dir, 'Li10GeP2S12.cif'))
        self.disordered_structure = parser.get_structures()[0]
        self.disordered_sg = SymmetryFinder(self.disordered_structure, 0.001)
        s = p.structure.copy()
        site = s[0]
        del s[0]
        s.append(site.species_and_occu, site.frac_coords)
        self.sg3 = SymmetryFinder(s, 0.001)
        parser = CifParser(os.path.join(test_dir, 'Graphite.cif'))
        graphite = parser.get_structures()[0]
        graphite.add_site_property("magmom", [0.1] * len(graphite))
        self.sg4 = SymmetryFinder(graphite, 0.001)

    def test_get_space_symbol(self):
        self.assertEqual(self.sg.get_spacegroup_symbol(), "Pnma")
        self.assertEqual(self.disordered_sg.get_spacegroup_symbol(),
                         "P4_2/nmc")
        self.assertEqual(self.sg3.get_spacegroup_symbol(), "Pnma")
        self.assertEqual(self.sg4.get_spacegroup_symbol(), "R-3m")

    def test_get_space_number(self):
        self.assertEqual(self.sg.get_spacegroup_number(), 62)
        self.assertEqual(self.disordered_sg.get_spacegroup_number(), 137)
        self.assertEqual(self.sg4.get_spacegroup_number(), 166)

    def test_get_hall(self):
        self.assertEqual(self.sg.get_hall(), '-P 2ac 2n')
        self.assertEqual(self.disordered_sg.get_hall(), 'P 4n 2n -1n')

    def test_get_pointgroup(self):
        self.assertEqual(self.sg.get_point_group(), 'mmm')
        self.assertEqual(self.disordered_sg.get_point_group(), '4/mmm')

    def test_get_symmetry_dataset(self):
        ds = self.sg.get_symmetry_dataset()
        self.assertEqual(ds['international'], 'Pnma')

    def test_get_crystal_system(self):
        crystal_system = self.sg.get_crystal_system()
        self.assertEqual('orthorhombic', crystal_system)
        self.assertEqual('tetragonal', self.disordered_sg.get_crystal_system())

    def test_get_symmetry_operations(self):
        fracsymmops = self.sg.get_symmetry_operations()
        symmops = self.sg.get_symmetry_operations(True)
        self.assertEqual(len(symmops), 8)
        latt = self.structure.lattice
        for fop, op in zip(fracsymmops, symmops):
            for site in self.structure:
                newfrac = fop.operate(site.frac_coords)
                newcart = op.operate(site.coords)
                self.assertTrue(np.allclose(latt.get_fractional_coords(newcart),
                                            newfrac))
                found = False
                newsite = PeriodicSite(site.species_and_occu, newcart, latt,
                                       coords_are_cartesian=True)
                for testsite in self.structure:
                    if newsite.is_periodic_image(testsite, 1e-3):
                        found = True
                        break
                self.assertTrue(found)

    def test_get_refined_structure(self):
        for a in self.sg.get_refined_structure().lattice.angles:
            self.assertEqual(a, 90)
        refined = self.disordered_sg.get_refined_structure()
        for a in refined.lattice.angles:
            self.assertEqual(a, 90)
        self.assertEqual(refined.lattice.a, refined.lattice.b)
        parser = CifParser(os.path.join(test_dir, 'Li2O.cif'))
        s = parser.get_structures()[0]
        sg = SymmetryFinder(s, 0.001)
        self.assertEqual(sg.get_refined_structure().num_sites, 4 * s.num_sites)

    def test_get_symmetrized_structure(self):
        symm_struct = self.sg.get_symmetrized_structure()
        for a in symm_struct.lattice.angles:
            self.assertEqual(a, 90)
        self.assertEqual(len(symm_struct.equivalent_sites), 5)

        symm_struct = self.disordered_sg.get_symmetrized_structure()
        self.assertEqual(len(symm_struct.equivalent_sites), 8)
        self.assertEqual(map(len, symm_struct.equivalent_sites), [16,4,8,4,2,8,8,8])
        s1 = symm_struct.equivalent_sites[1][1]
        s2 = symm_struct[symm_struct.equivalent_indices[1][1]]
        self.assertEqual(s1, s2)
        self.assertEqual(self.sg4.get_symmetrized_structure()[0].magmom, 0.1)

    def test_find_primitive(self):
        """
        F m -3 m Li2O testing of converting to primitive cell
        """
        parser = CifParser(os.path.join(test_dir, 'Li2O.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure)
        primitive_structure = s.find_primitive()
        self.assertEqual(primitive_structure.formula, "Li2 O1")
        # This isn't what is expected. All the angles should be 60
        self.assertAlmostEqual(primitive_structure.lattice.alpha, 60)
        self.assertAlmostEqual(primitive_structure.lattice.beta, 60)
        self.assertAlmostEqual(primitive_structure.lattice.gamma, 60)
        self.assertAlmostEqual(primitive_structure.lattice.volume,
                               structure.lattice.volume / 4.0)

    def test_get_ir_reciprocal_mesh(self):
        grid=self.sg.get_ir_reciprocal_mesh()
        self.assertEquals(len(grid), 216)
        self.assertAlmostEquals(grid[1][0][0], 0.1)
        self.assertAlmostEquals(grid[1][0][1], 0.0)
        self.assertAlmostEquals(grid[1][0][2], 0.0)
        self.assertEquals(grid[1][1], 2)

    def test_get_conventional_standard_structure(self):
        parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.b, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.c, 9.1980270633769461)

        parser = CifParser(os.path.join(test_dir, 'btet_1915.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.b, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.c, 4.2327080177761687)

        parser = CifParser(os.path.join(test_dir, 'orci_1010.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 2.9542233922299999)
        self.assertAlmostEqual(conv.lattice.b, 4.6330325651443296)
        self.assertAlmostEqual(conv.lattice.c, 5.373703587040775)

        parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 4.1430033493799998)
        self.assertAlmostEqual(conv.lattice.b, 31.437979757624728)
        self.assertAlmostEqual(conv.lattice.c, 3.99648651)

        parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 117.53832420192903)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 14.033435583000625)
        self.assertAlmostEqual(conv.lattice.b, 3.96052850731)
        self.assertAlmostEqual(conv.lattice.c, 6.8743926325200002)

        parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 120)
        self.assertAlmostEqual(conv.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.c, 6.9779585500000003)

    def test_get_primitive_standard_structure(self):
        parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.beta, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.gamma, 109.47122063400001)
        self.assertAlmostEqual(prim.lattice.a, 7.9657251015812145)
        self.assertAlmostEqual(prim.lattice.b, 7.9657251015812145)
        self.assertAlmostEqual(prim.lattice.c, 7.9657251015812145)

        parser = CifParser(os.path.join(test_dir, 'btet_1915.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 105.015053349)
        self.assertAlmostEqual(prim.lattice.beta, 105.015053349)
        self.assertAlmostEqual(prim.lattice.gamma, 118.80658411899999)
        self.assertAlmostEqual(prim.lattice.a, 4.1579321075608791)
        self.assertAlmostEqual(prim.lattice.b, 4.1579321075608791)
        self.assertAlmostEqual(prim.lattice.c, 4.1579321075608791)

        parser = CifParser(os.path.join(test_dir, 'orci_1010.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 134.78923546600001)
        self.assertAlmostEqual(prim.lattice.beta, 105.856239333)
        self.assertAlmostEqual(prim.lattice.gamma, 91.276341676000001)
        self.assertAlmostEqual(prim.lattice.a, 3.8428217771014852)
        self.assertAlmostEqual(prim.lattice.b, 3.8428217771014852)
        self.assertAlmostEqual(prim.lattice.c, 3.8428217771014852)

        parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 90)
        self.assertAlmostEqual(prim.lattice.beta, 90)
        self.assertAlmostEqual(prim.lattice.gamma, 164.985257335)
        self.assertAlmostEqual(prim.lattice.a, 15.854897098324196)
        self.assertAlmostEqual(prim.lattice.b, 15.854897098324196)
        self.assertAlmostEqual(prim.lattice.c, 3.99648651)

        parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 63.579155761999999)
        self.assertAlmostEqual(prim.lattice.beta, 116.42084423747779)
        self.assertAlmostEqual(prim.lattice.gamma, 148.47965136208569)
        self.assertAlmostEqual(prim.lattice.a, 7.2908007159612325)
        self.assertAlmostEqual(prim.lattice.b, 7.2908007159612325)
        self.assertAlmostEqual(prim.lattice.c, 6.8743926325200002)

        parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif'))
        structure = parser.get_structures(False)[0]
        s = SymmetryFinder(structure, symprec=1e-2)
        prim = s.get_primitive_standard_structure()
        self.assertAlmostEqual(prim.lattice.alpha, 90)
        self.assertAlmostEqual(prim.lattice.beta, 90)
        self.assertAlmostEqual(prim.lattice.gamma, 120)
        self.assertAlmostEqual(prim.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(prim.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(prim.lattice.c, 6.9779585500000003)
示例#33
0
    def __init__(self, struct, find_spacegroup=False):
        block = CifFile.CifBlock()
        latt = struct.lattice
        comp = struct.composition
        no_oxi_comp = Composition(comp.formula)
        spacegroup = ("P 1", 1)
        if find_spacegroup:
            sf = SymmetryFinder(struct, 0.001)
            spacegroup = (sf.get_spacegroup_symbol(),
                          sf.get_spacegroup_number())
        block["_symmetry_space_group_name_H-M"] = spacegroup[0]
        for cell_attr in ['a', 'b', 'c']:
            block["_cell_length_" + cell_attr] = str(getattr(latt, cell_attr))
        for cell_attr in ['alpha', 'beta', 'gamma']:
            block["_cell_angle_" + cell_attr] = float(getattr(latt, cell_attr))
        block["_chemical_name_systematic"] = "Generated by pymatgen"
        block["_symmetry_Int_Tables_number"] = spacegroup[1]
        block["_chemical_formula_structural"] = str(
            no_oxi_comp.reduced_formula)
        block["_chemical_formula_sum"] = str(no_oxi_comp.formula)
        block["_cell_volume"] = str(latt.volume)

        reduced_comp = Composition.from_formula(no_oxi_comp.reduced_formula)
        el = no_oxi_comp.elements[0]
        amt = comp[el]
        fu = int(amt / reduced_comp[Element(el.symbol)])

        block["_cell_formula_units_Z"] = str(fu)
        block.AddCifItem(
            ([["_symmetry_equiv_pos_site_id",
               "_symmetry_equiv_pos_as_xyz"]], [[["1"], ["x, y, z"]]]))

        contains_oxidation = True
        try:
            symbol_to_oxinum = {
                str(el): float(el.oxi_state)
                for el in comp.elements
            }
        except AttributeError:
            symbol_to_oxinum = {el.symbol: 0 for el in comp.elements}
            contains_oxidation = False
        if contains_oxidation:
            block.AddCifItem(
                ([["_atom_type_symbol", "_atom_type_oxidation_number"]],
                 [[symbol_to_oxinum.keys(),
                   symbol_to_oxinum.values()]]))

        atom_site_type_symbol = []
        atom_site_symmetry_multiplicity = []
        atom_site_fract_x = []
        atom_site_fract_y = []
        atom_site_fract_z = []
        atom_site_attached_hydrogens = []
        atom_site_B_iso_or_equiv = []
        atom_site_label = []
        atom_site_occupancy = []
        count = 1
        for site in struct:
            for sp, occu in site.species_and_occu.items():
                atom_site_type_symbol.append(str(sp))
                atom_site_symmetry_multiplicity.append("1")
                atom_site_fract_x.append("{0:f}".format(site.a))
                atom_site_fract_y.append("{0:f}".format(site.b))
                atom_site_fract_z.append("{0:f}".format(site.c))
                atom_site_attached_hydrogens.append("0")
                atom_site_B_iso_or_equiv.append(".")
                atom_site_label.append("{}{}".format(sp.symbol, count))
                atom_site_occupancy.append(str(occu))
                count += 1

        block["_atom_site_type_symbol"] = atom_site_type_symbol
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_label": atom_site_label})
        block.AddToLoop("_atom_site_type_symbol", {
            "_atom_site_symmetry_multiplicity":
            atom_site_symmetry_multiplicity
        })
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_fract_x": atom_site_fract_x})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_fract_y": atom_site_fract_y})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_fract_z": atom_site_fract_z})
        block.AddToLoop(
            "_atom_site_type_symbol",
            {"_atom_site_attached_hydrogens": atom_site_attached_hydrogens})
        block.AddToLoop(
            "_atom_site_type_symbol",
            {"_atom_site_B_iso_or_equiv": atom_site_B_iso_or_equiv})
        block.AddToLoop("_atom_site_type_symbol",
                        {"_atom_site_occupancy": atom_site_occupancy})

        self._cf = CifFile.CifFile()
        # AJ says: CIF Block names cannot be more than 75 characters or you
        # get an Exception
        self._cf[comp.reduced_formula[0:74]] = block
示例#34
0
def inter_descript_gen(cif_file, prune_args):
    # Use the number as struct identifier
    # Store the remaining string as formula
    print cif_file
    dir, filen = os.path.split(cif_file)
    print filen
    name = os.path.splitext(filen)[0]
    item = name.split('--')
    key = item[0]
    inter_descript_dict = {'formula': ''.join(item[1].split())}

    #read the file to pymatgen struct
    try:
        struct = CifParser(cif_file).get_structures(False)[0]
    except:
        print 'reading ', cif_file, ' failed'
        return None, filen

    symm_finder = SymmetryFinder(struct, symprec=1e-1)
    inter_descript_dict['crystal_system'] = symm_finder.get_crystal_system()
    inter_descript_dict['spacegroup_no'] = symm_finder.get_spacegroup_number()
    no_symmops = len(symm_finder.get_symmetry_operations())
    inter_descript_dict['no_symmops'] = no_symmops

    try:
        struct_val_rad = StructWithValenceIonicRadius(struct)
    except:
        print inter_descript_dict['formula']
        print "Unable to identify radii and valences"
        return None, filen

    try:
        inter = Interstitial(struct_val_rad)
    except:
        print inter_descript_dict['formula']
        print 'interstitial not generated'
        return None, filen

    valences = inter.struct_valences.values()
    valences.sort()
    try:
        anion_cation_charge_ratio = abs(valences[-1] / valences[0])
    except:  #BVAnalyzer fails sometimes and valences are set to 0
        print inter_descript_dict['formula']
        print valences
        anion_cation_charge_ratio = 0
    inter_descript_dict['charge_ratio'] = anion_cation_charge_ratio

    radii = inter.struct_radii.values()
    radii.sort()
    try:
        anion_cation_radii_ratio = radii[-1] / radii[0]
    except:
        anion_cation_radii_ratio = 0
    inter_descript_dict['radius_ratio'] = anion_cation_radii_ratio

    if prune_args[0] == "cation":
        inter.radius_prune_defectsites(
            radii[0])  #smallest element in the structure
    elif prune_args[0] == "anion":
        inter.radius_prune_defectsites(
            radii[-1])  #largest element in the structure
    else:
        el = prune_args[0]
        oxi_state = prune_args[1]
        print el, oxi_state
        inter.prune_defectsites(el, oxi_state)
    inter.prune_close_defectsites()

    if inter.defectsite_count() > 10:
        # Something wrong with the symmetry reduction of defects.
        # Ignoring the outlier
        return None, filen
        inter.reduce_defectsites()
    no_inter = inter.defectsite_count()
    if no_inter > 5:
        print "Tag:", key, inter_descript_dict['formula'], no_inter
    inter_descript_dict['no_inter'] = no_inter
    #print >>sys.stderr, inter_descript_dict[key]['formula'], "No. of inter", no_inter
    #ife = InterstitialFormationEnergy(inter)

    #Create a list storing a dictionary of properties for each interstitial
    inter_list = []
    for i in range(no_inter):
        inter_dict = {}
        inter_dict['coords'] = inter.get_defectsite(i).coords
        inter_dict['coord_no'] = inter.get_defectsite_coordination_number(i)
        inter_dict['coord_el'] = list(inter.get_coordinated_elements(i))
        inter_dict['radius'] = inter.get_radius(i)
        inter_dict['coord_chrg_sum'] = inter.get_coordsites_charge_sum(i)
        inter_list.append(inter_dict)
    inter_descript_dict['interstitials'] = inter_list
    return key, inter_descript_dict