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_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)
Beispiel #3
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)
Beispiel #4
0
    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_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)
Beispiel #6
0
    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_FCC(self):
        # Create the simulation cell.
        structure = Cell()
        structure.add_atom(Atom([0, 0, 0], 0))
        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))

        # 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(12, len(cell.get_faces()))
            self.assertAlmostEqual(0.25, cell.get_volume(), delta=1e-6)
            poly_index = cell.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_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_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_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_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)
Beispiel #13
0
    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)
Beispiel #14
0
 def setUp(self):
     self.cell = Cell()
Beispiel #15
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(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)
Beispiel #17
0
    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)
Beispiel #18
0
 def setUp(self):
     # Make a simple crystal.
     self.cell = Cell()
     self.cell.add_atom(Atom([0, 0, 0], 0))
Beispiel #19
0
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)
Beispiel #20
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())
Beispiel #21
0
    def test_FCC(self):
        # Create cell.
        structure = Cell()
        structure.add_atom(Atom([0, 0, 0], 0))
        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))

        # Create cell for atom1.
        cell = VoronoiCell(structure.get_atom(0), radical=True)

        # Compute faces.
        images = [
            AtomImage(structure.get_atom(i), sc) for i in range(4)
            for sc in VectorCombinationComputer(
                structure.get_lattice_vectors(),
                4.0).get_supercell_coordinates()
        ]
        faces = cell.compute_faces(images)

        # Get direct neighbors.
        direct_faces = cell.compute_direct_neighbors(faces)
        self.assertTrue(direct_faces[0].get_face_distance() <=
                        direct_faces[-1].get_face_distance())

        # Simple tests.
        self.assertEqual(12, len(direct_faces))
        self.assertEqual(len(images) - 12 - 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(1), [0, 0, 0]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(1), [0, -1, 0]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(1), [-1, 0, 0]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(1), [-1, -1, 0]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(2), [-1, 0, 0]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(2), [-1, 0, -1]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(2), [0, 0, 0]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(2), [0, 0, -1]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(3), [0, 0, 0]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(3), [0, 0, -1]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(3), [0, -1, 0]),
                        radical=True))
        neighboring_faces.append(
            VoronoiFace(structure.get_atom(0),
                        AtomImage(structure.get_atom(3), [0, -1, -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_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_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)
    def test_representation(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_representation(structure)
        self.assertEqual(1, len(mat))

        # 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, len(mat))

        # 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_representation(structure)
        if np.sum(mat - mat2) / len(mat) > 1e-6:
            sys.stderr.write("WARNING: Not insensitive to basis changes\n")
    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_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_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)
Beispiel #28
0
    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_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)
Beispiel #30
0
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())