예제 #1
0
파일: bonds.py 프로젝트: sikisis/pymatgen
def get_bond_length(sp1, sp2, bond_order=1):
    """
    Get the bond length between two species.

    Args:
        sp1:
            First specie.
        sp2:
            Second specie.
        bond_order:
            For species with different possible bond orders,
            this allows one to obtain the bond length for a particular bond
            order. For example, to get the C=C bond length instead of the
            C-C bond length, this should be set to 2. Defaults to 1.

    Returns:
        Bond length in Angstrom. None if no data is available.
    """

    syms = tuple(
        sorted([
            smart_element_or_specie(sp1).symbol,
            smart_element_or_specie(sp2).symbol
        ]))
    if syms in bond_lengths:
        all_lengths = bond_lengths[syms]
        if bond_order:
            return all_lengths.get(bond_order)
        else:
            return all_lengths.get(1)
    return None
예제 #2
0
파일: bonds.py 프로젝트: miaoliu/pymatgen
def get_bond_length(sp1, sp2, bond_order=1):
    """
    Get the bond length between two species.

    Args:
        sp1:
            First specie.
        sp2:
            Second specie.
        bond_order:
            For species with different possible bond orders,
            this allows one to obtain the bond length for a particular bond
            order. For example, to get the C=C bond length instead of the
            C-C bond length, this should be set to 2. Defaults to 1.

    Returns:
        Bond length in Angstrom. None if no data is available.
    """

    syms = tuple(sorted([smart_element_or_specie(sp1).symbol,
                         smart_element_or_specie(sp2).symbol]))
    if syms in bond_lengths:
        all_lengths = bond_lengths[syms]
        if bond_order:
            return all_lengths.get(bond_order)
        else:
            return all_lengths.get(1)
    return None
예제 #3
0
    def __init__(self, atoms_n_occu, coords, properties=None):
        """
        Create a *non-periodic* site.

        Args:
            atoms_n_occu:
                Species on the site. Can be:

                i.  A sequence of element / specie specified either as string
                    symbols, e.g. ["Li", "Fe2+", "P", ...] or atomic numbers,
                    e.g., (3, 56, ...) or actual Element or Specie objects.
                ii. List of dict of elements/species and occupancies, e.g.,
                    [{"Fe" : 0.5, "Mn":0.5}, ...]. This allows the setup of
                    disordered structures.
            coords:
                Cartesian coordinates of site.
            properties:
                Properties associated with the site as a dict, e.g.
                {"magmom": 5}. Defaults to None.
        """
        if issubclass(atoms_n_occu.__class__, collections.Mapping):
            self._species = Composition({smart_element_or_specie(k): v
                                         for k, v in atoms_n_occu.items()})
            totaloccu = self._species.num_atoms
            if totaloccu > 1:
                raise ValueError("Species occupancies sum to more than 1!")
            self._is_ordered = (totaloccu == 1 and len(self._species) == 1)
        else:
            self._species = Composition(
                {smart_element_or_specie(atoms_n_occu): 1})
            self._is_ordered = True

        self._coords = coords
        self._properties = properties if properties else {}
예제 #4
0
 def apply_transformation(self, structure):
     species_map = {}
     for k, v in self._species_map.items():
         if isinstance(v, dict):
             value = {smart_element_or_specie(x): y for x, y in v.items()}
         else:
             value = smart_element_or_specie(v)
         species_map[smart_element_or_specie(k)] = value
     s = Structure.from_sites(structure.sites)
     s.replace_species(species_map)
     return s
예제 #5
0
 def apply_transformation(self, structure):
     species_map = {}
     for k, v in self._species_map.items():
         if isinstance(v, dict):
             value = {smart_element_or_specie(x): y for x, y in v.items()}
         else:
             value = smart_element_or_specie(v)
         species_map[smart_element_or_specie(k)] = value
     s = Structure.from_sites(structure.sites)
     s.replace_species(species_map)
     return s
 def apply_transformation(self, structure):
     species_map = {}
     for k, v in self._species_map.items():
         if isinstance(v, dict):
             value = {smart_element_or_specie(x): y for x, y in v.items()}
         else:
             value = smart_element_or_specie(v)
         species_map[smart_element_or_specie(k)] = value
     editor = StructureEditor(structure)
     editor.replace_species(species_map)
     return editor.modified_structure
예제 #7
0
    def __init__(self, *args, **kwargs):
        """
        Very flexible Composition construction, similar to the built-in Python
        dict(). Also extended to allow simple string init.

        Args:
            Any form supported by the Python built-in dict() function.

            1. A dict of either {Element/Specie: amount},

               {string symbol:amount}, or {atomic number:amount} or any mixture
               of these. E.g., {Element("Li"):2 ,Element("O"):1},
               {"Li":2, "O":1}, {3:2, 8:1} all result in a Li2O composition.
            2. Keyword arg initialization, similar to a dict, e.g.,

               Compostion(Li = 2, O = 1)

            In addition, the Composition constructor also allows a single
            string as an input formula. E.g., Composition("Li2O").
        """
        if len(args) == 1 and isinstance(args[0], basestring):
            elmap = self._parse_formula(args[0])
        else:
            elmap = dict(*args, **kwargs)
        if any([e < 0 for e in elmap.values()]):
            raise ValueError("Amounts in Composition cannot be negative!")
        self._elmap = {smart_element_or_specie(k): v for k, v in elmap.items()}
        self._natoms = sum(self._elmap.values())
예제 #8
0
    def apply_transformation(self, structure, return_ranked_list=False):
        """
        Apply the transformation.

        Args:
            structure:
                input structure
            return_ranked_list:
                Boolean stating whether or not multiple structures are
                returned. If return_ranked_list is an int, that number of
                structures is returned.

        Returns:
            Depending on returned_ranked list, either a transformed structure
            or
            a list of dictionaries, where each dictionary is of the form
            {"structure" = .... , "other_arguments"}
            the key "transformation" is reserved for the transformation that
            was actually applied to the structure.
            This transformation is parsed by the alchemy classes for generating
            a more specific transformation history. Any other information will
            be stored in the transformation_parameters dictionary in the
            transmuted structure class.
        """
        sp = smart_element_or_specie(self._specie)
        specie_indices = [i for i in xrange(len(structure))
                          if structure[i].species_and_occu ==
                          Composition({sp: 1})]
        trans = PartialRemoveSitesTransformation([specie_indices],
                                                 [self._frac], algo=self._algo)
        return trans.apply_transformation(structure, return_ranked_list)
예제 #9
0
    def apply_transformation(self, structure, return_ranked_list=False):
        """
        Apply the transformation.

        Args:
            structure:
                input structure
            return_ranked_list:
                Boolean stating whether or not multiple structures are
                returned. If return_ranked_list is an int, that number of
                structures is returned.

        Returns:
            Depending on returned_ranked list, either a transformed structure
            or
            a list of dictionaries, where each dictionary is of the form
            {"structure" = .... , "other_arguments"}
            the key "transformation" is reserved for the transformation that
            was actually applied to the structure.
            This transformation is parsed by the alchemy classes for generating
            a more specific transformation history. Any other information will
            be stored in the transformation_parameters dictionary in the
            transmuted structure class.
        """
        sp = smart_element_or_specie(self._specie)
        specie_indices = [i for i in xrange(len(structure)) if structure[i].species_and_occu == Composition({sp: 1})]
        trans = PartialRemoveSitesTransformation([specie_indices], [self._frac], algo=self._algo)
        return trans.apply_transformation(structure, return_ranked_list)
예제 #10
0
def get_conversion_factor(structure, species, temperature):
    """
    Conversion factor to convert between cm^2/s diffusivity measurements and
    mS/cm conductivity measurements based on number of atoms of diffusing
    species and .

    Args:
        structure:
            Input structure.
        species:
            Diffusing species.
        temperature:
            Temperature of the diffusion run in Kelvin.

    Returns:
        Conversion factor.
        Conductivity (in mS/cm) = Conversion Factor * Diffusivity (in cm^2/s)
    """
    df_sp = smart_element_or_specie(species)
    if df_sp.Z in [1, 3, 11, 19, 37, 55]:
        z = 1
    else:
        z = df_sp.oxi_state

    n = structure.composition[species]

    V = structure.volume * 1e-24  # units cm^3
    F = ELECTRON_CHARGE * AVOGADROS_CONST  # sA/mol
    return 1000 * n / (V * AVOGADROS_CONST) * z ** 2 * F ** 2\
        / (BOLTZMANN_CONST * AVOGADROS_CONST * temperature)
예제 #11
0
    def __init__(self, *args, **kwargs):
        """
        Very flexible Composition construction, similar to the built-in Python
        dict(). Also extended to allow simple string init.

        Args:
            Any form supported by the Python built-in dict() function.

            1. A dict of either {Element/Specie: amount},

               {string symbol:amount}, or {atomic number:amount} or any mixture
               of these. E.g., {Element("Li"):2 ,Element("O"):1},
               {"Li":2, "O":1}, {3:2, 8:1} all result in a Li2O composition.
            2. Keyword arg initialization, similar to a dict, e.g.,

               Compostion(Li = 2, O = 1)

            In addition, the Composition constructor also allows a single
            string as an input formula. E.g., Composition("Li2O").
        """
        if len(args) == 1 and isinstance(args[0], basestring):
            elmap = self._parse_formula(args[0])
        else:
            elmap = dict(*args, **kwargs)
        if any([e < 0 for e in elmap.values()]):
            raise CompositionError("Amounts in Composition cannot be "
                                   "negative!")
        self._elmap = {smart_element_or_specie(k): v for k, v in elmap.items()}
        self._natoms = sum(self._elmap.values())
예제 #12
0
 def apply_transformation(self, structure):
     charge = structure.charge
     specie = smart_element_or_specie(self._charge_balance_sp)
     num_to_remove = charge / specie.oxi_state
     num_in_structure = structure.composition[specie]
     removal_fraction = num_to_remove / num_in_structure
     if removal_fraction < 0:
         raise ValueError("addition of specie not yet supported by " "ChargeBalanceTransformation")
     trans = SubstitutionTransformation({self._charge_balance_sp: {self._charge_balance_sp: 1 - removal_fraction}})
     return trans.apply_transformation(structure)
예제 #13
0
    def get_wt_fraction(self, el):
        """
        Args:
            el:
                Element or Specie

        Returns:
            Weight fraction for element el in Composition
        """
        return smart_element_or_specie(el).atomic_mass * self[el] / self.weight
예제 #14
0
    def get_wt_fraction(self, el):
        """
        Args:
            el:
                Element or Specie

        Returns:
            Weight fraction for element el in Composition
        """
        return smart_element_or_specie(el).atomic_mass * self[el] / self.weight
예제 #15
0
def reduce_formula(sym_amt):
    """
    Help method to reduce a sym_amt dict to a reduced formula and factor.

    Args:
        Dict of the form {symbol: amount}.

    Returns:
        (reduced_formula, factor).
    """
    syms = sorted(sym_amt.keys(), key=lambda s: smart_element_or_specie(s).X)

    syms = filter(lambda s: sym_amt[s] > Composition.amount_tolerance, syms)
    num_el = len(syms)
    contains_polyanion = (num_el >= 3
                          and smart_element_or_specie(syms[num_el - 1]).X -
                          smart_element_or_specie(syms[num_el - 2]).X < 1.65)

    factor = reduce(gcd, sym_amt.values())
    reduced_form = []
    n = num_el - 2 if contains_polyanion else num_el
    for i in range(0, n):
        s = syms[i]
        normamt = sym_amt[s] * 1.0 / factor
        reduced_form.append(s)
        reduced_form.append(formula_double_format(normamt))

    if contains_polyanion:
        poly_sym_amt = {
            syms[i]: sym_amt[syms[i]] / factor
            for i in range(n, num_el)
        }
        (poly_form, poly_factor) = reduce_formula(poly_sym_amt)

        if poly_factor != 1:
            reduced_form.append("({}){}".format(poly_form, int(poly_factor)))
        else:
            reduced_form.append(poly_form)

    reduced_form = "".join(reduced_form)

    return reduced_form, factor
예제 #16
0
def reduce_formula(sym_amt):
    """
    Help method to reduce a sym_amt dict to a reduced formula and factor.

    Args:
        Dict of the form {symbol: amount}.

    Returns:
        (reduced_formula, factor).
    """
    syms = sorted(sym_amt.keys(),
                  key=lambda s: smart_element_or_specie(s).X)

    syms = filter(lambda s: sym_amt[s] > Composition.amount_tolerance,
                  syms)
    num_el = len(syms)
    contains_polyanion = (num_el >= 3 and
                          smart_element_or_specie(syms[num_el - 1]).X
                          - smart_element_or_specie(syms[num_el - 2]).X < 1.65)

    factor = reduce(gcd, sym_amt.values())
    reduced_form = []
    n = num_el - 2 if contains_polyanion else num_el
    for i in range(0, n):
        s = syms[i]
        normamt = sym_amt[s] * 1.0 / factor
        reduced_form.append(s)
        reduced_form.append(formula_double_format(normamt))

    if contains_polyanion:
        poly_sym_amt = {syms[i]: sym_amt[syms[i]] / factor
                        for i in range(n, num_el)}
        (poly_form, poly_factor) = reduce_formula(poly_sym_amt)

        if poly_factor != 1:
            reduced_form.append("({}){}".format(poly_form, int(poly_factor)))
        else:
            reduced_form.append(poly_form)

    reduced_form = "".join(reduced_form)

    return reduced_form, factor
예제 #17
0
 def formula(self):
     """
     Returns a formula string, with elements sorted by electronegativity,
     e.g., Li4 Fe4 P4 O16.
     """
     sym_amt = self.get_el_amt_dict()
     syms = sorted(sym_amt.keys(),
                   key=lambda s: smart_element_or_specie(s).X)
     formula = []
     for s in syms:
         if sym_amt[s] != 0:
             formula.append(s + formula_double_format(sym_amt[s], False))
     return " ".join(formula)
예제 #18
0
 def formula(self):
     """
     Returns a formula string, with elements sorted by electronegativity,
     e.g., Li4 Fe4 P4 O16.
     """
     sym_amt = self.get_el_amt_dict()
     syms = sorted(sym_amt.keys(),
                   key=lambda s: smart_element_or_specie(s).X)
     formula = []
     for s in syms:
         if sym_amt[s] != 0:
             formula.append(s + formula_double_format(sym_amt[s], False))
     return " ".join(formula)
예제 #19
0
 def __add__(self, other):
     """
     Adds two compositions. For example, an Fe2O3 composition + an FeO
     composition gives a Fe3O4 composition.
     """
     new_el_map = {el: self[el] for el in self}
     for k in other.keys():
         el = smart_element_or_specie(k)
         if el in self:
             new_el_map[el] += other[k]
         else:
             new_el_map[el] = other[k]
     return Composition(new_el_map)
예제 #20
0
 def __add__(self, other):
     """
     Adds two compositions. For example, an Fe2O3 composition + an FeO
     composition gives a Fe3O4 composition.
     """
     new_el_map = {el: self[el] for el in self}
     for k in other.keys():
         el = smart_element_or_specie(k)
         if el in self:
             new_el_map[el] += other[k]
         else:
             new_el_map[el] = other[k]
     return Composition(new_el_map)
예제 #21
0
    def apply_transformation(self, structure, return_ranked_list=False):
        #Make a mutable structure first
        mods = Structure.from_sites(structure)
        for sp, spin in self.mag_species_spin.items():
            sp = smart_element_or_specie(sp)
            oxi_state = getattr(sp, "oxi_state", 0)
            up = Specie(sp.symbol, oxi_state, {"spin": abs(spin)})
            down = Specie(sp.symbol, oxi_state, {"spin": -abs(spin)})
            mods.replace_species(
                {sp: Composition({up: self.order_parameter,
                                  down: 1 - self.order_parameter})})

        enum_args = self.enum_kwargs

        enum_args["min_cell_size"] = max(int(
            MagOrderingTransformation.determine_min_cell(
                structure, self.mag_species_spin,
                self.order_parameter)),
            enum_args.get("min_cell_size"))

        max_cell = self.enum_kwargs.get('max_cell_size')
        if max_cell:
            if enum_args["min_cell_size"] > max_cell:
                raise ValueError('Specified max cell size is smaller'
                                 ' than the minimum enumerable cell size')
        else:
            enum_args["max_cell_size"] = enum_args["min_cell_size"]

        t = EnumerateStructureTransformation(**enum_args)

        alls = t.apply_transformation(mods,
                                      return_ranked_list=return_ranked_list)

        try:
            num_to_return = int(return_ranked_list)
        except ValueError:
            num_to_return = 1

        if num_to_return == 1:
            return alls[0]["structure"]

        m = StructureMatcher(comparator=SpinComparator())

        grouped = m.group_structures([d["structure"] for d in alls])

        alls = [{"structure": g[0], "energy": self.emodel.get_energy(g[0])}
                for g in grouped]

        self._all_structures = sorted(alls, key=lambda d: d["energy"])

        return self._all_structures[0:num_to_return]
예제 #22
0
 def __init__(self, specie_and_min_dist_dict):
     """
     Args:
         specie_and_min_dist_dict:
             A species string to float mapping. For example, {"Na+": 1}
             means that all Na+ ions must be at least 1 Angstrom away from
             each other. Multiple species criteria can be applied. Note that
             the testing is done based on the actual object. If you have a
             structure with Element, you must use {"Na":1} instead to filter
             based on Element and not Specie.
     """
     self.specie_and_min_dist = {smart_element_or_specie(k): v
                                 for k, v
                                 in specie_and_min_dist_dict.items()}
예제 #23
0
 def apply_transformation(self, structure):
     charge = structure.charge
     specie = smart_element_or_specie(self._charge_balance_sp)
     num_to_remove = charge / specie.oxi_state
     num_in_structure = structure.composition[specie]
     removal_fraction = num_to_remove / num_in_structure
     if removal_fraction < 0:
         raise ValueError("addition of specie not yet supported by "
                          "ChargeBalanceTransformation")
     trans = SubstitutionTransformation({
         self._charge_balance_sp: {
             self._charge_balance_sp: 1 - removal_fraction
         }
     })
     return trans.apply_transformation(structure)
예제 #24
0
파일: filters.py 프로젝트: sikisis/pymatgen
 def __init__(self, specie_and_min_dist_dict):
     """
     Args:
         specie_and_min_dist_dict:
             A species string to float mapping. For example, {"Na+": 1}
             means that all Na+ ions must be at least 1 Angstrom away from
             each other. Multiple species criteria can be applied. Note that
             the testing is done based on the actual object. If you have a
             structure with Element, you must use {"Na":1} instead to filter
             based on Element and not Specie.
     """
     self.specie_and_min_dist = {
         smart_element_or_specie(k): v
         for k, v in specie_and_min_dist_dict.items()
     }
예제 #25
0
    def __sub__(self, other):
        """
        Subtracts two compositions. For example, an Fe2O3 composition - an FeO
        composition gives an FeO2 composition.

        Raises:
            CompositionError if the subtracted composition is greater than the
            original composition in any of its elements.
        """
        new_el_map = {el: self[el] for el in self}
        for k in other.keys():
            el = smart_element_or_specie(k)
            if el in self and other[k] <= self[el]:
                new_el_map[el] -= other[k]
            else:
                raise CompositionError(
                    "All elements in subtracted composition must exist in "
                    "original composition in equal or lesser amount!")
        return Composition(new_el_map)
예제 #26
0
    def __sub__(self, other):
        """
        Subtracts two compositions. For example, an Fe2O3 composition - an FeO
        composition gives an FeO2 composition.

        Raises:
            ValueError if the subtracted composition is greater than the
            original composition in any of its elements.
        """
        new_el_map = {el: self[el] for el in self}
        for k in other.keys():
            el = smart_element_or_specie(k)
            if el in self and other[k] <= self[el]:
                new_el_map[el] -= other[k]
            else:
                raise ValueError(("All elements in subtracted composition "
                                  "must exist in original composition in "
                                  "equal or lesser amount!"))
        return Composition(new_el_map)
예제 #27
0
 def __getitem__(self, el):
     """
     Get the amount for element.
     """
     return self._elmap.get(smart_element_or_specie(el), 0)
 def apply_transformation(self, structure):
     editor = StructureEditor(structure)
     map(editor.remove_species, [[smart_element_or_specie(sp)]
                                 for sp in self._species])
     return editor.modified_structure
예제 #29
0
 def apply_transformation(self, structure):
     s = Structure.from_sites(structure.sites)
     map(s.remove_species, [[smart_element_or_specie(sp)] for sp in self._species])
     return s
예제 #30
0
 def apply_transformation(self, structure):
     s = Structure.from_sites(structure.sites)
     map(s.remove_species, [[smart_element_or_specie(sp)]
                            for sp in self._species])
     return s
예제 #31
0
 def __getitem__(self, el):
     """
     Get the amount for element.
     """
     return self._elmap.get(smart_element_or_specie(el), 0)
예제 #32
0
 def test_smart_element_or_specie(self):
     self.assertEqual(smart_element_or_specie("Fe2+"), Specie("Fe", 2))
     self.assertEqual(smart_element_or_specie("3"), Element("Li"))
     self.assertEqual(smart_element_or_specie("U"), Element("U"))
     self.assertEqual(smart_element_or_specie("X2+"), DummySpecie("X", 2))
     self.assertEqual(smart_element_or_specie("Mn3+"), Specie("Mn", 3))
예제 #33
0
 def test_smart_element_or_specie(self):
     self.assertEqual(smart_element_or_specie("Fe2+"), Specie("Fe", 2))
     self.assertEqual(smart_element_or_specie("3"), Element("Li"))
     self.assertEqual(smart_element_or_specie("U"), Element("U"))
     self.assertEqual(smart_element_or_specie("X2+"), DummySpecie("X", 2))
     self.assertEqual(smart_element_or_specie("Mn3+"), Specie("Mn", 3))