コード例 #1
0
def Ewald_energy(structure_in, core_charges, verbose=True):
    #-#
    from copy import deepcopy
    from pymatgen import Lattice, Structure
    from pymatgen.analysis import ewald

    structure = deepcopy(structure_in)
    lattice = Lattice(structure.get_cell())
    coords = structure.get_scaled_positions()
    structure.charges = [
        core_charges[x] for x in structure.get_chemical_symbols()
    ]
    struct = Structure(lattice,
                       structure.get_chemical_symbols(),
                       coords,
                       site_properties={"charge": structure.charges})

    Ew = ewald.EwaldSummation(struct, compute_forces=True)
    #Ew= ewald.EwaldSummation(struct, eta=0.057887, acc_factor= 12,compute_forces=True)

    if verbose:
        print("=" * 50)
        print("Real space          energy:", Ew.real_space_energy, "[eV]")
        print("Reciprocal space    energy:",
              Ew.reciprocal_space_energy + Ew.point_energy, "[eV]")
        print("=" * 50)
        print("Total electrostatic energy:", Ew.total_energy, "[eV]")

    return Ew
コード例 #2
0
def ewald_matrix_features(data, noa, data_type="train", file_name_type=""):

    # noa - number of atoms in unit cell
    logger.info(
        "Extracting Ewald matrix features. data_type {0}".format(data_type))

    logger.info("data.shape: " + str(data.shape))
    ids, x, y_fe, y_bg = split_data_into_id_x_y(data, data_type=data_type)

    logger.info("x.shape: " + str(x.shape))

    n, m = ids.shape
    ewald_sum_data = np.zeros((n, 11))

    if noa != -1:
        ewald_sum_real_energy_matrix = np.zeros((n, noa * noa))
        ewald_sum_reciprocal_energy_matrix = np.zeros((n, noa * noa))
        ewald_sum_total_energy_matrix = np.zeros((n, noa * noa))
        ewald_sum_point_energy_matrix = np.zeros((n, noa))

    for i in range(n):
        id = int(ids[i, 0])
        print("id: {0}".format(id))

        vectors, uc_atoms = read_geometry_file(data_type + "/" + str(id) +
                                               "/geometry.xyz")
        atom_coords, atom_labels, site_properties = convert_uc_atoms_to_input_for_pymatgen(
            uc_atoms)

        lv1 = x[i, 5]
        lv2 = x[i, 6]
        lv3 = x[i, 7]

        lv1_c = vector_length(vectors[0])
        lv2_c = vector_length(vectors[1])
        lv3_c = vector_length(vectors[2])

        alpha = x[i, 8]
        beta = x[i, 9]
        gamma = x[i, 10]

        logger.info("lv1: {0}, lv2: {1}, lv3: {2}".format(lv1, lv2, lv3))
        logger.info("lv1: {0}, lv2: {1}, lv3: {2}".format(lv1_c, lv2_c, lv3_c))
        logger.info("alpha: {0}, beta: {1}, gamma: {2}".format(
            alpha, beta, gamma))

        lattice = pymatgen.Lattice.from_parameters(a=lv1,
                                                   b=lv2,
                                                   c=lv3,
                                                   alpha=alpha,
                                                   beta=beta,
                                                   gamma=gamma)

        structure = pymatgen.Structure(lattice,
                                       atom_labels,
                                       atom_coords,
                                       site_properties=site_properties)

        ewald_sum = ewald.EwaldSummation(structure)

        logger.info("ewald_sum: \n{0}".format(ewald_sum))

        logger.info("Real space energy: {0}".format(
            ewald_sum.real_space_energy))
        logger.info("Reciprocal energy: {0}".format(
            ewald_sum.reciprocal_space_energy))
        logger.info("Point energy: {0}".format(ewald_sum.point_energy))
        logger.info("Total energy: {0}".format(ewald_sum.total_energy))

        ewald_sum_data[i][0] = ewald_sum.real_space_energy / len(uc_atoms)
        ewald_sum_data[i][1] = ewald_sum.reciprocal_space_energy / len(
            uc_atoms)
        ewald_sum_data[i][2] = ewald_sum.point_energy / len(uc_atoms)
        ewald_sum_data[i][3] = ewald_sum.total_energy / len(uc_atoms)

        ewald_sum_data[i][4] = np.trace(ewald_sum.real_space_energy_matrix)
        ewald_sum_data[i][5] = np.trace(
            ewald_sum.reciprocal_space_energy_matrix)
        ewald_sum_data[i][6] = np.trace(ewald_sum.total_energy_matrix)
        ewald_sum_data[i][7] = np.sum(ewald_sum.point_energy_matrix)

        ewald_sum_data[i][8] = np.trace(
            np.fliplr(ewald_sum.real_space_energy_matrix))
        ewald_sum_data[i][9] = np.trace(
            np.fliplr(ewald_sum.reciprocal_space_energy_matrix))
        ewald_sum_data[i][10] = np.trace(
            np.fliplr(ewald_sum.total_energy_matrix))

        if noa != -1:
            ewald_sum_real_energy_matrix[
                i, :] = ewald_sum.real_space_energy_matrix.reshape(-1, )
            ewald_sum_reciprocal_energy_matrix[
                i, :] = ewald_sum.reciprocal_space_energy_matrix.reshape(-1, )
            ewald_sum_total_energy_matrix[
                i, :] = ewald_sum.total_energy_matrix.reshape(-1, )
            ewald_sum_point_energy_matrix[
                i, :] = ewald_sum.point_energy_matrix.reshape(-1, )

        logger.info("real_space_energy_matrix trace: " +
                    str(ewald_sum_data[i][4]))
        logger.info("reciprocal_space_energy_matrix trace: " +
                    str(ewald_sum_data[i][5]))
        logger.info("total_energy_matrix trace: " + str(ewald_sum_data[i][6]))

    ewald_sum_data = np.hstack((ids, ewald_sum_data))

    if noa != -1:
        ewald_sum_real_energy_matrix = np.hstack(
            (ids, ewald_sum_real_energy_matrix))
        ewald_sum_reciprocal_energy_matrix = np.hstack(
            (ids, ewald_sum_reciprocal_energy_matrix))
        ewald_sum_total_energy_matrix = np.hstack(
            (ids, ewald_sum_total_energy_matrix))
        ewald_sum_point_energy_matrix = np.hstack(
            (ids, ewald_sum_point_energy_matrix))

    np.savetxt(file_name_type + "_ewald_sum_data.csv",
               ewald_sum_data,
               delimiter=",")
    np.save(file_name_type + "_ewald_sum_data.npy", ewald_sum_data)

    if noa != -1:
        np.save(file_name_type + "_ewald_sum_real_energy_matrix.npy",
                ewald_sum_real_energy_matrix)
        np.save(file_name_type + "_ewald_sum_reciprocal_energy_matrix.npy",
                ewald_sum_reciprocal_energy_matrix)
        np.save(file_name_type + "_ewald_sum_total_energy_matrix.npy",
                ewald_sum_total_energy_matrix)
        np.save(file_name_type + "_ewald_sum_point_energy_matrix.npy",
                ewald_sum_point_energy_matrix)
コード例 #3
0
ファイル: Eswald_test.py プロジェクト: leexa90/Projects
def ewald_matrix_features(data, data_type="train", file_name=""):

    # noa - number of atoms in unit cell
    # ids - ids of each point
    # x - the provides features in *.csv
    # y_fe - formation energy (not used here)
    # y_bg - band gap
    ids, x, y_fe, y_bg = split_data_into_id_x_y(data, data_type=data_type)

    n, m = ids.shape
    ewald_sum_data = {}
    for i in range(n):
        ewald_sum_data[i] = [[], [], [], [], []]
        c_id = int(ids[i, 0])
        logger.info("c_id: {0}".format(c_id))

        vectors, uc_atoms = read_geometry_file(data_type + "/" + str(c_id) +
                                               "/geometry.xyz")
        atom_coords, atom_labels, site_properties = convert_uc_atoms_to_input_for_pymatgen(
            uc_atoms)

        # Check the vectors from *.csv with the ones
        # from geometry.xyz.
        lv1 = x[c_id - 1, 5]
        lv2 = x[c_id - 1, 6]
        lv3 = x[c_id - 1, 7]

        lv1_c = vector_length(vectors[0])
        lv2_c = vector_length(vectors[1])
        lv3_c = vector_length(vectors[2])
        print x.shape
        alpha = x[c_id - 1, 8]
        beta = x[c_id - 1, 9]
        gamma = x[c_id - 1, 10]

        logger.info("lv1: {0}, lv2: {1}, lv3: {2}".format(lv1, lv2, lv3))
        logger.info("lv1: {0}, lv2: {1}, lv3: {2}".format(lv1_c, lv2_c, lv3_c))
        logger.info("alpha: {0}, beta: {1}, gamma: {2}".format(
            alpha, beta, gamma))

        # Create a lattice
        lattice = pymatgen.Lattice.from_parameters(a=lv1,
                                                   b=lv2,
                                                   c=lv3,
                                                   alpha=alpha,
                                                   beta=beta,
                                                   gamma=gamma)

        # Create a structure representation in pymatgen
        structure = pymatgen.Structure(lattice,
                                       atom_labels,
                                       atom_coords,
                                       site_properties=site_properties)

        # Get the Ewald sum
        ewald_sum = ewald.EwaldSummation(structure, compute_forces=True)

        logger.info("ewald_sum: \n{0}".format(ewald_sum))

        logger.info("Real space energy: {0}".format(
            ewald_sum.real_space_energy))
        logger.info("Reciprocal energy: {0}".format(
            ewald_sum.reciprocal_space_energy))
        logger.info("Point energy: {0}".format(ewald_sum.point_energy))
        logger.info("Total energy: {0}".format(ewald_sum.total_energy))

        # Calcualte the traces.
        # Note: point_energy_matrix is an array. We convert it
        # into a diagonal matrix and then compute the trace.
        ewald_sum_data[i][0] = ewald_sum.real_space_energy_matrix
        ewald_sum_data[i][1] = ewald_sum.reciprocal_space_energy_matrix
        ewald_sum_data[i][2] = ewald_sum.total_energy_matrix
        ewald_sum_data[i][3] = ewald_sum.point_energy_matrix
        ewald_sum_data[i][4] = ewald_sum.forces

    # Take only space group and number of total atoms from x.
    features = ewald_sum_data
    np.save(file_name, features)

    return features
コード例 #4
0
ファイル: EneVsVm.py プロジェクト: zhenming-xu/MAST
def CalcV_M(structure):
    dummyPoscarLatStr = mg.core.structure.Structure(structure.lattice, ["F-"],
                                                    [[0, 0, 0]])
    V_M = ewald.EwaldSummation(dummyPoscarLatStr).total_energy * (-2)
    return V_M
コード例 #5
0
def EF_H2O_wannier(structure_in, core_charges, verbose=True):
    #-#
    from copy import deepcopy
    from ase.neighborlist import NeighborList
    from ase import Atom, Atoms
    from pymatgen import Lattice, Structure
    from pymatgen.analysis import ewald

    structure = deepcopy(structure_in)
    index_Ow = get_indexes_Ow(structure)

    if "WANNIER_xyz" in structure.row.data.keys():
        nwannier = len(structure.row.data["WANNIER_xyz"])
        structure.extend(
            Atoms(symbols="W" * nwannier,
                  positions=structure.row.data["WANNIER_xyz"],
                  cell=structure.get_cell()))
    else:
        print("ERROR: Missing WANNIER_xyz")
        sys.exit()

    nl = NeighborList([1.2 / 2] * len(structure),
                      skin=0,
                      self_interaction=False,
                      bothways=True)
    nl.update(structure)

    indexH = [
        i for i, x in enumerate(structure.get_chemical_symbols()) if x == 'H'
    ]  # H indexes
    indexW = [
        i for i, x in enumerate(structure.get_chemical_symbols()) if x == 'W'
    ]  # W indexes

    # Run Ewald
    print("Running Ewald ...")
    lattice = Lattice(structure.get_cell())
    coords = structure.get_scaled_positions()
    structure.charges = [
        core_charges[x] for x in structure.get_chemical_symbols()
    ]
    struct = Structure(lattice,
                       structure.get_chemical_symbols(),
                       coords,
                       site_properties={"charge": structure.charges})
    Ew = ewald.EwaldSummation(struct, compute_forces=True)
    print("Done")

    for iOw in index_Ow:
        print(" Ow idx:", iOw)
        print("=" * 50)

        vCENTER = (
            structure.get_cell()[0] + structure.get_cell()[1] +
            structure.get_cell()[2]
        ) / 2.  # get translation vector to put the O in the center of the box
        structure.translate(-structure.get_positions()[iOw] +
                            vCENTER)  # center the O in the box
        structure.set_scaled_positions(
            structure.get_scaled_positions())  # put back everything in the box

        neighbors = nl.get_neighbors(iOw)[0]
        indexH_loc = np.intersect1d(neighbors, indexH)
        vOH1 = structure.get_positions()[
            indexH_loc[0]] - structure.get_positions()[iOw]
        vOH2 = structure.get_positions()[
            indexH_loc[1]] - structure.get_positions()[iOw]
        vMid = (vOH1 / np.linalg.norm(vOH1) + vOH2 / np.linalg.norm(vOH2))
        vMid = vMid / np.linalg.norm(vMid)

        for j in indexH_loc:
            vOH = structure.get_positions()[j] - structure.get_positions()[iOw]
            uOH = vOH / np.linalg.norm(vOH)
            OH = structure.get_distance(iOw, j, mic=True)

            # Total EF at H position
            EF_H = Ew.forces[j] / structure.charges[j] * eV_a2au
            print(
                " {:>2}{:<4}{:>2}{:<4} dist: {:.6f}   chg{:<4} {:7.4f}".format(
                    structure.get_chemical_symbols()[j], j,
                    structure.get_chemical_symbols()[j], j, 0, j,
                    structure.charges[j]))

            # O contribution at the H
            EF_OatH = structure.charges[iOw] / (4. * np.pi * e0 *
                                                (OH)**2) * (vOH / OH) * eV_a2au

            # Contribution from the other H
            indexHother = np.setdiff1d(indexH_loc,
                                       j)  # the index of the other H
            vHH = structure.get_positions()[j] - structure.get_positions()[
                indexHother[0]]
            HH = structure.get_distance(indexHother[0], j, mic=True)

            EF_HatH = structure.charges[indexHother[0]] / (
                4. * np.pi * e0 * (HH)**2) * (vHH / HH) * eV_a2au
            print(
                " {:>2}{:<4}{:>2}{:<4} dist: {:.6f}   chg{:<4} {:7.4f}".format(
                    structure.get_chemical_symbols()[j], j,
                    structure.get_chemical_symbols()[indexHother[0]],
                    indexHother[0], HH, indexHother[0],
                    structure.charges[indexHother[0]]))

            EF_H = EF_H - EF_OatH - EF_HatH

            # Wannier centers
            indexW_loc = np.intersect1d(neighbors, indexW)
            for k in indexW_loc:
                vXH = structure.get_positions()[j] - structure.get_positions(
                )[k]
                XH = structure.get_distance(j, k, mic=True)
                print(" {:>2}{:<4}{:>2}{:<4} dist: {:.6f}   chg{:<4} {:7.4f}".
                      format(structure.get_chemical_symbols()[j], j,
                             structure.get_chemical_symbols()[k], k, XH, k,
                             structure.charges[k]))

                EF_XatH = structure.charges[k] / (4. * np.pi * e0 *
                                                  (XH)**2) * (vXH /
                                                              XH) * eV_a2au
                EF_H = EF_H - EF_XatH

            print("-" * 50)
            print(" H{0:<4}  rOH= {1:9.6f}  EF@H_along_bisector= {2:3f} a.u.".
                  format(j, OH, np.dot(EF_H, vMid)))
            print("                        EF@H_along_OH_bond=  {0:3f} a.u.\n".
                  format(np.dot(EF_H, uOH)))