예제 #1
0
def plane_orientation(
        images: List[Tuple[int, int, int]]) -> Tuple[int, int, int]:
    """
    Get the orientation (surface normal) from a list of rank 2 connected images.

    Args:
        images: (n, 3) int array of the images.

    Returns:
        The surface normal as a (3, ) int array.
    """
    from pymatgen.core.lattice import get_integer_index

    vertices = np.array(images)
    g = vertices.sum(axis=0) / vertices.shape[0]
    _, _, vh = np.linalg.svd(vertices - g)  # run singular value decomposition
    return get_integer_index(vh[2, :])  # return unitary norm
예제 #2
0
def line_orientation(
        images: List[Tuple[int, int, int]]) -> Tuple[int, int, int]:
    """
    Get the orientation (direction vector) from a list of rank 1 connected images.

    Args:
        images: (n, 3) int array of the images.

    Returns:
        The orientation vector as a (3, ) int array.
    """
    from pymatgen.core.lattice import get_integer_index

    vertices = np.array(images)
    g = vertices.sum(axis=0) / vertices.shape[0]
    _, _, vh = np.linalg.svd(vertices - g)  # run singular value decomposition

    return get_integer_index(vh[0, :])  # return line of best fit
예제 #3
0
def get_structure_components(bonded_structure, inc_orientation=False,
                             inc_site_ids=False, inc_molecule_graph=False):
    """
    Gets information on the components in a bonded structure.

    Correctly determines the dimensionality of all structures, regardless of
    structure type or improper connections due to periodic boundary conditions.

    Requires a StructureGraph object as input. This can be generated using one
    of the NearNeighbor classes. For example, using the CrystalNN class::

        bonded_structure = CrystalNN().get_bonded_structure(structure)

    Based on the modified breadth-first-search algorithm described in:

    P. Larsem, M. Pandey, M. Strange, K. W. Jacobsen, 2018, arXiv:1808.02114

    Args:
        bonded_structure (StructureGraph): A structure with bonds, represented
            as a pymatgen structure graph. For example, generated using the
            CrystalNN.get_bonded_structure() method.
        inc_orientation (bool, optional): Whether to include the orientation
            of the structure component. For surfaces, the miller index is given,
            for one-dimensional structures, the direction of the chain is given.
        inc_site_ids (bool, optional): Whether to include the site indices
            of the sites in the structure component.
        inc_molecule_graph (bool, optional): Whether to include MoleculeGraph
            objects for zero-dimensional components.

    Returns:
        (list of dict): Information on the components in a structure as a list
        of dictionaries with the keys:

        - "structure_graph": A pymatgen StructureGraph object for the
            component.
        - "dimensionality": The dimensionality of the structure component as an
            int.
        - "orientation": If inc_orientation is `True`, the orientation of the
            component as a tuple. E.g. (1, 1, 1)
        - "site_ids": If inc_site_ids is `True`, the site indices of the
            sites in the component as a tuple.
        - "molecule_graph": If inc_molecule_graph is `True`, the site a
            MoleculeGraph object for zero-dimensional components.
    """
    import networkx as nx  # optional dependency therefore not top level import

    comp_graphs = (bonded_structure.graph.subgraph(c) for c in
                   nx.weakly_connected_components(bonded_structure.graph))

    components = []
    for graph in comp_graphs:
        dimensionality, vertices = calculate_dimensionality_of_site(
            bonded_structure, list(graph.nodes())[0], inc_vertices=True)

        component = {'dimensionality': dimensionality}

        if inc_orientation:
            if dimensionality in [1, 2]:
                vertices = np.array(vertices)

                g = vertices.sum(axis=0) / vertices.shape[0]

                # run singular value decomposition
                _, _, vh = np.linalg.svd(vertices - g)

                # get direction (first column is best fit line,
                # 3rd column is unitary norm)
                index = 2 if dimensionality == 2 else 0
                orientation = get_integer_index(vh[index, :])
            else:
                orientation = None

            component['orientation'] = orientation

        if inc_site_ids:
            component['site_ids'] = tuple(graph.nodes())

        if inc_molecule_graph and dimensionality == 0:
            component['molecule_graph'] = zero_d_graph_to_molecule_graph(
                bonded_structure, graph)

        component_structure = Structure.from_sites(
            [bonded_structure.structure[n] for n in sorted(graph.nodes())])

        sorted_graph = nx.convert_node_labels_to_integers(
            graph, ordering="sorted")
        component_graph = StructureGraph(
            component_structure,
            graph_data=json_graph.adjacency_data(sorted_graph))
        component['structure_graph'] = component_graph

        components.append(component)
    return components
예제 #4
0
def get_structure_component_info(bonded_structure, inc_orientation=False):
    """
    Gets information on the components in a bonded structure.

    Correctly determines the dimensionality of all structures, regardless of
    structure type or improper connections due to periodic boundary conditions.

    Requires a StructureGraph object as input. This can be generated using one
    of the NearNeighbor classes. For example, using the CrystalNN class::

        bonded_structure = CrystalNN().get_bonded_structure(structure)

    Based on the modified breadth-first-search algorithm described in:

    P. Larsem, M. Pandey, M. Strange, K. W. Jacobsen, 2018, arXiv:1808.02114

    Args:
        bonded_structure (StructureGraph): A structure with bonds, represented
            as a pymatgen structure graph. For example, generated using the
            CrystalNN.get_bonded_structure() method.
        inc_orientation (bool, optional): Whether to include the orientation
            of the structure component. For surfaces, the miller index is given,
            for one-dimensional structures, the direction of the chain is given.

    Returns:
        (list of dict): Information on the components in a structure as a list
        of dictionaries with the keys:

        - "structure": A pymatgen Structure object containing the component
            atoms.
        - "dimensionality": The dimensionality of the structure component as an
            int.
        - "orientation": If inc_orientation is `True`, the orientation of the
            component as a tuple. E.g. (1, 1, 1)
    """
    import networkx as nx  # optional dependency therefore not top level import

    comp_graphs = (
        bonded_structure.graph.subgraph(c)
        for c in nx.weakly_connected_components(bonded_structure.graph))

    components = []
    for graph in comp_graphs:
        sites = [bonded_structure.structure[n] for n in graph.nodes()]
        component_structure = Structure.from_sites(sites)

        dimensionality, vertices = calculate_dimensionality_of_site(
            bonded_structure, list(graph.nodes())[0], inc_vertices=True)

        component = {
            'structure': component_structure,
            'dimensionality': dimensionality
        }

        if inc_orientation:
            if dimensionality in [1, 2]:
                vertices = np.array(vertices)

                g = vertices.sum(axis=0) / vertices.shape[0]

                # run singular value decomposition
                _, _, vh = np.linalg.svd(vertices - g)

                # get direction (first column is best fit line,
                # 3rd column is unitary norm)
                index = 2 if dimensionality == 2 else 0
                orientation = get_integer_index(vh[index, :])
            else:
                orientation = None

            component['orientation'] = orientation

        components.append(component)
    return components
예제 #5
0
def get_structure_components(
    bonded_structure,
    inc_orientation=False,
    inc_site_ids=False,
    inc_molecule_graph=False,
):
    """
    Gets information on the components in a bonded structure.

    Correctly determines the dimensionality of all structures, regardless of
    structure type or improper connections due to periodic boundary conditions.

    Requires a StructureGraph object as input. This can be generated using one
    of the NearNeighbor classes. For example, using the CrystalNN class::

        bonded_structure = CrystalNN().get_bonded_structure(structure)

    Based on the modified breadth-first-search algorithm described in:

    P. M. Larsen, M. Pandey, M. Strange, K. W. Jacobsen. Definition of a
    scoring parameter to identify low-dimensional materials components.
    Phys. Rev. Materials 3, 034003 (2019).

    Args:
        bonded_structure (StructureGraph): A structure with bonds, represented
            as a pymatgen structure graph. For example, generated using the
            CrystalNN.get_bonded_structure() method.
        inc_orientation (bool, optional): Whether to include the orientation
            of the structure component. For surfaces, the miller index is given,
            for one-dimensional structures, the direction of the chain is given.
        inc_site_ids (bool, optional): Whether to include the site indices
            of the sites in the structure component.
        inc_molecule_graph (bool, optional): Whether to include MoleculeGraph
            objects for zero-dimensional components.

    Returns:
        (list of dict): Information on the components in a structure as a list
        of dictionaries with the keys:

        - "structure_graph": A pymatgen StructureGraph object for the
            component.
        - "dimensionality": The dimensionality of the structure component as an
            int.
        - "orientation": If inc_orientation is `True`, the orientation of the
            component as a tuple. E.g. (1, 1, 1)
        - "site_ids": If inc_site_ids is `True`, the site indices of the
            sites in the component as a tuple.
        - "molecule_graph": If inc_molecule_graph is `True`, the site a
            MoleculeGraph object for zero-dimensional components.
    """
    import networkx as nx  # optional dependency therefore not top level import

    comp_graphs = (
        bonded_structure.graph.subgraph(c)
        for c in nx.weakly_connected_components(bonded_structure.graph))

    components = []
    for graph in comp_graphs:
        dimensionality, vertices = calculate_dimensionality_of_site(
            bonded_structure, list(graph.nodes())[0], inc_vertices=True)

        component = {"dimensionality": dimensionality}

        if inc_orientation:
            if dimensionality in [1, 2]:
                vertices = np.array(vertices)

                g = vertices.sum(axis=0) / vertices.shape[0]

                # run singular value decomposition
                _, _, vh = np.linalg.svd(vertices - g)

                # get direction (first column is best fit line,
                # 3rd column is unitary norm)
                index = 2 if dimensionality == 2 else 0
                orientation = get_integer_index(vh[index, :])
            else:
                orientation = None

            component["orientation"] = orientation

        if inc_site_ids:
            component["site_ids"] = tuple(graph.nodes())

        if inc_molecule_graph and dimensionality == 0:
            component["molecule_graph"] = zero_d_graph_to_molecule_graph(
                bonded_structure, graph)

        component_structure = Structure.from_sites(
            [bonded_structure.structure[n] for n in sorted(graph.nodes())])

        sorted_graph = nx.convert_node_labels_to_integers(graph,
                                                          ordering="sorted")
        component_graph = StructureGraph(
            component_structure,
            graph_data=json_graph.adjacency_data(sorted_graph))
        component["structure_graph"] = component_graph

        components.append(component)
    return components