def extrema_coords(volumetric_data: VolumetricData,
                   find_min: bool,
                   params: VolumetricDataAnalyzeParams) -> DataFrame:
    result = ChargeDensityAnalyzer(chgcar=volumetric_data)
    result.get_local_extrema(threshold_frac=params.threshold_frac,
                             threshold_abs=params.threshold_abs,
                             find_min=find_min)
    if params.min_dist:
        # Remove sites near host atoms.
        result.remove_collisions(params.min_dist)
    if params.tol:
        try:
            # Cluster interstitials that are too close together using a tol.
            result.cluster_nodes(tol=params.tol)
        except ValueError:
            # error raised when only a single local extreme point.
            pass
    if params.radius:
        result.sort_sites_by_integrated_chg(r=params.radius)
    result = result.extrema_df
    if "avg_charge_den" in result.columns:
        result.rename(columns={'avg_charge_den': 'ave_value'}, inplace=True)
    result.rename(columns={'Charge Density': 'value'}, inplace=True)
    logger.info("\n" + result.__str__())
    return result
def interstitials_from_volumetric_data(volumetric_data: VolumetricData,
                                       find_min: bool = True,
                                       threshold_frac: float = None,
                                       threshold_abs: float = None,
                                       min_dist: float = 0.5,
                                       tol: float = 0.5,
                                       radius: float = 0.4) -> None:

    cda = ChargeDensityAnalyzer(chgcar=volumetric_data)
    cda.get_local_extrema(threshold_frac=threshold_frac,
                          threshold_abs=threshold_abs,
                          find_min=find_min)
    cda.sort_sites_by_integrated_chg(r=radius)
    # Remove sites near host atoms.
    cda.remove_collisions(min_dist)
    # Cluster interstitials that are too close together using a tol.
    try:
        cda.cluster_nodes(tol=tol)
    except ValueError:
        # error raised when only a single local extreme point.
        pass
    print(cda.extrema_df)

    structure: Structure = volumetric_data.structure.copy()
    start_index = len(structure)
    end_index = len(structure) + len(cda.extrema_coords)
    interstitial_indices = [i for i in range(start_index, end_index)]
    for coords in cda.extrema_coords:
        structure.append(Element.H, coords)
    symmetrizer = StructureSymmetrizer(structure)
    equiv_atoms = symmetrizer.spglib_sym_data["equivalent_atoms"]

    print(f"Host symmetry {symmetrizer.spglib_sym_data['international']}")
    print("++ Inequivalent indices and site symmetries ++")
    orig_num_atoms = len(volumetric_data.structure)

    structure_for_visualize: Structure = volumetric_data.structure.copy()

    for i, ii in enumerate(interstitial_indices):
        if ii == equiv_atoms[ii]:
            idx = orig_num_atoms + i
            coords = structure[idx].frac_coords

            def element():
                for z in range(1, 100):
                    e = Element.from_Z(z)
                    if e not in structure_for_visualize.composition:
                        yield e

            structure_for_visualize.append(next(element()), coords)

            idx_coords = \
                f"{i:>3} {coords[0]:8.4f} {coords[1]:8.4f} {coords[2]:8.4f}"
            print(idx_coords,
                  symmetrizer.spglib_sym_data["site_symmetry_symbols"][ii])

        structure_for_visualize.to(filename="POSCAR-w-interstitials")
Exemple #3
0
 def test_cluster_nodes(self):
     ca = ChargeDensityAnalyzer(self.chg_FePO4)
     ca.get_local_extrema()
     ca.cluster_nodes(tol=20)
     self.assertEqual(len(ca.extrema_df), 1)
 def test_cluster_nodes(self):
     ca = ChargeDensityAnalyzer(self.chg_FePO4)
     ca.get_local_extrema()
     ca.cluster_nodes(tol=20)
     self.assertEqual(len(ca.extrema_df), 1)