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__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 __init__( self, symbol="X", position=(0, 0, 0), tag=None, momentum=None, mass=None, magmom=None, charge=None, atoms=None, index=None, pse=None, element=None, **qwargs ): if element is None and symbol: element = symbol if tag or momentum or mass or magmom or charge: raise ValueError("Not supported parameter used!") SparseArrayElement.__init__(self, **qwargs) # super(SparseArrayElement, self).__init__(**qwargs) # verify that element is given (as string, ChemicalElement object or nucleus number if pse is None: pse = PeriodicTable() if element is None or element == "X": if "Z" in qwargs: el_symbol = pse.atomic_number_to_abbreviation(qwargs["Z"]) self._lists["element"] = pse.element(el_symbol) else: raise ValueError( "Need at least element name, Chemical element object or nucleus number" ) else: if isinstance(element, string_types): el_symbol = element self._lists["element"] = pse.element(el_symbol) elif isinstance(element, str): el_symbol = element self._lists["element"] = pse.element(el_symbol) elif isinstance(element, ChemicalElement): self._lists["element"] = element else: raise ValueError("Unknown element type") self._position = np.array(position) # ASE compatibility self.index = index self._atoms = atoms
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)
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
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()
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 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()
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__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__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 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)
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_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()])
def __init__(self, symbol="X", position=(0, 0, 0), tag=None, momentum=None, mass=None, magmom=None, charge=None, atoms=None, index=None, pse=None, element=None, **qwargs): if element is None: element = symbol SparseArrayElement.__init__(self, **qwargs) # super(SparseArrayElement, self).__init__(**qwargs) # verify that element is given (as string, ChemicalElement object or nucleus number if pse is None: pse = PeriodicTable() if element is None or element == "X": if "Z" in qwargs: el_symbol = pse.atomic_number_to_abbreviation(qwargs["Z"]) self._lists["element"] = pse.element(el_symbol) else: if isinstance(element, string_types): el_symbol = element self._lists["element"] = pse.element(el_symbol) elif isinstance(element, str): el_symbol = element self._lists["element"] = pse.element(el_symbol) elif isinstance(element, ChemicalElement): self._lists["element"] = element else: raise ValueError("Unknown element type") # KeyError handling required for user defined elements try: ASEAtom.__init__(self, symbol=symbol, position=position, tag=tag, momentum=momentum, mass=mass, magmom=magmom, charge=charge, atoms=atoms, index=index) except KeyError: symbol = pse.Parent[symbol] ASEAtom.__init__(self, symbol=symbol, position=position, tag=tag, momentum=momentum, mass=mass, magmom=magmom, charge=charge, atoms=atoms, index=index) # ASE compatibility for tags for key, val in qwargs.items(): self.data[key] = val
def read_atoms(filename="structure.sx"): """ Args: filename (str): Filename of the sphinx structure file Returns: pyiron.objects.structure.atoms.Atoms instance """ file_string = [] with open(filename) as f: for line in f: line = line.strip() file_string.append(line) cell_trigger = "cell" cell_string = list() species_list = list() species_trigger = "element" positions_dict = OrderedDict() positions = list() pse = PeriodicTable() for i, line in enumerate(file_string): if cell_trigger in line: for j in range(len(file_string)): line_str = file_string[i + j] cell_string.append(line_str) if ";" in line_str: break if species_trigger in line: species = (line.strip().split("=")[-1].replace(";", "").replace( '"', "").strip()) species_list.append(pse.element(species)) positions_dict[species] = 0 for j in range(len(file_string) - i): line_str = file_string[i + j] k = 0 if "atom" in line_str: break_loop = False while not break_loop: position_string = " ".join( file_string[i + j + k].split("=")[-1]) replace_list = ["[", "]", ";", "}"] for rep in replace_list: position_string = ( "".join(position_string).replace(rep, " ").split()) positions.append( np.array(position_string[0].split(","), dtype=float)) positions_dict[species] += 1 k += 1 if (i + j + k) <= len(file_string) - 1: if ("element" in file_string[i + j + k] or "atom" not in file_string[i + j + k]): break_loop = True break indices = list() for i, val in enumerate(positions_dict.values()): indices.append(np.ones(val, dtype=int) * i) indices = np.hstack(indices) replace_list = ["cell", "=", "[", "]", ",", ";"] for rep in replace_list: cell_string = " ".join(cell_string).replace(rep, " ").split() cell = np.array(cell_string, dtype=float).reshape( (3, 3)) * BOHR_TO_ANGSTROM atoms = Atoms( species=species_list, indices=indices, cell=cell, positions=np.array(positions) * BOHR_TO_ANGSTROM, ) return atoms
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)
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)
def setUpClass(cls): cls.Fe_atom = Atom("Fe") pse = PeriodicTable() al = pse.element("Al", spin=-1) cls.Al_atom = Atom(al)
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)
def setUpClass(cls): cls.Fe_atom = Atom("Fe") pse = PeriodicTable() al = pse.element("Al", spin=-1) cls.Al_atom = Atom(al) cls.Ne_atom = Atom("Ne", charge=-0.1, momentum=0.5, spin=-1)
def setUp(self): self.Fe_atom = Atom("Fe") pse = PeriodicTable() Al = pse.element("Al", spin=-1) self.Al_atom = Atom(Al)
class GenericInteractive(AtomisticGenericJob, InteractiveBase): def __init__(self, project, job_name): super(GenericInteractive, self).__init__(project, job_name) self.output = GenericInteractiveOutput(job=self) self._structure_previous = None self._structure_current = None self._interactive_enforce_structure_reset = False self._interactive_grand_canonical = False self._interactive_fetch_completed = True self._interactive_species_lst = np.array([]) self._periodic_table = PeriodicTable() self.interactive_cache = { "cells": [], "energy_pot": [], "energy_tot": [], "forces": [], "positions": [], "pressures": [], "stress": [], "steps": [], "temperature": [], "indices": [], "computation_time": [], "unwrapped_positions": [], "atom_spin_constraints": [], "atom_spins": [], "magnetic_forces": [], "volume": [], } @property def interactive_enforce_structure_reset(self): return self._interactive_enforce_structure_reset @interactive_enforce_structure_reset.setter def interactive_enforce_structure_reset(self, reset): if not isinstance(reset, bool): raise AssertionError() self._interactive_enforce_structure_reset = reset @property def initial_structure(self): return AtomisticGenericJob.structure.fget(self) @property def current_structure(self): return self.structure @current_structure.setter def current_structure(self, structure): self.structure = structure @property def structure(self): if self._structure_current is not None: return self._structure_current elif ( self.server.run_mode.interactive or self.server.run_mode.interactive_non_modal ): self._structure_current = AtomisticGenericJob.structure.fget(self) return self._structure_current else: return AtomisticGenericJob.structure.fget(self) @structure.setter def structure(self, structure): if ( self.server.run_mode.interactive or self.server.run_mode.interactive_non_modal ): # only overwrite the initial structure if it is not set already. if AtomisticGenericJob.structure.fget(self) is None: AtomisticGenericJob.structure.fset(self, structure.copy()) self._structure_current = structure else: AtomisticGenericJob.structure.fset(self, structure) def species_from_hdf(self): if ( "output" in self.project_hdf5.list_groups() and "interactive" in self.project_hdf5["output"].list_groups() and "species" in self.project_hdf5["output/interactive"].list_nodes() ): with self.project_hdf5.open("output/interactive") as hdf: self._interactive_species_lst = np.array(hdf["species"]) def run_if_interactive(self): self.status.running = True if self.structure is None: raise ValueError("Input structure not set. Use method set_structure()") if not self.interactive_is_activated(): self.interactive_initialize_interface() pre_struct = self.get_structure(-1) if pre_struct is not None: self._structure_previous = pre_struct else: self._structure_previous = self.structure.copy() if self._structure_current is not None: if ( len(self._structure_current) != len(self._structure_previous) and not self._interactive_grand_canonical ): raise ValueError( "The number of atoms changed, this is currently not supported!" ) index_merge_lst = self._interactive_species_lst.tolist() + list( self._structure_current.get_species_symbols() ) el_lst = sorted(set(index_merge_lst), key=index_merge_lst.index) current_structure_index = [ el_lst.index(el) for el in self._structure_current.get_chemical_symbols() ] previous_structure_index = [ el_lst.index(el) for el in self._structure_previous.get_chemical_symbols() ] if not self._interactive_enforce_structure_reset: if not np.allclose( self._structure_current.cell, self._structure_previous.cell, rtol=1e-15, atol=1e-15, ): self._logger.debug("Generic library: cell changed!") self.interactive_cells_setter(self._structure_current.cell) if not np.allclose( self._structure_current.get_scaled_positions(), self._structure_previous.get_scaled_positions(), rtol=1e-15, atol=1e-15, ): self._logger.debug("Generic library: positions changed!") self.interactive_positions_setter(self._structure_current.positions) if np.any(self._structure_current.get_initial_magnetic_moments()) and ( None in self._structure_previous.get_initial_magnetic_moments() or not np.allclose( self._structure_current.get_initial_magnetic_moments(), self._structure_previous.get_initial_magnetic_moments(), ) ): self._logger.debug("Generic library: magnetic moments changed!") self.interactive_spin_constraints_setter( self._structure_current.get_initial_magnetic_moments() ) if not np.array_equal( np.array(current_structure_index), np.array(previous_structure_index), ): self._logger.debug("Generic library: indices changed!") self.interactive_indices_setter(self._structure_current.indices) else: self._logger.debug("Generic library: structure changed!") self.interactive_structure_setter(self._structure_current) def interactive_cells_getter(self): return self.initial_structure.cell def interactive_collect(self): if "cells" in self.interactive_cache.keys(): self.interactive_cache["cells"].append(self.interactive_cells_getter()) if "energy_pot" in self.interactive_cache.keys(): self.interactive_cache["energy_pot"].append( self.interactive_energy_pot_getter() ) if "energy_tot" in self.interactive_cache.keys(): self.interactive_cache["energy_tot"].append( self.interactive_energy_tot_getter() ) if "forces" in self.interactive_cache.keys(): self.interactive_cache["forces"].append(self.interactive_forces_getter()) if "positions" in self.interactive_cache.keys(): self.interactive_cache["positions"].append( self.interactive_positions_getter() ) if "pressures" in self.interactive_cache.keys(): self.interactive_cache["pressures"].append( self.interactive_pressures_getter() ) if "stress" in self.interactive_cache.keys(): self.interactive_cache["stress"].append(self.interactive_stress_getter()) if "steps" in self.interactive_cache.keys(): self.interactive_cache["steps"].append(self.interactive_steps_getter()) if "temperature" in self.interactive_cache.keys(): self.interactive_cache["temperature"].append( self.interactive_temperatures_getter() ) if "computation_time" in self.interactive_cache.keys(): self.interactive_cache["computation_time"].append( self.interactive_time_getter() ) if "indices" in self.interactive_cache.keys(): self.interactive_cache["indices"].append(self.interactive_indices_getter()) if "atom_spins" in self.interactive_cache.keys(): self.interactive_cache["atom_spins"].append(self.interactive_spins_getter()) if "atom_spin_constraints" in self.interactive_cache.keys(): if self._generic_input["fix_spin_constraint"]: self.interactive_cache["atom_spin_constraints"].append( self.interactive_spin_constraints_getter() ) if "magnetic_forces" in self.interactive_cache.keys(): if self._generic_input["fix_spin_constraint"]: self.interactive_cache["magnetic_forces"].append( self.interactive_magnetic_forces_getter() ) if "unwrapped_positions" in self.interactive_cache.keys(): self.interactive_cache["unwrapped_positions"].append( self.interactive_unwrapped_positions_getter() ) if "volume" in self.interactive_cache.keys(): self.interactive_cache["volume"].append(self.interactive_volume_getter()) if ( len(list(self.interactive_cache.keys())) > 0 and len(self.interactive_cache[list(self.interactive_cache.keys())[0]]) % self._interactive_flush_frequency == 0 ): self.interactive_flush(path="interactive") if self.server.run_mode.interactive_non_modal: self._interactive_fetch_completed = True def interactive_flush(self, path="interactive", include_last_step=False): """ Args: path: include_last_step: Returns: """ with self.project_hdf5.open("output") as hdf_output: with hdf_output.open(path) as hdf: hdf["species"] = self._interactive_species_lst.tolist() super(GenericInteractive, self).interactive_flush( path=path, include_last_step=include_last_step ) def interactive_indices_getter(self): species_symbols = np.array( [e.Abbreviation for e in self.current_structure.species] ) self._interactive_species_lst = self._extend_species_elements( struct_species=species_symbols, species_array=self._interactive_species_lst ) index_merge_lst = self._interactive_species_lst.tolist() + list( self._structure_current.get_species_symbols() ) el_lst = sorted(set(index_merge_lst), key=index_merge_lst.index) current_structure_index = np.array( [el_lst.index(el) for el in self._structure_current.get_chemical_symbols()] ) return current_structure_index def interactive_positions_getter(self): return self.current_structure.positions def interactive_steps_getter(self): return len(self.interactive_cache[list(self.interactive_cache.keys())[0]]) def interactive_time_getter(self): return self.interactive_steps_getter() def interactive_volume_getter(self): return self.initial_structure.get_volume() def get_structure(self, iteration_step=-1, wrap_atoms=True): """ Gets the structure from a given iteration step of the simulation (MD/ionic relaxation). For static calculations there is only one ionic iteration step Args: iteration_step (int): Step for which the structure is requested Returns: atomistics.structure.atoms.Atoms object """ if ( self.server.run_mode.interactive or self.server.run_mode.interactive_non_modal ): # Warning: We only copy symbols, positions and cell information - no tags. if len(self.output.indices) != 0: indices = self.output.indices[iteration_step] else: indices = self.get("output/generic/indices") if len(self._interactive_species_lst) == 0: el_lst = [el.Abbreviation for el in self.structure.species] else: el_lst = self._interactive_species_lst.tolist() if indices is not None: if wrap_atoms: positions = self.output.positions[iteration_step] else: if len(self.output.unwrapped_positions) > max([iteration_step, 0]): positions = self.output.unwrapped_positions[iteration_step] else: positions = ( self.output.positions[iteration_step] + self.output.total_displacements[iteration_step] ) atoms = Atoms( symbols=np.array([el_lst[el] for el in indices]), positions=positions, cell=self.output.cells[iteration_step], ) # Update indicies to match the indicies in the cache. atoms.set_species([self._periodic_table.element(el) for el in el_lst]) atoms.indices = indices if wrap_atoms: atoms = atoms.center_coordinates_in_unit_cell() return atoms else: return None else: if ( self.get("output/generic/cells") is not None and len(self.get("output/generic/cells")) != 0 ): return super(GenericInteractive, self).get_structure( iteration_step=iteration_step, wrap_atoms=wrap_atoms ) else: return None @staticmethod def _extend_species_elements(struct_species, species_array): if not all(np.isin(struct_species, species_array)): new_elements_index = np.invert(np.isin(struct_species, species_array)) species_array = np.append(species_array, struct_species[new_elements_index]) return species_array # Functions which have to be implemented by the fin def interactive_cells_setter(self, cell): raise NotImplementedError("interactive_cells_getter() is not implemented!") def interactive_energy_pot_getter(self): raise NotImplementedError("interactive_energy_pot_getter() is not implemented!") def interactive_energy_tot_getter(self): raise NotImplementedError("interactive_energy_tot_getter() is not implemented!") def interactive_forces_getter(self): raise NotImplementedError("interactive_forces_getter() is not implemented!") def interactive_indices_setter(self, indices): raise NotImplementedError("interactive_indices_setter() is not implemented!") def interactive_spins_getter(self): raise NotImplementedError("interactive_spins_getter() is not implemented!") def interactive_spin_constraints_getter(self): raise NotImplementedError( "interactive_spin_constraints_getter() is not implemented!" ) def interactive_magnetic_forces_getter(self): raise NotImplementedError( "interactive_magnetic_forces_getter() is not implemented!" ) def interactive_spin_constraints_setter(self, spins): raise NotImplementedError( "iinteractive_spin_constraints_setter() is not implemented!" ) def interactive_initialize_interface(self): raise NotImplementedError( "interactive_initialize_interface() is not implemented!" ) def interactive_positions_setter(self, positions): raise NotImplementedError("interactive_positions_setter() is not implemented!") def interactive_pressures_getter(self): raise NotImplementedError("interactive_pressures_getter() is not implemented!") def interactive_stress_getter(self): raise NotImplementedError("interactive_stress_getter() is not implemented!") def interactive_structure_setter(self, structure): raise NotImplementedError("interactive_structure_setter() is not implemented!") def interactive_temperatures_getter(self): raise NotImplementedError( "interactive_temperatures_getter() is not implemented!" ) def interactive_unwrapped_positions_getter(self): raise NotImplementedError( "interactive_unwrapped_positions_getter() is not implemented!" )
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)