【问题标题】:Get graph from a structure with pymatgen使用 pymatgen 从结构中获取图形
【发布时间】:2023-02-10 12:35:40
【问题描述】:

给定一个 cif 文件,我想获得某种材料的图形表示(作为数据结构)。我正在尝试使用代表 CrN 晶胞的 cif file

我正在尝试使用 pymatgen 的 StructureGraph 类,但我遇到了一些问题。在这个 link 中,他们建议使用 with_local_env_strategy() 方法,但是当我尝试使用它时出现错误。这是我的代码:

from pymatgen.analysis.graphs import StructureGraph
from pymatgen.analysis.local_env import NearNeighbors
from pymatgen.core import Structure

filename = 'CrN.cif'
structure = Structure.from_file(filename)
nn = NearNeighbors()
strategy = nn.get_all_nn_info(structure)
strucGraph = StructureGraph.with_local_env_strategy(supercell, strategy, weights=False, edge_properties=False)

错误:

【问题讨论】:

    标签: python graph pymatgen


    【解决方案1】:

    由于我不是材料学科的专家(我只是一名系统工程师和一名数学家),我提出了这两种可能的解决方案:

    使用 get_neighbors() 方法,给定一个给定半径的球形邻域,获得最近的邻居:

    from pymatgen.core import Structure
    import networkx as nx
    import numpy as np
    
    filename = 'CrN.cif'
    structure = Structure.from_file(filename)
    supercell = structure.copy()
    supercell.make_supercell([2,2,2])
    G = nx.Graph()
    for i, site in enumerate(supercell):
        G.add_node(i)
        G.nodes[i]["Species"] = label_set[site.species]
        G.nodes[i]["position"] = (site.x, site.y, site.z)
    
    for i, site in enumerate(supercell):
        neighbors = [(n.index, n.nn_distance) for n in supercell.get_neighbors(site, r=3)]
        for n in neighbors:
            G.add_edge(i, n[0], weight=n[1])
    

    第二种方法更可定制,我放在这里的代码考虑了欧几里德距离,但是,对于 2 个原子连接的标准,可以使用其他标准,例如能量。

    def space_euclidean_distance(p1, p2):
        dist = np.sqrt(np.sum((p1-p2)**2, axis=0))
        return dist
    
    lattice = supercell.lattice
    fractional_coords = supercell.frac_coords
    
    # Convert the fractional coordinates to Cartesian coordinates using the lattice vectors
    cartesian_coords = lattice.get_cartesian_coords(fractional_coords)
    distances = []
    N = len(cartesian_coords)
    for i in range(N):
        p1 = cartesian_coords[i]
        dist_i = {}
        for j in range(N):
            p2 = cartesian_coords[j]
            if j != i:
                dist_i[j] = space_euclidean_distance(p1, p2)
        distances.append(dist_i)
    
    G2 = nx.Graph()
    for i, site in enumerate(supercell):
        G2.add_node(i)
        G2.nodes[i]["Species"] = label_set[site.species]
    for i in range(N):
        for key, value in distances[i].items():
            if value <= 2.5: #metric for connection of 2 atoms
                G2.add_edge(i, key, weight=value)
    

    【讨论】:

      【解决方案2】:

      您必须传递该策略的一个实例,而不是提取的邻居本身。下面的代码应该可以工作。

      from pymatgen.analysis.graphs import StructureGraph
      from pymatgen.analysis.local_env import NearNeighbors
      from pymatgen.core import Structure
      
      filename = 'CrN.cif'
      structure = Structure.from_file(filename)
      nn = NearNeighbors()
      strategy = nn.get_all_nn_info(structure)
      strucGraph = StructureGraph.with_local_env_strategy(supercell, nn, weights=False, edge_properties=False)
      

      我假设您已经从 Structure 对象创建了一个超级单元,然后将其传入。

      【讨论】:

        猜你喜欢
        • 2017-06-24
        • 1970-01-01
        • 2021-07-20
        • 2017-02-03
        • 1970-01-01
        • 2021-01-20
        • 1970-01-01
        • 2018-07-13
        • 1970-01-01
        相关资源
        最近更新 更多