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()
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)
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()
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])
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)
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})
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})
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)