示例#1
0
    def test_equality(self):
        """ Test that AtomicStructure is equal to itself but not others """
        self.assertEqual(self.structure, self.structure)
        self.assertEqual(self.structure, deepcopy(self.structure))
        self.assertNotEqual(self.structure, self.substructure)

        # Special case: make structures from Crystals
        c1 = Crystal.from_database("vo2-m1")
        c2 = deepcopy(c1)
        s1 = AtomicStructure(atoms=c1)
        s2 = AtomicStructure(atoms=c2.atoms)
        self.assertEqual(s1, s2)
示例#2
0
def test_equality(structure):
    """ Test that AtomicStructure is equal to itself but not others """
    substructure = next(iter(structure.substructures))
    assert structure == structure
    assert structure == deepcopy(structure)
    assert structure != substructure

    # Special case: make structures from Crystals
    c1 = Crystal.from_database("vo2-m1")
    c2 = deepcopy(c1)
    s1 = AtomicStructure(atoms=c1)
    s2 = AtomicStructure(atoms=c2.atoms)
    assert s1 == s2
示例#3
0
def test_addition(structure):
    """ Test the addition of two different AtomicStructures works as expected. """
    new_struct = AtomicStructure(
        atoms=[Atom("U", [0, 1, 0])],
        substructures=[
            AtomicStructure(atoms=[Atom("Ag", [0.5, 0, 0]), Atom("Ag", [1, 0.3, 1])])
        ],
    )

    addition = structure + new_struct

    assert len(new_struct) + len(structure) == len(addition)
    assert len(new_struct.atoms) + len(structure.atoms) == len(addition.atoms)
    assert len(new_struct.substructures) + len(structure.substructures) == len(
        addition.substructures
    )
示例#4
0
 def test_chemical_composition_add_to_unity(self):
     """ Test that AtomicStructure.chemical_composition always adds up to 1 """
     # Faster to create a large atomic structure from a Crystal object
     # Testing for 10 crystal structures only
     for name in islice(Crystal.builtins, 10):
         with self.subTest("Chemical composition: " + name):
             structure = AtomicStructure(atoms=Crystal.from_database(name))
             self.assertAlmostEqual(sum(structure.chemical_composition.values()), 1)
示例#5
0
    def test_substructure_preservation(self):
        """ Test that initializing a crystal with substructures preserves the substructures """
        atoms = [Atom("Ag", [0, 0, 0]), Atom("Ag", [1, 1, 1])]
        substructures = [AtomicStructure(atoms=[Atom("U", [0, 0, 0])])]
        c = Crystal(unitcell=atoms + substructures, lattice_vectors=np.eye(3))

        self.assertEqual(len(c), 3)
        self.assertIn(substructures[0], c.substructures)
示例#6
0
def test_substructure_preservation():
    """Test that initializing a crystal with substructures preserves the substructures"""
    atoms = [Atom("Ag", [0, 0, 0]), Atom("Ag", [1, 1, 1])]
    substructures = [AtomicStructure(atoms=[Atom("U", [0, 0, 0])])]
    c = Crystal(unitcell=atoms + substructures, lattice_vectors=np.eye(3))

    assert len(c) == 3
    assert substructures[0] in c.substructures
示例#7
0
def test_chemical_formula_hill_notation(structure):
    """ Test that the Hill notation, where elements are alphabetically ordered except C and H, which are first. """
    structure = AtomicStructure(
        atoms=[
            Atom("Ag", [0, 1, 0]),
            Atom("C", [0, 0, 0]),
            Atom("H", [0, 1, 0]),
            Atom("U", [1, 1, 1]),
        ]
    )
    assert structure.chemical_formula == "C H Ag U"
示例#8
0
    def test_addition(self):
        """ Test the addition of two different AtomicStructures works as expected. """
        new_struct = AtomicStructure(
            atoms=[Atom("U", [0, 1, 0])],
            substructures=[
                AtomicStructure(
                    atoms=[Atom("Ag", [0.5, 0, 0]), Atom("Ag", [1, 0.3, 1])]
                )
            ],
        )

        addition = self.structure + new_struct

        self.assertEqual(len(new_struct) + len(self.structure), len(addition))
        self.assertEqual(
            len(new_struct.atoms) + len(self.structure.atoms), len(addition.atoms)
        )
        self.assertEqual(
            len(new_struct.substructures) + len(self.structure.substructures),
            len(addition.substructures),
        )
示例#9
0
def test_truthiness(structure):
    """ Test that empty AtomicStructures are falsey, and truthy otherwise. """
    empty_structure = AtomicStructure()
    assert not empty_structure

    assert structure
示例#10
0
def test_addition_trivial(structure):
    """ Test that the addition of two AtomicStructures, one being empty, works as expected """
    addition = structure + AtomicStructure()
    assert addition == structure
    assert addition is not structure
示例#11
0
def structure():
    substructure = AtomicStructure(atoms=[Atom("U", [0, 0, 0])])
    return AtomicStructure(
        atoms=[Atom("Ag", [0, 0, 0]), Atom("Ag", [1, 1, 1])],
        substructures=[substructure],
    )
示例#12
0
def test_chemical_composition_add_to_unity(name):
    """ Test that AtomicStructure.chemical_composition always adds up to 1 """
    # Faster to create a large atomic structure from a Crystal object
    # Testing for 10 crystal structures only
    structure = AtomicStructure(atoms=Crystal.from_database(name))
    assert round(abs(sum(structure.chemical_composition.values()) - 1), 7) == 0
示例#13
0
    def test_truthiness(self):
        """ Test that empty AtomicStructures are falsey, and truthy otherwise. """
        empty_structure = AtomicStructure()
        self.assertFalse(empty_structure)

        self.assertTrue(self.structure)
示例#14
0
 def test_addition_trivial(self):
     """ Test that the addition of two AtomicStructures, one being empty, works as expected """
     addition = self.structure + AtomicStructure()
     self.assertEqual(addition, self.structure)
     self.assertIsNot(addition, self.structure)
示例#15
0
 def setUp(self):
     self.substructure = AtomicStructure(atoms=[Atom("U", [0, 0, 0])])
     self.structure = AtomicStructure(
         atoms=[Atom("Ag", [0, 0, 0]), Atom("Ag", [1, 1, 1])],
         substructures=[self.substructure],
     )
示例#16
0
class TestAtomicStructure(unittest.TestCase):
    def setUp(self):
        self.substructure = AtomicStructure(atoms=[Atom("U", [0, 0, 0])])
        self.structure = AtomicStructure(
            atoms=[Atom("Ag", [0, 0, 0]), Atom("Ag", [1, 1, 1])],
            substructures=[self.substructure],
        )

    def test_iteration(self):
        """ Test iteration of AtomicStructure yields from orphan atoms and substructure atoms alike """
        elements = [atm.element for atm in self.structure]
        self.assertTrue(len(elements), 3)

    def test_addition_trivial(self):
        """ Test that the addition of two AtomicStructures, one being empty, works as expected """
        addition = self.structure + AtomicStructure()
        self.assertEqual(addition, self.structure)
        self.assertIsNot(addition, self.structure)

    def test_addition_uniqueness(self):
        """ Test that the addition of two AtomicStructures, works as expected regarding unique atoms """
        self.assertEqual(self.structure + self.structure, self.structure)

    def test_addition(self):
        """ Test the addition of two different AtomicStructures works as expected. """
        new_struct = AtomicStructure(
            atoms=[Atom("U", [0, 1, 0])],
            substructures=[
                AtomicStructure(
                    atoms=[Atom("Ag", [0.5, 0, 0]), Atom("Ag", [1, 0.3, 1])]
                )
            ],
        )

        addition = self.structure + new_struct

        self.assertEqual(len(new_struct) + len(self.structure), len(addition))
        self.assertEqual(
            len(new_struct.atoms) + len(self.structure.atoms), len(addition.atoms)
        )
        self.assertEqual(
            len(new_struct.substructures) + len(self.structure.substructures),
            len(addition.substructures),
        )

    def test_addition_subclasses(self):
        """ Test that the addition of two subclass of AtomicStructures is preserved under addition. """

        class NewAtomicStructure(AtomicStructure):
            pass

        addition = NewAtomicStructure() + NewAtomicStructure()
        self.assertIs(type(addition), NewAtomicStructure)

    def test_truthiness(self):
        """ Test that empty AtomicStructures are falsey, and truthy otherwise. """
        empty_structure = AtomicStructure()
        self.assertFalse(empty_structure)

        self.assertTrue(self.structure)

    def test_trivial_transformation(self):
        """ Test that the identity transformation of an AtomicStructure works as expected. """
        transformed = self.structure.transform(np.eye(3))

        # transformed structure should be different, but equal, to original structure
        self.assertIsNot(transformed, self.structure)
        self.assertEqual(transformed, self.structure)

    def test_transformations_inversions(self):
        """ Test that symmetry operations work as expected when inverted. """
        operator = np.random.random(size=(3, 3))
        inv_op = np.linalg.inv(operator)

        transformed1 = self.structure.transform(operator)
        transformed2 = transformed1.transform(inv_op)

        # transformed2 structure should be different, but equal, to original structure
        self.assertIsNot(transformed2, self.structure)
        self.assertEqual(transformed2, self.structure)

    def test_transform_subclass(self):
        """ Test that the object returned by the transform() method is the 
        same class as the method caller. """

        class NewAtomicStructure(AtomicStructure):
            pass

        structure = NewAtomicStructure(
            atoms=[Atom("Ag", [0, 0, 0]), Atom("Ag", [1, 1, 1])]
        )
        transformed = structure.transform(np.eye(3))

        self.assertIs(type(transformed), type(structure))

    def test_transformations_correctness(self):
        """ Test that AtomicStructure.transform() works as expected. """
        operator = 2 * np.eye(3)
        transformed = self.structure.transform(operator)

        expected_atoms = [atm.transform(operator) for atm in self.structure]

        for atm in expected_atoms:
            self.assertIn(atm, transformed)

    def test_itersorted(self):
        """ Test that AtomicStructure.itersorted() works as expected """
        sorted_from_structure = list(self.structure.itersorted())
        sorted_from_list = list(sorted(self.structure, key=lambda a: a.element))

        self.assertListEqual(sorted_from_structure, sorted_from_list)

    def test_chemical_composition_trivial(self):
        """ Test that AtomicStructure.chemical_composition works as expected """
        expected = {"U": 1 / 3, "Ag": 2 / 3}
        self.assertDictEqual(self.structure.chemical_composition, expected)

    def test_chemical_composition_add_to_unity(self):
        """ Test that AtomicStructure.chemical_composition always adds up to 1 """
        # Faster to create a large atomic structure from a Crystal object
        # Testing for 10 crystal structures only
        for name in islice(Crystal.builtins, 10):
            with self.subTest("Chemical composition: " + name):
                structure = AtomicStructure(atoms=Crystal.from_database(name))
                self.assertAlmostEqual(sum(structure.chemical_composition.values()), 1)

    def test_chemical_formula(self):
        """ Test that AtomicStructure.chemical_formula is working as expected. """
        self.assertEqual(self.structure.chemical_formula, "Ag2 U")

    def test_chemical_formula_hill_notation(self):
        """ Test that the Hill notation, where elements are alphabetically ordered except C and H, which are first. """
        structure = AtomicStructure(
            atoms=[
                Atom("Ag", [0, 1, 0]),
                Atom("C", [0, 0, 0]),
                Atom("H", [0, 1, 0]),
                Atom("U", [1, 1, 1]),
            ]
        )
        self.assertEqual(structure.chemical_formula, "C H Ag U")

    def test_length(self):
        """ Test the __len__ methods """
        self.assertTrue(len(self.structure), 3)

    def test_containership_substructures(self):
        """ Test that containership works on substructure and atoms separately """
        self.assertIn(self.substructure, self.structure)
        self.assertNotIn(self.structure, self.substructure)

    def test_containership_atoms(self):
        """ Test that atom containership testing is working, even in substructures """
        atm = next(iter(self.substructure))
        self.assertIn(atm, self.structure)

    def test_equality(self):
        """ Test that AtomicStructure is equal to itself but not others """
        self.assertEqual(self.structure, self.structure)
        self.assertEqual(self.structure, deepcopy(self.structure))
        self.assertNotEqual(self.structure, self.substructure)

    def test_array(self):
        """ Test AtomicStructure.__array__ """
        arr = np.array(self.structure)
        self.assertSequenceEqual(arr.shape, (len(self.structure), 4))

    def test_picklable(self):
        """ Test that Crystal instances can be pickled, and that the unpickled instance
        is identical to the source """
        pickled = pickle.dumps(self.structure)
        unpickled = pickle.loads(pickled)
        self.assertEqual(self.structure, unpickled)

    def test_abstract_base_classes(self):
        """ Test that AtomicStructure fits with collections.abc module """
        for abstract_base_class in (abc.Hashable, abc.Iterable, abc.Sized):
            self.assertIsInstance(self.structure, abstract_base_class)

    def test_satisfying(self):
        """ Test the AtomicStructure.satisfying method """
        uranium = self.structure.satisfying(lambda a: a.element == "U")
        silver = self.structure.satisfying(lambda a: a.element == "Ag")

        self.assertEqual(len(uranium), 1)
        self.assertEqual(len(silver), 2)