Ejemplo n.º 1
0
def get_midpoint(structure : Structure, atom_1, atom_2):
    a = structure.lattice.a
    b = structure.lattice.b
    c = structure.lattice.c
    d = 999
    for x in [0,1,-1]:
        for y in [0,1,-1]:
            for z in [0,1,-1]:
                jimage = np.array([x,y,z])
                temp_d = structure.get_distance(atom_1, atom_2, jimage=jimage)
                if temp_d < d:
                    d = temp_d
                    coord = structure[atom_1].frac_coords + structure[atom_2].frac_coords - jimage
                    coord /= 2
                    if d < a*0.5 and d < b*0.5 and d < c*0.5:
                        return coord
    return coord
Ejemplo n.º 2
0
def get_octa_geom(
    df_coord_i=None,
    active_site_j=None,
    atoms=None,
    octahedra_atoms=None,
    verbose=False,
):
    """
    """
    #| - get_octa_geom

    octahedra_atoms_i = octahedra_atoms

    out_dict = dict(
        active_o_metal_dist=None,
        ir_o_mean=None,
        ir_o_std=None,
    )

    process_system = True

    row_coord_i = df_coord_i[df_coord_i.structure_index == active_site_j]
    row_coord_i = row_coord_i.iloc[0]

    nn_info_i = row_coord_i.nn_info

    # ir_nn = nn_info_i[0]

    found_active_Ir = False
    for nn_j in nn_info_i:
        if nn_j["site"].specie.symbol == "Ir":
            ir_nn = nn_j
            found_active_Ir = True
    mess_i = "Didn't find the Ir atom that the active O is bound to"
    # assert found_active_Ir, mess_i

    if not found_active_Ir:
        process_system = False

    num_non_H_neigh = 0
    for nn_j in nn_info_i:
        site_j = nn_j["site"]
        if site_j.specie.name != "H":
            num_non_H_neigh += 1

    if num_non_H_neigh != 1:
        process_system = False

    # | - __old__
    # if len(nn_info_i) != 1:
    # if len(nn_info_i) != 1:
    # active_o_has_1_neigh = True

    # print("Need to return NaN")
    # active_o_has_1_neigh = False
    #
    # else:
    # if active_o_has_1_neigh:
    # __|

    if process_system:

        if octahedra_atoms_i is not None:

            # | - Use octahedra_atoms_i to get info
            lattice_cell = atoms.cell.tolist()

            # #####################################################
            lattice = Lattice(lattice_cell)

            atom_Ir = atoms[ir_nn["site_index"]]

            active_o_metal_dist = None

            ir_o_distances = []
            for O_index_i in octahedra_atoms_i:
                # if atoms[59].symbol == "O":

                atom_O_i = atoms[O_index_i]

                if atom_O_i.symbol == "O":
                    coords = [
                        atom_Ir.position,
                        atom_O_i.position,
                    ]

                    struct = Structure(
                        lattice,
                        [atom_Ir.symbol, atom_O_i.symbol],
                        coords,
                        coords_are_cartesian=True,
                    )

                    dist_i = struct.get_distance(0, 1)
                    # print(dist_i)
                    ir_o_distances.append(dist_i)

                    if O_index_i == int(active_site_j):
                        # print(333 * "TMEP | ")
                        active_o_metal_dist = dist_i

            ir_o_mean = np.mean(ir_o_distances)
            ir_o_std = np.std(ir_o_distances)

            # __|

        else:

            # ir_coord = ir_nn["site"].coords
            ir_site_index = ir_nn["site_index"]
            ir_coord = atoms[ir_site_index].position

            #| - Calculating the distance between the active O atom and Ir
            atom_active_o = atoms[int(active_site_j)]

            ir_coord_tmp = ir_nn["site"].coords

            # diff_list = atom_active_o.position - ir_coord
            diff_list = atom_active_o.position - ir_coord_tmp
            dist_i = (np.sum([i**2 for i in diff_list]))**(1 / 2)

            # ir_nn["site"].coords

            # out_dict["active_o_metal_dist"] = dist_i

            active_o_metal_dist = dist_i
            #__|

            #| - Getting stats on all 6 Ir-O bonds
            row_coord_j = df_coord_i[df_coord_i.structure_index ==
                                     ir_site_index]
            row_coord_j = row_coord_j.iloc[0]

            nn_info_ir = row_coord_j.nn_info

            ir_o_distances = []
            if len(nn_info_ir) != 6:
                tmp = 42
            else:
                for nn_j in nn_info_ir:
                    diff_list = nn_j["site"].coords - ir_coord
                    dist_i = (np.sum([i**2 for i in diff_list]))**(1 / 2)
                    ir_o_distances.append(dist_i)

                # ir_o_mean = np.mean(ir_o_distances)
                # ir_o_std = np.std(ir_o_distances)

                # out_dict["ir_o_mean"] = ir_o_mean
                # out_dict["ir_o_std"] = ir_o_std
            #__|

        ir_o_mean = np.mean(ir_o_distances)
        ir_o_std = np.std(ir_o_distances)

        # #################################################
        out_dict["ir_o_mean"] = ir_o_mean
        out_dict["ir_o_std"] = ir_o_std
        out_dict["active_o_metal_dist"] = active_o_metal_dist
        # #################################################

    return (out_dict)
def _get_distance_checked_landmarks(
    good_landmarks: list,
    metal_radii: dict,
    metal_substructure: Structure,
    tolerance_factor_1: float,
    direction_dict: dict = None,
) -> list:
    """
    Loops over landmarks and checks that the maximum distance in a chain formed by them is smaller
    than the threshold.

    Args:
        good_landmarks (list): list of tuples of the landmarks
        metal_radii (dict): dictionary with the radius for each metal
        metal_substructure (pymatgen.Structure): pymatgen.Structure object with only the metallic parts
        tolerance_factor_1 (float): tolerance for the distance threshold
        direction_dict (dict): dictionary with the direction (value) each landmark (key) is parallel to

    Returns:
        list of landmarks that fullfill the distance criterion.

    """
    distance_checked_landmarks = []

    if direction_dict:
        a = metal_substructure.lattice.a
        b = metal_substructure.lattice.b
        c = metal_substructure.lattice.c

        lattice = np.array([a, b, c])

        metal_coord = np.abs(metal_substructure.cart_coords)

        for landmark in good_landmarks:
            direction = direction_dict[landmark]

            if isinstance(direction, (np.ndarray, list)):
                max_distance = (
                    metal_radii[metal_substructure[landmark[0]].species_string]
                    * tolerance_factor_1)

                direction = direction_dict[landmark]

                maximum_point_translation = lattice * direction

                # now, project the relevant coordinates
                coord_0 = metal_coord[landmark[0]] * direction
                coord_1 = metal_coord[landmark[1]] * direction

                distance_0 = np.min([norm(coord_0), norm(coord_1)])
                distance_1 = np.min([
                    norm(maximum_point_translation - coord_0),
                    norm(maximum_point_translation - coord_1),
                ])

                distance_2 = metal_substructure.get_distance(
                    landmark[0], landmark[1])

                relevant_distance = np.max(
                    [distance_0, distance_1, distance_2])

                if relevant_distance < max_distance:
                    logger.debug('%s is within distance threshold of %s',
                                 landmark, max_distance)
                    distance_checked_landmarks.append(landmark)
                else:
                    logger.debug(
                        'the distance was too large between %s for a threshold of %s',
                        landmark,
                        max_distance,
                    )

    else:
        for landmark in good_landmarks:
            max_distance = (
                metal_radii[metal_substructure[landmark[0]].species_string] *
                tolerance_factor_1)

            distance = metal_substructure.get_distance(landmark[0],
                                                       landmark[1])
            if distance < max_distance:
                logger.debug('%s is within distance threshold of %s', landmark,
                             max_distance)
                distance_checked_landmarks.append(landmark)
            else:
                logger.debug(
                    'the distance was too large between %s for a threshold of %s',
                    landmark,
                    max_distance,
                )

    return distance_checked_landmarks
Ejemplo n.º 4
0
def get_ave_drift(atoms_init, atoms_final):
    """
    """
    #| - get_ave_drift
    # atoms_init = atoms_init_data
    # atoms_final = atoms_sorted_good
    #
    # atoms_init.write("__temp__/00_atoms_init.traj")
    # atoms_final.write("__temp__/00_atoms_final.traj")

    # #####################################################
    # Check that number of atoms are the same
    num_atoms_init = atoms_init.get_global_number_of_atoms()
    num_atoms_final = atoms_final.get_global_number_of_atoms()

    mess_i = "TEMP isdjfisjd"
    assert num_atoms_init == num_atoms_final, mess_i
    num_atoms = num_atoms_init

    # #####################################################
    # Check that constraints are the same
    constr_init = atoms_init.constraints[0]
    constr_init = list(np.sort(constr_init.index))

    constr_final = atoms_final.constraints[0]
    constr_final = list(np.sort(constr_final.index))

    mess_i = "Constraints need to be equal"
    assert constr_init == constr_final, mess_i
    constr = constr_init

    # #####################################################
    # Check lattice cells are equal
    # lattice_cells_equal = np.all(atoms_init.cell == atoms_final.cell)
    lattice_cells_equal = np.allclose(
        atoms_init.cell,
        atoms_final.cell,
    )
    mess_i = "sijfidsifj"
    assert lattice_cells_equal, mess_i
    lattice_cell = atoms_init.cell.tolist()

    # if True:
    #     ind_i = 39
    #     atom_init = atoms_init[ind_i]
    #     atom_final = atoms_final[ind_i]

    # #####################################################
    data_dict_list = []
    # #####################################################
    for atom_init, atom_final in zip(atoms_init, atoms_final):
        # #####################################################
        data_dict_i = dict()
        # #####################################################

        pos_round_init = np.round(atom_init.position, 2)
        pos_round_final = np.round(atom_final.position, 2)

        # #####################################################
        mess_i = "This should always be true"
        assert atom_init.index == atom_final.index, mess_i
        index_i = atom_init.index

        atom_constr_i = index_i in constr

        # #####################################################
        lattice = Lattice(lattice_cell)

        coords = [
            atom_init.position,
            atom_final.position,
        ]

        struct = Structure(
            lattice,
            [atom_init.symbol, atom_final.symbol],
            coords,
            coords_are_cartesian=True,
        )

        dist_i = struct.get_distance(0, 1)

        # #####################################################
        data_dict_i["index"] = index_i
        data_dict_i["distance"] = dist_i
        data_dict_i["distance_round"] = np.round(dist_i, 2)
        data_dict_i["constrained"] = atom_constr_i
        data_dict_i["pos_round_init"] = pos_round_init
        data_dict_i["pos_round_final"] = pos_round_final
        # #####################################################
        data_dict_list.append(data_dict_i)
        # #####################################################

    # #####################################################3###
    df = pd.DataFrame(data_dict_list)
    df = df.set_index("index", drop=False)
    # #####################################################3###

    ave_dist_pa = df.distance.sum() / num_atoms

    return (ave_dist_pa)