Exemplo n.º 1
0
    def parse_atom_information_to_dict(self, node, d):
        """
        Parses atom information from a node to a dictionary

        Args:
            node (xml.etree.Element instance): The node to parse
            d (dict): The dictionary to which data is to be parsed
        """
        if not (node.tag == "atominfo"):
            raise AssertionError()
        species_dict = OrderedDict()
        for leaf in node:
            if leaf.tag == "atoms":
                d["n_atoms"] = self._parse_vector(leaf)[0]
            if leaf.tag == "types":
                d["n_species"] = self._parse_vector(leaf)[0]
            if leaf.tag == "array":
                if leaf.attrib["name"] == "atomtypes":
                    for item in leaf:
                        if item.tag == "set":
                            for sp in item:
                                elements = sp
                                if elements[1].text in species_dict.keys():
                                    pse = PeriodicTable()
                                    count = 1
                                    not_unique = True
                                    species_key = None
                                    while not_unique:
                                        species_key = "_".join(
                                            [elements[1].text,
                                             str(count)])
                                        if species_key not in species_dict.keys(
                                        ):
                                            not_unique = False
                                        else:
                                            count += 1
                                    if species_key is not None:
                                        pse.add_element(
                                            elements[1].text, species_key)
                                        special_element = pse.element(
                                            species_key)
                                        species_dict[special_element] = dict()
                                        species_dict[special_element][
                                            "n_atoms"] = int(elements[0].text)
                                        species_dict[special_element][
                                            "valence"] = float(
                                                elements[3].text)
                                else:
                                    species_key = elements[1].text
                                    species_dict[species_key] = dict()
                                    species_dict[species_key]["n_atoms"] = int(
                                        elements[0].text)
                                    species_dict[species_key][
                                        "valence"] = float(elements[3].text)
        d["species_dict"] = species_dict
        species_list = list()
        for key, val in species_dict.items():
            for sp in np.tile([key], species_dict[key]["n_atoms"]):
                species_list.append(clean_character(sp))
        d["species_list"] = species_list
Exemplo n.º 2
0
 def test_ge__(self):
     pse = PeriodicTable()
     pse.add_element("O", "O_up", spin="up")
     o_1 = pse.element("O")
     o_2 = pse.element("O")
     self.assertTrue(o_1 <= o_2)
     self.assertTrue(o_1 >= o_2)
Exemplo n.º 3
0
 def setUpClass(cls):
     cls.file_location = os.path.dirname(os.path.abspath(__file__))
     cls.project = Project(os.path.join(cls.file_location, "../static/sphinx"))
     pt = PeriodicTable()
     pt.add_element(parent_element="Fe", new_element="Fe_up", spin="0.5")
     Fe_up = pt.element("Fe_up")
     cls.basis = Atoms(
         elements=[Fe_up, Fe_up],
         scaled_positions=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]],
         cell=2.6 * np.eye(3),
     )
     cls.sphinx = cls.project.create_job("Sphinx", "job_sphinx")
     cls.sphinx_2_3 = cls.project.create_job("Sphinx", "sphinx_test_2_3")
     cls.sphinx_2_5 = cls.project.create_job("Sphinx", "sphinx_test_2_5")
     cls.sphinx.structure = cls.basis
     cls.sphinx_2_3.structure = Atoms(
         elements=["Fe", "Fe"],
         scaled_positions=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]],
         cell=2.6 * np.eye(3),
     )
     cls.sphinx_2_5.structure = Atoms(
         elements=["Fe", "Ni"],
         scaled_positions=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]],
         cell=2.83 * np.eye(3),
     )
     cls.current_dir = os.path.abspath(os.getcwd())
     cls.sphinx._create_working_directory()
     cls.sphinx_2_3._create_working_directory()
     cls.sphinx.write_input()
     cls.sphinx.version = "2.6"
     cls.sphinx_2_3.to_hdf()
     cls.sphinx_2_3.decompress()
     cls.sphinx_2_5.decompress()
Exemplo n.º 4
0
    def test_get_parent_basis(self):
        periodic_table = PeriodicTable()
        periodic_table.add_element(parent_element="O", new_element="O_up")
        O_up = periodic_table.element("O_up")

        O_basis = Atoms([O_up],
                        cell=10.0 * np.eye(3),
                        scaled_positions=[[0.5, 0.5, 0.5]])
        O_simple = Atoms(["O"],
                         cell=10.0 * np.eye(3),
                         scaled_positions=[[0.5, 0.5, 0.5]])
        O_parent = O_basis.get_parent_basis()
        self.assertNotEqual(O_basis, O_parent)
        self.assertEqual(O_simple, O_parent)
        self.assertEqual(O_parent[0].symbol, "O")
        periodic_table.add_element(parent_element="O", new_element="O_down")
        O_down = periodic_table.element("O_down")
        O_basis = Atoms([O_up, O_down],
                        cell=10.0 * np.eye(3),
                        scaled_positions=[[0.5, 0.5, 0.5], [0, 0, 0]])
        O_simple = Atoms(["O", "O"],
                         cell=10.0 * np.eye(3),
                         scaled_positions=[[0.5, 0.5, 0.5]])
        O_parent = O_basis.get_parent_basis()
        self.assertNotEqual(O_basis, O_parent)
        self.assertEqual(O_simple, O_parent)
        self.assertEqual(O_parent.get_chemical_formula(), "O2")
        self.assertEqual(len(O_basis.species), 2)
        self.assertEqual(len(O_simple.species), 1)
        self.assertEqual(len(O_parent.species), 1)
Exemplo n.º 5
0
 def setUpClass(cls):
     cls.file_location = os.path.dirname(os.path.abspath(__file__))
     cls.project = Project(
         os.path.join(cls.file_location, "../static/sphinx"))
     pt = PeriodicTable()
     pt.add_element(parent_element="Fe", new_element="Fe_up", spin="0.5")
     Fe_up = pt.element("Fe_up")
     cls.basis = Atoms(
         elements=[Fe_up, Fe_up],
         scaled_positions=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]],
         cell=2.6 * np.eye(3),
     )
     cls.sphinx = cls.project.create_job("Sphinx", "job_sphinx")
     cls.sphinx_band_structure = cls.project.create_job(
         "Sphinx", "sphinx_test_bs")
     cls.sphinx_2_3 = cls.project.create_job("Sphinx", "sphinx_test_2_3")
     cls.sphinx_2_5 = cls.project.create_job("Sphinx", "sphinx_test_2_5")
     cls.sphinx_aborted = cls.project.create_job("Sphinx",
                                                 "sphinx_test_aborted")
     cls.sphinx.structure = cls.basis
     cls.sphinx.fix_spin_constraint = True
     cls.sphinx_band_structure.structure = cls.project.create_structure(
         "Fe", "bcc", 2.81)
     cls.sphinx_band_structure.structure = cls.sphinx_band_structure.structure.create_line_mode_structure(
     )
     cls.sphinx_2_3.structure = Atoms(
         elements=["Fe", "Fe"],
         scaled_positions=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]],
         cell=2.6 * np.eye(3),
     )
     cls.sphinx_2_5.structure = Atoms(
         elements=["Fe", "Ni"],
         scaled_positions=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]],
         cell=2.83 * np.eye(3),
     )
     cls.sphinx_aborted.structure = Atoms(
         elements=32 * ["Fe"],
         scaled_positions=np.arange(32 * 3).reshape(-1, 3) / (32 * 3),
         cell=3.5 * np.eye(3),
     )
     cls.sphinx_aborted.status.aborted = True
     cls.current_dir = os.path.abspath(os.getcwd())
     cls.sphinx._create_working_directory()
     cls.sphinx_2_3._create_working_directory()
     cls.sphinx.input["VaspPot"] = False
     cls.sphinx.structure.add_tag(selective_dynamics=(True, True, True))
     cls.sphinx.structure.selective_dynamics[1] = (False, False, False)
     cls.sphinx.load_default_groups()
     cls.sphinx.fix_symmetry = False
     cls.sphinx.write_input()
     try:
         cls.sphinx.version = "2.6"
     except ValueError:
         cls.sphinx.version = "2.6.2_default"
     cls.sphinx_2_3.to_hdf()
     cls.sphinx_2_3.decompress()
     cls.sphinx_2_5.decompress()
Exemplo n.º 6
0
 def test_get_chemical_symbols(self):
     self.assertTrue(
         np.array_equal(self.CO2.get_chemical_symbols(), ["C", "O", "O"]))
     cell = np.eye(3) * 10.0
     pse = PeriodicTable()
     pse.add_element("O", "O_up", spin="up")
     o_up = pse.element("O_up")
     basis = Atoms([o_up], scaled_positions=[[0.27, 0.27, 0.27]], cell=cell)
     self.assertTrue(np.array_equal(basis.get_chemical_symbols(), ["O_up"]))
Exemplo n.º 7
0
 def test__eq__(self):
     pse = PeriodicTable()
     pse.add_element("O", "O_up", spin="up")
     o_up = pse.element("O_up")
     o_1 = pse.element("O")
     o_2 = pse.element("O")
     h_1 = pse.element("H")
     self.assertNotEqual(o_up, o_1)
     self.assertNotEqual(o_up, o_2)
     self.assertEqual(o_1, o_2)
     self.assertNotEqual(o_1, h_1)
Exemplo n.º 8
0
    def test__delitem__(self):
        cell = np.eye(3) * 10.0
        basis_0 = Atoms(["O"], scaled_positions=[[0.5, 0.5, 0.5]], cell=cell)
        basis_1 = Atoms(["H"],
                        scaled_positions=[[0.75, 0.75, 0.75]],
                        cell=cell)
        basis_2 = Atoms(["H"],
                        scaled_positions=[[0.25, 0.25, 0.25]],
                        cell=cell)
        basis_3 = Atoms(["H", "O", "N"],
                        scaled_positions=[[0.35, 0.35, 0.35], [0., 0., 0.],
                                          [0., 0., 0.1]],
                        cell=cell)

        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis_4 = Atoms([o_up],
                        scaled_positions=[[0.27, 0.27, 0.27]],
                        cell=cell)
        b = basis_0 + basis_1 + basis_2 + basis_3 + basis_4
        O_indices = b.select_index("O")
        self.assertEqual(len(b), 7)
        self.assertEqual(len(b.indices), 7)
        self.assertEqual(len(b.species), 4)
        b.__delitem__(O_indices[0])
        self.assertEqual(b.get_chemical_formula(), "H3NOO_up")
        self.assertEqual(len(b), 6)
        self.assertEqual(len(b.indices), 6)
        self.assertEqual(len(b._tag_list), 6)
        self.assertEqual(len(b.species), 4)
        O_indices = b.select_index("O")
        b.__delitem__(O_indices)
        self.assertEqual(b.get_chemical_formula(), "H3NO_up")
        self.assertEqual(len(b), 5)
        self.assertEqual(len(b.indices), 5)
        self.assertEqual(len(b.species), 3)
        self.assertEqual(np.max(b.indices), 2)
        N_indices = b.select_index("N")
        b.__delitem__(N_indices)
        self.assertEqual(b.get_chemical_formula(), "H3O_up")
        self.assertEqual(len(b), 4)
        self.assertEqual(len(b.indices), 4)
        self.assertEqual(len(b.species), 2)
        self.assertEqual(np.max(b.indices), 1)
        O_indices = b.select_index(o_up)
        b.__delitem__(O_indices)
        self.assertEqual(b.get_chemical_formula(), "H3")
        self.assertEqual(len(b), 3)
        self.assertEqual(len(b.indices), 3)
        self.assertEqual(len(b.species), 1)
        self.assertEqual(np.max(b.indices), 0)
Exemplo n.º 9
0
 def test_gt__(self):
     pse = PeriodicTable()
     pse.add_element("O", "O_up", spin="up")
     o_up = pse.element("O_up")
     o_1 = pse.element("O")
     o_2 = pse.element("O")
     h_1 = pse.element("H")
     self.assertTrue(o_up > o_1)
     self.assertFalse(o_up < o_2)
     self.assertFalse(o_1 > o_2)
     self.assertFalse(o_1 < o_2)
     self.assertTrue(o_1 > h_1)
     self.assertTrue(o_up > h_1)
Exemplo n.º 10
0
 def test_parent_index(self):
     basis_Mg = CrystalStructure("Mg",
                                 bravais_basis="fcc",
                                 lattice_constant=4.2)
     basis_O = CrystalStructure("O",
                                bravais_basis="fcc",
                                lattice_constant=4.2)
     basis_O.positions += [0., 0., 0.5]
     basis = basis_Mg + basis_O
     basis.center_coordinates_in_unit_cell()
     basis.set_repeat([2, 2, 2])
     o_indices = basis.select_index("O")
     pse = PeriodicTable()
     pse.add_element("O", "O_up", spin="up")
     o_up = pse.element("O_up")
     basis[o_indices] = o_up
     self.assertTrue(np.array_equal(o_indices, basis.select_index(o_up)))
     self.assertEqual(len(basis.select_index("O")), 0)
     self.assertTrue(
         np.array_equal(o_indices, basis.select_parent_index("O")))
Exemplo n.º 11
0
    def create_element(
        parent_element, new_element_name=None, spin=None, potential_file=None
    ):
        """

        Args:
            parent_element (str, int): The parent element eq. "N", "O", "Mg" etc.
            new_element_name (str): The name of the new parent element (can be arbitrary)
            spin (float): Value of the magnetic moment (with sign)
            potential_file (str): Location of the new potential file if necessary

        Returns:
            atomistics.structure.periodic_table.ChemicalElement instance
        """
        periodic_table = PeriodicTable()
        if new_element_name is None:
            if spin is not None:
                new_element_name = (
                    parent_element + "_spin_" + str(spin).replace(".", "_")
                )
            else:
                new_element_name = parent_element + "_1"
        if potential_file is not None:
            if spin is not None:
                periodic_table.add_element(
                    parent_element=parent_element,
                    new_element=new_element_name,
                    spin=str(spin),
                    pseudo_potcar_file=potential_file,
                )
            else:
                periodic_table.add_element(
                    parent_element=parent_element,
                    new_element=new_element_name,
                    pseudo_potcar_file=potential_file,
                )
        elif spin is not None:
            periodic_table.add_element(
                parent_element=parent_element,
                new_element=new_element_name,
                spin=str(spin),
            )
        else:
            periodic_table.add_element(
                parent_element=parent_element, new_element=new_element_name
            )
        return periodic_table.element(new_element_name)
Exemplo n.º 12
0
class TestPeriodicTable(unittest.TestCase):
    """
    define unittest snippets for all python files in the structure directory
    these tests should run fast (a few 10 ms)
    TODO: add write and load to h5 (e.g. addElement needs respective changes in read/load routines)
    """

    def setUp(self):
        self.pse = PeriodicTable()

    def test_numbertechnic(self):
        el1 = self.pse.element(1)
        self.assertEqual(el1.Abbreviation, 'H')

    def test_Element_by_Abbreviation(self):
        el1 = self.pse.element("Na")
        self.assertEqual(el1.Abbreviation, 'Na')

    def test_Element_by_Index(self):
        el1 = self.pse.element(20)
        self.assertEqual(el1.Abbreviation, 'Ca')

    def test_Abbreviation_range(self):
        self.assertEqual(len(self.pse.dataframe.Abbreviation[self.pse.Period < 4]), 18)

    def test_add_element_without_tags(self):
        fe_up = self.pse.add_element("Fe", "B_up")
        self.assertEqual(int(fe_up.MeltingPoint), 1811)

    def test_add_Abbreviation_bug(self):
        fe_up = self.pse.add_element("Fe", "B_up")
        self.assertEqual(fe_up.Abbreviation, "B_up")

    def test_add_element_tags(self):
        fe_up = self.pse.add_element("Fe", "Fe_up", spin="up", pseudo_name='GGA', testtag='testtest')
        self.assertEqual(fe_up.Abbreviation, "Fe_up")
        self.assertEqual(fe_up.tags['spin'], "up")
        self.assertEqual(fe_up.tags["pseudo_name"], "GGA")
        self.assertEqual(fe_up.tags["testtag"], "testtest")

    def test_atomic_mass(self):
        el1 = self.pse.element("Fe")
        self.assertAlmostEqual(el1.AtomicMass, 55.845001, places=6)

    def test_group(self):
        el1 = self.pse.element("Fe")
        self.assertEqual(el1.Group, 8)

    def test_Period(self):
        el1 = self.pse.element("Fe")
        self.assertEqual(el1.Period, 4)

    def test_add_MeltingPoint(self):
        el1 = self.pse.element("Fe")
        self.assertEqual(int(el1.MeltingPoint), 1811)

    def test_set_item(self):
        el1 = self.pse.element('Fe')
        el1.MeltingPoint = 1900
        self.assertEqual(int(el1.MeltingPoint), 1900)

    def test_is_element(self):
        self.assertEqual(self.pse.is_element('Fe'), True)

    def test_Chemical_Element_to_and_from_hdf(self):
        ni_up = self.pse.add_element("Ni", "Ni_up", spin="up")
        pr = Project(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_periodic_table'))
        basis = pr.create_structure(element=ni_up, bravais_basis='fcc', lattice_constant=3.7)
        ham = pr.create_job(pr.job_type.Lammps, 'lammps_test_1')
        test_ham = pr.create_job(pr.job_type.Lammps, 'lammps_test_1')
        ham.structure = basis
        ham.to_hdf()
        test_ham.from_hdf()
        self.assertEqual(test_ham['input/structure/species'][0], ham['input/structure/species'][0])
        ham.remove()

    def test_Chemical_Element_to_and_from_hdf_with_None_Parent(self):
        pr = Project(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_periodic_table'))
        basis = pr.create_structure(element='Ni', bravais_basis='fcc', lattice_constant=3.7)
        ham = pr.create_job(pr.job_type.Lammps, 'lammps_test_2')
        test_ham = pr.create_job(pr.job_type.Lammps, 'lammps_test_2')
        ham.structure = basis
        ham.to_hdf()
        test_ham.from_hdf()
        self.assertEqual(test_ham['input/structure/species'][0], ham['input/structure/species'][0])
        ham.remove()

    def test_add_tags(self):
        tag_dic = {'a': 'b', 'c': 'd', 'e': 'f'}
        fe_up = self.pse.add_element("Fe", "Fe_up", spin="up", pseudo_name='GGA', testtag='testtest')
        fe_up.add_tags(tag_dic)
        self.assertEqual(fe_up.tags['spin'], "up")
        self.assertEqual(fe_up.tags["a"], "b")
        self.assertEqual(fe_up.tags["c"], "d")
        self.assertEqual(fe_up.tags["e"], "f")

    def test__eq__(self):
        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        o_1 = pse.element("O")
        o_2 = pse.element("O")
        h_1 = pse.element("H")
        self.assertNotEqual(o_up, o_1)
        self.assertNotEqual(o_up, o_2)
        self.assertEqual(o_1, o_2)
        self.assertNotEqual(o_1, h_1)

    def test_gt__(self):
        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        o_1 = pse.element("O")
        o_2 = pse.element("O")
        h_1 = pse.element("H")
        self.assertTrue(o_up > o_1)
        self.assertFalse(o_up < o_2)
        self.assertFalse(o_1 > o_2)
        self.assertFalse(o_1 < o_2)
        self.assertTrue(o_1 > h_1)
        self.assertTrue(o_up > h_1)

    def test_ge__(self):
        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_1 = pse.element("O")
        o_2 = pse.element("O")
        self.assertTrue(o_1 <= o_2)
        self.assertTrue(o_1 >= o_2)
Exemplo n.º 13
0
    def test__setitem__(self):
        basis = self.CO2.copy()
        basis[0] = 'H'
        basis[1] = 'H'
        self.assertEqual(basis.get_chemical_formula(), "H2O")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis = self.CO2.copy()
        basis[0] = 'H'
        basis[np.int64(0)] = 'H'
        self.assertEqual(basis.get_chemical_formula(), "HO2")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis[0] = 'O'
        self.assertEqual(basis.get_chemical_formula(), "O3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
        basis = self.CO2.copy()
        basis[[2]] = 'N'
        self.assertEqual(basis.get_chemical_formula(), "CNO")
        self.assertEqual(len(basis.species), 3)
        self.assertEqual(len(basis.get_species_symbols()), 3)
        basis = self.CO2.copy()
        basis[[0]] = 'H'
        basis[np.array([0])] = 'H'
        self.assertEqual(basis.get_chemical_formula(), "HO2")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)

        basis = self.CO2.copy()
        basis[[0]] = 'N'
        self.assertEqual(basis.get_chemical_formula(), "NO2")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis[[0]] = 'O'
        self.assertEqual(basis.get_chemical_formula(), "O3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
        basis[[0, 2]] = 'H'
        self.assertEqual(basis.get_chemical_formula(), "H2O")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis[[0, 2]] = o_up
        self.assertEqual(basis.get_chemical_formula(), "OO_up2")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis[0:3] = "N"
        self.assertEqual(basis.get_chemical_formula(), "N3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
        basis[:] = "Ne"
        self.assertEqual(basis.get_chemical_formula(), "Ne3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
        basis[-2:] = "H"
        self.assertEqual(basis.get_chemical_formula(), "H2Ne")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis[0:3] = "O"
        self.assertEqual(basis.get_chemical_formula(), "O3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
Exemplo n.º 14
0
    def test__add__(self):
        cell = np.eye(3) * 10.0
        basis_0 = Atoms(["O"], scaled_positions=[[0.5, 0.5, 0.5]], cell=cell)
        basis_1 = Atoms(["H"],
                        scaled_positions=[[0.75, 0.75, 0.75]],
                        cell=cell)
        basis_2 = Atoms(["H"],
                        scaled_positions=[[0.25, 0.25, 0.25]],
                        cell=cell)
        basis_3 = Atoms(["H", "O", "N"],
                        scaled_positions=[[0.35, 0.35, 0.35], [0., 0., 0.],
                                          [0., 0., 0.1]],
                        cell=cell)

        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis_4 = Atoms([o_up],
                        scaled_positions=[[0.27, 0.27, 0.27]],
                        cell=np.eye(3) * 20.0)
        b = basis_0 + basis_1
        self.assertEqual(b.get_chemical_formula(), "HO")
        b = basis_0 + basis_1 + basis_2
        self.assertEqual(b.get_chemical_formula(), "H2O")
        b += basis_2
        self.assertEqual(b.get_chemical_formula(), "H3O")
        b = basis_0 + basis_1 + basis_2 + basis_3
        self.assertEqual(b.get_chemical_formula(), "H3NO2")
        self.assertTrue(
            np.array_equal(b.scaled_positions[b.select_index("N")],
                           [[0., 0., 0.1]]))
        self.assertTrue(
            np.allclose(
                b.scaled_positions[b.select_index("H")],
                [[0.75, 0.75, 0.75], [0.25, 0.25, 0.25], [0.35, 0.35, 0.35]]))
        self.assertTrue(
            np.allclose(b.scaled_positions[b.select_index("O")],
                        [[0.5, 0.5, 0.5], [0., 0., 0.]]))
        b.set_repeat([2, 2, 2])
        self.assertEqual(b.get_chemical_formula(), "H24N8O16")
        b += basis_4
        self.assertEqual(b.get_chemical_formula(), "H24N8O16O_up")
        self.assertTrue(
            np.allclose(b.scaled_positions[b.select_index(o_up)],
                        [[0.27, 0.27, 0.27]]))
        COX = self.C2 + Atom("O", position=[0, 0, -2])
        COX += Atom("O", position=[0, 0, -4])
        COX += COX
        n_objects = len(set(COX.get_species_objects()))
        n_species = len(set(COX.get_chemical_elements()))
        self.assertEqual(n_objects, n_species)
        self.assertEqual(n_objects, 2)
        self.assertEqual(n_species, 2)
        basis_Mg = CrystalStructure("Mg",
                                    bravais_basis="fcc",
                                    lattice_constant=4.2)
        basis_O = CrystalStructure("O",
                                   bravais_basis="fcc",
                                   lattice_constant=4.2)
        # basis_O.set_relative()
        basis_O.scaled_positions += [0., 0., 0.5]
        basis = basis_Mg + basis_O
        self.assertEqual(len(basis._tag_list),
                         len(basis_Mg._tag_list) + len(basis_O._tag_list))
        basis.center_coordinates_in_unit_cell()
        self.assertEqual(basis.get_spacegroup()["Number"], 225)
Exemplo n.º 15
0
class TestAtoms(unittest.TestCase):
    @classmethod
    def tearDownClass(cls):
        if sys.version_info[0] >= 3:
            file_location = os.path.dirname(os.path.abspath(__file__))
            if os.path.isfile(
                    os.path.join(file_location,
                                 "../../static/atomistics/test_hdf")):
                os.remove(
                    os.path.join(file_location,
                                 "../../static/atomistics/test_hdf"))

    def setUp(self):
        pass
        self.CO2 = Atoms("CO2",
                         positions=[[0, 0, 0], [0, 0, 1.5], [0, 1.5, 0]])
        C = Atom('C').element
        self.C3 = Atoms([C, C, C], positions=[[0, 0, 0], [0, 0, 2], [0, 2, 0]])
        self.C2 = Atoms(2 * [Atom('C')])

    def test__init__(self):
        pos, cell = generate_fcc_lattice()
        pse = PeriodicTable()
        el = pse.element("Al")
        basis = Atoms()
        self.assertIsInstance(basis, Atoms)
        self.assertIsInstance(basis.info, dict)
        self.assertIsInstance(basis.arrays, dict)
        self.assertIsInstance(basis.adsorbate_info, dict)
        self.assertIsInstance(basis.units, dict)
        self.assertIsInstance(basis.pbc, (bool, list, np.ndarray))
        self.assertIsInstance(basis.indices, np.ndarray)
        self.assertIsNone(basis._internal_positions)
        self.assertIsNone(basis.positions)
        self.assertIsNone(basis.scaled_positions)
        self.assertIsInstance(basis.species, list)
        self.assertIsInstance(basis.elements, np.ndarray)
        self.assertIsNone(basis.cell)
        basis = Atoms(symbols='Al', positions=pos, cell=cell)
        self.assertIsInstance(basis, Atoms)
        self.assertEqual(basis.get_spacegroup()["Number"], 225)
        basis = Atoms(elements='Al', positions=pos, cell=cell)
        self.assertIsInstance(basis, Atoms)
        basis = Atoms(elements=['Al'], positions=pos, cell=cell)
        self.assertIsInstance(basis, Atoms)
        self.assertRaises(ValueError,
                          Atoms,
                          symbols="Pt",
                          elements='Al',
                          positions=pos,
                          cell=cell)
        basis = Atoms(numbers=[13], positions=pos, cell=cell)
        self.assertEqual(basis.get_majority_species()[1], "Al")
        basis = Atoms(species=[el], indices=[0], positions=pos, cell=cell)
        self.assertEqual(basis.get_majority_species()[1], "Al")
        self.assertIsInstance(basis, Atoms)
        self.assertIsInstance(basis.info, dict)
        self.assertIsInstance(basis.arrays, dict)
        self.assertIsInstance(basis.adsorbate_info, dict)
        self.assertIsInstance(basis.units, dict)
        self.assertIsInstance(basis.pbc, (bool, list, np.ndarray))
        self.assertIsInstance(basis.indices, np.ndarray)
        self.assertIsInstance(basis.species, list)
        self.assertIsInstance(basis.cell, np.ndarray)
        self.assertIsInstance(basis._internal_positions, np.ndarray)
        self.assertIsInstance(basis.positions, np.ndarray)
        self.assertIsInstance(basis.scaled_positions, np.ndarray)
        self.assertIsInstance(basis.elements, np.ndarray)

    def test_set_species(self):
        pos, cell = generate_fcc_lattice()
        pse = PeriodicTable()
        el = pse.element("Pt")
        basis = Atoms(symbols='Al', positions=pos, cell=cell)
        self.assertEqual(basis.get_chemical_formula(), "Al")
        basis.set_species([el])
        self.assertEqual(basis.get_chemical_formula(), "Pt")
        self.assertTrue("Al" not in [sp.Abbreviation]
                        for sp in basis._species_to_index_dict.keys())
        self.assertTrue("Pt" in [sp.Abbreviation]
                        for sp in basis._species_to_index_dict.keys())

    def test_new_array(self):
        pos, cell = generate_fcc_lattice()
        basis = Atoms(symbols='Al', positions=pos, cell=cell)
        basis.set_repeat([10, 10, 10])
        spins = np.ones(len(basis))
        basis.new_array(name="spins", a=spins)
        self.assertTrue(np.array_equal(basis.arrays['spins'], spins))

    def test_set_array(self):
        pos, cell = generate_fcc_lattice()
        basis = Atoms(symbols='Al', positions=pos, cell=cell)
        basis.set_repeat([10, 10, 10])
        spins = np.ones(len(basis), dtype=float)
        basis.set_array(name="spins", a=2 * spins, dtype=int)
        self.assertTrue(np.array_equal(basis.arrays['spins'], 2 * spins))

    def test_get_array(self):
        pos, cell = generate_fcc_lattice()
        basis = Atoms(symbols='Al', positions=pos, cell=cell)
        basis.set_repeat([10, 10, 10])
        spins = np.ones(len(basis), dtype=float)
        basis.set_array(name="spins", a=2 * spins, dtype=int)
        self.assertTrue(np.array_equal(basis.arrays['spins'], 2 * spins))
        self.assertTrue(
            np.array_equal(basis.get_array(name="spins"), 2 * spins))

    def test_add_tags(self):
        self.CO2.add_tag(test_tag="a")
        self.assertIsInstance(self.CO2.test_tag, SparseList)
        self.assertEqual(self.CO2.test_tag[0], "a")
        self.assertEqual(self.CO2.test_tag[0], self.CO2.test_tag[2])
        self.assertIsInstance(self.CO2.test_tag.list(), list)
        self.CO2.add_tag(selective_dynamics=[True, True, True])
        self.CO2.selective_dynamics[1] = [True, False, True]
        self.assertEqual(self.CO2.selective_dynamics[1], [True, False, True])
        self.assertIsInstance(self.CO2.selective_dynamics.list(), list)

    def test_get_tags(self):
        self.CO2.add_tag(test_tag="a")
        self.assertIsInstance(self.CO2.test_tag, SparseList)
        self.assertIsInstance(self.CO2.get_tags(), type(dict().keys()))

    def test_get_pbc(self):
        self.assertTrue(np.array_equal(self.CO2.pbc, self.CO2.get_pbc()))
        self.assertEqual(len(self.CO2.get_pbc()), 3)

    def test_set_pbc(self):
        self.CO2.set_pbc(value=[True, True, False])
        self.assertTrue(np.array_equal(self.CO2.pbc, self.CO2.get_pbc()))
        self.assertTrue(np.array_equal([True, True, False],
                                       self.CO2.get_pbc()))
        self.CO2.set_pbc(value=False)
        self.assertTrue(
            np.array_equal([False, False, False], self.CO2.get_pbc()))
        self.assertTrue(np.array_equal(self.CO2.pbc, self.CO2.get_pbc()))

    def test_chemical_element(self):
        self.assertIsInstance(self.CO2.convert_element('C'), ChemicalElement)
        self.assertEqual(len(self.CO2.species), 2)

    def test_copy(self):
        pos, cell = generate_fcc_lattice()
        basis = Atoms(symbols='Al', positions=pos, cell=cell)
        basis_copy = basis.copy()
        self.assertEqual(basis, basis_copy)
        basis_copy[:] = "Pt"
        self.assertNotEqual(basis, basis_copy)

    def test_numbers_to_elements(self):
        num_list = [1, 12, 13, 6]
        self.assertTrue(
            np.array_equal([
                el.Abbreviation
                for el in self.CO2.numbers_to_elements(num_list)
            ], ['H', 'Mg', 'Al', 'C']))

    def test_to_hdf(self):
        if sys.version_info[0] >= 3:
            filename = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                    "../../static/atomistics/test_hdf")
            abs_filename = os.path.abspath(filename)
            hdf_obj = FileHDFio(abs_filename)
            pos, cell = generate_fcc_lattice()
            basis = Atoms(symbols='Al', positions=pos, cell=cell)
            basis.set_repeat([2, 2, 2])
            basis.to_hdf(hdf_obj, "test_structure")
            self.assertTrue(
                np.array_equal(hdf_obj["test_structure/positions"],
                               basis.positions))
            basis_new = Atoms().from_hdf(hdf_obj, "test_structure")
            self.assertEqual(basis, basis_new)

    def test_from_hdf(self):
        if sys.version_info[0] >= 3:
            filename = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                    "../../static/atomistics/test_hdf")
            abs_filename = os.path.abspath(filename)
            hdf_obj = FileHDFio(abs_filename)
            pos, cell = generate_fcc_lattice()
            basis_store = Atoms(symbols='Al', positions=pos, cell=cell)
            basis_store.set_repeat([2, 2, 2])
            basis_store.to_hdf(hdf_obj, "simple_structure")
            basis = Atoms().from_hdf(hdf_obj, group_name="simple_structure")
            self.assertEqual(len(basis), 8)
            self.assertEqual(basis.get_majority_species()[1], "Al")
            self.assertEqual(basis.get_spacegroup()['Number'], 225)

    def create_Fe_bcc(self):
        self.pse = PeriodicTable()
        self.pse.add_element("Fe", "Fe_up", spin="up", pseudo_name='GGA')
        self.pse.add_element("Fe", "Fe_down", spin="down", pseudo_name='GGA')
        Fe_up = self.pse.element("Fe_up")
        Fe_down = self.pse.element("Fe_down")
        self.Fe_bcc = Atoms([Fe_up, Fe_down],
                            scaled_positions=[[0, 0, 0], [0.25, 0.25, 0.25]],
                            cell=np.identity(3))
        self.Fe_bcc.add_tag("group")
        self.Fe_bcc.group[:] = 0

    def test_convert_formula(self):
        self.assertEqual(self.CO2.convert_formula('C'), ['C'])
        self.assertEqual(self.CO2.convert_formula('C3'), ['C', 'C', 'C'])
        self.assertEqual(self.CO2.convert_formula('CO2'), ['C', 'O', 'O'])
        self.assertEqual(self.CO2.convert_formula('CO2Fe'),
                         ['C', 'O', 'O', 'Fe'])
        self.assertEqual(self.CO2.convert_formula('CO2FeF21'),
                         ['C', 'O', 'O', 'Fe', 'F', 'F'])

    def test__getitem__(self):
        self.assertEqual(self.CO2[0].symbol, 'C')
        self.assertEqual(self.C3[2].position.tolist(), [0, 2, 0])
        self.assertTrue((self.C3[1:].positions == np.array([[0, 0, 2],
                                                            [0, 2, 0]])).all())
        short_basis = self.CO2[0]
        self.assertIsInstance(short_basis, Atom)
        short_basis = self.CO2[[0]]
        self.assertIsInstance(short_basis, Atoms)
        self.assertEqual(short_basis.indices[0], 0)
        self.assertEqual(len(short_basis.species), 1)
        short_basis = self.CO2[[2]]
        self.assertIsInstance(short_basis, Atoms)
        self.assertEqual(short_basis.indices[0], 0)
        self.assertEqual(len(short_basis.species), 1)
        basis_Mg = CrystalStructure("Mg",
                                    bravais_basis="fcc",
                                    lattice_constant=4.2)
        basis_O = CrystalStructure("O",
                                   bravais_basis="fcc",
                                   lattice_constant=4.2)
        basis_O.positions += [0., 0., 0.5]
        basis = basis_Mg + basis_O
        basis.center_coordinates_in_unit_cell()
        basis.set_repeat([3, 3, 3])
        mg_indices = basis.select_index("Mg")
        o_indices = basis.select_index("O")
        basis_new = basis[mg_indices] + basis[o_indices]
        self.assertEqual(len(basis_new._tag_list),
                         len(basis[mg_indices]) + len(basis[o_indices]))
        self.assertEqual(basis_new.get_spacegroup()["Number"], 225)

    def test_positions(self):
        self.assertEqual(self.CO2[1:].positions[1:].tolist(),
                         [[0.0, 1.5, 0.0]])
        self.CO2.positions[1][0] = 5.
        self.assertEqual(self.CO2.positions[1].tolist(), [5.0, 0, 1.5])

    def test_set_positions(self):
        pos, cell = generate_fcc_lattice()
        basis = Atoms(symbols='Al', positions=pos, cell=cell)
        basis.set_positions(np.array([[2.5, 2.5, 2.5]]))
        self.assertTrue(np.array_equal(basis.positions, [[2.5, 2.5, 2.5]]))

    def test_set_scaled_positions(self):
        pos, cell = generate_fcc_lattice()
        basis = Atoms(symbols='Al', positions=pos, cell=cell, a=4.2)
        basis.set_scaled_positions(np.array([[0.5, 0.5, 0.5]]))
        self.assertTrue(
            np.array_equal(basis.scaled_positions, [[0.5, 0.5, 0.5]]))
        self.assertTrue(
            np.array_equal(basis.positions,
                           np.dot([[0.5, 0.5, 0.5]], basis.cell)))

    def test_cell(self):
        CO = Atoms("CO",
                   positions=[[0, 0, 0], [0, 0, 2]],
                   cell=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                   pbc=[True, True, True])
        self.assertTrue((CO.get_cell() == np.identity(3)).all())
        self.assertTrue((CO.cell == np.identity(3)).all())
        CO.cell[2][2] = 10.
        self.assertTrue(CO.cell[2, 2] == 10.)

    def test_add(self):
        COX = self.C2 + Atom("O", position=[0, 0, -2])
        COX += Atom("O", position=[0, 0, -4])
        COX += COX
        n_objects = len(set(COX.get_species_objects()))
        n_species = len(set(COX.get_chemical_elements()))
        self.assertEqual(n_objects, n_species)

    def test_pbc(self):
        CO = Atoms("CO",
                   positions=[[0, 0, 0], [0, 0, 2]],
                   cell=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                   pbc=[True, True, True])
        self.assertTrue((CO.pbc == np.array([True, True, True])).all())
        CO.set_pbc((True, True, False))

    def test_get_masses_DOF(self):
        self.assertEqual(len(self.CO2.get_masses_dof()),
                         len(self.CO2.positions.flatten()))

    def test_get_parent_basis(self):
        periodic_table = PeriodicTable()
        periodic_table.add_element(parent_element="O", new_element="O_up")
        O_up = periodic_table.element("O_up")

        O_basis = Atoms([O_up],
                        cell=10.0 * np.eye(3),
                        scaled_positions=[[0.5, 0.5, 0.5]])
        O_simple = Atoms(["O"],
                         cell=10.0 * np.eye(3),
                         scaled_positions=[[0.5, 0.5, 0.5]])
        O_parent = O_basis.get_parent_basis()
        self.assertNotEqual(O_basis, O_parent)
        self.assertEqual(O_simple, O_parent)
        self.assertEqual(O_parent[0].symbol, "O")
        periodic_table.add_element(parent_element="O", new_element="O_down")
        O_down = periodic_table.element("O_down")
        O_basis = Atoms([O_up, O_down],
                        cell=10.0 * np.eye(3),
                        scaled_positions=[[0.5, 0.5, 0.5], [0, 0, 0]])
        O_simple = Atoms(["O", "O"],
                         cell=10.0 * np.eye(3),
                         scaled_positions=[[0.5, 0.5, 0.5]])
        O_parent = O_basis.get_parent_basis()
        self.assertNotEqual(O_basis, O_parent)
        self.assertEqual(O_simple, O_parent)
        self.assertEqual(O_parent.get_chemical_formula(), "O2")
        self.assertEqual(len(O_basis.species), 2)
        self.assertEqual(len(O_simple.species), 1)
        self.assertEqual(len(O_parent.species), 1)

    def test_profiling(self):
        num = 1000
        C100 = Atoms(num * ["C"], positions=[(0, 0, 0) for _ in range(num)])
        self.assertEqual(len(C100), num)

    def test_Au(self):
        a = 4.05  # Gold lattice constant
        b = a / 2.
        fcc = Atoms(['Au'], cell=[(0, b, b), (b, 0, b), (b, b, 0)], pbc=True)
        # print fcc
        # print "volume: ", fcc.get_volume()

    def test_set_absolute(self):
        a = 4.05  # Gold lattice constant
        b = a / 2.
        positions = np.array([(0.5, 0.4, 0.)])
        fcc = Atoms(symbols=['Au'],
                    scaled_positions=positions,
                    cell=[(0, b, b), (b, 0, b), (b, b, 0)],
                    pbc=True)
        # fcc.set_absolute()
        # print fcc.positions
        # fcc.set_relative()
        self.assertTrue(
            np.linalg.norm(fcc.scaled_positions - positions) < 1e-10)

    def test_repeat(self):
        basis_Mg = CrystalStructure("Mg",
                                    bravais_basis="fcc",
                                    lattice_constant=4.2)
        basis_O = CrystalStructure("O",
                                   bravais_basis="fcc",
                                   lattice_constant=4.2)
        basis_O.scaled_positions += [0., 0., 0.5]
        basis = basis_Mg + basis_O
        basis.center_coordinates_in_unit_cell()
        basis.add_tag(selective_dynamics=[True, True, True])
        basis.selective_dynamics[basis.select_index("O")] = [
            False, False, False
        ]
        len_before = len(basis)
        sel_dyn_before = np.array(basis.selective_dynamics.list())
        self.assertTrue(
            np.alltrue(
                np.logical_not(
                    np.alltrue(sel_dyn_before[basis.select_index("O")],
                               axis=1))))
        self.assertTrue(
            np.alltrue(
                np.alltrue(sel_dyn_before[basis.select_index("Mg")], axis=1)))
        basis.set_repeat([3, 3, 2])
        sel_dyn_after = np.array(basis.selective_dynamics.list())
        len_after = len(basis)
        self.assertEqual(basis.get_spacegroup()["Number"], 225)
        self.assertEqual(len_before * 18, len_after)
        self.assertEqual(len(sel_dyn_before) * 18, len(sel_dyn_after))
        self.assertTrue(
            np.alltrue(
                np.logical_not(
                    np.alltrue(sel_dyn_after[basis.select_index("O")],
                               axis=1))))
        self.assertTrue(
            np.alltrue(
                np.alltrue(sel_dyn_after[basis.select_index("Mg")], axis=1)))

    def test_boundary(self):
        cell = 2.2 * np.identity(3)
        NaCl = Atoms('NaCl',
                     scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                     cell=cell)
        NaCl.set_repeat([3, 3, 3])
        # NaCl.plot3d()
        NaCl_bound = NaCl.get_boundary_region(0.2)
        # NaCl_bound.plot3d()

    def test_get_distance(self):
        cell = 2.2 * np.identity(3)
        NaCl = Atoms('NaCl',
                     scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                     cell=cell)
        self.assertAlmostEqual(NaCl.get_distance(0, 1), 2.2 * 0.5 * np.sqrt(3))
        self.assertAlmostEqual(NaCl.get_distance(0, [0, 0, 0.5]), 0.5)
        self.assertAlmostEqual(NaCl.get_distance([0, 0, 0], [0, 0, 0.5]), 0.5)

    def test_get_neighbors(self):
        cell = 2.2 * np.identity(3)
        NaCl = Atoms('NaCl',
                     scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                     cell=cell)
        # NaCl.repeat([3, 3, 3])
        # NaCl.positions = [(1,1,1)]
        boundary = NaCl.get_boundary_region(3.5)
        extended_cell = NaCl + boundary
        # extended_cell.plot3d()
        nbr_dict = NaCl.get_neighbors(num_neighbors=12, t_vec=True)
        # print nbr_dict.distances
        # print [set(s) for s in nbr_dict.shells]

    def test_center_coordinates(self):
        cell = 2.2 * np.identity(3)
        NaCl = Atoms('NaCl',
                     scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                     cell=cell)
        NaCl.set_repeat([3, 3, 3])
        NaCl.positions += [2.2, 2.2, 2.2]
        NaCl.center_coordinates_in_unit_cell(origin=-0.5)
        self.assertTrue(-0.5 < np.min(NaCl.scaled_positions))
        self.assertTrue(np.max(NaCl.scaled_positions < 0.5))
        NaCl.center_coordinates_in_unit_cell(origin=0.)
        self.assertTrue(0 <= np.min(NaCl.positions))
        self.assertTrue(np.max(NaCl.scaled_positions < 1))

    def test_get_shells(self):
        dim = 3
        cell = 2.2 * np.identity(dim)
        Al_sc = Atoms('AlAl',
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=cell)
        Al_sc.set_repeat([3, 3, 3])
        self.assertEqual(np.round(Al_sc.get_shells()[2], 6), 2.2)

    def test_get_shell_matrix(self):
        basis = Atoms('FeFe',
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=np.identity(3))
        output = basis.get_shell_matrix(shell=1)
        self.assertIsInstance(output, np.ndarray)
        self.assertEqual(np.sum(output), 16)
        self.assertTrue(np.all(np.dot(output, output) == np.identity(2) * 64))

    def test_get_distance_matrix(self):
        basis = Atoms('FeFe',
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=np.identity(3))
        output = basis.get_distance_matrix()
        self.assertIsInstance(output, np.ndarray)
        output = np.rint(output * 2 / np.sqrt(3))
        self.assertTrue(np.all(np.dot(output, output) == np.identity(2)))

    def test_cluster_analysis(self):
        import random
        cell = 2.2 * np.identity(3)
        Al_sc = Atoms(elements=['Al', 'Al'],
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=cell)
        Al_sc.set_repeat([4, 4, 4])
        radius = Al_sc.get_shell_radius()
        neighbors = Al_sc.get_neighbors(radius=radius,
                                        num_neighbors=100,
                                        t_vec=False,
                                        exclude_self=True)

        c_Zn = 0.1
        pse = PeriodicTable()
        Zn = pse.element("Zn")
        random.seed(123456)
        for _ in range(1):
            Zn_ind = random.sample(range(len(Al_sc)), int(c_Zn * len(Al_sc)))
            # for i_Zn in Zn_ind:
            #     Al_sc.elements[i_Zn] = Zn

            cluster = Al_sc.cluster_analysis(Zn_ind, neighbors)
            cluster_len = np.sort([len(v) for k, v in cluster.items()])
            # print np.histogram(cluster_len), np.sum(cluster_len), len(Zn_ind)
            # for key, value in cluster.items():
            #     el = pse.Element((key % 100) + 1)
            #     for i_el in value:
            #         Al_sc.elements[i_el] = el
            # Al_sc.plot3d()

    def test_get_bonds(self):
        dim = 3
        cell = 2.62 * np.identity(dim)
        d1, d2 = 0.6, 0.6
        H2O = Atoms('H2O',
                    scaled_positions=[(d1, d2, 0), (d1, -d2, 0), (0, 0, 0)],
                    cell=cell)
        H2O.set_repeat([1, 1, 3])
        # H2O.plot3d(show_bonds=True) #, bond_stretch=2)
        # print H2O.get_bonds(radius=2.)[0]
        # print np.sum(H2O.get_masses())/H2O.get_volume()

    def test_get_symmetry(self):
        cell = 2.2 * np.identity(3)
        Al = Atoms('AlAl', positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                   cell=cell).repeat(2)
        self.assertEqual(len(set(Al.get_symmetry()['equivalent_atoms'])), 1)
        self.assertEqual(len(Al.get_symmetry()['translations']), 96)
        self.assertEqual(len(Al.get_symmetry()['translations']),
                         len(Al.get_symmetry()['rotations']))

    def _get_voronoi_vertices(self):
        cell = 2.2 * np.identity(3)
        Al = Atoms('AlAl',
                   scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                   cell=cell)
        pos, box = Al._get_voronoi_vertices()
        self.assertEqual(len(pos), 14)

    def get_equivalent_voronoi_vertices(self):
        cell = 2.2 * np.identity(3)
        Al = Atoms('AlAl', positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                   cell=cell).repeat(2)
        pos, box = Al._get_voronoi_vertices()
        self.assertEqual(len(Al), 69)
        self.assertEqual(len(len(Al.get_species_symbols())), 2)
        Al = Atoms('AlAl',
                   scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                   cell=cell).repeat(2)
        pos = Al.get_equivalent_voronoi_vertices()
        self.assertEqual(len(pos), 1)

    def test_get_parent_symbols(self):
        self.assertTrue(
            np.array_equal(self.CO2.get_parent_symbols(), ["C", "O", "O"]))
        self.assertTrue(
            np.array_equal(self.CO2.get_parent_symbols(),
                           self.CO2.get_chemical_symbols()))
        cell = np.eye(3) * 10.0
        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis = Atoms([o_up], scaled_positions=[[0.27, 0.27, 0.27]], cell=cell)
        self.assertTrue(np.array_equal(basis.get_parent_symbols(), ["O"]))
        self.assertFalse(
            np.array_equal(basis.get_parent_symbols(),
                           basis.get_chemical_symbols()))

    def test_get_chemical_symbols(self):
        self.assertTrue(
            np.array_equal(self.CO2.get_chemical_symbols(), ["C", "O", "O"]))
        cell = np.eye(3) * 10.0
        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis = Atoms([o_up], scaled_positions=[[0.27, 0.27, 0.27]], cell=cell)
        self.assertTrue(np.array_equal(basis.get_chemical_symbols(), ["O_up"]))

    def test_get_symmetry_dataset(self):
        cell = 2.2 * np.identity(3)
        Al_sc = Atoms('AlAl',
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=cell)
        Al_sc.set_repeat([2, 2, 2])
        self.assertEqual(Al_sc.get_symmetry_dataset()['number'], 229)

    def test_get_space_group(self):
        cell = 2.2 * np.identity(3)
        Al_sc = Atoms('AlAl',
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=cell)
        self.assertEqual(Al_sc.get_spacegroup()['InternationalTableSymbol'],
                         'Im-3m')
        self.assertEqual(Al_sc.get_spacegroup()['Number'], 229)
        cell = 4.2 * (0.5 * np.ones((3, 3)) - 0.5 * np.eye(3))
        Al_fcc = Atoms('Al', scaled_positions=[(0, 0, 0)], cell=cell)
        self.assertEqual(Al_fcc.get_spacegroup()['InternationalTableSymbol'],
                         'Fm-3m')
        self.assertEqual(Al_fcc.get_spacegroup()['Number'], 225)
        a = 3.18
        c = 1.623 * a
        cell = np.eye(3)
        cell[0, 0] = a
        cell[2, 2] = c
        cell[1, 0] = -a / 2.
        cell[1, 1] = np.sqrt(3) * a / 2.
        pos = np.array([[0., 0., 0.], [1. / 3., 2. / 3., 1. / 2.]])
        Mg_hcp = Atoms('Mg2', scaled_positions=pos, cell=cell)
        self.assertEqual(Mg_hcp.get_spacegroup()['Number'], 194)
        cell = np.eye(3)
        cell[0, 0] = a
        cell[2, 2] = c
        cell[1, 1] = np.sqrt(3) * a
        pos = np.array([[0., 0., 0.], [0.5, 0.5, 0.], [0.5, 0.16666667, 0.5],
                        [0., 0.66666667, 0.5]])
        Mg_hcp = Atoms('Mg4', scaled_positions=pos, cell=cell)
        self.assertEqual(Mg_hcp.get_spacegroup()['Number'], 194)

    def test_get_primitive_cell(self):
        cell = 2.2 * np.identity(3)
        Al_sc = Atoms('AlFe',
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=cell)
        Al_sc.set_repeat([2, 2, 2])
        primitive_cell = Al_sc.get_primitive_cell()
        self.assertEqual(primitive_cell.get_spacegroup()['Number'], 221)

    def test_get_ir_reciprocal_mesh(self):
        cell = 2.2 * np.identity(3)
        Al_sc = Atoms('AlAl',
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=cell)
        self.assertEqual(len(Al_sc.get_ir_reciprocal_mesh([3, 3, 3])[0]), 27)

    def test_get_number_species_atoms(self):
        self.assertEqual(list(self.CO2.get_number_species_atoms().values()),
                         [1, 2])

    def test_get_chemical_formula(self):
        self.assertEqual(self.CO2.get_chemical_formula(), "CO2")

    def test_get_equivalent_atoms(self):
        cell = 2.2 * np.identity(3)
        Al_sc = Atoms('AlFe',
                      scaled_positions=[(0, 0, 0), (0.5, 0.5, 0.5)],
                      cell=cell)
        Al_sc.set_repeat([2, 2, 2])

    def test_center(self):
        old_pos = self.CO2.positions.copy()
        self.CO2.center(vacuum=5)
        new_array = old_pos + 5 * np.ones(3)
        self.assertTrue(np.array_equal(self.CO2.positions, new_array))

    def test_get_positions(self):
        basis_Mg = CrystalStructure("Mg",
                                    bravais_basis="fcc",
                                    lattice_constant=4.2)
        self.assertTrue(
            np.array_equal(basis_Mg.positions, basis_Mg.get_positions()))

    def test_get_scaled_positions(self):
        basis_Mg = CrystalStructure("Mg",
                                    bravais_basis="fcc",
                                    lattice_constant=4.2)
        self.assertTrue(
            np.array_equal(basis_Mg.scaled_positions,
                           basis_Mg.get_scaled_positions()))

    def test_occupy_lattice(self):
        basis_Mg = CrystalStructure("Mg",
                                    bravais_basis="fcc",
                                    lattice_constant=4.2)
        basis_O = CrystalStructure("O",
                                   bravais_basis="fcc",
                                   lattice_constant=4.2)
        basis_O.scaled_positions += [0., 0., 0.5]
        basis = basis_Mg + basis_O
        basis.center_coordinates_in_unit_cell()
        orig_basis = basis.copy()
        self.assertEqual(basis.get_chemical_formula(), "Mg4O4")
        Mg_indices = basis.select_index("Mg")
        O_indices = basis.select_index("O")
        basis.occupy_lattice(Na=Mg_indices)
        self.assertEqual(basis.get_chemical_formula(), "Na4O4")
        basis.occupy_lattice(Cl=O_indices)
        self.assertEqual(basis.get_chemical_formula(), "Cl4Na4")
        self.assertTrue(np.array_equal(basis.select_index("Na"), Mg_indices))
        self.assertTrue(np.array_equal(basis.select_index("Cl"), O_indices))
        orig_basis.set_repeat([2, 2, 2])
        Mg_indices = orig_basis.select_index("Mg")
        O_indices = orig_basis.select_index("O")
        orig_basis.occupy_lattice(Cl=O_indices, Na=Mg_indices)
        self.assertEqual(orig_basis.get_chemical_formula(), "Cl32Na32")
        orig_basis.occupy_lattice(H=O_indices[0])
        self.assertEqual(orig_basis.get_chemical_formula(), "Cl31HNa32")

    def test_select_index(self):
        self.assertTrue(np.array_equal(self.CO2.select_index("C"), [0]))
        self.assertTrue(np.array_equal(self.CO2.select_index("O"), [1, 2]))

    def test_parent_index(self):
        basis_Mg = CrystalStructure("Mg",
                                    bravais_basis="fcc",
                                    lattice_constant=4.2)
        basis_O = CrystalStructure("O",
                                   bravais_basis="fcc",
                                   lattice_constant=4.2)
        basis_O.positions += [0., 0., 0.5]
        basis = basis_Mg + basis_O
        basis.center_coordinates_in_unit_cell()
        basis.set_repeat([2, 2, 2])
        o_indices = basis.select_index("O")
        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis[o_indices] = o_up
        self.assertTrue(np.array_equal(o_indices, basis.select_index(o_up)))
        self.assertEqual(len(basis.select_index("O")), 0)
        self.assertTrue(
            np.array_equal(o_indices, basis.select_parent_index("O")))

    def test__eq__(self):
        test_basis = self.CO2.copy()
        self.assertEqual(test_basis, self.CO2)
        test_basis.positions[2] += 0.0
        self.assertEqual(test_basis, self.CO2)
        self.assertNotEqual(self.C2, self.CO2)

    def test__add__(self):
        cell = np.eye(3) * 10.0
        basis_0 = Atoms(["O"], scaled_positions=[[0.5, 0.5, 0.5]], cell=cell)
        basis_1 = Atoms(["H"],
                        scaled_positions=[[0.75, 0.75, 0.75]],
                        cell=cell)
        basis_2 = Atoms(["H"],
                        scaled_positions=[[0.25, 0.25, 0.25]],
                        cell=cell)
        basis_3 = Atoms(["H", "O", "N"],
                        scaled_positions=[[0.35, 0.35, 0.35], [0., 0., 0.],
                                          [0., 0., 0.1]],
                        cell=cell)

        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis_4 = Atoms([o_up],
                        scaled_positions=[[0.27, 0.27, 0.27]],
                        cell=np.eye(3) * 20.0)
        b = basis_0 + basis_1
        self.assertEqual(b.get_chemical_formula(), "HO")
        b = basis_0 + basis_1 + basis_2
        self.assertEqual(b.get_chemical_formula(), "H2O")
        b += basis_2
        self.assertEqual(b.get_chemical_formula(), "H3O")
        b = basis_0 + basis_1 + basis_2 + basis_3
        self.assertEqual(b.get_chemical_formula(), "H3NO2")
        self.assertTrue(
            np.array_equal(b.scaled_positions[b.select_index("N")],
                           [[0., 0., 0.1]]))
        self.assertTrue(
            np.allclose(
                b.scaled_positions[b.select_index("H")],
                [[0.75, 0.75, 0.75], [0.25, 0.25, 0.25], [0.35, 0.35, 0.35]]))
        self.assertTrue(
            np.allclose(b.scaled_positions[b.select_index("O")],
                        [[0.5, 0.5, 0.5], [0., 0., 0.]]))
        b.set_repeat([2, 2, 2])
        self.assertEqual(b.get_chemical_formula(), "H24N8O16")
        b += basis_4
        self.assertEqual(b.get_chemical_formula(), "H24N8O16O_up")
        self.assertTrue(
            np.allclose(b.scaled_positions[b.select_index(o_up)],
                        [[0.27, 0.27, 0.27]]))
        COX = self.C2 + Atom("O", position=[0, 0, -2])
        COX += Atom("O", position=[0, 0, -4])
        COX += COX
        n_objects = len(set(COX.get_species_objects()))
        n_species = len(set(COX.get_chemical_elements()))
        self.assertEqual(n_objects, n_species)
        self.assertEqual(n_objects, 2)
        self.assertEqual(n_species, 2)
        basis_Mg = CrystalStructure("Mg",
                                    bravais_basis="fcc",
                                    lattice_constant=4.2)
        basis_O = CrystalStructure("O",
                                   bravais_basis="fcc",
                                   lattice_constant=4.2)
        # basis_O.set_relative()
        basis_O.scaled_positions += [0., 0., 0.5]
        basis = basis_Mg + basis_O
        self.assertEqual(len(basis._tag_list),
                         len(basis_Mg._tag_list) + len(basis_O._tag_list))
        basis.center_coordinates_in_unit_cell()
        self.assertEqual(basis.get_spacegroup()["Number"], 225)

    def test__delitem__(self):
        cell = np.eye(3) * 10.0
        basis_0 = Atoms(["O"], scaled_positions=[[0.5, 0.5, 0.5]], cell=cell)
        basis_1 = Atoms(["H"],
                        scaled_positions=[[0.75, 0.75, 0.75]],
                        cell=cell)
        basis_2 = Atoms(["H"],
                        scaled_positions=[[0.25, 0.25, 0.25]],
                        cell=cell)
        basis_3 = Atoms(["H", "O", "N"],
                        scaled_positions=[[0.35, 0.35, 0.35], [0., 0., 0.],
                                          [0., 0., 0.1]],
                        cell=cell)

        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis_4 = Atoms([o_up],
                        scaled_positions=[[0.27, 0.27, 0.27]],
                        cell=cell)
        b = basis_0 + basis_1 + basis_2 + basis_3 + basis_4
        O_indices = b.select_index("O")
        self.assertEqual(len(b), 7)
        self.assertEqual(len(b.indices), 7)
        self.assertEqual(len(b.species), 4)
        b.__delitem__(O_indices[0])
        self.assertEqual(b.get_chemical_formula(), "H3NOO_up")
        self.assertEqual(len(b), 6)
        self.assertEqual(len(b.indices), 6)
        self.assertEqual(len(b._tag_list), 6)
        self.assertEqual(len(b.species), 4)
        O_indices = b.select_index("O")
        b.__delitem__(O_indices)
        self.assertEqual(b.get_chemical_formula(), "H3NO_up")
        self.assertEqual(len(b), 5)
        self.assertEqual(len(b.indices), 5)
        self.assertEqual(len(b.species), 3)
        self.assertEqual(np.max(b.indices), 2)
        N_indices = b.select_index("N")
        b.__delitem__(N_indices)
        self.assertEqual(b.get_chemical_formula(), "H3O_up")
        self.assertEqual(len(b), 4)
        self.assertEqual(len(b.indices), 4)
        self.assertEqual(len(b.species), 2)
        self.assertEqual(np.max(b.indices), 1)
        O_indices = b.select_index(o_up)
        b.__delitem__(O_indices)
        self.assertEqual(b.get_chemical_formula(), "H3")
        self.assertEqual(len(b), 3)
        self.assertEqual(len(b.indices), 3)
        self.assertEqual(len(b.species), 1)
        self.assertEqual(np.max(b.indices), 0)

    def test__setitem__(self):
        basis = self.CO2.copy()
        basis[0] = 'H'
        basis[1] = 'H'
        self.assertEqual(basis.get_chemical_formula(), "H2O")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis = self.CO2.copy()
        basis[0] = 'H'
        basis[np.int64(0)] = 'H'
        self.assertEqual(basis.get_chemical_formula(), "HO2")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis[0] = 'O'
        self.assertEqual(basis.get_chemical_formula(), "O3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
        basis = self.CO2.copy()
        basis[[2]] = 'N'
        self.assertEqual(basis.get_chemical_formula(), "CNO")
        self.assertEqual(len(basis.species), 3)
        self.assertEqual(len(basis.get_species_symbols()), 3)
        basis = self.CO2.copy()
        basis[[0]] = 'H'
        basis[np.array([0])] = 'H'
        self.assertEqual(basis.get_chemical_formula(), "HO2")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)

        basis = self.CO2.copy()
        basis[[0]] = 'N'
        self.assertEqual(basis.get_chemical_formula(), "NO2")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis[[0]] = 'O'
        self.assertEqual(basis.get_chemical_formula(), "O3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
        basis[[0, 2]] = 'H'
        self.assertEqual(basis.get_chemical_formula(), "H2O")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        pse = PeriodicTable()
        pse.add_element("O", "O_up", spin="up")
        o_up = pse.element("O_up")
        basis[[0, 2]] = o_up
        self.assertEqual(basis.get_chemical_formula(), "OO_up2")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis[0:3] = "N"
        self.assertEqual(basis.get_chemical_formula(), "N3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
        basis[:] = "Ne"
        self.assertEqual(basis.get_chemical_formula(), "Ne3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)
        basis[-2:] = "H"
        self.assertEqual(basis.get_chemical_formula(), "H2Ne")
        self.assertEqual(len(basis.species), 2)
        self.assertEqual(len(basis.get_species_symbols()), 2)
        basis[0:3] = "O"
        self.assertEqual(basis.get_chemical_formula(), "O3")
        self.assertEqual(len(basis.species), 1)
        self.assertEqual(len(basis.get_species_symbols()), 1)