예제 #1
0
 def setUp(self):
     struct = Structure.from_file(
         f"{dir_path}/full_path_files/MnO2_full_Li.vasp")
     self.fpm = FullPathMapper(structure=struct,
                               migrating_specie='Li',
                               max_path_length=4)
     self.fpm.populate_edges_with_migration_paths()
     self.fpm.group_and_label_hops()
예제 #2
0
class FullPathMapperSimpleTest(unittest.TestCase):
    def setUp(self):
        struct = Structure.from_file(get_path("MnO2_full_Li.vasp",
                                              dirname="full_path_files"))
        self.fpm = FullPathMapper(structure=struct, migrating_specie='Li', max_path_length=4)

    def test_get_pos_and_migration_path(self):
        """
        Make sure that we can populate the graph with MigrationPath Objects
        """
        self.fpm._get_pos_and_migration_path(0, 1, 1)
        self.assertAlmostEqual(self.fpm.s_graph.graph[0][1][1]['hop'].length, 3.571248, 4)
예제 #3
0
    def setUp(self):
        struct = Structure.from_file(
            f"{dir_path}/full_path_files/MnO2_full_Li.vasp")
        self.fpm_li = FullPathMapper(structure=struct,
                                     migrating_specie="Li",
                                     max_path_length=4)
        self.fpm_li.populate_edges_with_migration_paths()
        self.fpm_li.group_and_label_hops()

        # Particularity difficult pathfinding since both the starting and ending positions are outside the unit cell
        struct = Structure.from_file(
            f"{dir_path}/full_path_files/Mg_2atom.vasp")
        self.fpm_mg = FullPathMapper(structure=struct,
                                     migrating_specie="Mg",
                                     max_path_length=2)
        self.fpm_mg.populate_edges_with_migration_paths()
        self.fpm_mg.group_and_label_hops()
예제 #4
0
class FullPathMapperComplexTest(unittest.TestCase):
    def setUp(self):
        struct = Structure.from_file(get_path("MnO2_full_Li.vasp",
                                              dirname="full_path_files"))
        self.fpm = FullPathMapper(structure=struct, migrating_specie='Li', max_path_length=4)
        self.fpm.populate_edges_with_migration_paths()
        self.fpm.group_and_label_hops()

    def test_group_and_label_hops(self):
        """
        Check that the set of end points in a group of similiarly labeled hops are all the same
        """
        edge_labs = np.array([d['hop_label'] for u, v, d in self.fpm.s_graph.graph.edges(data=True)])

        site_labs = np.array([(d['hop'].symm_structure.wyckoff_symbols[d['hop'].iindex],
                               d['hop'].symm_structure.wyckoff_symbols[d['hop'].eindex]) for u, v, d in
                              self.fpm.s_graph.graph.edges(data=True)])

        for itr in range(edge_labs.max()):
            sub_set = site_labs[edge_labs == itr]
            for end_point_labels in sub_set:
                self.assertTrue(sorted(end_point_labels) == sorted(sub_set[0]))

    def test_unique_hops_dict(self):
        """
        Check that the unique hops are inequilvalent
        """
        self.fpm.get_unique_hops_dict()
        unique_list = [v for k, v in self.fpm.unique_hops.items()]
        all_pairs = [(mg1, mg2) for i1, mg1 in enumerate(unique_list) for mg2 in unique_list[i1 + 1:]]

        for migration_path in all_pairs:
            self.assertNotEqual(migration_path[0], migration_path[1])
예제 #5
0
 def setUp(self):
     struct = Structure.from_file(
         f"{dir_path}/full_path_files/MnO2_full_Li.vasp")
     self.fpm = FullPathMapper(structure=struct,
                               migrating_specie='Li',
                               max_path_length=4)
예제 #6
0
class FullPathMapperComplexTest(unittest.TestCase):
    def setUp(self):
        struct = Structure.from_file(
            f"{dir_path}/full_path_files/MnO2_full_Li.vasp")
        self.fpm_li = FullPathMapper(structure=struct,
                                     migrating_specie="Li",
                                     max_path_length=4)
        self.fpm_li.populate_edges_with_migration_paths()
        self.fpm_li.group_and_label_hops()

        # Particularity difficult pathfinding since both the starting and ending positions are outside the unit cell
        struct = Structure.from_file(
            f"{dir_path}/full_path_files/Mg_2atom.vasp")
        self.fpm_mg = FullPathMapper(structure=struct,
                                     migrating_specie="Mg",
                                     max_path_length=2)
        self.fpm_mg.populate_edges_with_migration_paths()
        self.fpm_mg.group_and_label_hops()

    def test_group_and_label_hops(self):
        """
        Check that the set of end points in a group of similiarly labeled hops are all the same
        """
        edge_labs = np.array([
            d["hop_label"]
            for u, v, d in self.fpm_li.s_graph.graph.edges(data=True)
        ])

        site_labs = np.array([(
            d["hop"].symm_structure.wyckoff_symbols[d["hop"].iindex],
            d["hop"].symm_structure.wyckoff_symbols[d["hop"].eindex],
        ) for u, v, d in self.fpm_li.s_graph.graph.edges(data=True)])

        for itr in range(edge_labs.max()):
            sub_set = site_labs[edge_labs == itr]
            for end_point_labels in sub_set:
                self.assertTrue(sorted(end_point_labels) == sorted(sub_set[0]))

    def test_unique_hops_dict(self):
        """
        Check that the unique hops are inequilvalent
        """
        self.fpm_li._populate_unique_hops_dict()
        unique_list = [v for k, v in self.fpm_li.unique_hops.items()]
        all_pairs = [(mg1, mg2) for i1, mg1 in enumerate(unique_list)
                     for mg2 in unique_list[i1 + 1:]]

        for migration_path in all_pairs:
            self.assertNotEqual(migration_path[0]["hop"],
                                migration_path[1]["hop"])

    def test_add_data_to_similar_edges(self):
        # passing normal data
        self.fpm_li.add_data_to_similar_edges(0, {"key0": "data"})
        for u, v, d in self.fpm_li.s_graph.graph.edges(data=True):
            if d["hop_label"] == 0:
                self.assertEqual(d["key0"], "data")

        # passing ordered list data
        migration_path = self.fpm_li.unique_hops[1]["hop"]
        self.fpm_li.add_data_to_similar_edges(1, {"key1": [1, 2, 3]},
                                              m_path=migration_path)
        for u, v, d in self.fpm_li.s_graph.graph.edges(data=True):
            if d["hop_label"] == 1:
                self.assertEqual(d["key1"], [1, 2, 3])

        # passing ordered list with direction
        migration_path_reversed = MigrationPath(
            isite=migration_path.esite,
            esite=migration_path.isite,
            symm_structure=migration_path.symm_structure,
        )
        self.fpm_li.add_data_to_similar_edges(2, {"key2": [1, 2, 3]},
                                              m_path=migration_path_reversed)
        for u, v, d in self.fpm_li.s_graph.graph.edges(data=True):
            if d["hop_label"] == 2:
                self.assertEqual(d["key2"], [3, 2, 1])

    def test_assign_cost_to_graph(self):
        self.fpm_li.assign_cost_to_graph()  # use 'hop_distance'
        for u, v, d in self.fpm_li.s_graph.graph.edges(data=True):
            self.assertAlmostEqual(d["cost"], d["hop_distance"], 4)

        self.fpm_li.assign_cost_to_graph(
            cost_keys=["hop_distance", "hop_distance"])
        for u, v, d in self.fpm_li.s_graph.graph.edges(data=True):
            self.assertAlmostEqual(d["cost"],
                                   d["hop_distance"] * d["hop_distance"], 4)

    def test_periodic_dijkstra(self):
        self.fpm_li.assign_cost_to_graph()  # use 'hop_distance'

        # test the connection graph
        sgraph = self.fpm_li.s_graph
        G = sgraph.graph.to_undirected()
        conn_dict = _get_adjacency_with_images(G)
        for u in conn_dict.keys():
            for v in conn_dict[u]:
                for k, d in conn_dict[u][v].items():
                    neg_image = tuple(-dim_ for dim_ in d["to_jimage"])
                    opposite_connections = [
                        d2_["to_jimage"]
                        for k2_, d2_ in conn_dict[v][u].items()
                    ]
                    self.assertIn(neg_image, opposite_connections)

    def test_get_intercalating_path(self):
        self.fpm_li.assign_cost_to_graph()  # use 'hop_distance'
        paths = [*self.fpm_li.get_intercalating_path()]
        p_strings = {
            "->".join(map(str, get_hop_site_sequence(ipath, start_u=u)))
            for u, ipath in paths
        }
        self.assertIn("5->7->5", p_strings)
        # convert each pathway to a string representation
        paths = [*self.fpm_li.get_intercalating_path(max_val=2.0)]
        p_strings = {
            "->".join(map(str, get_hop_site_sequence(ipath, start_u=u)))
            for u, ipath in paths
        }

        # After checking trimming the graph more hops are needed for the same path
        self.assertIn("5->3->7->2->5", p_strings)

        self.fpm_mg.assign_cost_to_graph()  # use 'hop_distance'
        paths = [*self.fpm_mg.get_intercalating_path()]
        p_strings = {
            "->".join(map(str, get_hop_site_sequence(ipath, start_u=u)))
            for u, ipath in paths
        }
        self.assertIn("1->0->1", p_strings)

    def test_not_matching_first(self):
        structure = Structure.from_file(
            f"{dir_path}/pathfinder_files/Li6MnO4.json")
        fpm_lmo = FullPathMapper(structure, "Li", max_path_length=4)
        for u, v, d in fpm_lmo.s_graph.graph.edges(data=True):
            self.assertIn(d["hop"].eindex, {0, 1})
예제 #7
0
 def test_not_matching_first(self):
     structure = Structure.from_file(
         f"{dir_path}/pathfinder_files/Li6MnO4.json")
     fpm_lmo = FullPathMapper(structure, "Li", max_path_length=4)
     for u, v, d in fpm_lmo.s_graph.graph.edges(data=True):
         self.assertIn(d["hop"].eindex, {0, 1})
예제 #8
0
 def setUp(self):
     struct = Structure.from_file(get_path("MnO2_full_Li.vasp",
                                           dirname="full_path_files"))
     self.fpm = FullPathMapper(structure=struct, migrating_specie='Li', max_path_length=4)