def test_results(self): # Structure of a B2 crystal. structure = Cell() structure.add_atom(Atom([0, 0, 0], 0)) structure.add_atom(Atom([0.5, 0.5, 0.5], 1)) structure.set_type_name(0, "Al") structure.set_type_name(1, "Ni") entry = CrystalStructureEntry(structure, name="B2", radii=None) entries = [entry] # Create feature generator. gen = ChemicalOrderingAttributeGenerator() gen.set_weighted(False) gen.set_shells([1, 2]) # Generate features. features = gen.generate_features(entries) # Test results. self.assertAlmostEqual(0.142857, features.values[0][0], delta=1e-6) self.assertAlmostEqual(0.04, features.values[0][1], delta=1e-6) # Now with weights. gen.set_weighted(True) features = gen.generate_features(entries) # Test results. self.assertAlmostEqual(0.551982, features.values[0][0], delta=1e-6) self.assertAlmostEqual(0.253856, features.values[0][1], delta=1e-6)
def test_unit_cell_choice(self): # Create a B2 structure with lattice parameter of 1. structure = Cell() structure.add_atom(Atom([0, 0, 0], 0)) structure.add_atom(Atom([0.5, 0.5, 0.5], 1)) # Create a 2x1x1 supercell. supercell = Cell() supercell.set_basis(lengths=[2, 1, 1], angles=[90, 90, 90]) supercell.add_atom(Atom([0, 0, 0], 0)) supercell.add_atom(Atom([0.5, 0, 0], 0)) supercell.add_atom(Atom([0.25, 0.5, 0.5], 1)) supercell.add_atom(Atom([0.75, 0.5, 0.5], 1)) self.tool.set_cut_off_distance(3.0) self.tool.set_n_windows(10) self.tool.set_smoothing_factor(4) # Compute the primitive cell AP-RDF. self.tool.analyze_structure(structure) p_ap_rdf = self.tool.compute_APRDF([1, 2]) # Compute the supercell AP-RDF. self.tool.analyze_structure(supercell) sc_ap_rdf = self.tool.compute_APRDF([1, 2]) # Compare results. np_tst.assert_array_almost_equal(p_ap_rdf, sc_ap_rdf)
def test_results2(self): # Create a B1-HHe structure. structure = Cell() basis = np.zeros((3, 3)) basis[0] = np.array([0, 0.5, 0.5]) basis[1] = np.array([0.5, 0, 0.5]) basis[2] = np.array([0.5, 0.5, 0]) structure.set_basis(basis=basis) structure.add_atom(Atom([0, 0, 0], 0)) structure.add_atom(Atom([0.5, 0.5, 0.5], 1)) structure.set_type_name(0, "H") structure.set_type_name(1, "He") entries = [CrystalStructureEntry(structure, name="B1-HHe", radii=None)] # Get the feature generator. gen = self.get_generator() gen.clear_elemental_properties() gen.add_elemental_property("Number") # Generate features. features = gen.generate_features(entries) # Test the results. self.assertEqual(self.expected_count(), features.shape[1]) np_tst.assert_array_almost_equal([1, 0, 1, 1, 0, 0, 0, 0, 0, 0], features.values[0])
def test_creation(self): # Make a simple crystal. cell = Cell() cell.add_atom(Atom([0, 0, 0], 0)) # Initialize faces. image = AtomImage(cell.get_atom(0), [0, 0, 1]) face1 = VoronoiFace(cell.get_atom(0), image, radical=True) image = AtomImage(cell.get_atom(0), [0, 1, 0]) face2 = VoronoiFace(cell.get_atom(0), image, radical=True) image = AtomImage(cell.get_atom(0), [1, 0, 0]) face3 = VoronoiFace(cell.get_atom(0), image, radical=True) # Create edges. edge1 = VoronoiEdge(face1, face2) edge2 = VoronoiEdge(face1, face3) # Create vertex. vertex = VoronoiVertex(edge1=edge1, edge2=edge2) # Test properties. self.assertEqual(edge2, vertex.get_previous_edge()) self.assertEqual(edge1, vertex.get_next_edge()) # Make sure the order of edges on creation doesn't matter. self.assertEqual(vertex, VoronoiVertex(edge1=edge2, edge2=edge1)) # Create a new vertex, ensure that it is different. edge3 = VoronoiEdge(face2, face3) self.assertFalse(vertex.__eq__(VoronoiVertex(edge1=edge3, edge2=edge2)))
def test_matrix(self): # Make a simple structure. structure = Cell() structure.add_atom(Atom([0, 0, 0], 0)) structure.set_type_name(0, "Al") # Compute the sine matrix. mat = self.r.compute_coulomb_matrix(structure) self.assertEqual(1, mat.shape[0]) self.assertEqual(1, mat.shape[1]) self.assertAlmostEqual(0.5 * 13 ** 2.4, mat[0, 0],delta=1e-6) # Add another atom and repeat. structure.add_atom(Atom([0.5, 0.5, 0.5], 0)) mat = self.r.compute_coulomb_matrix(structure) self.assertEqual(2, mat.shape[0]) self.assertEqual(2, mat.shape[1]) # Test: Is it insensitive to basis changes. new_basis = structure.get_basis() new_basis[1, 0] = 12 structure.set_basis(basis=new_basis) self.assertAlmostEqual(1.0, structure.volume(), delta=1e-6) mat2 = self.r.compute_coulomb_matrix(structure) if np.linalg.norm(mat - mat2) > 1e-6: sys.stderr.write("WARNING: Not insensitive to basis changes\n")
def test_distance(self): # Make two simple structures. structure1 = Cell() structure1.add_atom(Atom([0, 0, 0], 0)) structure1.set_type_name(0, "Al") structure2 = Cell() structure2.add_atom(Atom([0, 0, 0], 0)) structure2.set_type_name(0, "Ni") # Compute representations of each structure. rep1 = self.r.compute_representation(structure1) rep2 = self.r.compute_representation(structure2) # Check that similarity between identical structures is 1.0. self.assertAlmostEqual(1.0, self.r.compute_similarity(rep1, rep1), delta=1e-6) self.assertAlmostEqual(1.0, self.r.compute_similarity(rep2, rep2), delta=1e-6) # Check symmetry. self.assertAlmostEqual(self.r.compute_similarity(rep1, rep2), self.r.compute_similarity(rep2, rep1), delta=1e-6) # Check that similarity between these structures is less than 1.0. self.assertTrue(self.r.compute_similarity(rep1, rep2) < 1.0)
def test_intersection(self): # Create cell. structure = Cell() structure.add_atom(Atom([0, 0, 0], 0)) # Create cell for atom1. cell = VoronoiCell(structure.get_atom(0), radical=True) # Make sure direct faces match up with expectations. neighboring_faces = [] neighboring_faces.append(AtomImage(structure.get_atom(0), [1, 0, 0])) neighboring_faces.append(AtomImage(structure.get_atom(0), [-1, 0, 0])) neighboring_faces.append(AtomImage(structure.get_atom(0), [0, 1, 0])) neighboring_faces.append(AtomImage(structure.get_atom(0), [0, -1, 0])) neighboring_faces.append(AtomImage(structure.get_atom(0), [0, 0, 2])) neighboring_faces.append(AtomImage(structure.get_atom(0), [0, 0, -1])) # Assemble cell. cell.compute_cell_helper(neighboring_faces) # Perform cut. cut_face = VoronoiFace(cell.get_atom(), AtomImage(cell.get_atom(), [0, 0, 1]), radical=True) cell.compute_intersection(cut_face) # Check results. self.assertTrue(cut_face.is_closed()) self.assertEqual(4, cut_face.n_edges()) self.assertTrue(cell.geometry_is_valid()) self.assertEqual(6, cell.n_faces()) self.assertAlmostEqual(1.0, cell.get_volume(), delta=1e-6)
def test_big(self): # Number of atoms in each direction. n_atom = 4 structure = Cell() structure.set_basis(lengths=[2 * n_atom, 2 * n_atom, 2 * n_atom], angles=[90, 90, 90]) # Add a bunch of atoms. step_size = 1.0 / n_atom for x in range(n_atom): for y in range(n_atom): for z in range(n_atom): new_pos = np.array([x, y, z], dtype=float) + \ np.random.random(3) / n_atom new_pos *= step_size structure.add_atom(Atom(new_pos, 0)) # Compute the cells. cells = VoronoiTessellationCalculator.compute(structure, radical=True) total_vol = 0.0 for cell in cells: total_vol += cell.get_volume() self.assertTrue(cell.geometry_is_valid()) vol_error = (total_vol - structure.volume()) / structure.volume() self.assertAlmostEqual(0.0, vol_error, delta=1e-2)
def test_supercell(self): # Create cell. structure = Cell() structure.add_atom(Atom([0, 0, 0], 0)) # Create cell for atom1. cell = VoronoiCell(structure.get_atom(0), radical=True) # Compute faces. images = [ AtomImage(structure.get_atom(0), sc) for sc in VectorCombinationComputer( structure.get_lattice_vectors(), 1.1).get_supercell_coordinates() ] faces = cell.compute_faces(images) # Get direct neighbors. direct_faces = cell.compute_direct_neighbors(faces) # Simple tests. self.assertEqual(6, len(direct_faces)) self.assertEqual(len(images) - 6 - 1, len(faces)) # Make sure direct faces match up with expectations. neighboring_faces = [] neighboring_faces.append( VoronoiFace(structure.get_atom(0), AtomImage(structure.get_atom(0), [1, 0, 0]), radical=True)) neighboring_faces.append( VoronoiFace(structure.get_atom(0), AtomImage(structure.get_atom(0), [-1, 0, 0]), radical=True)) neighboring_faces.append( VoronoiFace(structure.get_atom(0), AtomImage(structure.get_atom(0), [0, 1, 0]), radical=True)) neighboring_faces.append( VoronoiFace(structure.get_atom(0), AtomImage(structure.get_atom(0), [0, -1, 0]), radical=True)) neighboring_faces.append( VoronoiFace(structure.get_atom(0), AtomImage(structure.get_atom(0), [0, 0, 1]), radical=True)) neighboring_faces.append( VoronoiFace(structure.get_atom(0), AtomImage(structure.get_atom(0), [0, 0, -1]), radical=True)) # Test whether they are all there. for f in neighboring_faces: direct_faces.remove(f) self.assertTrue(len(direct_faces) == 0)
def test_to_string(self): # Make B2-CuZr cell = Cell() cell.add_atom(Atom([0, 0, 0], 0)) cell.add_atom(Atom([0.5, 0.5, 0.5], 1)) cell.set_type_name(0, "Cu") cell.set_type_name(1, "Zr") CuZr = CrystalStructureEntry(cell, "B2", None) name = CuZr.__str__() # print(name) self.assertTrue("CuZr" in name) self.assertTrue("B2" in name)
def test_constructor(self): # Create a Voronoi tessellation of a BCC crystal. bcc = Cell() atom = Atom([0, 0, 0], 0) bcc.add_atom(atom) atom = Atom([0.5, 0.5, 0.5], 0) bcc.add_atom(atom) # Prepare. tool = VoronoiCellBasedAnalysis(radical=True) tool.analyze_structure(bcc) # Create a new instance based on a B2 crystal. b2 = bcc.__copy__() b2.get_atom(1).set_type(1) tool2 = VoronoiCellBasedAnalysis(old_tessellation=tool, new_structure=b2)
def test_BCC(self): # Structure of bcc. structure = Cell() atom = Atom([0, 0, 0], 0) structure.add_atom(atom) atom = Atom([0.5, 0.5, 0.5], 0) structure.add_atom(atom) # Prepare. tool = VoronoiCellBasedAnalysis(radical=True) tool.analyze_structure(structure) # Check results. n_eff = 11.95692194 np_tst.assert_array_almost_equal( [n_eff, n_eff], tool.get_effective_coordination_numbers()) self.assertAlmostEqual(14.0, tool.face_count_average(), delta=1e-2) self.assertAlmostEqual(0.0, tool.face_count_variance(), delta=1e-2) self.assertAlmostEqual(14.0, tool.face_count_minimum(), delta=1e-2) self.assertAlmostEqual(14.0, tool.face_count_maximum(), delta=1e-2) self.assertAlmostEqual(1, len(tool.get_unique_polyhedron_shapes()), delta=1e-2) self.assertAlmostEqual(0.0, tool.volume_variance(), delta=1e-2) self.assertAlmostEqual(0.5, tool.volume_fraction_minimum(), delta=1e-2) self.assertAlmostEqual(0.5, tool.volume_fraction_maximum(), delta=1e-2) self.assertAlmostEqual(0.68, tool.max_packing_efficiency(), delta=1e-2) self.assertAlmostEqual(0, tool.mean_bcc_dissimilarity(), delta=1e-2) self.assertAlmostEqual(14.0 / 12.0, tool.mean_fcc_dissimilarity(), delta=1e-2) self.assertAlmostEqual(8.0 / 6.0, tool.mean_sc_dissimilarity(), delta=1e-2) bond_lengths = tool.bond_lengths() self.assertEqual(2, len(bond_lengths)) self.assertEqual(14, len(bond_lengths[0])) self.assertAlmostEqual(math.sqrt(3) / 2, bond_lengths[0][0], delta=1e-6) self.assertAlmostEqual(1.0, bond_lengths[0][12], delta=1e-6) mean_bond_lengths = tool.mean_bond_lengths() var_bond_lengths = tool.bond_length_variance(mean_bond_lengths) self.assertTrue(var_bond_lengths[0] > 0)
def test_FCC_primitive(self): # Create the simulation cell. structure = Cell() structure.set_basis(lengths=[0.70710678118655, 0.70710678118655, 1.0], angles=[45, 90, 60]) structure.add_atom(Atom([0, 0, 0], 0)) # Run tessellation. result = VoronoiTessellationCalculator.compute(structure, radical=False) # Test results. self.assertEqual(structure.n_atoms(), len(result)) self.assertTrue(result[0].geometry_is_valid()) self.assertEqual(12, len(result[0].get_faces())) poly_index = result[0].get_polyhedron_shape() self.assertEqual(12, poly_index[4]) poly_index = result[0].get_coordination_shell_shape(result) self.assertEqual(12, poly_index[4])
def test_replacement(self): # Make B2-CuZr cell = Cell() cell.add_atom(Atom([0, 0, 0], 0)) cell.add_atom(Atom([0.5, 0.5, 0.5], 1)) cell.set_type_name(0, "Cu") cell.set_type_name(1, "Zr") CuZr = CrystalStructureEntry(cell, "CuZr", None) # Run Voronoi tessellation. CuZr.compute_voronoi_tessellation() # Make B2-NiZr changes = {"Cu":"Ni"} NiZr = CuZr.replace_elements(changes) # Make sure the tessellation object did not change. self.assertTrue(CuZr.compute_voronoi_tessellation() is NiZr.compute_voronoi_tessellation()) # Make sure the two are still unchanged. self.assertAlmostEqual(0.5, CuZr.get_element_fraction(name="Cu"), delta=1e-6) self.assertAlmostEqual(0.0, CuZr.get_element_fraction(name="Ni"), delta=1e-6) self.assertAlmostEqual(0.0, NiZr.get_element_fraction(name="Cu"), delta=1e-6) self.assertAlmostEqual(0.5, NiZr.get_element_fraction(name="Ni"), delta=1e-6) # Now, change the structure such that it has fewer types. changes["Ni"] = "Zr" bccZr = NiZr.replace_elements(changes) # Make sure the structure only has one type. self.assertAlmostEqual(1.0, bccZr.get_element_fraction(name="Zr"), delta=1e-6) self.assertEqual(1, bccZr.get_structure().n_types()) self.assertFalse(NiZr.compute_voronoi_tessellation() is bccZr.compute_voronoi_tessellation())
def test(self): structure = Cell() structure.set_basis(lengths=[3.2, 3.2, 3.2], angles=[90, 90, 90]) structure.add_atom(Atom([0, 0, 0], 0)) structure.add_atom(Atom([0.5, 0.5, 0.5], 1)) structure.set_type_name(0, "Ni") structure.set_type_name(1, "Al") entry = CrystalStructureEntry(structure, name="B2-NiAl", radii=None) entries = [entry] # Create feature generator. gen = APRDFAttributeGenerator() gen.set_cut_off_distance(3.2) gen.set_num_points(2) gen.set_smoothing_parameter(100) gen.add_elemental_property("Number") # Generate features. features = gen.generate_features(entries) self.assertEqual(2, len(features.columns)) ap_rdf = features.values # Assemble known contributors. # [0] -> Number of neighbors * P_i * P_j # [1] -> Bond distance contributors = [] contributors.append([2 * 8 * 13 * 28, 3.2 * math.sqrt(3) / 2]) # A-B # 1st NN. contributors.append([6 * 13 * 13, 3.2 * 1]) # A-A 2nd NN. contributors.append([6 * 28 * 28, 3.2 * 1]) # B-B 2nd NN. contributors.append([8 * 13 * 13, 3.2 * math.sqrt(3)]) # A-A 3rd NN. contributors.append([8 * 28 * 28, 3.2 * math.sqrt(3)]) # B-B 3rd NN. eval_dist = [1.6, 3.2] expected_ap_rdf = [ sum([c[0] * math.exp(-100 * (c[1] - r)**2) for c in contributors]) / 2 for r in eval_dist ] np_tst.assert_array_almost_equal(expected_ap_rdf, ap_rdf[0])
def test_conversion(self): # Make an FCC cell. cell = Cell() cell.set_basis(lengths=[3.5, 3.6, 3.4], angles=[89, 90, 91]) cell.add_atom(Atom([0, 0, 0], 0)) cell.add_atom(Atom([0.5, 0.5, 0], 1)) cell.add_atom(Atom([0.5, 0, 0.5], 1)) cell.add_atom(Atom([0, 0.5, 0.5], 1)) cell.set_type_name(0, "Al") cell.set_type_name(1, "Ni") # Convert it to string. vio = VASP5IO() temp = vio.convert_structure_to_string(cell) # Convert it back. new_cell = vio.parse_file(list_of_lines=temp) # Check to make sure everything is good. self.assertAlmostEqual(cell.volume(), new_cell.volume(), delta=1e-4) self.assertEqual(cell.n_types(), new_cell.n_types()) np_tst.assert_array_almost_equal(cell.get_lattice_vectors()[1], new_cell.get_lattice_vectors()[1], decimal=4) new_temp = vio.convert_structure_to_string(new_cell) np_tst.assert_equal(temp, new_temp)
def test_results2(self): # Create a L12-H3He structure. # Structure of L12. structure = Cell() structure.add_atom(Atom([0, 0, 0], 1)) structure.add_atom(Atom([0.5, 0.5, 0], 0)) structure.add_atom(Atom([0.5, 0, 0.5], 0)) structure.add_atom(Atom([0, 0.5, 0.5], 0)) structure.set_type_name(0, "H") structure.set_type_name(1, "He") entries = [ CrystalStructureEntry(structure, name="L12-HHe", radii=None) ] # Get the feature generator. gen = self.get_generator() gen.clear_shells() gen.clear_elemental_properties() gen.add_shell(1) gen.add_elemental_property("Number") # Generate features. features = gen.generate_features(entries) # Test the results. self.assertEqual(5, features.shape[1]) np_tst.assert_array_almost_equal( [0.166666667, 0.083333333, 0, 2.0 / 9, 2.0 / 9], features.values[0])
def test(self): # Make two simple structures. structure1 = Cell() structure1.add_atom(Atom([0, 0, 0], 0)) structure1.set_type_name(0, "Al") entries = [] entry1 = CrystalStructureEntry(structure1, name="Al", radii=None) entries.append(entry1) structure2 = Cell() structure2.add_atom(Atom([0, 0, 0], 0)) structure2.set_type_name(0, "Ni") structure2.add_atom(Atom([0, 0.5, 0], 1)) structure2.set_type_name(1, "Al") structure2.add_atom(Atom([0, 0, 0.5], 1)) entry2 = CrystalStructureEntry(structure2, name="NiAl2", radii=None) entries.append(entry2) # Create feature generator. gen = PRDFAttributeGenerator() gen.set_cut_off_distance(3.0) gen.set_n_points(5) gen.set_elements(entries) # Add extra element H. gen.add_element(name="H") # Generate features. features = gen.generate_features(entries) # Test results. self.assertEqual(3 * 3 * 5, features.shape[1]) self.assertEqual(3 * 3 * 5, len(features.values[0])) self.assertAlmostEqual(0, sum(features.values[0][0 : 4 * 5]), delta=1e-6) # First 4 PRDFs are H-X. self.assertTrue(max(features.values[0][4 * 5 : 5 * 5]) > 0) self.assertAlmostEqual(0, sum(features.values[0][6 * 5 : 9 * 5]), delta=1e-6) # Only Al in structure. self.assertEqual(3 * 3 * 5, len(features.values[1])) self.assertAlmostEqual(0, sum(features.values[1][0: 4 * 5]), delta=1e-6) # First 4 PRDFs are H-X. self.assertTrue(max(features.values[1][4 * 5: 5 * 5]) > 0) self.assertTrue(max(features.values[1][5 * 5: 6 * 5]) > 0) self.assertAlmostEqual(0, sum(features.values[1][6 * 5: 7 * 5]), delta=1e-6) # Only Al in structure. self.assertTrue(max(features.values[1][7 * 5: 8 * 5]) > 0) self.assertTrue(max(features.values[1][8 * 5: 9 * 5]) > 0)
def test_vertex_replacement(self): # Create cell. structure = Cell() structure.add_atom(Atom([0, 0, 0], 0)) # Create cell for atom1. cell = VoronoiCell(structure.get_atom(0), radical=True) # Compute faces. images = [ AtomImage(structure.get_atom(0), sc) for sc in VectorCombinationComputer( structure.get_lattice_vectors(), 1.1).get_supercell_coordinates() ] cell.compute_cell_helper(images) # Make sure it turned out OK. self.assertAlmostEqual(1.0, cell.get_volume(), delta=1e-6) # Find position of atom that will take corner off. p = Plane(p1=(0.4, 0.5, 0.5), p2=(0.5, 0.4, 0.5), p3=(0.5, 0.5, 0.4), tolerance=1e-6) atm_pos = p.project([0, 0, 0]) atm_pos *= 2 structure.add_atom(Atom(atm_pos, 0)) # Cut off the corner. cell.compute_intersection( VoronoiFace(cell.get_atom(), AtomImage(structure.get_atom(1), [0, 0, 0]), radical=False)) vol = cell.get_volume() self.assertEqual(7, cell.n_faces()) # Compute a cell that will cut off just slightly more area. p = Plane(p1=(0.4, 0.5, 0.5), p2=(0.5, 0.35, 0.5), p3=(0.5, 0.5, 0.35), tolerance=1e-6) atm_pos = p.project([0, 0, 0]) atm_pos *= 2 structure.add_atom(Atom(atm_pos, 0)) new_face = VoronoiFace(cell.get_atom(), AtomImage(structure.get_atom(2), [0, 0, 0]), radical=False) self.assertTrue(cell.compute_intersection(new_face)) self.assertEqual(7, cell.n_faces()) self.assertTrue(cell.get_volume() < vol) self.assertTrue(cell.geometry_is_valid()) # Remove that face. cell.remove_face(new_face) self.assertEqual(6, cell.n_faces()) self.assertEqual(6, cell.get_polyhedron_shape()[4]) self.assertAlmostEqual(1.0, cell.get_volume(), delta=1e-6) self.assertTrue(cell.geometry_is_valid())
def test_random_packing(self): # Number of atoms in each direction. n_atom = 4 structure = Cell() structure.set_basis(lengths=[2 * n_atom, 2 * n_atom, 2 * n_atom], angles=[90, 90, 90]) # Add a bunch of atoms. for x in range(n_atom): for y in range(n_atom): for z in range(n_atom): structure.add_atom(Atom(np.random.random(3), 0)) # Compute the cells. cells = VoronoiTessellationCalculator.compute(structure, radical=True) total_vol = 0.0 for cell in cells: total_vol += cell.get_volume() self.assertTrue(cell.geometry_is_valid()) vol_error = (total_vol - structure.volume()) / structure.volume() self.assertAlmostEqual(0.0, vol_error, delta=1e-2)
def test_BCC(self): # Create the simulation cell. structure = Cell() atom = Atom([0, 0, 0], 0) structure.add_atom(atom) atom = Atom([0.5, 0.5, 0.5], 0) structure.add_atom(atom) # Run tessellation. result = VoronoiTessellationCalculator.compute(structure, radical=False) # Test results. self.assertEqual(structure.n_atoms(), len(result)) for cell in result: self.assertTrue(cell.geometry_is_valid()) self.assertEqual(14, len(cell.get_faces())) self.assertAlmostEqual(0.5, cell.get_volume(), delta=1e-6) poly_index = cell.get_polyhedron_shape() self.assertEqual(8, poly_index[6]) poly_index = result[0].get_coordination_shell_shape(result) self.assertEqual(6, poly_index[4]) self.assertEqual(8, poly_index[6])
def test_APRDF(self): # Create a B2 structure with lattice parameter of 1. structure = Cell() structure.add_atom(Atom([0, 0, 0], 0)) structure.add_atom(Atom([0.5, 0.5, 0.5], 1)) self.tool.set_n_windows(2) self.tool.set_cut_off_distance(1.0) self.tool.set_smoothing_factor(100) self.tool.analyze_structure(structure) # Trivial: Properties == 0. ap_rdf = self.tool.compute_APRDF([0, 0]) np_tst.assert_array_almost_equal([0.5, 1], self.tool.get_evaluation_distances()) np_tst.assert_array_almost_equal([0, 0], ap_rdf) # Actual case. ap_rdf = self.tool.compute_APRDF([1, 2]) # Assemble known contributors. # [0] -> Number of neighbors * P_i * P_j # [1] -> Bond distance contributors = [] contributors.append([2 * 8 * 2 * 1, math.sqrt(3) / 2]) # A-B 1st NN. contributors.append([6 * 1 * 1, 1]) # A-A 2nd NN. contributors.append([6 * 2 * 2, 1]) # B-B 2nd NN. contributors.append([8 * 1 * 1, math.sqrt(3)]) # A-A 3rd NN. contributors.append([8 * 2 * 2, math.sqrt(3)]) # B-B 3rd NN. eval_dist = [0.5, 1] expected_ap_rdf = [ sum([c[0] * math.exp(-100 * (c[1] - r)**2) for c in contributors]) / 2 for r in eval_dist ] np_tst.assert_array_almost_equal(expected_ap_rdf, ap_rdf, decimal=3)
def test_equals(self): # Make other cell other = Cell() # First check. self.assertTrue(self.cell.__eq__(other)) # Adjust basis. self.cell.set_basis(lengths=[1, 2, 3], angles=[70, 80, 90]) self.assertFalse(self.cell.__eq__(other)) other.set_basis(lengths=[1, 2, 3], angles=[70, 80, 90]) self.assertTrue(self.cell.__eq__(other)) # Add an atom to 0,0,0 self.cell.add_atom(Atom([0, 0, 0], 0)) self.assertFalse(self.cell.__eq__(other)) other.add_atom(Atom([0, 0, 0], 0)) self.assertTrue(self.cell.__eq__(other)) # Changing names. self.cell.set_type_name(0, "Al") self.assertFalse(self.cell.__eq__(other)) other.set_type_name(0, "Al") self.assertTrue(self.cell.__eq__(other)) # Adding more atoms of different type. self.cell.add_atom(Atom([0.5, 0.5, 0], 1)) other.add_atom(Atom([0.5, 0.5, 0], 0)) self.assertFalse(self.cell.__eq__(other)) other.get_atom(1).set_type(1) self.assertTrue(self.cell.__eq__(other)) # Adding atoms with different positions. self.cell.add_atom(Atom([0.5, 0, 0.5], 1)) other.add_atom(Atom([0, 0.5, 0.5], 1)) self.assertFalse(self.cell.__eq__(other)) # Adding atoms out of sequence. other.add_atom(Atom([0.5, 0, 0.5], 1)) self.cell.add_atom(Atom([0, 0.5, 0.5], 1)) self.assertTrue(self.cell.__eq__(other))
def test(self): # Make two simple structures. structure1 = Cell() structure1.add_atom(Atom([0, 0, 0], 0)) structure1.set_type_name(0, "Al") entries = [] entry1 = CrystalStructureEntry(structure1, name="Al", radii=None) entries.append(entry1) structure2 = Cell() structure2.add_atom(Atom([0, 0, 0], 0)) structure2.set_type_name(0, "Ni") structure2.add_atom(Atom([0, 0.5, 0], 1)) structure2.set_type_name(1, "Al") structure2.add_atom(Atom([0, 0, 0.5], 1)) entry2 = CrystalStructureEntry(structure2, name="NiAl2", radii=None) entries.append(entry2) # Create feature generator. gen = CoulombMatrixAttributeGenerator() gen.set_n_eigenvalues(10) # Generate features. features = gen.generate_features(entries) # Test results. self.assertEqual(10, features.shape[1]) self.assertNotAlmostEqual(0, features.values[0][0], delta=1e-6) for i in range(1, 10): self.assertAlmostEqual(0, features.values[0][i], delta=1e-6) self.assertNotAlmostEqual(0, features.values[1][0], delta=1e-6) self.assertNotAlmostEqual(0, features.values[1][1], delta=1e-6) self.assertNotAlmostEqual(0, features.values[1][2], delta=1e-6) for i in range(3, 10): self.assertAlmostEqual(0, features.values[1][i], delta=1e-6)
def test_B2(self): # Structure of bcc. structure = Cell() atom = Atom([0, 0, 0], 0) structure.add_atom(atom) atom = Atom([0.5, 0.5, 0.5], 1) structure.add_atom(atom) # Prepare. tool = VoronoiCellBasedAnalysis(radical=True) tool.analyze_structure(structure) # Check results. n_eff = 11.95692194 np_tst.assert_array_almost_equal( [n_eff, n_eff], tool.get_effective_coordination_numbers()) self.assertAlmostEqual(14.0, tool.face_count_average(), delta=1e-2) self.assertAlmostEqual(0.0, tool.face_count_variance(), delta=1e-2) self.assertAlmostEqual(14.0, tool.face_count_minimum(), delta=1e-2) self.assertAlmostEqual(14.0, tool.face_count_maximum(), delta=1e-2) self.assertAlmostEqual(1, len(tool.get_unique_polyhedron_shapes()), delta=1e-2) self.assertAlmostEqual(0.0, tool.volume_variance(), delta=1e-2) self.assertAlmostEqual(0.5, tool.volume_fraction_minimum(), delta=1e-2) self.assertAlmostEqual(0.5, tool.volume_fraction_maximum(), delta=1e-2) self.assertAlmostEqual(0.68, tool.max_packing_efficiency(), delta=1e-2) self.assertAlmostEqual(0, tool.mean_bcc_dissimilarity(), delta=1e-2) self.assertAlmostEqual(14.0 / 12.0, tool.mean_fcc_dissimilarity(), delta=1e-2) self.assertAlmostEqual(8.0 / 6.0, tool.mean_sc_dissimilarity(), delta=1e-2) bond_lengths = tool.bond_lengths() self.assertEqual(2, len(bond_lengths)) self.assertEqual(14, len(bond_lengths[0])) self.assertAlmostEqual(math.sqrt(3) / 2, bond_lengths[0][0], delta=1e-6) self.assertAlmostEqual(1.0, bond_lengths[0][12], delta=1e-6) mean_bond_lengths = tool.mean_bond_lengths() var_bond_lengths = tool.bond_length_variance(mean_bond_lengths) self.assertTrue(var_bond_lengths[0] > 0) # Check ordering parameters (against values computed by hand). np_tst.assert_array_almost_equal([0.142857, -0.142857], tool.get_neighbor_ordering_parameters( 1, False)[0], decimal=2) np_tst.assert_array_almost_equal([-0.04, 0.04], tool.get_neighbor_ordering_parameters( 2, False)[0], decimal=2) np_tst.assert_array_almost_equal([0.551982, -0.551982], tool.get_neighbor_ordering_parameters( 1, True)[0], decimal=2) np_tst.assert_array_almost_equal([-0.253856, 0.253856], tool.get_neighbor_ordering_parameters( 2, True)[0], decimal=2) self.assertAlmostEqual(0.142857, tool.warren_cowley_ordering_magnitude(1, False), delta=1e-2) self.assertAlmostEqual(0.04, tool.warren_cowley_ordering_magnitude(2, False), delta=1e-2) self.assertAlmostEqual(0.551982, tool.warren_cowley_ordering_magnitude(1, True), delta=1e-2) self.assertAlmostEqual(0.253856, tool.warren_cowley_ordering_magnitude(2, True), delta=1e-2)
def test_L12(self): # Structure of L12. structure = Cell() atom = Atom([0, 0, 0], 1) structure.add_atom(atom) atom = Atom([0.5, 0.5, 0], 0) structure.add_atom(atom) atom = Atom([0.5, 0, 0.5], 0) structure.add_atom(atom) atom = Atom([0, 0.5, 0.5], 0) structure.add_atom(atom) # Prepare. tool = VoronoiCellBasedAnalysis(radical=True) tool.analyze_structure(structure) # Check results. np_tst.assert_array_almost_equal( [12, 12, 12, 12], tool.get_effective_coordination_numbers()) self.assertAlmostEqual(12.0, tool.face_count_average(), delta=1e-2) self.assertAlmostEqual(0.0, tool.face_count_variance(), delta=1e-2) self.assertAlmostEqual(12.0, tool.face_count_minimum(), delta=1e-2) self.assertAlmostEqual(12.0, tool.face_count_maximum(), delta=1e-2) self.assertAlmostEqual(1, len(tool.get_unique_polyhedron_shapes()), delta=1e-2) self.assertAlmostEqual(0.0, tool.volume_variance(), delta=1e-2) self.assertAlmostEqual(0.25, tool.volume_fraction_minimum(), delta=1e-2) self.assertAlmostEqual(0.25, tool.volume_fraction_maximum(), delta=1e-2) self.assertAlmostEqual(0.74, tool.max_packing_efficiency(), delta=1e-2) self.assertAlmostEqual(1, tool.mean_bcc_dissimilarity(), delta=1e-2) self.assertAlmostEqual(0, tool.mean_fcc_dissimilarity(), delta=1e-2) self.assertAlmostEqual(1, tool.mean_sc_dissimilarity(), delta=1e-2) bond_lengths = tool.bond_lengths() self.assertEqual(4, len(bond_lengths)) self.assertEqual(12, len(bond_lengths[0])) self.assertAlmostEqual(math.sqrt(2) / 2, bond_lengths[0][0], delta=1e-6) mean_bond_lengths = tool.mean_bond_lengths() var_bond_lengths = tool.bond_length_variance(mean_bond_lengths) self.assertAlmostEqual(0, var_bond_lengths[0], delta=1e-6) # Neighbor analysis results. neigh_diff = tool.neighbor_property_differences([-1, 1], 1) np_tst.assert_array_almost_equal([2, 8.0 / 12.0, 2.0 / 3, 2.0 / 3], neigh_diff, decimal=5) neigh_diff = tool.neighbor_property_differences([-1, 1], 2) np_tst.assert_array_almost_equal( [192.0 / 132, 64.0 / 132.0, 64.0 / 132, 64.0 / 132], neigh_diff, decimal=5) neigh_var = tool.neighbor_property_variances([-1, 1], 1) # Type 0 has 8 type 0 NNs and 4 type 1, mean = -1/3. # Type 1 has 12 type 0 NNs, therefore variance = 0. # variance = 8/12 * (-1 + 1/3)^2 + 4/12 + (1 + 1/3)^2. a_var = 2.0 / 3.0 * (-1 + 1.0 / 3.0)**2 + 1.0 / 3.0 * (1 + 1.0 / 3.0)**2 np_tst.assert_array_almost_equal([0, a_var, a_var, a_var], neigh_var, decimal=5) neigh_var = tool.neighbor_property_variances([-1, 1], 2) # Type 0 has 68 type 0 2nd NN and 16 type 1. # Type 1 has 48 type 0 2nd NN and 36 type 1 type0_var = 0.734618916 type1_var = 0.79338843 np_tst.assert_array_almost_equal( [type1_var, type0_var, type0_var, type0_var], neigh_var, decimal=5)
def test_B1(self): # Structure of rocksalt. structure = Cell() basis = np.zeros((3, 3)) basis[0] = np.array([0, 0.5, 0.5]) basis[1] = np.array([0.5, 0, 0.5]) basis[2] = np.array([0.5, 0.5, 0]) structure.set_basis(basis=basis) atom = Atom([0, 0, 0], 0) structure.add_atom(atom) atom = Atom([0.5, 0.5, 0.5], 1) structure.add_atom(atom) # Prepare. tool = VoronoiCellBasedAnalysis(radical=True) tool.analyze_structure(structure) # Check results. n_eff = 6 np_tst.assert_array_almost_equal( [n_eff, n_eff], tool.get_effective_coordination_numbers()) self.assertAlmostEqual(6.0, tool.face_count_average(), delta=1e-2) self.assertAlmostEqual(0.0, tool.face_count_variance(), delta=1e-2) self.assertAlmostEqual(6.0, tool.face_count_minimum(), delta=1e-2) self.assertAlmostEqual(6.0, tool.face_count_maximum(), delta=1e-2) self.assertAlmostEqual(1, len(tool.get_unique_polyhedron_shapes()), delta=1e-2) self.assertAlmostEqual(0.0, tool.volume_variance(), delta=1e-2) self.assertAlmostEqual(0.5, tool.volume_fraction_minimum(), delta=1e-2) self.assertAlmostEqual(0.5, tool.volume_fraction_maximum(), delta=1e-2) np_tst.assert_array_almost_equal([1, -1], tool.get_neighbor_ordering_parameters( 1, False)[0], decimal=2) np_tst.assert_array_almost_equal([-1, 1], tool.get_neighbor_ordering_parameters( 2, False)[0], decimal=2) np_tst.assert_array_almost_equal([1, -1], tool.get_neighbor_ordering_parameters( 3, False)[0], decimal=2) np_tst.assert_array_almost_equal([-1, 1], tool.get_neighbor_ordering_parameters( 2, True)[0], decimal=2) np_tst.assert_array_almost_equal([1, -1], tool.get_neighbor_ordering_parameters( 3, True)[0], decimal=2) np_tst.assert_array_almost_equal([1, -1], tool.get_neighbor_ordering_parameters( 3, True)[0], decimal=2) self.assertAlmostEqual(1, tool.warren_cowley_ordering_magnitude(1, False), delta=1e-2) self.assertAlmostEqual(1, tool.warren_cowley_ordering_magnitude(2, False), delta=1e-2) self.assertAlmostEqual(1, tool.warren_cowley_ordering_magnitude(1, True), delta=1e-2) self.assertAlmostEqual(1, tool.warren_cowley_ordering_magnitude(2, True), delta=1e-2) bond_lengths = tool.bond_lengths() self.assertEqual(2, len(bond_lengths)) self.assertEqual(6, len(bond_lengths[0])) self.assertAlmostEqual(0.5, bond_lengths[0][0], delta=1e-6) mean_bond_lengths = tool.mean_bond_lengths() self.assertEqual(2, len(mean_bond_lengths)) self.assertAlmostEqual(0.5, mean_bond_lengths[0], delta=1e-6) var_bond_lengths = tool.bond_length_variance(mean_bond_lengths) self.assertAlmostEqual(0, var_bond_lengths[0], delta=1e-6) # Neighbor property attributes. np_tst.assert_array_almost_equal([1, 1], tool.neighbor_property_differences( [0, 1], 1)) np_tst.assert_array_almost_equal([0, 0], tool.neighbor_property_differences( [0, 1], 2)) np_tst.assert_array_almost_equal([0, 0], tool.neighbor_property_variances( [0, 1], 1)) np_tst.assert_array_almost_equal([0, 0], tool.neighbor_property_variances( [0, 1], 2))
def test_simple_cubic(self): # Create the simulation cell. structure = Cell() atom = Atom([0, 0, 0], 0) structure.add_atom(atom) # Run tessellation. result = VoronoiTessellationCalculator.compute(structure, radical=False) # Test results. self.assertEqual(structure.n_atoms(), len(result)) self.assertEqual(6, len(result[0].get_faces())) self.assertAlmostEqual(structure.volume(), result[0].get_volume(), delta=1e-6) poly_index = result[0].get_polyhedron_shape() self.assertEqual(6, poly_index[4]) poly_index = result[0].get_coordination_shell_shape(result) self.assertEqual(6, poly_index[0]) # Test out the nearest neighbor shells. # 1st NN shell. nns = result[0].get_neighbor_shell(result, 1) self.assertEqual(6, len(nns)) # 2nd NN shell. nns = result[0].get_neighbor_shell(result, 2) self.assertEqual(18, len(nns)) # 3rd - 5th NN shell. for s in range(3, 6): nns = result[0].get_neighbor_shell(result, s) for image in nns: cell = image.get_supercell() self.assertAlmostEqual(s, sum([abs(cell[i]) for i in range( 3)]), delta=1e-6) # Test path NNs. # 0th NN. paths = result[0].get_neighbors_by_walks(result, 0) self.assertEqual(1, len(paths)) total_weight = sum(list(paths.values())) self.assertAlmostEqual(1.0, total_weight, delta=1e-6) # 1st NN. paths = result[0].get_neighbors_by_walks(result, 1) self.assertEqual(6, len(paths)) total_weight = sum(list(paths.values())) np_tst.assert_array_almost_equal([1/6.0]*6, list(paths.values())) self.assertAlmostEqual(1.0, total_weight, delta=1e-6) # 2nd NN. paths = result[0].get_neighbors_by_walks(result, 2) self.assertEqual(18, len(paths)) total_weight = sum(list(paths.values())) for (k,v) in iteritems(paths): if 2 in k.get_supercell() or -2 in k.get_supercell(): self.assertAlmostEqual(1 / 30.0, v, delta=1e-6) else: self.assertAlmostEqual(2 / 30.0, v, delta=1e-6) self.assertAlmostEqual(1.0, total_weight, delta=1e-6)
class testCell(unittest.TestCase): cell = None # Create one instance per test. def setUp(self): self.cell = Cell() # Destroy instance as soon as test is over. def tearDown(self): self.cell = None def test_set_basis(self): # Test using angles and lattice parameters as input. self.cell.set_basis(lengths=[5.643, 6.621,4.885], angles=[91.83, 93.58, 107.69]) self.assertAlmostEqual(173.30, self.cell.volume(), delta=1e-2) np_tst.assert_array_almost_equal([5.643, 6.621,4.885], self.cell.get_lattice_parameters()) np_tst.assert_array_almost_equal([91.83, 93.58, 107.69], self.cell.get_lattice_angles_radians(radians=False)) # Simple test with a primitive cell. basis = np.zeros((3, 3)) basis[0] = np.array([0, 2.986, 2.986]) basis[1] = np.array([2.986, 0, 2.986]) basis[2] = np.array([2.986, 2.986, 0]) self.cell.set_basis(basis=basis) self.assertAlmostEqual(13.312*4, self.cell.volume(), delta=1e-3) np_tst.assert_array_almost_equal([4.223, 4.223, 4.223], self.cell.get_lattice_parameters(), decimal=3) np_tst.assert_array_almost_equal([60, 60, 60], self.cell.get_lattice_angles_radians(radians=False)) def test_aligned_basis(self): # Simple test with a primitive cell. basis = np.zeros((3, 3)) basis[0] = np.array([0, 2.986, 2.986]) basis[1] = np.array([2.986, 0, 2.986]) basis[2] = np.array([2.986, 2.986, 0]) self.cell.set_basis(basis=basis) # Compute the aligned basis. aligned_basis = self.cell.get_aligned_basis() self.assertAlmostEqual(0, aligned_basis[1][0], delta=1e-6) self.assertAlmostEqual(0, aligned_basis[2][0], delta=1e-6) self.assertAlmostEqual(0, aligned_basis[2][1], delta=1e-6) def test_clone(self): self.cell.add_atom(Atom([0, 0, 0], 0)) self.cell.set_type_name(0, "A") # Test adding atoms. clone = self.cell.__copy__() self.assertEqual(clone, self.cell) clone.add_atom(Atom([0, 0.5, 0], 0)) self.assertFalse(clone.__eq__(self.cell)) # Test changing atom. clone = self.cell.__copy__() clone.get_atom(0).set_type(1) self.assertFalse(clone.__eq__(self.cell)) # Test changing basis. clone = self.cell.__copy__() clone.set_basis(lengths=[2, 1, 1], angles=[90, 90, 90]) self.assertFalse(clone.__eq__(self.cell)) def test_lattice_vectors(self): self.cell.set_basis(lengths=[1, 2, 3], angles=[80, 90, 70]) l_vec = self.cell.get_lattice_vectors() np_tst.assert_array_almost_equal([[1.0, 0.0, 0.0], [0.684, 1.879, 0.0], [0.0, 0.554, 2.948]], l_vec, decimal=3) # FCC primitive cell. self.cell.set_basis(lengths=[0.70710678118655, 0.70710678118655, 0.70710678118655], angles=[60, 60, 60]) self.assertAlmostEqual(0.25, self.cell.volume(), delta=1e-6) l_vec = self.cell.get_lattice_vectors() self.assertAlmostEqual(0.70710678118655, norm(l_vec[0]), delta=1e-2) def test_fractional_to_cartesian(self): self.cell.set_basis(lengths=[1, 2, 3], angles=[80, 90, 70]) np_tst.assert_array_almost_equal([0.2368, 0.5421, 0.8844], self.cell.convert_fractional_to_cartesian([0.1, 0.2, 0.3]), decimal=3) def test_cartesian_to_fractional(self): self.cell.set_basis(lengths=[1, 2, 3], angles=[80, 90, 70]) np_tst.assert_array_almost_equal([0.1, 0.2, 0.3], self.cell.convert_cartesian_to_fractional([0.2368, 0.5421, 0.8844]), decimal=3) def test_supercell_translation(self): self.cell.set_basis(lengths=[0.70710678118655, 0.70710678118655, 0.70710678118655], angles=[60, 60, 60]) self.assertAlmostEqual(0.25, self.cell.volume(), delta=1e-6) l_vec = self.cell.get_lattice_vectors() # Check a few. pos = self.cell.get_periodic_image([0, 0, 0], 1, 0, 0) np_tst.assert_array_almost_equal([0.70710678000000, 0, 0], pos, decimal=3) pos = self.cell.get_periodic_image([0, 0, 0], 1, 1, 0) np_tst.assert_array_almost_equal([1.06066017000000, 0.61237243466821, 0], pos, decimal=3) pos = self.cell.get_periodic_image([0, 0, 0], 1, 1, 1) np_tst.assert_array_almost_equal([1.41421356000000, 0.81649657955762, 0.57735026918963], pos, decimal=3) def test_equals(self): # Make other cell other = Cell() # First check. self.assertTrue(self.cell.__eq__(other)) # Adjust basis. self.cell.set_basis(lengths=[1, 2, 3], angles=[70, 80, 90]) self.assertFalse(self.cell.__eq__(other)) other.set_basis(lengths=[1, 2, 3], angles=[70, 80, 90]) self.assertTrue(self.cell.__eq__(other)) # Add an atom to 0,0,0 self.cell.add_atom(Atom([0, 0, 0], 0)) self.assertFalse(self.cell.__eq__(other)) other.add_atom(Atom([0, 0, 0], 0)) self.assertTrue(self.cell.__eq__(other)) # Changing names. self.cell.set_type_name(0, "Al") self.assertFalse(self.cell.__eq__(other)) other.set_type_name(0, "Al") self.assertTrue(self.cell.__eq__(other)) # Adding more atoms of different type. self.cell.add_atom(Atom([0.5, 0.5, 0], 1)) other.add_atom(Atom([0.5, 0.5, 0], 0)) self.assertFalse(self.cell.__eq__(other)) other.get_atom(1).set_type(1) self.assertTrue(self.cell.__eq__(other)) # Adding atoms with different positions. self.cell.add_atom(Atom([0.5, 0, 0.5], 1)) other.add_atom(Atom([0, 0.5, 0.5], 1)) self.assertFalse(self.cell.__eq__(other)) # Adding atoms out of sequence. other.add_atom(Atom([0.5, 0, 0.5], 1)) self.cell.add_atom(Atom([0, 0.5, 0.5], 1)) self.assertTrue(self.cell.__eq__(other)) def test_minimum_distance(self): # Simple case: orthogonal axes. # Origin. self.cell.add_atom(Atom([0, 0, 0], 1)) # C face center. self.cell.add_atom(Atom([0.5, 0.5, 0], 1)) dist = self.cell.get_minimum_distance(point1=[0, 0, 0], point2=[0.5, 0.5, 0]) self.assertAlmostEqual(math.sqrt(0.5), dist, delta=1e-6) dist = self.cell.get_minimum_distance(point1=[0, 0, 0], point2=[2.5, 0.5, -10]) self.assertAlmostEqual(math.sqrt(0.5), dist, delta=1e-6) # Difficult case: Non-conventional unit cell. basis = self.cell.get_basis() basis[1][0] = 108 self.cell.set_basis(basis=basis) dist = self.cell.get_minimum_distance(point1=[0, 0, 0], point2=[0.5, 0.5, 0]) self.assertAlmostEqual(math.sqrt(0.5), dist, delta=1e-6) dist = self.cell.get_minimum_distance(point1=[0, 0, 0], point2=[5.5, 0.5, 0]) self.assertAlmostEqual(math.sqrt(0.5), dist, delta=1e-6) dist = self.cell.get_minimum_distance(point1=[0, 0, 0], point2=[5.5, -10.5, 0]) self.assertAlmostEqual(math.sqrt(0.5), dist, delta=1e-6) def test_get_closest_image_simple(self): # Simple case: orthogonal axes. # Origin. self.cell.add_atom(Atom([0, 0, 0], 1)) # C face center. self.cell.add_atom(Atom([0.75, 0.75, 0.75], 1)) image = self.cell.get_minimum_distance(center=0, neighbor=1) np_tst.assert_array_almost_equal([-0.25, -0.25, -0.25], image.get_position(), decimal=6) np_tst.assert_array_equal([-1, -1, -1], image.get_supercell()) def test_get_closest_image_difficult(self): # Difficult case: Non-conventional unit cell. # Origin. self.cell.add_atom(Atom([0, 0, 0], 1)) # Body face center. self.cell.add_atom(Atom([0.5, 0.5, 0.5], 1)) basis = self.cell.get_basis() basis[1][0] = 108 self.cell.set_basis(basis=basis) image = self.cell.get_minimum_distance(center=0, neighbor=1) np_tst.assert_array_almost_equal([-0.5, -0.5, 0.5], image.get_position(), decimal=6) np_tst.assert_array_equal([-1, 53, 0], image.get_supercell()) def test_replacement(self): # Make the original cell B2-CuZr self.cell.add_atom(Atom([0, 0, 0], 0)) self.cell.add_atom(Atom([0.5, 0.5, 0.5], 1)) self.cell.set_type_name(0, "Cu") self.cell.set_type_name(1, "Zr") # Replace Cu with Ni. to_change = {"Cu":"Ni"} self.cell.replace_type_names(to_change) self.assertEqual("Ni", self.cell.get_type_name(0)) self.assertEqual("Zr", self.cell.get_type_name(1)) # Replace Ni with Cu and Zr with Ti. to_change = {"Ni": "Cu", "Zr":"Ti"} self.cell.replace_type_names(to_change) self.assertEqual("Cu", self.cell.get_type_name(0)) self.assertEqual("Ti", self.cell.get_type_name(1)) # Exchange Cu and Ti. to_change = {"Ti": "Cu", "Cu": "Ti"} self.cell.replace_type_names(to_change) self.assertEqual("Ti", self.cell.get_type_name(0)) self.assertEqual("Cu", self.cell.get_type_name(1)) # Make everything Cu. to_change = {"Ti": "Cu"} self.cell.replace_type_names(to_change) self.assertEqual("Cu", self.cell.get_type_name(0)) self.assertEqual("Cu", self.cell.get_type_name(1)) # Make everything W. to_change = {"Cu":"W"} self.cell.replace_type_names(to_change) self.assertEqual("W", self.cell.get_type_name(0)) self.assertEqual("W", self.cell.get_type_name(1)) # Merge types. self.cell.merge_like_types() self.assertEqual(1, self.cell.n_types())
class testVoronoiEdge(unittest.TestCase): def setUp(self): # Make a simple crystal. self.cell = Cell() self.cell.add_atom(Atom([0, 0, 0], 0)) def tearDown(self): self.cell = None def test_initialize(self): # Initialize faces. image = AtomImage(self.cell.get_atom(0), [0, 0, 1]) face1 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [0, 1, 0]) face2 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # Create edge. edge = VoronoiEdge(face1, face2) # Check out properties. np_tst.assert_array_almost_equal([-1, 0, 0], edge.get_line().get_direction()) def test_is_next(self): # Initialize faces. image = AtomImage(self.cell.get_atom(0), [0, 0, 1]) face1 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [0, 1, 0]) face2 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [1, 0, 0]) face3 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # Create edges. edge1 = VoronoiEdge(face1, face2) edge2 = VoronoiEdge(face1, face3) # Check proper ordering. self.assertTrue(edge2.is_ccw(edge2=edge1)) self.assertFalse(edge1.is_ccw(edge2=edge2)) self.assertFalse(edge2.is_ccw(edge2=edge2)) def test_simple_intersection(self): # Initialize faces. image = AtomImage(self.cell.get_atom(0), [0, 0, 1]) face1 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [0, 1, 0]) face2 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [1, 0, 0]) face3 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [2, 0, 0]) face4 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [-1, 0, 0]) face5 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # Create edges. edge1 = VoronoiEdge(face1, face2) edge2 = VoronoiEdge(face1, face3) edge3 = VoronoiEdge(face1, face4) edge4 = VoronoiEdge(face1, face5) # Compute intersection. self.assertTrue(VoronoiEdge.compute_intersection(edge1, edge3)) self.assertTrue(VoronoiEdge.compute_intersection(edge1, edge2)) self.assertTrue(VoronoiEdge.compute_intersection(edge1, edge4)) # Test properties. np_tst.assert_array_almost_equal( [0.5, 0.5, 0.5], edge1.get_start_vertex().get_position()) np_tst.assert_array_almost_equal([0.5, 0.5, 0.5], edge2.get_end_vertex().get_position()) self.assertAlmostEqual(1.0, edge1.get_length(), delta=1e-6) # Compute intersection that shouldn't happen. self.assertFalse(VoronoiEdge.compute_intersection(edge1, edge3)) def test_join(self): # Initialize faces. image = AtomImage(self.cell.get_atom(0), [0, 0, 1]) face1 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [0, 1, 0]) face2 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [1, 0, 0]) face3 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [2, 0, 0]) face4 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # Create edges. edge1 = VoronoiEdge(face1, face2) edge2 = VoronoiEdge(face1, face3) edge3 = VoronoiEdge(face1, face4) # Join edge1 & edge2. VoronoiEdge.compute_intersection(edge1, edge2, just_join=True) np_tst.assert_array_almost_equal( [0.5, 0.5, 0.5], edge1.get_start_vertex().get_position()) self.assertEqual(edge2, edge1.get_previous_edge()) # Join edge1 & edge3. VoronoiEdge.compute_intersection(edge1, edge3, just_join=True) np_tst.assert_array_almost_equal( [1.0, 0.5, 0.5], edge1.get_start_vertex().get_position()) self.assertEqual(edge3, edge1.get_previous_edge()) def test_compare(self): # Initialize faces. image = AtomImage(self.cell.get_atom(0), [0, 0, 1]) face1 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [0, 1, 0]) face2 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [1, 0, 0]) face3 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # Create edges. edge1 = VoronoiEdge(face1, face2) edge2 = VoronoiEdge(face1, face3) # Tests. self.assertEqual(0, edge1.__cmp__(edge1)) self.assertTrue(edge1.__cmp__(edge2) != 0) self.assertTrue(edge1.__cmp__(edge2) == -1 * edge2.__cmp__(edge1)) self.assertFalse(edge1.__eq__(edge2)) self.assertTrue(edge1.__eq__(edge1)) def test_next_edge(self): # Initialize faces. image = AtomImage(self.cell.get_atom(0), [0, 0, 1]) face1 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [0, 1, 0]) face2 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [-1, 1, 0]) face3 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [-1, 0, 0]) face4 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # Create edges. edge1 = VoronoiEdge(face1, face2) edge2 = VoronoiEdge(face1, face3) edge3 = VoronoiEdge(face1, face4) # Verify that edge2 and edge3 intersect edge1 in the same place. p1 = edge1.get_line().intersection(edge2.get_line()) p2 = edge1.get_line().intersection(edge3.get_line()) np_tst.assert_array_almost_equal(p1, p2) # Verify that when tasked with distinguishing between the two, it # recognizes that edge3 is the correct choice choices = [edge2, edge3] self.assertTrue(edge1.is_ccw(edge2=edge2)) self.assertEqual(edge3, edge1.find_next_edge(choices)) # Add more conflicting choices. image = AtomImage(self.cell.get_atom(0), [-2, 0, 0]) face4 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # A farther edge. choices.append(VoronoiEdge(face1, face4)) image = AtomImage(self.cell.get_atom(0), [1, 0, 0]) face4 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # A CW edge. choices.append(VoronoiEdge(face1, face4)) self.assertEqual(edge3, edge1.find_next_edge(choices)) def test_pair(self): # Initialize faces. image = AtomImage(self.cell.get_atom(0), [0, 0, 1]) face1 = VoronoiFace(self.cell.get_atom(0), image, radical=True) image = AtomImage(self.cell.get_atom(0), [0, 1, 0]) face2 = VoronoiFace(self.cell.get_atom(0), image, radical=True) # Create edge. edge = VoronoiEdge(face1, face2) # Create pair. pair = edge.generate_pair() # Tests. self.assertEqual(edge.get_edge_face(), pair.get_intersecting_face()) self.assertEqual(edge.get_intersecting_face(), pair.get_edge_face()) dir1 = edge.get_line().get_direction() dir2 = -1 * pair.get_line().get_direction() np_tst.assert_array_almost_equal(dir1, dir2)