Пример #1
0
    def test_attributes(self):
        is_true = {("Xe", "Kr") : "is_noble_gas",
                   ("Fe", "Ni") : 'is_transition_metal',
                   ('Li', 'Cs') : 'is_alkali',
                   ('Ca', 'Mg') : 'is_alkaline',
                   ('F', 'Br', 'I') : 'is_halogen',
                   ('La',) : 'is_lanthanoid',
                   ('U', 'Pu') : 'is_actinoid',
                   ('Si', 'Ge') : 'is_metalloid'
                   }

        for k, v in is_true.items():
            for sym in k:
                self.assertTrue(getattr(Element(sym), v), sym + ' is false')

        keys = ["name", "Z", "mendeleev_no", "atomic_mass", "electronic_structure", "X", "atomic_radius", "min_oxidation_state",
                        "max_oxidation_state", "electrical_resistivity", "velocity_of_sound",
                        "reflectivity", "refractive_index", "poissons_ratio", "molar_volume", "thermal_conductivity", "melting_point", "boiling_point",
                        "liquid_range", "critical_temperature", "superconduction_temperature",
                        "bulk_modulus", "youngs_modulus", "brinell_hardness", "rigidity_modulus", "mineral_hardness",
                        "vickers_hardness", "density_of_solid", "coefficient_of_linear_thermal_expansion", "oxidation_states", "common_oxidation_states", 'average_ionic_radius', 'ionic_radii']

        #Test all elements up to Uranium
        for i in range(1, 93):
            for k in keys:
                self.assertIsNotNone(getattr(Element.from_Z(i), k))
            el = Element.from_Z(i)
            if len(el.oxidation_states) > 0:
                self.assertEqual(max(el.oxidation_states), el.max_oxidation_state)
                self.assertEqual(min(el.oxidation_states), el.min_oxidation_state)
Пример #2
0
    def test_attributes(self):
        is_true = {("Xe", "Kr"): "is_noble_gas",
                   ("Fe", "Ni"): "is_transition_metal",
                   ("Li", "Cs"): "is_alkali",
                   ("Ca", "Mg"): "is_alkaline",
                   ("F", "Br", "I"): "is_halogen",
                   ("La",): "is_lanthanoid",
                   ("U", "Pu"): "is_actinoid",
                   ("Si", "Ge"): "is_metalloid",
                   ("O", "Te"): "is_chalcogen"}

        for k, v in is_true.items():
            for sym in k:
                self.assertTrue(getattr(Element(sym), v), sym + " is false")

        keys = ["mendeleev_no", "atomic_mass",
                "electronic_structure", "atomic_radius",
                "min_oxidation_state", "max_oxidation_state",
                "electrical_resistivity", "velocity_of_sound", "reflectivity",
                "refractive_index", "poissons_ratio", "molar_volume",
                "thermal_conductivity", "melting_point", "boiling_point",
                "liquid_range", "critical_temperature",
                "superconduction_temperature",
                "bulk_modulus", "youngs_modulus", "brinell_hardness",
                "rigidity_modulus", "mineral_hardness",
                "vickers_hardness", "density_of_solid",
                "atomic_orbitals", "coefficient_of_linear_thermal_expansion",
                "oxidation_states",
                "common_oxidation_states", "average_ionic_radius",
                "average_cationic_radius", "average_anionic_radius",
                "ionic_radii", "long_name", "metallic_radius", "iupac_ordering"]

        # Test all elements up to Uranium
        for i in range(1, 104):
            el = Element.from_Z(i)
            d = el.data
            for k in keys:
                k_str = k.capitalize().replace("_", " ")
                if k_str in d and (not str(d[k_str]).startswith("no data")):
                    self.assertIsNotNone(getattr(el, k))
                elif k == "long_name":
                    self.assertEqual(getattr(el, "long_name"), d["Name"])
                elif k == "iupac_ordering":
                    self.assertTrue("IUPAC ordering" in d)
                    self.assertIsNotNone(getattr(el, k))
            el = Element.from_Z(i)
            if len(el.oxidation_states) > 0:
                self.assertEqual(max(el.oxidation_states),
                                 el.max_oxidation_state)
                self.assertEqual(min(el.oxidation_states),
                                 el.min_oxidation_state)

            if el.symbol not in ["He", "Ne", "Ar"]:
                self.assertTrue(el.X > 0, "No electroneg for %s" % el)

        self.assertRaises(ValueError, Element.from_Z, 1000)
Пример #3
0
 def test_equals(self):
     random_z = random.randint(1, 92)
     fixed_el = Element.from_Z(random_z)
     other_z = random.randint(1, 92)
     while other_z == random_z:
         other_z = random.randint(1, 92)
     comp1 = Composition({fixed_el:1, Element.from_Z(other_z) :0})
     other_z = random.randint(1, 92)
     while other_z == random_z:
         other_z = random.randint(1, 92)
     comp2 = Composition({fixed_el:1, Element.from_Z(other_z) :0})
     self.assertEqual(comp1, comp2, "Composition equality test failed. %s should be equal to %s" % (comp1.formula, comp2.formula))
     self.assertEqual(comp1.__hash__(), comp2.__hash__(), "Hashcode equality test failed!")
Пример #4
0
    def test_element(self):
        symbols = list()
        for i in range(1, 102):
            el = Element.from_Z(i)
            self.assertGreater(el.atomic_mass, 0,
                               "Atomic mass cannot be negative!")
            self.assertNotIn(el.symbol, symbols,
                             "Duplicate symbol for " + el.symbol)
            symbols.append(""" + el.symbol + """)
            self.assertIsNotNone(el.group,
                                 "Group cannot be none for Z=" + str(i))
            self.assertIsNotNone(el.row, "Row cannot be none for Z=" + str(i))

            #Test all properties
            all_attr = ["Z", "symbol", "X", "name", "atomic_mass",
                        "atomic_radius", "max_oxidation_state",
                        "min_oxidation_state", "mendeleev_no",
                        "electrical_resistivity", "velocity_of_sound",
                        "reflectivity", "refractive_index", "poissons_ratio",
                        "molar_volume", "electronic_structure",
                        "thermal_conductivity", "boiling_point",
                        "melting_point", "critical_temperature",
                        "superconduction_temperature", "liquid_range",
                        "bulk_modulus", "youngs_modulus", "brinell_hardness",
                        "rigidity_modulus", "mineral_hardness",
                        "vickers_hardness", "density_of_solid",
                        "coefficient_of_linear_thermal_expansion"]

            for a in all_attr:
                self.assertIsNotNone(el, a)
Пример #5
0
    def test_pickle(self):
        el1 = Element.Fe
        o = pickle.dumps(el1)
        self.assertEqual(el1, pickle.loads(o))

        #Test all elements up to Uranium
        for i in range(1, 93):
            self.serialize_with_pickle(Element.from_Z(i), test_eq=True)
Пример #6
0
def from_string(string, symbols=None):
    structures = []
    timesteps = []
    steps = string.split("ITEM: TIMESTEP")
    steps.pop(0)
    for step in steps:
        lines = tuple(step.split("\n"))
        mdstep = int(lines[1])
        natoms = int(lines[3])
        xbox   = tuple((lines[5] + " 0").split())
        ybox   = tuple((lines[6] + " 0").split())
        zbox   = tuple((lines[7] + " 0").split())
        xlo = float(xbox[0])
        xhi = float(xbox[1])
        xy  = float(xbox[2])
        ylo = float(ybox[0])
        yhi = float(ybox[1])
        xz  = float(ybox[2])
        zlo = float(zbox[0])
        zhi = float(zbox[1])
        yz  = float(zbox[2])
        xlo -= np.min([0, xy, xz, xy+xz])
        xhi -= np.max([0, xy, xz, xy+xz])
        ylo -= np.min([0, yz])
        yhi -= np.max([0, yz])
      
        lattice = [xhi-xlo, 0, 0, xy, yhi-ylo, 0, xz, yz, zhi-zlo]
        atoms = [[float(j) for j in line.split()] for line in lines[9:-1]]
        atoms = sorted(atoms, key=lambda a_entry: a_entry[0], reverse=True) 

        coords = []
        atomic_sym = []
        while (len(atoms)):
           one = atoms.pop()
           typ = one[1]
           coo = one[2:5]
           sym = symbols[typ] if symbols else Element.from_Z(typ).symbol
           atomic_sym.append(sym)
           coords.append(coo)
        struct = Structure(lattice, atomic_sym, coords,
                   to_unit_cell=False, validate_proximity=False,
                   coords_are_cartesian=False)
        structures.append(struct)
        timesteps.append(mdstep)
        
    return lmpdump(structures, timesteps)
Пример #7
0
    def test_element(self):
        symbols = list()
        for i in range(1, 102):
            el = Element.from_Z(i)
            self.assertGreater(el.atomic_mass, 0, "Atomic mass cannot be negative!")
            self.assertNotIn(el.symbol, symbols, "Duplicate symbol for " + el.symbol)
            symbols.append('"' + el.symbol + '"')
            self.assertIsNotNone(el.group, "Group cannot be none for Z=" + str(i))
            self.assertIsNotNone(el.row, "Row cannot be none for Z=" + str(i))

            #Test all properties
            all_attr = ['Z', 'symbol', 'X', 'name', 'atomic_mass', 'atomic_radius', 'max_oxidation_state', 'min_oxidation_state', 'mendeleev_no',
            'electrical_resistivity', 'velocity_of_sound', 'reflectivity', 'refractive_index', 'poissons_ratio', 'molar_volume' , 'electronic_structure',
            'thermal_conductivity', 'boiling_point', 'melting_point', 'critical_temperature', 'superconduction_temperature', 'liquid_range', 'bulk_modulus',
            'youngs_modulus', 'brinell_hardness', 'rigidity_modulus', 'mineral_hardness', 'vickers_hardness', 'density_of_solid', 'coefficient_of_linear_thermal_expansion']

            for a in all_attr:
                self.assertIsNotNone(el, a)
Пример #8
0
def get_transformed_entries(entries, elements):
    comp_matrix = get_comp_matrix(entries, elements)
    newmat = []
    energies = []
    for i in xrange(len(elements)):
        col = comp_matrix[:, i]
        maxval = max(col)
        maxind = list(col).index(maxval)
        newmat.append(comp_matrix[maxind])
        energies.append(entries[i].energy_per_atom)
    invm = np.linalg.inv(np.array(newmat).transpose())
    newentries = []
    for i in xrange(len(entries)):
        entry = entries[i]
        lincomp = np.dot(invm, comp_matrix[i])
        lincomp = np.around(lincomp, 5)
        comp = Composition({Element.from_Z(j + 1):lincomp[j] for j in xrange(len(elements))})
        scaled_energy = entry.energy_per_atom - sum(lincomp * energies)
        newentries.append(TransformedPDEntry(comp, scaled_energy, entry))
    return newentries
Пример #9
0
    def test_attributes(self):
        is_true = {
            ("Xe", "Kr"): "is_noble_gas",
            ("Fe", "Ni"): "is_transition_metal",
            ("Li", "Cs"): "is_alkali",
            ("Ca", "Mg"): "is_alkaline",
            ("F", "Br", "I"): "is_halogen",
            ("La", ): "is_lanthanoid",
            ("U", "Pu"): "is_actinoid",
            ("Si", "Ge"): "is_metalloid",
            ("O", "Te"): "is_chalcogen",
        }

        for k, v in is_true.items():
            for sym in k:
                self.assertTrue(getattr(Element(sym), v), sym + " is false")

        keys = [
            "mendeleev_no",
            "atomic_mass",
            "electronic_structure",
            "atomic_radius",
            "min_oxidation_state",
            "max_oxidation_state",
            "electrical_resistivity",
            "velocity_of_sound",
            "reflectivity",
            "refractive_index",
            "poissons_ratio",
            "molar_volume",
            "thermal_conductivity",
            "melting_point",
            "boiling_point",
            "liquid_range",
            "critical_temperature",
            "superconduction_temperature",
            "bulk_modulus",
            "youngs_modulus",
            "brinell_hardness",
            "rigidity_modulus",
            "mineral_hardness",
            "vickers_hardness",
            "density_of_solid",
            "atomic_orbitals",
            "coefficient_of_linear_thermal_expansion",
            "oxidation_states",
            "common_oxidation_states",
            "average_ionic_radius",
            "average_cationic_radius",
            "average_anionic_radius",
            "ionic_radii",
            "long_name",
            "metallic_radius",
            "iupac_ordering",
            "ground_level",
            "ionization_energies",
        ]

        # Test all elements up to Uranium
        for i in range(1, 104):
            el = Element.from_Z(i)
            d = el.data
            for k in keys:
                k_str = k.capitalize().replace("_", " ")
                if k_str in d and (not str(d[k_str]).startswith("no data")):
                    self.assertIsNotNone(getattr(el, k))
                elif k == "long_name":
                    self.assertEqual(getattr(el, "long_name"), d["Name"])
                elif k == "iupac_ordering":
                    self.assertTrue("IUPAC ordering" in d)
                    self.assertIsNotNone(getattr(el, k))
            el = Element.from_Z(i)
            if len(el.oxidation_states) > 0:
                self.assertEqual(max(el.oxidation_states),
                                 el.max_oxidation_state)
                self.assertEqual(min(el.oxidation_states),
                                 el.min_oxidation_state)

            if el.symbol not in ["He", "Ne", "Ar"]:
                self.assertTrue(el.X > 0, f"No electroneg for {el}")

        self.assertRaises(ValueError, Element.from_Z, 1000)
Пример #10
0
    def write_xdatcar(self, filepath="XDATCAR", groupby_type=True, overwrite=False, to_unit_cell=False):
        """
        Write Xdatcar file with unit cell and atomic positions to file ``filepath``.

        Args:
            filepath: Xdatcar filename. If None, a temporary file is created.
            groupby_type: If True, atoms are grouped by type. Note that this option
                may change the order of the atoms. This option is needed because
                there are post-processing tools (e.g. ovito) that do not work as expected
                if the atoms in the structure are not grouped by type.
            overwrite: raise RuntimeError, if False and filepath exists.
            to_unit_cell (bool): Whether to translate sites into the unit cell.

        Return:
            path to Xdatcar file.
        """
        if filepath is not None and os.path.exists(filepath) and not overwrite:
            raise RuntimeError("Cannot overwrite pre-existing file `%s`" % filepath)
        if filepath is None:
            import tempfile
            fd, filepath = tempfile.mkstemp(text=True, suffix="_XDATCAR")

        # int typat[natom], double znucl[npsp]
        # NB: typat is double in the HIST.nc file
        typat = self.reader.read_value("typat").astype(int)
        znucl = self.reader.read_value("znucl")
        ntypat = self.reader.read_dimvalue("ntypat")
        num_pseudos = self.reader.read_dimvalue("npsp")
        if num_pseudos != ntypat:
            raise NotImplementedError("Alchemical mixing is not supported, num_pseudos != ntypat")
        #print("znucl:", znucl, "\ntypat:", typat)

        symb2pos = OrderedDict()
        symbols_atom = []
        for iatom, itype in enumerate(typat):
            itype = itype - 1
            symbol = Element.from_Z(int(znucl[itype])).symbol
            if symbol not in symb2pos: symb2pos[symbol] = []
            symb2pos[symbol].append(iatom)
            symbols_atom.append(symbol)

        if not groupby_type:
            group_ids = np.arange(self.reader.natom)
        else:
            group_ids = []
            for pos_list in symb2pos.values():
                group_ids.extend(pos_list)
            group_ids = np.array(group_ids, dtype=np.int)

        comment = " %s\n" % self.initial_structure.formula
        with open(filepath, "wt") as fh:
            # comment line  + scaling factor set to 1.0
            fh.write(comment)
            fh.write("1.0\n")
            for vec in self.initial_structure.lattice.matrix:
                fh.write("%.12f %.12f %.12f\n" % (vec[0], vec[1], vec[2]))
            if not groupby_type:
                fh.write(" ".join(symbols_atom) + "\n")
                fh.write("1 " * len(symbols_atom) + "\n")
            else:
                fh.write(" ".join(symb2pos.keys()) + "\n")
                fh.write(" ".join(str(len(p)) for p in symb2pos.values()) + "\n")

            # Write atomic positions in reduced coordinates.
            xred_list = self.reader.read_value("xred")
            if to_unit_cell:
                xred_list = xred_list % 1

            for step in range(self.num_steps):
                fh.write("Direct configuration= %d\n" % (step + 1))
                frac_coords = xred_list[step, group_ids]
                for fs in frac_coords:
                    fh.write("%.12f %.12f %.12f\n" % (fs[0], fs[1], fs[2]))

        return filepath
Пример #11
0
def get_ranked_list_goldschmidt_halffill():
    #TODO: get the oxidation state right!!!

    filename = "goldschmidt_rank_halffill.p"
    if os.path.exists(filename):
        with open(filename) as f:
            return pickle.load(f)

    from ga_optimization_ternary.fitness_evaluators import FitnessEvaluator, eval_fitness_simple
    all_AB = FitnessEvaluator(eval_fitness_simple, 10)._reverse_dict.keys()
    print 'generating goldschmidt ranks...'
    cand_score = {}  # dictionary of cand_tuple:score. a high score is BAD

    for a in all_AB:
        for b in all_AB:
            for x in range(7):
                r_a = Element.from_Z(
                    a
                ).average_ionic_radius  # TODO: get the correct oxidation state!
                r_b = Element.from_Z(b).average_ionic_radius
                r_x = None
                if x == 0:
                    r_x = Element("O").ionic_radii[-2]
                elif x == 1:
                    r_x = Element("O").ionic_radii[-2] * 2 / 3 + Element(
                        "N").ionic_radii[-3] * 1 / 3
                elif x == 2:
                    r_x = Element("O").ionic_radii[-2] * 1 / 3 + Element(
                        "N").ionic_radii[-3] * 2 / 3
                elif x == 3:
                    r_x = Element("N").ionic_radii[-3]
                elif x == 4:
                    r_x = Element("O").ionic_radii[-2] * 2 / 3 + Element(
                        "F").ionic_radii[-1] * 1 / 3
                elif x == 5:
                    r_x = Element("O").ionic_radii[-2] * 1 / 3 + Element(
                        "F").ionic_radii[-1] * 1 / 3 + Element(
                            "N").ionic_radii[-3] * 1 / 3
                elif x == 6:
                    r_x = Element("O").ionic_radii[-2] * 2 / 3 + Element(
                        "S").ionic_radii[-2] * 1 / 3

                goldschmidt = (r_a + r_x) / (math.sqrt(2) * (r_b + r_x))
                score = abs(goldschmidt - 1)  # a high score is bad, like golf

                #nelectrons must be even
                ne_a = Element.from_Z(a).Z
                ne_b = Element.from_Z(b).Z
                ne_x = None
                if x == 0:
                    ne_x = Element("O").Z * 3
                elif x == 1:
                    ne_x = Element("O").Z * 2 + Element("N").Z
                elif x == 2:
                    ne_x = Element("O").Z + Element("N").Z * 2
                elif x == 3:
                    ne_x = Element("N").Z
                elif x == 4:
                    ne_x = Element("O").Z * 2 + Element("F").Z
                elif x == 5:
                    ne_x = Element("O").Z + Element("F").Z + Element("N").Z
                elif x == 6:
                    ne_x = Element("O").Z * 2 + Element("S").Z

                #modify the score based on charge-balance
                even_found = False
                el_a = Element.from_Z(a)
                el_b = Element.from_Z(b)
                val_x = 0
                if x == 0:
                    val_x = -2 * 3
                elif x == 1:
                    val_x = (-2 * 2) + (-3 * 1)
                elif x == 2:
                    val_x = (-2 * 1) + (-3 * 2)
                elif x == 3:
                    val_x = -3 * 3
                elif x == 4:
                    val_x = (-2 * 2) + (-1 * 1)
                elif x == 5:
                    val_x = (-2 * 1) + (-1 * 1) + (-3 * 1)
                elif x == 6:
                    val_x = (-2 * 2) + (-2 * 1)

                for a_oxi in el_a.oxidation_states:
                    for b_oxi in el_b.oxidation_states:
                        if (ne_a + ne_b + ne_x) % 2 == 0 and (a_oxi + b_oxi +
                                                              val_x) == 0:
                            even_found = True

                if not even_found:
                    score = score + 100
                cand_score[(a, b, x)] = score

    results = sorted(cand_score, key=cand_score.get)
    with open(filename, "wb") as f:
        pickle.dump(results, f)
    return results
Пример #12
0
 def amu_symbol(self):
     """Atomic mass units"""
     amu_list = self.reader.read_value("atomic_mass_units")
     atomic_numbers = self.reader.read_value("atomic_numbers")
     amu = {Element.from_Z(at).symbol: a for at, a in zip(atomic_numbers, amu_list)}
     return amu
Пример #13
0
    def from_string(data, default_names=None):
        """
        Reads a Poscar from a string.

        The code will try its best to determine the elements in the POSCAR in
        the following order:
        1. If default_names are supplied and valid, it will use those. Usually,
        default names comes from an external source, such as a POTCAR in the
        same directory.
        2. If there are no valid default names but the input file is Vasp5-like
        and contains element symbols in the 6th line, the code will use that.
        3. Failing (2), the code will check if a symbol is provided at the end
        of each coordinate.

        If all else fails, the code will just assign the first n elements in
        increasing atomic number, where n is the number of species, to the
        Poscar. For example, H, He, Li, ....  This will ensure at least a
        unique element is assigned to each site and any analysis that does not
        require specific elemental properties should work fine.

        Args:
            data:
                string containing Poscar data.
            default_names:
                default symbols for the POSCAR file, usually coming from a
                POTCAR in the same directory.

        Returns:
            Poscar object.
        """

        chunks = re.split("^\s*$", data.strip(), flags=re.MULTILINE)

        #Parse positions
        lines = tuple(clean_lines(chunks[0].split("\n"), False))
        comment = lines[0]
        scale = float(lines[1])
        lattice = np.array([map(float, line.split())
                            for line in lines[2:5]])
        if scale < 0:
            # In vasp, a negative scale factor is treated as a volume. We need
            # to translate this to a proper lattice vector scaling.
            vol = abs(det(lattice))
            lattice *= (-scale / vol) ** (1 / 3)
        else:
            lattice *= scale

        vasp5_symbols = False
        try:
            natoms = map(int, lines[5].split())
            ipos = 6
        except ValueError:
            vasp5_symbols = True
            symbols = lines[5].split()
            natoms = map(int, lines[6].split())
            atomic_symbols = list()
            for i in xrange(len(natoms)):
                atomic_symbols.extend([symbols[i]] * natoms[i])
            ipos = 7

        postype = lines[ipos].split()[0]

        sdynamics = False
        # Selective dynamics
        if postype[0] in "sS":
            sdynamics = True
            ipos += 1
            postype = lines[ipos].split()[0]

        cart = postype[0] in "cCkK"
        nsites = sum(natoms)

        # If default_names is specified (usually coming from a POTCAR), use
        # them. This is in line with Vasp"s parsing order that the POTCAR
        # specified is the default used.
        if default_names:
            try:
                atomic_symbols = []
                for i in xrange(len(natoms)):
                    atomic_symbols.extend([default_names[i]] * natoms[i])
                vasp5_symbols = True
            except IndexError:
                pass

        if not vasp5_symbols:
            ind = 3 if not sdynamics else 6
            try:
                #check if names are appended at the end of the coordinates.
                atomic_symbols = [l.split()[ind]
                                  for l in lines[ipos + 1:ipos + 1 + nsites]]
                #Ensure symbols are valid elements
                if not all([Element.is_valid_symbol(sym)
                            for sym in atomic_symbols]):
                    raise ValueError("Non-valid symbols detected.")
                vasp5_symbols = True
            except (ValueError, IndexError):
                #Defaulting to false names.
                atomic_symbols = []
                for i in xrange(len(natoms)):
                    sym = Element.from_Z(i + 1).symbol
                    atomic_symbols.extend([sym] * natoms[i])
                warnings.warn("Elements in POSCAR cannot be determined. "
                              "Defaulting to false names {}."
                              .format(" ".join(atomic_symbols)))

        # read the atomic coordinates
        coords = []
        selective_dynamics = list() if sdynamics else None
        for i in xrange(nsites):
            toks = lines[ipos + 1 + i].split()
            coords.append(map(float, toks[:3]))
            if sdynamics:
                selective_dynamics.append([tok.upper()[0] == "T"
                                           for tok in toks[3:6]])

        struct = Structure(lattice, atomic_symbols, coords, False, False, cart)

        #parse velocities if any
        velocities = []
        if len(chunks) > 1:
            for line in chunks[1].strip().split("\n"):
                velocities.append([float(tok) for tok in line.split()])

        predictor_corrector = []
        if len(chunks) > 2:
            lines = chunks[2].strip().split("\n")
            predictor_corrector.append([int(lines[0])])
            for line in lines[1:]:
                predictor_corrector.append([float(tok)
                                            for tok in line.split()])

        return Poscar(struct, comment, selective_dynamics, vasp5_symbols,
                      velocities=velocities,
                      predictor_corrector=predictor_corrector)
Пример #14
0
    def _parse(self, filename):

        start_patt = re.compile(" \(Enter \S+l101\.exe\)")
        route_patt = re.compile(" #[pPnNtT]*.*")
        charge_mul_patt = re.compile("Charge\s+=\s*([-\\d]+)\s+" "Multiplicity\s+=\s*(\d+)")
        num_basis_func_patt = re.compile("([0-9]+)\s+basis functions")
        pcm_patt = re.compile("Polarizable Continuum Model")
        stat_type_patt = re.compile("imaginary frequencies")
        scf_patt = re.compile("E\(.*\)\s*=\s*([-\.\d]+)\s+")
        mp2_patt = re.compile("EUMP2\s*=\s*(.*)")
        oniom_patt = re.compile("ONIOM:\s+extrapolated energy\s*=\s*(.*)")
        termination_patt = re.compile("(Normal|Error) termination of Gaussian")
        std_orientation_patt = re.compile("Standard orientation")
        end_patt = re.compile("--+")
        orbital_patt = re.compile("Alpha\s*\S+\s*eigenvalues --(.*)")
        thermo_patt = re.compile("(Zero-point|Thermal) correction(.*)=" "\s+([\d\.-]+)")

        self.properly_terminated = False
        self.is_pcm = False
        self.stationary_type = "Minimum"
        self.structures = []
        self.corrections = {}
        self.energies = []

        coord_txt = []
        read_coord = 0
        orbitals_txt = []
        parse_stage = 0
        num_basis_found = False
        terminated = False

        with zopen(filename, "r") as f:
            for line in f:
                if parse_stage == 0:
                    if start_patt.search(line):
                        parse_stage = 1
                    elif route_patt.search(line):
                        self.route = {}
                        for tok in line.split():
                            sub_tok = tok.strip().split("=")
                            key = sub_tok[0].upper()
                            self.route[key] = sub_tok[1].upper() if len(sub_tok) > 1 else ""
                            m = re.match("(\w+)/([^/]+)", key)
                            if m:
                                self.functional = m.group(1)
                                self.basis_set = m.group(2)
                elif parse_stage == 1:
                    if charge_mul_patt.search(line):
                        m = charge_mul_patt.search(line)
                        self.charge = int(m.group(1))
                        self.spin_mult = int(m.group(2))
                        parse_stage = 2
                elif parse_stage == 2:

                    if self.is_pcm:
                        self._check_pcm(line)

                    if "FREQ" in self.route and thermo_patt.search(line):
                        m = thermo_patt.search(line)
                        if m.group(1) == "Zero-point":
                            self.corrections["Zero-point"] = float(m.group(3))
                        else:
                            key = m.group(2).strip(" to ")
                            self.corrections[key] = float(m.group(3))

                    if read_coord:
                        if not end_patt.search(line):
                            coord_txt.append(line)
                        else:
                            read_coord = (read_coord + 1) % 4
                            if not read_coord:
                                sp = []
                                coords = []
                                for l in coord_txt[2:]:
                                    toks = l.split()
                                    sp.append(Element.from_Z(int(toks[1])))
                                    coords.append(map(float, toks[3:6]))
                                self.structures.append(Molecule(sp, coords))
                    elif termination_patt.search(line):
                        m = termination_patt.search(line)
                        if m.group(1) == "Normal":
                            self.properly_terminated = True
                        terminated = True
                    elif (not num_basis_found) and num_basis_func_patt.search(line):
                        m = num_basis_func_patt.search(line)
                        self.num_basis_func = int(m.group(1))
                        num_basis_found = True
                    elif (not self.is_pcm) and pcm_patt.search(line):
                        self.is_pcm = True
                        self.pcm = {}
                    elif "FREQ" in self.route and "OPT" in self.route and stat_type_patt.search(line):
                        self.stationary_type = "Saddle"
                    elif mp2_patt.search(line):
                        m = mp2_patt.search(line)
                        self.energies.append(float(m.group(1).replace("D", "E")))
                    elif oniom_patt.search(line):
                        m = oniom_patt.matcher(line)
                        self.energies.append(float(m.group(1)))
                    elif scf_patt.search(line):
                        m = scf_patt.search(line)
                        self.energies.append(float(m.group(1)))
                    elif std_orientation_patt.search(line):
                        coord_txt = []
                        read_coord = 1
                    elif orbital_patt.search(line):
                        orbitals_txt.append(line)
        if not terminated:
            raise IOError("Bad Gaussian output file.")
def get_excluded_list():
    
    filename = "excluded_compounds.p"
    if os.path.exists(filename):
        with open(filename) as f:
            return pickle.load(f)
    
    from ga_optimization_ternary.fitness_evaluators import FitnessEvaluator, eval_fitness_simple
    all_AB = FitnessEvaluator(eval_fitness_simple, 10)._reverse_dict.keys()
    print 'generating exclusion ranks...'
    exclusions = []
    
    for a in all_AB:
        for b in all_AB:
            for x in range(7):
                
                #nelectrons must be even
                ne_a = Element.from_Z(a).Z
                ne_b = Element.from_Z(b).Z
                ne_x = None
                if x == 0:
                    ne_x = Element("O").Z * 3
                elif x == 1:
                    ne_x = Element("O").Z * 2 + Element("N").Z
                elif x == 2:
                    ne_x = Element("O").Z + Element("N").Z * 2
                elif x == 3:
                    ne_x = Element("N").Z
                elif x == 4:
                    ne_x = Element("O").Z * 2 + Element("F").Z
                elif x == 5:
                    ne_x = Element("O").Z + Element("F").Z + Element("N").Z
                elif x == 6:
                    ne_x = Element("O").Z * 2 + Element("S").Z
                
                #modify the score based on charge-balance
                even_found = False
                el_a = Element.from_Z(a)
                el_b = Element.from_Z(b)
                val_x = 0
                if x == 0:
                    val_x = -2 * 3
                elif x == 1:
                    val_x = (-2 * 2) + (-3 * 1)
                elif x == 2:
                    val_x = (-2 * 1) + (-3 * 2)
                elif x == 3:
                    val_x = -3 * 3
                elif x == 4:
                    val_x = (-2 * 2) + (-1 * 1)
                elif x == 5:
                    val_x = (-2 * 1) + (-1 * 1) + (-3 * 1)
                elif x == 6:
                    val_x = (-2 * 2) + (-2 * 1)
                
                for a_oxi in el_a.oxidation_states:
                    for b_oxi in el_b.oxidation_states:
                        if (ne_a + ne_b + ne_x) % 2 == 0 and (a_oxi + b_oxi + val_x) == 0:
                            even_found = True
                
                if not even_found:
                    exclusions.append((a, b, x))
                
    with open(filename, "wb") as f:
        pickle.dump(exclusions, f)
    return exclusions
Пример #16
0
def get_excluded_list():

    filename = "excluded_compounds.p"
    if os.path.exists(filename):
        with open(filename) as f:
            return pickle.load(f)

    from ga_optimization_ternary.fitness_evaluators import FitnessEvaluator, eval_fitness_simple
    all_AB = FitnessEvaluator(eval_fitness_simple, 10)._reverse_dict.keys()
    print 'generating exclusion ranks...'
    exclusions = []

    for a in all_AB:
        for b in all_AB:
            for x in range(7):

                #nelectrons must be even
                ne_a = Element.from_Z(a).Z
                ne_b = Element.from_Z(b).Z
                ne_x = None
                if x == 0:
                    ne_x = Element("O").Z * 3
                elif x == 1:
                    ne_x = Element("O").Z * 2 + Element("N").Z
                elif x == 2:
                    ne_x = Element("O").Z + Element("N").Z * 2
                elif x == 3:
                    ne_x = Element("N").Z
                elif x == 4:
                    ne_x = Element("O").Z * 2 + Element("F").Z
                elif x == 5:
                    ne_x = Element("O").Z + Element("F").Z + Element("N").Z
                elif x == 6:
                    ne_x = Element("O").Z * 2 + Element("S").Z

                #modify the score based on charge-balance
                even_found = False
                el_a = Element.from_Z(a)
                el_b = Element.from_Z(b)
                val_x = 0
                if x == 0:
                    val_x = -2 * 3
                elif x == 1:
                    val_x = (-2 * 2) + (-3 * 1)
                elif x == 2:
                    val_x = (-2 * 1) + (-3 * 2)
                elif x == 3:
                    val_x = -3 * 3
                elif x == 4:
                    val_x = (-2 * 2) + (-1 * 1)
                elif x == 5:
                    val_x = (-2 * 1) + (-1 * 1) + (-3 * 1)
                elif x == 6:
                    val_x = (-2 * 2) + (-2 * 1)

                for a_oxi in el_a.oxidation_states:
                    for b_oxi in el_b.oxidation_states:
                        if (ne_a + ne_b + ne_x) % 2 == 0 and (a_oxi + b_oxi +
                                                              val_x) == 0:
                            even_found = True

                if not even_found:
                    exclusions.append((a, b, x))

    with open(filename, "wb") as f:
        pickle.dump(exclusions, f)
    return exclusions
def get_ranked_list_goldschmidt_halffill():
    #TODO: get the oxidation state right!!!
    
    filename = "goldschmidt_rank_halffill.p"
    if os.path.exists(filename):
        with open(filename) as f:
            return pickle.load(f)
    
    from ga_optimization_ternary.fitness_evaluators import FitnessEvaluator, eval_fitness_simple
    all_AB = FitnessEvaluator(eval_fitness_simple, 10)._reverse_dict.keys()
    print 'generating goldschmidt ranks...'
    cand_score = {}  # dictionary of cand_tuple:score. a high score is BAD
    
    for a in all_AB:
        for b in all_AB:
            for x in range(7):
                r_a = Element.from_Z(a).average_ionic_radius  # TODO: get the correct oxidation state!
                r_b = Element.from_Z(b).average_ionic_radius
                r_x = None
                if x == 0:
                    r_x = Element("O").ionic_radii[-2]
                elif x == 1:
                    r_x = Element("O").ionic_radii[-2] * 2/3 + Element("N").ionic_radii[-3] * 1/3
                elif x == 2:
                    r_x = Element("O").ionic_radii[-2] * 1/3 + Element("N").ionic_radii[-3] * 2/3
                elif x == 3:
                    r_x = Element("N").ionic_radii[-3]
                elif x == 4:
                    r_x = Element("O").ionic_radii[-2] * 2/3 + Element("F").ionic_radii[-1] * 1/3
                elif x == 5:
                    r_x = Element("O").ionic_radii[-2] * 1/3 + Element("F").ionic_radii[-1] * 1/3 + Element("N").ionic_radii[-3] * 1/3
                elif x == 6:
                    r_x = Element("O").ionic_radii[-2] * 2/3 + Element("S").ionic_radii[-2] * 1/3
                
                goldschmidt = (r_a + r_x)/(math.sqrt(2) *(r_b+r_x))
                score = abs(goldschmidt - 1)  # a high score is bad, like golf
                
                #nelectrons must be even
                ne_a = Element.from_Z(a).Z
                ne_b = Element.from_Z(b).Z
                ne_x = None
                if x == 0:
                    ne_x = Element("O").Z * 3
                elif x == 1:
                    ne_x = Element("O").Z * 2 + Element("N").Z
                elif x == 2:
                    ne_x = Element("O").Z + Element("N").Z * 2
                elif x == 3:
                    ne_x = Element("N").Z
                elif x == 4:
                    ne_x = Element("O").Z * 2 + Element("F").Z
                elif x == 5:
                    ne_x = Element("O").Z + Element("F").Z + Element("N").Z
                elif x == 6:
                    ne_x = Element("O").Z * 2 + Element("S").Z
                
                #modify the score based on charge-balance
                even_found = False
                el_a = Element.from_Z(a)
                el_b = Element.from_Z(b)
                val_x = 0
                if x == 0:
                    val_x = -2 * 3
                elif x == 1:
                    val_x = (-2 * 2) + (-3 * 1)
                elif x == 2:
                    val_x = (-2 * 1) + (-3 * 2)
                elif x == 3:
                    val_x = -3 * 3
                elif x == 4:
                    val_x = (-2 * 2) + (-1 * 1)
                elif x == 5:
                    val_x = (-2 * 1) + (-1 * 1) + (-3 * 1)
                elif x == 6:
                    val_x = (-2 * 2) + (-2 * 1)
                
                for a_oxi in el_a.oxidation_states:
                    for b_oxi in el_b.oxidation_states:
                        if (ne_a + ne_b + ne_x) % 2 == 0 and (a_oxi + b_oxi + val_x) == 0:
                            even_found = True
                
                if not even_found:
                    score = score + 100
                cand_score[(a, b, x)] = score
            
    results = sorted(cand_score, key=cand_score.get)
    with open(filename, "wb") as f:
        pickle.dump(results, f)
    return results