def test_distance_fractional(self): """ Test the fractional distance between atoms """ atm1 = Atom("He", [0, 0, 0]) atm2 = Atom("He", [1, 0, 0]) self.assertEqual(distance_fractional(atm1, atm2), 1) self.assertEqual(distance_fractional(atm1, atm2), distance_fractional(atm2, atm1))
def test_distance_cartesian(self): """ Test the cartesian distance between atom """ lattice = Lattice(4 * np.eye(3)) # Cubic lattice side length 4 angs atm1 = Atom("He", [0, 0, 0], lattice=lattice) atm2 = Atom("He", [1, 0, 0], lattice=lattice) self.assertEqual(distance_cartesian(atm1, atm2), 4.0)
def test_atomic_distance_cartesian(): """Test the cartesian distance between atom""" lattice = Lattice(4 * np.eye(3)) # Cubic lattice side length 4 angs atm1 = Atom("He", [0, 0, 0], lattice=lattice) atm2 = Atom("He", [1, 0, 0], lattice=lattice) assert distance_cartesian(atm1, atm2) == 4.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)
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
def test_transform_subclass(structure): """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)) assert type(transformed) is type(structure)
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"
def test_atomic_distance_different_lattice(): """Test that fractional and cartesian distances between atoms in different lattices raises an error.""" lattice1 = Lattice(np.eye(3)) lattice2 = Lattice(2 * np.eye(3)) atm1 = Atom("He", [0, 0, 0], lattice=lattice1) atm2 = Atom("He", [1, 0, 0], lattice=lattice2) with pytest.raises(RuntimeError): distance_fractional(atm1, atm2) with pytest.raises(RuntimeError): distance_cartesian(atm1, atm2)
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 )
def test_distance_different_lattice(self): """ Test that fractional and cartesian distances between atoms in different lattices raises an error. """ lattice1 = Lattice(np.eye(3)) lattice2 = Lattice(2 * np.eye(3)) atm1 = Atom("He", [0, 0, 0], lattice=lattice1) atm2 = Atom("He", [1, 0, 0], lattice=lattice2) with self.subTest("Fractional distance"): with self.assertRaises(RuntimeError): distance_fractional(atm1, atm2) with self.subTest("Cartesian distance"): with self.assertRaises(RuntimeError): distance_cartesian(atm1, atm2)
def test_trivial(self): """ Test that the symmetry_reduction function returns the unit cell when there is only one possibility. """ ucell = set([Atom("H", coords=[0, 0, 0])]) symops = [np.eye(4)] asym_cell = symmetry_reduction(ucell, symops) self.assertEqual(ucell, asym_cell)
def aspherical_affe(atom, s): """ Aspherical atomic form factors for electron scattering. Only atoms lighter than Xe (and including) are supported (Z <= 54). Parameters ---------- atom : crystals.Atom, int, or str Atomic number, atomic symbol, or Atom instance. Atomic symbols are expected to be properly capitalized, e.g. ``As`` or ``W``. Note that if `atom` is provided as an int or str, the ground state electronic structure is used. If an `crystals.Atom` object is provided, then its electronic structure will be used to construct the electron form factor. s : array_like Scattering vector norm Returns ------- eff : `~numpy.ndarray`, dtype float Atomic form factor for electron scattering. Raises ------ ValueError : scattering information is not available, for example if the atomic number is larger than 54 References ---------- .. [#] Jin-Cheng Zheng, Lijun Wu and Yimei Zhu. "Aspherical electron scattering factors and their parameterizations for elements from H to Xe" (2009). J. Appl. Cryst. vol 42, pp. 1043 - 1053. """ if isinstance(atom, (int, str)): atom = Atom(atom) element = atom.element return _affe_parametrization(s, aspherical_ff[element]["total"])
def test_input_types(self): """ Test that is_element() works as expected for all supported input types """ atm = Atom("V", [0, 0, 0]) self.assertTrue(is_element(atm.element)(atm)) self.assertTrue(is_element(atm.atomic_number)(atm)) self.assertTrue(is_element(atm)(atm))
def test_symmetry_reduction_simple_translation(): """Test that symmetry_reduction works on a unitcell where two atoms are linked by a translation""" symops = [np.eye(4), translation_matrix([0, 0, 1 / 3])] asym_cell = set([Atom("H", coords=[0, 0, 0])]) unitcell = set(symmetry_expansion(asym_cell, symmetry_operators=symops)) asym_cell2 = symmetry_reduction(unitcell, symops) assert asym_cell == asym_cell2
def __init__(self, unitCell, latticeVectors): self._unitCell = [Atom(atom[0], coords=atom[1]) for atom in unitCell] Crystal.__init__(self, self._unitCell, latticeVectors) self.atomsPerUnitCell = len(unitCell) self.atomicWeights = [atom.mass for atom in self._unitCell] self.atomLabels = [ f'{inx}_{atom.element}' for atom, inx in zip(self._unitCell, range(self.atomsPerUnitCell)) ]
def test_int(self): """ Test that affe(int, ...) also works """ atomic_number = randint(1, 103) nG = np.random.random(size=(16, 32)) from_int = affe(atomic_number, nG) from_atom = affe(Atom(atomic_number, [0, 0, 0]), nG) self.assertTrue(np.allclose(from_int, from_atom))
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 _generate_unitcell_atoms(crystal: Crystal): for atm in crystal: for factors in product(range(-2, 2), range(-2, 2), range(-2, 2)): coords = atm.coords_fractional + np.asarray(factors) if np.all(coords <= 1.1) and np.all(coords >= -0.1): yield Atom( element=atm.element, coords=coords, lattice=Lattice(crystal.lattice_vectors), displacement=atm.displacement, magmom=atm.magmom, occupancy=atm.occupancy, )
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], )
def test_out_shape(self): nG = np.random.random(size=(16, 32)) eff = affe(Atom("He", coords=[0, 0, 0]), nG) self.assertSequenceEqual(eff.shape, nG.shape)
def test_side_effects(self): nG = np.random.random(size=(16, 32)) nG.setflags(write=False) # if nG is written to, Exception is raised affe(Atom("He", coords=[0, 0, 0]), nG)
def test_init(self): """ Test that Atom can be instantiated with an element str or atomic number """ by_element = Atom("C", coords=(0, 0, 0)) by_number = Atom(6, coords=(0, 0, 0)) self.assertEqual(by_element, by_number)
def setUp(self): self.atom = Atom(randint(1, 103), coords=np.random.random((3, )))
def test_out_shape(): nG = np.random.random(size=(16, 32)) eff = affe(Atom("He", coords=[0, 0, 0]), nG) assert eff.shape == nG.shape
assert Element("H") == expected assert Element("Hydrogen") == expected assert Element("hydrogen") == expected # not case sensitive assert Element(1) == expected assert Element(expected) == expected def test_atom_init(): """Test that Atom can be instantiated with an element str or atomic number""" by_element = Atom("C", coords=(0, 0, 0)) by_number = Atom(6, coords=(0, 0, 0)) assert by_element == by_number @pytest.mark.parametrize("atom", map(lambda s: Atom(s, [0, 0, 0]), islice(chemical_symbols, 50))) def test_atom_equality(atom): """Test __eq__ for atoms""" other = deepcopy(atom) assert atom == atom assert atom == other other.coords_fractional = atom.coords_fractional + 1 assert atom != other @pytest.mark.parametrize("atom", map(lambda s: Atom(s, [0, 0, 0]), islice(chemical_symbols, 50))) def test_atom_trivial_transform(atom):
def test_atomic_distance_fractional(): """Test the fractional distance between atoms""" atm1 = Atom("He", [0, 0, 0]) atm2 = Atom("He", [1, 0, 0]) assert distance_fractional(atm1, atm2) == 1 assert distance_fractional(atm1, atm2) == distance_fractional(atm2, atm1)
def test_atom_init(): """Test that Atom can be instantiated with an element str or atomic number""" by_element = Atom("C", coords=(0, 0, 0)) by_number = Atom(6, coords=(0, 0, 0)) assert by_element == by_number
from crystals import Crystal,Atom,symmetry_expansion,write_xyz # import rotating_crystal as rcc; imp.reload(rcc) cif='225.cif' #201(SC), 212,225,229 lattice_vectors = np.diag([2,2,2]) cCIF = Crystal.from_cif('../dat/Carbone_SC/'+cif) # cCIF = Crystal.from_database('Fe') syms = cCIF.symmetry_operations() atoms = [Atom(z, c) for z,c in zip(['C','C','C'], [[0.5,0.5,0],[0,0.5,0.5],[0.5,0.,0.5]]) ] # atoms = [Atom('C', [0.5,0.5,1])] # atoms = [Atom('C', [1.,1.,1.])] syms4 = [ np.hstack([np.vstack([s[0],[0,0,0]]), np.vstack([s[1][:,None],1]) ]) for s in syms] unitcell = symmetry_expansion(atoms,syms4) C = Crystal(unitcell, lattice_vectors) print('international_number:', cCIF.symmetry()['international_number']) print('international_number:', C.symmetry()['international_number']) print(C) # write_xyz(C,'test.xyz')
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], )