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.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_2_5.structure.set_initial_magnetic_moments([2, 2]) 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() cls.sphinx_2_3.to_hdf() cls.sphinx_2_3.decompress() cls.sphinx_2_5.decompress() cls.sphinx_2_5.collect_output()
def 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 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 read_atoms(filename="structure.sx"): """ Args: filename (str): Filename of the sphinx structure file Returns: pyiron_atomistics.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 = [ "[", "]", ";", "}", "movable", "X", "Y", "Z" ] 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 __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
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_input_functions = { 'index': self.interactive_index_organizer, 'cell': self.interactive_cell_organizer, 'positions': self.interactive_positions_organizer, 'magnetic_moments': self.interactive_magmom_organizer } self.interactive_output_functions = { 'cells': self.interactive_cells_getter, 'energy_pot': self.interactive_energy_pot_getter, 'energy_tot': self.interactive_energy_tot_getter, 'forces': self.interactive_forces_getter, 'positions': self.interactive_positions_getter, 'pressures': self.interactive_pressures_getter, 'stress': self.interactive_stress_getter, 'steps': self.interactive_steps_getter, 'temperature': self.interactive_temperatures_getter, 'indices': self.interactive_indices_getter, 'computation_time': self.interactive_computation_time_getter, 'unwrapped_positions': self.interactive_unwrapped_positions_getter, 'atom_spin_constraints': self.interactive_atom_spin_constraints_getter, 'atom_spins': self.interactive_atom_spins_getter, 'magnetic_forces': self.interactive_magnetic_forces_getter, 'volume': self.interactive_volume_getter } self.interactive_cache = defaultdict(list) @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() if self._structure_previous is None: self._structure_previous = self.structure.copy() self._update_previous_structure() 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!" ) if not self._interactive_enforce_structure_reset: functions_to_execute = list( self.interactive_input_functions.values()) for v in functions_to_execute: v() else: self._logger.debug("Generic library: structure changed!") self.interactive_structure_setter(self._structure_current) def interactive_index_organizer(self): 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 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) def interactive_cell_organizer(self): 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!") try: self.interactive_cells_setter(self._structure_current.cell) except NotImplementedError: del self.interactive_input_functions['cell'] def interactive_positions_organizer(self): if not np.allclose( self._structure_current.positions, self._structure_previous.positions, rtol=1e-15, atol=1e-15, ): self._logger.debug("Generic library: positions changed!") self.interactive_positions_setter( self._structure_current.positions) def interactive_magmom_organizer(self): if all(mm is None for mm in self._structure_current.get_initial_magnetic_moments()): del self.interactive_input_functions['magnetic_moments'] elif (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!") try: self.interactive_spin_constraints_setter( self._structure_current.get_initial_magnetic_moments()) except NotImplementedError: del self.interactive_input_functions['magnetic_moments'] def interactive_cells_getter(self): return self.initial_structure.cell def interactive_collect(self): del_key_lst = [] for k, v in self.interactive_output_functions.items(): try: value = v() if value is not None: self.interactive_cache[k].append(value) else: del_key_lst.append(k) except NotImplementedError: del_key_lst.append(k) for k in del_key_lst: del self.interactive_output_functions[k] 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 _update_previous_structure(self): """ Update the previous structure to the last step configuration Args: wrap_atoms (bool): """ try: indices = self.output.indices[-1] positions = self.output.positions[-1] cell = self.output.cells[-1] except IndexError: return 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() self._structure_previous = self._structure_previous.__class__( positions=positions, cell=cell, indices=indices, species=[self._periodic_table.element(el) for el in el_lst], ) @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_atom_spin_constraints_getter(self): raise NotImplementedError( "interactive_atom_spin_constraints_getter() is not implemented!") def interactive_atom_spins_getter(self): raise NotImplementedError( "interactive_atom_spins_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_computation_time_getter(self): raise NotImplementedError( "interactive_computation_time_getter() 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!")
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( clean_character(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