def first_appearing_index(structure: Structure, element: Union[str, Element]) -> int: """Return first index where the specie appears. Return 0 if not exist If the element does not exist, 0 is returned. Args: structure: Input structure element: String of element or Element Return: Int of first index """ if isinstance(element, Element): element = str(element) if element in structure.symbol_set: return min(structure.indices_from_symbol(element)) else: return 0
def analyze(topology: Structure, skin: float = 5e-3) -> List[Molecule]: # containers for the output fragments = [] # we iterate over non-dummies dmat = topology.distance_matrix dummies = numpy.array(topology.indices_from_symbol("X")) not_dummies = numpy.array( [i for i in range(len(topology)) if i not in dummies]) # initialize and set tags tags = numpy.zeros(len(topology), dtype=int) tags[dummies] = dummies + 1 topology.add_site_property(property_name="tags", values=tags) # TODO : site properties # get the distances between centers and connections distances = dmat[not_dummies][:, dummies] coordinations = numpy.array(topology.atomic_numbers)[not_dummies] partitions = numpy.argsort(distances, axis=1) for center_idx, best_dummies in enumerate(partitions): coordination = coordinations[center_idx] if coordination < len(best_dummies): best_dummies = best_dummies[:coordination] cutoff = distances[center_idx][best_dummies].max() + skin # now extract the corresponding fragment fragment_center = topology.sites[not_dummies[center_idx]] fragment_sites = topology.get_neighbors(fragment_center, r=cutoff) # some topologies in the RCSR have a crazy size # we ignore them with the heat of a thousand suns assert len( fragment_sites) <= 12, "Fragment size larger than limit of 12." # store as molecule to use the point group analysis fragment = Molecule.from_sites( fragment_sites) #, charge=1, spin_multiplicity=1) # this is needed because X have no mass, leading to a # symmetrization error. fragment.replace_species({"X": "He"}) pg = PointGroupAnalyzer(fragment, tolerance=0.1) # from pymatgen.io.ase import AseAtomsAdaptor # view(AseAtomsAdaptor.get_atoms(fragment)) if pg.sch_symbol == "C1": raise ("NoSymm") fragment.replace_species({"He": "X"}) fragments.append(Fragment(atoms=fragment, symmetry=pg, name="slot")) return fragments
def calc_orbital_character(procar: Procar, structure: Structure, spin: Spin, band_index: int, kpoint_index: int): """ Method returning a dictionary of projections on elements. Args: procar (Procar): Procar object to be parsed. structure (Structure): Input structure used for extracting symbol_set spin (Spin): band_index (int): kpoint_index (int): Returns (dict): a dictionary in the {Element:{s: value, p: value, d: value} where s, p, and d are OrbitalType in pymatgen. """ orbital_components = {} def projection_sum(atom_indices: tuple, first: int, last: int): end = last + 1 procar_sum = np.sum(procar.data[spin][kpoint_index, band_index, atom_indices, first:end]) return float(procar_sum) for element in structure.symbol_set: # get list of index indices = structure.indices_from_symbol(element) orbital_components[element] = \ {"s": round(projection_sum(indices, 0, 0), 3), "p": round(projection_sum(indices, 1, 3), 3), "d": round(projection_sum(indices, 4, 8), 3)} try: orbital_components[element]["f"] = \ round(projection_sum(indices, 9, 16), 3) except KeyError: pass return orbital_components
def _get_indices_from_list_str(structure: Structure, arg: Sequence[str]) -> Sequence[int]: return tuple(flatten([structure.indices_from_symbol(sp) for sp in arg]))
def _get_indices_from_str(structure: Structure, arg: str) -> Sequence[int]: return structure.indices_from_symbol(arg)