def test_disordered_primitive_to_ordered_supercell(self): sm_atoms = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='num_atoms', comparator=OrderDisorderElementComparator()) sm_sites = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='num_sites', comparator=OrderDisorderElementComparator()) lp = Lattice.orthorhombic(10, 20, 30) pcoords = [[0, 0, 0], [0.5, 0.5, 0.5]] ls = Lattice.orthorhombic(20, 20, 30) scoords = [[0, 0, 0], [0.75, 0.5, 0.5]] prim = Structure(lp, [{'Na': 0.5}, {'Cl': 0.5}], pcoords) supercell = Structure(ls, ['Na', 'Cl'], scoords) supercell.make_supercell([[-1, 1, 0], [0, 1, 1], [1, 0, 0]]) self.assertFalse(sm_sites.fit(prim, supercell)) self.assertTrue(sm_atoms.fit(prim, supercell)) self.assertRaises(ValueError, sm_atoms.get_s2_like_s1, prim, supercell) self.assertEqual(len(sm_atoms.get_s2_like_s1(supercell, prim)), 4)
def test_ordered_primitive_to_disordered_supercell(self): sm_atoms = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='num_atoms', comparator=OrderDisorderElementComparator()) sm_sites = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='num_sites', comparator=OrderDisorderElementComparator()) lp = Lattice.orthorhombic(10, 20, 30) pcoords = [[0, 0, 0], [0.5, 0.5, 0.5]] ls = Lattice.orthorhombic(20, 20, 30) scoords = [[0, 0, 0], [0.5, 0, 0], [0.25, 0.5, 0.5], [0.75, 0.5, 0.5]] s1 = Structure(lp, ['Na', 'Cl'], pcoords) s2 = Structure(ls, [{'Na': 0.5}, {'Na': 0.5}, {'Cl': 0.5}, {'Cl': 0.5}], scoords) self.assertTrue(sm_sites.fit(s1, s2)) self.assertFalse(sm_atoms.fit(s1, s2))
def test_disordered_primitive_to_ordered_supercell(self): sm_atoms = StructureMatcher( ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='num_atoms', comparator=OrderDisorderElementComparator()) sm_sites = StructureMatcher( ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='num_sites', comparator=OrderDisorderElementComparator()) lp = Lattice.orthorhombic(10, 20, 30) pcoords = [[0, 0, 0], [0.5, 0.5, 0.5]] ls = Lattice.orthorhombic(20, 20, 30) scoords = [[0, 0, 0], [0.75, 0.5, 0.5]] prim = Structure(lp, [{'Na': 0.5}, {'Cl': 0.5}], pcoords) supercell = Structure(ls, ['Na', 'Cl'], scoords) supercell.make_supercell([[-1, 1, 0], [0, 1, 1], [1, 0, 0]]) self.assertFalse(sm_sites.fit(prim, supercell)) self.assertTrue(sm_atoms.fit(prim, supercell)) self.assertRaises(ValueError, sm_atoms.get_s2_like_s1, prim, supercell) self.assertEqual(len(sm_atoms.get_s2_like_s1(supercell, prim)), 4)
def test_get_mapping(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=False, allow_subset=True) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Ag', 'Si', 'Si'], [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]]) s1.make_supercell([2, 1, 1]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]]) shuffle = [2, 0, 1, 3, 5, 4] s1 = Structure.from_sites([s1[i] for i in shuffle]) # test the mapping s2.make_supercell([2, 1, 1]) # equal sizes for i, x in enumerate(sm.get_mapping(s1, s2)): self.assertEqual(s1[x].species, s2[i].species) del s1[0] # s1 is subset of s2 for i, x in enumerate(sm.get_mapping(s2, s1)): self.assertEqual(s1[i].species, s2[x].species) # s2 is smaller than s1 del s2[0] del s2[1] self.assertRaises(ValueError, sm.get_mapping, s2, s1)
def test_lattice_2_lmpbox(self): matrix = np.diag(np.random.randint(5, 14, size=(3,))) \ + np.random.rand(3, 3) * 0.2 - 0.1 init_latt = Lattice(matrix) frac_coords = np.random.rand(10, 3) init_structure = Structure(init_latt, ["H"] * 10, frac_coords) origin = np.random.rand(3) * 10 - 5 box, symmop = lattice_2_lmpbox(lattice=init_latt, origin=origin) boxed_latt = box.to_lattice() np.testing.assert_array_almost_equal(init_latt.abc, boxed_latt.abc) np.testing.assert_array_almost_equal(init_latt.angles, boxed_latt.angles) cart_coords = symmop.operate_multi(init_structure.cart_coords) - origin boxed_structure = Structure(boxed_latt, ["H"] * 10, cart_coords, coords_are_cartesian=True) np.testing.assert_array_almost_equal(boxed_structure.frac_coords, frac_coords) tetra_latt = Lattice.tetragonal(5, 5) tetra_box, _ = lattice_2_lmpbox(tetra_latt) self.assertIsNone(tetra_box.tilt) ortho_latt = Lattice.orthorhombic(5, 5, 5) ortho_box, _ = lattice_2_lmpbox(ortho_latt) self.assertIsNone(ortho_box.tilt) rot_tetra_latt = Lattice([[5, 0, 0], [0, 2, 2], [0, -2, 2]]) _, rotop = lattice_2_lmpbox(rot_tetra_latt) np.testing. \ assert_array_almost_equal(rotop.rotation_matrix, [[1, 0, 0], [0, 2 ** 0.5 / 2, 2 ** 0.5 / 2], [0, -2 ** 0.5 / 2, 2 ** 0.5 / 2]])
def test_get_supercell_matrix(self): sm = StructureMatcher(ltol=0.1, stol=0.3, angle_tol=2, primitive_cell=False, scale=True, attempt_supercell=True) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s1.make_supercell([2, 1, 1]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0.1, 0], [0, 0.1, -0.95], [-.7, .5, .375]]) result = sm.get_supercell_matrix(s1, s2) self.assertTrue((result == [[-2, 0, 0], [0, 1, 0], [0, 0, 1]]).all()) s1 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s1.make_supercell([[1, -1, 0], [0, 0, -1], [0, 1, 0]]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0.1, 0], [0, 0.1, -0.95], [-.7, .5, .375]]) result = sm.get_supercell_matrix(s1, s2) self.assertTrue((result == [[-1, -1, 0], [0, 0, -1], [0, 1, 0]]).all()) # test when the supercell is a subset sm = StructureMatcher(ltol=0.1, stol=0.3, angle_tol=2, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True) del s1[0] result = sm.get_supercell_matrix(s1, s2) self.assertTrue((result == [[-1, -1, 0], [0, 0, -1], [0, 1, 0]]).all())
def test_sulfide_type(self): # NaS2 -> polysulfide latt = Lattice.tetragonal(9.59650, 11.78850) species = ["Na"] * 2 + ["S"] * 2 coords = [[0.00000, 0.00000, 0.17000], [0.27600, 0.25000, 0.12500], [0.03400, 0.25000, 0.29600], [0.14700, 0.11600, 0.40000]] struct = Structure.from_spacegroup(122, latt, species, coords) self.assertEqual(sulfide_type(struct), "polysulfide") # NaCl type NaS -> sulfide latt = Lattice.cubic(5.75) species = ["Na", "S"] coords = [[0.00000, 0.00000, 0.00000], [0.50000, 0.50000, 0.50000]] struct = Structure.from_spacegroup(225, latt, species, coords) self.assertEqual(sulfide_type(struct), "sulfide") # Na2S2O3 -> None (sulfate) latt = Lattice.monoclinic(6.40100, 8.10000, 8.47400, 96.8800) species = ["Na"] * 2 + ["S"] * 2 + ["O"] * 3 coords = [[0.29706, 0.62396, 0.08575], [0.37673, 0.30411, 0.45416], [0.52324, 0.10651, 0.21126], [0.29660, -0.04671, 0.26607], [0.17577, 0.03720, 0.38049], [0.38604, -0.20144, 0.33624], [0.16248, -0.08546, 0.11608]] struct = Structure.from_spacegroup(14, latt, species, coords) self.assertEqual(sulfide_type(struct), None) # Na3PS3O -> sulfide latt = Lattice.orthorhombic(9.51050, 11.54630, 5.93230) species = ["Na"] * 2 + ["S"] * 2 + ["P", "O"] coords = [[0.19920, 0.11580, 0.24950], [0.00000, 0.36840, 0.29380], [0.32210, 0.36730, 0.22530], [0.50000, 0.11910, 0.27210], [0.50000, 0.29400, 0.35500], [0.50000, 0.30300, 0.61140]] struct = Structure.from_spacegroup(36, latt, species, coords) self.assertEqual(sulfide_type(struct), "sulfide")
def test_find_match1(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True, attempt_supercell=False) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0.1, 0], [0, 0.1, -0.95], [.7, .5, .375]]) s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False) match = sm._strict_match(s1, s2, fu, s1_supercell=True, use_rms=True, break_on_match=False) scale_matrix = match[2] s2.make_supercell(scale_matrix) fc = s2.frac_coords + match[3] fc -= np.round(fc) self.assertAlmostEqual(np.sum(fc), 0.9) self.assertAlmostEqual(np.sum(fc[:, :2]), 0.1) cart_dist = np.sum(match[1] * (l.volume / 3)**(1 / 3)) self.assertAlmostEqual(cart_dist, 0.15)
def test_find_match2(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True, attempt_supercell=False) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Si', 'Si'], [[0, 0, 0.1], [0, 0, 0.2]]) s2 = Structure(l, ['Si', 'Si'], [[0, 0.1, 0], [0, 0.1, -0.95]]) s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False) match = sm._strict_match(s1, s2, fu, s1_supercell=False, use_rms=True, break_on_match=False) scale_matrix = match[2] s2.make_supercell(scale_matrix) s2.translate_sites(range(len(s2)), match[3]) self.assertAlmostEqual(np.sum(s2.frac_coords), 0.3) self.assertAlmostEqual(np.sum(s2.frac_coords[:, :2]), 0)
def test_get_mapping(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=False, allow_subset=True) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Ag', 'Si', 'Si'], [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]]) s1.make_supercell([2, 1, 1]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]]) shuffle = [2, 0, 1, 3, 5, 4] s1 = Structure.from_sites([s1[i] for i in shuffle]) #test the mapping s2.make_supercell([2, 1, 1]) #equal sizes for i, x in enumerate(sm.get_mapping(s1, s2)): self.assertEqual(s1[x].species_and_occu, s2[i].species_and_occu) del s1[0] #s1 is subset of s2 for i, x in enumerate(sm.get_mapping(s2, s1)): self.assertEqual(s1[i].species_and_occu, s2[x].species_and_occu) #s2 is smaller than s1 del s2[0] del s2[1] self.assertRaises(ValueError, sm.get_mapping, s2, s1)
def test_lattice_2_lmpbox(self): matrix = np.diag(np.random.randint(5, 14, size=(3,))) \ + np.random.rand(3, 3) * 0.2 - 0.1 init_latt = Lattice(matrix) frac_coords = np.random.rand(10, 3) init_structure = Structure(init_latt, ["H"] * 10, frac_coords) origin = np.random.rand(3) * 10 - 5 box, symmop = lattice_2_lmpbox(lattice=init_latt, origin=origin) boxed_latt = box.to_lattice() np.testing.assert_array_almost_equal(init_latt.abc, boxed_latt.abc) np.testing.assert_array_almost_equal(init_latt.angles, boxed_latt.angles) cart_coords = symmop.operate_multi(init_structure.cart_coords) \ - origin boxed_structure = Structure(boxed_latt, ["H"] * 10, cart_coords, coords_are_cartesian=True) np.testing.assert_array_almost_equal(boxed_structure.frac_coords, frac_coords) tetra_latt = Lattice.tetragonal(5, 5) tetra_box, _ = lattice_2_lmpbox(tetra_latt) self.assertIsNone(tetra_box.tilt) ortho_latt = Lattice.orthorhombic(5, 5, 5) ortho_box, _ = lattice_2_lmpbox(ortho_latt) self.assertIsNone(ortho_box.tilt) rot_tetra_latt = Lattice([[5, 0, 0], [0, 2, 2], [0, -2, 2]]) _, rotop = lattice_2_lmpbox(rot_tetra_latt) np.testing.\ assert_array_almost_equal(rotop.rotation_matrix, [[1, 0, 0], [0, 2 ** 0.5 / 2, 2 ** 0.5 / 2], [0, -2 ** 0.5 / 2, 2 ** 0.5 / 2]])
def test_create_supercell(a_centered_orthorhombic): cs = SupercellMaker(a_centered_orthorhombic) actual_lattice = cs.conv_structure.lattice expected = Lattice.orthorhombic(1, 4, 6) assert actual_lattice == expected actual = cs.supercell.matrix expected = [[6, 0, 0], [0, 2, 0], [0, 0, 1]] np.testing.assert_array_equal(actual, expected)
def test_get_s2_large_s2(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=False, attempt_supercell=True, allow_subset=False, supercell_size='volume') l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Ag', 'Si', 'Si'], [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]]) l2 = Lattice.orthorhombic(1.01, 2.01, 3.01) s2 = Structure(l2, ['Si', 'Si', 'Ag'], [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]]) s2.make_supercell([[0, -1, 0], [1, 0, 0], [0, 0, 1]]) result = sm.get_s2_like_s1(s1, s2) for x, y in zip(s1, result): self.assertLess(x.distance(y), 0.08)
def ortho_conventional(): lattice = Lattice.orthorhombic(5, 6, 7) coords = [ [0.0, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.5], ] return IStructure(lattice=lattice, species=["H"] * 4 + ["He"] * 4, coords=coords)
def test_rms_vs_minimax(self): # This tests that structures with adjusted RMS less than stol, but minimax # greater than stol are treated properly # stol=0.3 gives exactly an ftol of 0.1 on the c axis sm = StructureMatcher(ltol=0.2, stol=0.301, angle_tol=1, primitive_cell=False) l = Lattice.orthorhombic(1, 2, 12) sp = ["Si", "Si", "Al"] s1 = Structure(l, sp, [[0.5, 0, 0], [0, 0, 0], [0, 0, 0.5]]) s2 = Structure(l, sp, [[0.5, 0, 0], [0, 0, 0], [0, 0, 0.6]]) self.assertArrayAlmostEqual(sm.get_rms_dist(s1, s2), (0.32 ** 0.5 / 2, 0.4)) self.assertEqual(sm.fit(s1, s2), False) self.assertEqual(sm.fit_anonymous(s1, s2), False) self.assertEqual(sm.get_mapping(s1, s2), None)
def test_sulfide_type(self): # NaS2 -> polysulfide latt = Lattice.tetragonal(9.59650, 11.78850) species = ["Na"] * 2 + ["S"] * 2 coords = [[0.00000, 0.00000, 0.17000], [0.27600, 0.25000, 0.12500], [0.03400, 0.25000, 0.29600], [0.14700, 0.11600, 0.40000]] struct = Structure.from_spacegroup(122, latt, species, coords) self.assertEqual(sulfide_type(struct), "polysulfide") # NaCl type NaS -> sulfide latt = Lattice.cubic(5.75) species = ["Na", "S"] coords = [[0.00000, 0.00000, 0.00000], [0.50000, 0.50000, 0.50000]] struct = Structure.from_spacegroup(225, latt, species, coords) self.assertEqual(sulfide_type(struct), "sulfide") # Na2S2O3 -> None (sulfate) latt = Lattice.monoclinic(6.40100, 8.10000, 8.47400, 96.8800) species = ["Na"] * 2 + ["S"] * 2 + ["O"] * 3 coords = [[0.29706, 0.62396, 0.08575], [0.37673, 0.30411, 0.45416], [0.52324, 0.10651, 0.21126], [0.29660, -0.04671, 0.26607], [0.17577, 0.03720, 0.38049], [0.38604, -0.20144, 0.33624], [0.16248, -0.08546, 0.11608]] struct = Structure.from_spacegroup(14, latt, species, coords) self.assertEqual(sulfide_type(struct), None) # Na3PS3O -> sulfide latt = Lattice.orthorhombic(9.51050, 11.54630, 5.93230) species = ["Na"] * 2 + ["S"] * 2 + ["P", "O"] coords = [[0.19920, 0.11580, 0.24950], [0.00000, 0.36840, 0.29380], [0.32210, 0.36730, 0.22530], [0.50000, 0.11910, 0.27210], [0.50000, 0.29400, 0.35500], [0.50000, 0.30300, 0.61140]] struct = Structure.from_spacegroup(36, latt, species, coords) self.assertEqual(sulfide_type(struct), "sulfide") # test for unphysical cells struct.scale_lattice(struct.volume*10) self.assertEqual(sulfide_type(struct), "sulfide")
def test_find_match2(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True, attempt_supercell=False) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Si', 'Si'], [[0, 0, 0.1], [0, 0, 0.2]]) s2 = Structure(l, ['Si', 'Si'], [[0, 0.1, 0], [0, 0.1, -0.95]]) s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False) match = sm._strict_match(s1, s2, fu, s1_supercell=False, use_rms=True, break_on_match=False) scale_matrix = match[2] s2.make_supercell(scale_matrix) s2.translate_sites(range(len(s2)), match[3]) self.assertAlmostEqual(np.sum(s2.frac_coords) % 1, 0.3) self.assertAlmostEqual(np.sum(s2.frac_coords[:, :2]) % 1, 0)
def test_oi_ti_bravais(): structure = Structure(Lattice.orthorhombic(20, 8, 6), species=["H"] * 2, coords=[[0.0] * 3, [0.5] * 3]) generator = StructureKpointsGenerator(structure, task=Task.structure_opt, kpt_density=5) generator.generate_input() primitive_structure = StructureSymmetrizer(structure).primitive expected_generator = StructureKpointsGenerator(primitive_structure, task=Task.structure_opt, kpt_density=5) expected_generator.generate_input() assert generator.num_kpts == expected_generator.num_kpts assert generator.kpoints.kpts_shift == expected_generator.kpoints.kpts_shift
def test_occupancy_comparator(self): lp = Lattice.orthorhombic(10, 20, 30) pcoords = [[0, 0, 0], [0.5, 0.5, 0.5]] s1 = Structure(lp, [{'Na': 0.6, 'K': 0.4}, 'Cl'], pcoords) s2 = Structure(lp, [{'Xa': 0.4, 'Xb': 0.6}, 'Cl'], pcoords) s3 = Structure(lp, [{'Xa': 0.5, 'Xb': 0.5}, 'Cl'], pcoords) sm_sites = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='num_sites', comparator=OccupancyComparator()) self.assertTrue(sm_sites.fit(s1, s2)) self.assertFalse(sm_sites.fit(s1, s3))
def test_species_order(): lattice = Lattice.orthorhombic(5, 6, 7) coords = [ [0.0, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.5], ] structure = Structure(lattice=lattice, species=["H"] * 4 + ["He"] * 4, coords=coords) supercell = structure * [1, 1, 2] actual = [e.specie for e in StructureSymmetrizer(supercell).conventional] expected = [Element.H] * 4 + [Element.He] * 4 assert actual == expected
def test_subset(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=False, allow_subset=True) l = Lattice.orthorhombic(10, 20, 30) s1 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s2 = Structure(l, ['Si', 'Ag'], [[0, 0.1, 0], [-.7, .5, .4]]) result = sm.get_s2_like_s1(s1, s2) self.assertEqual( len(find_in_coord_list_pbc(result.frac_coords, [0, 0, 0.1])), 1) self.assertEqual( len(find_in_coord_list_pbc(result.frac_coords, [0.7, 0.4, 0.5])), 1) #test with fewer species in s2 s1 = Structure(l, ['Si', 'Ag', 'Si'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s2 = Structure(l, ['Si', 'Si'], [[0, 0.1, 0], [-.7, .5, .4]]) result = sm.get_s2_like_s1(s1, s2) mindists = np.min(s1.lattice.get_all_distances(s1.frac_coords, result.frac_coords), axis=0) self.assertLess(np.max(mindists), 1e-6) self.assertEqual( len(find_in_coord_list_pbc(result.frac_coords, [0, 0, 0.1])), 1) self.assertEqual( len(find_in_coord_list_pbc(result.frac_coords, [0.7, 0.4, 0.5])), 1) #test with not enough sites in s1 #test with fewer species in s2 s1 = Structure(l, ['Si', 'Ag', 'Cl'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s2 = Structure(l, ['Si', 'Si'], [[0, 0.1, 0], [-.7, .5, .4]]) self.assertEqual(sm.get_s2_like_s1(s1, s2), None)
def test_find_match1(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True, attempt_supercell=False) l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Si', 'Si', 'Ag'], [[0,0,0.1],[0,0,0.2],[.7,.4,.5]]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0,0.1,0],[0,0.1,-0.95],[.7,.5,.375]]) s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False) match = sm._strict_match(s1, s2, fu, s1_supercell = True, use_rms = True, break_on_match = False) scale_matrix = match[2] s2.make_supercell(scale_matrix) fc = s2.frac_coords + match[3] fc -= np.round(fc) self.assertAlmostEqual(np.sum(fc), 0.9) self.assertAlmostEqual(np.sum(fc[:,:2]), 0.1) cart_dist = np.sum(match[1] * (l.volume/3) ** (1/3)) self.assertAlmostEqual(cart_dist, 0.15)
def test_cart_dists(self): sm = StructureMatcher() l = Lattice.orthorhombic(1, 2, 3) s1 = np.array([[0.13, 0.25, 0.37], [0.1, 0.2, 0.3]]) s2 = np.array([[0.11, 0.22, 0.33]]) s3 = np.array([[0.1, 0.2, 0.3], [0.11, 0.2, 0.3]]) s4 = np.array([[0.1, 0.2, 0.3], [0.1, 0.6, 0.7]]) mask = np.array([[False, False]]) mask2 = np.array([[False, True]]) mask3 = np.array([[False, False], [False, False]]) mask4 = np.array([[False, True], [False, True]]) n1 = (len(s1) / l.volume)**(1 / 3) n2 = (len(s2) / l.volume)**(1 / 3) self.assertRaises(ValueError, sm._cart_dists, s2, s1, l, mask.T, n2) self.assertRaises(ValueError, sm._cart_dists, s1, s2, l, mask.T, n1) d, ft, s = sm._cart_dists(s1, s2, l, mask, n1) self.assertTrue(np.allclose(d, [0])) self.assertTrue(np.allclose(ft, [-0.01, -0.02, -0.03])) self.assertTrue(np.allclose(s, [1])) #check that masking best value works d, ft, s = sm._cart_dists(s1, s2, l, mask2, n1) self.assertTrue(np.allclose(d, [0])) self.assertTrue(np.allclose(ft, [0.02, 0.03, 0.04])) self.assertTrue(np.allclose(s, [0])) #check that averaging of translation is done properly d, ft, s = sm._cart_dists(s1, s3, l, mask3, n1) self.assertTrue(np.allclose(d, [0.08093341] * 2)) self.assertTrue(np.allclose(ft, [0.01, 0.025, 0.035])) self.assertTrue(np.allclose(s, [1, 0])) #check distances are large when mask allows no 'real' mapping d, ft, s = sm._cart_dists(s1, s4, l, mask4, n1) self.assertTrue(np.min(d) > 1e8) self.assertTrue(np.min(ft) > 1e8)
def test_cart_dists(self): sm = StructureMatcher() l = Lattice.orthorhombic(1, 2, 3) s1 = np.array([[0.13, 0.25, 0.37], [0.1, 0.2, 0.3]]) s2 = np.array([[0.11, 0.22, 0.33]]) s3 = np.array([[0.1, 0.2, 0.3], [0.11, 0.2, 0.3]]) s4 = np.array([[0.1, 0.2, 0.3], [0.1, 0.6, 0.7]]) mask = np.array([[False, False]]) mask2 = np.array([[False, True]]) mask3 = np.array([[False, False], [False, False]]) mask4 = np.array([[False, True], [False, True]]) n1 = (len(s1) / l.volume) ** (1 / 3) n2 = (len(s2) / l.volume) ** (1 / 3) self.assertRaises(ValueError, sm._cart_dists, s2, s1, l, mask.T, n2) self.assertRaises(ValueError, sm._cart_dists, s1, s2, l, mask.T, n1) d, ft, s = sm._cart_dists(s1, s2, l, mask, n1) self.assertTrue(np.allclose(d, [0])) self.assertTrue(np.allclose(ft, [-0.01, -0.02, -0.03])) self.assertTrue(np.allclose(s, [1])) # check that masking best value works d, ft, s = sm._cart_dists(s1, s2, l, mask2, n1) self.assertTrue(np.allclose(d, [0])) self.assertTrue(np.allclose(ft, [0.02, 0.03, 0.04])) self.assertTrue(np.allclose(s, [0])) # check that averaging of translation is done properly d, ft, s = sm._cart_dists(s1, s3, l, mask3, n1) self.assertTrue(np.allclose(d, [0.08093341] * 2)) self.assertTrue(np.allclose(ft, [0.01, 0.025, 0.035])) self.assertTrue(np.allclose(s, [1, 0])) # check distances are large when mask allows no 'real' mapping d, ft, s = sm._cart_dists(s1, s4, l, mask4, n1) self.assertTrue(np.min(d) > 1e8) self.assertTrue(np.min(ft) > 1e8)
def test_subset(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=False, allow_subset=True) l = Lattice.orthorhombic(10, 20, 30) s1 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s2 = Structure(l, ['Si', 'Ag'], [[0, 0.1, 0], [-.7, .5, .4]]) result = sm.get_s2_like_s1(s1, s2) self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords, [0, 0, 0.1])), 1) self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords, [0.7, 0.4, 0.5])), 1) # test with fewer species in s2 s1 = Structure(l, ['Si', 'Ag', 'Si'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s2 = Structure(l, ['Si', 'Si'], [[0, 0.1, 0], [-.7, .5, .4]]) result = sm.get_s2_like_s1(s1, s2) mindists = np.min(s1.lattice.get_all_distances( s1.frac_coords, result.frac_coords), axis=0) self.assertLess(np.max(mindists), 1e-6) self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords, [0, 0, 0.1])), 1) self.assertEqual(len(find_in_coord_list_pbc(result.frac_coords, [0.7, 0.4, 0.5])), 1) # test with not enough sites in s1 # test with fewer species in s2 s1 = Structure(l, ['Si', 'Ag', 'Cl'], [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]]) s2 = Structure(l, ['Si', 'Si'], [[0, 0.1, 0], [-.7, .5, .4]]) self.assertEqual(sm.get_s2_like_s1(s1, s2), None)
def test_init(self): filepath = os.path.join(test_dir, 'input/23221-ZDsSsJoEW14.res') res = Res.from_file(filepath) comp = res.structure.composition self.assertEqual(comp, Composition.from_formula("C194H60")) #print res res_string = """TITL CELL 1.0 1.0 1.0 1.0 90.0 90.0 90.0 LATT -1 SFAC Si F Si 1 0.000000 0.000000 0.000000 1.0 F 2 0.750000 0.500000 0.750000 1.0""" res = Res.from_string(res_string) self.assertEqual(res.structure.composition, Composition("SiF")) self.assertEquals(res.structure.num_sites, 2) #print res struct = Structure(Lattice.orthorhombic(2.5, 3.5, 7.0), ['Na', 'Cl'], [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) res = Res(struct) res_string = str(res) lines = res_string.splitlines() self.assertEqual(lines[1], "CELL 1.0 2.5 3.5 7.0 90.0 90.0 90.0")
def get_orthogonal_grain(self): a, b, c = self.lattice.abc new_latt = Lattice.orthorhombic(a, b, c) return Structure(new_latt, self.species, self.frac_coords)
def test_supercell_subsets(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='volume') sm_no_s = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=False, supercell_size='volume') l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Ag', 'Si', 'Si'], [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]]) s1.make_supercell([2, 1, 1]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]]) shuffle = [0, 2, 1, 3, 4, 5] s1 = Structure.from_sites([s1[i] for i in shuffle]) #test when s1 is exact supercell of s2 result = sm.get_s2_like_s1(s1, s2) for a, b in zip(s1, result): self.assertTrue(a.distance(b) < 0.08) self.assertEqual(a.species_and_occu, b.species_and_occu) self.assertTrue(sm.fit(s1, s2)) self.assertTrue(sm.fit(s2, s1)) self.assertTrue(sm_no_s.fit(s1, s2)) self.assertTrue(sm_no_s.fit(s2, s1)) rms = (0.048604032430991401, 0.059527539448807391) self.assertTrue(np.allclose(sm.get_rms_dist(s1, s2), rms)) self.assertTrue(np.allclose(sm.get_rms_dist(s2, s1), rms)) #test when the supercell is a subset of s2 subset_supercell = s1.copy() del subset_supercell[0] result = sm.get_s2_like_s1(subset_supercell, s2) self.assertEqual(len(result), 6) for a, b in zip(subset_supercell, result): self.assertTrue(a.distance(b) < 0.08) self.assertEqual(a.species_and_occu, b.species_and_occu) self.assertTrue(sm.fit(subset_supercell, s2)) self.assertTrue(sm.fit(s2, subset_supercell)) self.assertFalse(sm_no_s.fit(subset_supercell, s2)) self.assertFalse(sm_no_s.fit(s2, subset_supercell)) rms = (0.053243049896333279, 0.059527539448807336) self.assertTrue(np.allclose(sm.get_rms_dist(subset_supercell, s2), rms)) self.assertTrue(np.allclose(sm.get_rms_dist(s2, subset_supercell), rms)) #test when s2 (once made a supercell) is a subset of s1 s2_missing_site = s2.copy() del s2_missing_site[1] result = sm.get_s2_like_s1(s1, s2_missing_site) for a, b in zip((s1[i] for i in (0, 2, 4, 5)), result): self.assertTrue(a.distance(b) < 0.08) self.assertEqual(a.species_and_occu, b.species_and_occu) self.assertTrue(sm.fit(s1, s2_missing_site)) self.assertTrue(sm.fit(s2_missing_site, s1)) self.assertFalse(sm_no_s.fit(s1, s2_missing_site)) self.assertFalse(sm_no_s.fit(s2_missing_site, s1)) rms = (0.029763769724403633, 0.029763769724403987) self.assertTrue(np.allclose(sm.get_rms_dist(s1, s2_missing_site), rms)) self.assertTrue(np.allclose(sm.get_rms_dist(s2_missing_site, s1), rms))
def test_supercell_subsets(self): sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=True, supercell_size='volume') sm_no_s = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True, attempt_supercell=True, allow_subset=False, supercell_size='volume') l = Lattice.orthorhombic(1, 2, 3) s1 = Structure(l, ['Ag', 'Si', 'Si'], [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]]) s1.make_supercell([2, 1, 1]) s2 = Structure(l, ['Si', 'Si', 'Ag'], [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]]) shuffle = [0, 2, 1, 3, 4, 5] s1 = Structure.from_sites([s1[i] for i in shuffle]) # test when s1 is exact supercell of s2 result = sm.get_s2_like_s1(s1, s2) for a, b in zip(s1, result): self.assertTrue(a.distance(b) < 0.08) self.assertEqual(a.species, b.species) self.assertTrue(sm.fit(s1, s2)) self.assertTrue(sm.fit(s2, s1)) self.assertTrue(sm_no_s.fit(s1, s2)) self.assertTrue(sm_no_s.fit(s2, s1)) rms = (0.048604032430991401, 0.059527539448807391) self.assertTrue(np.allclose(sm.get_rms_dist(s1, s2), rms)) self.assertTrue(np.allclose(sm.get_rms_dist(s2, s1), rms)) # test when the supercell is a subset of s2 subset_supercell = s1.copy() del subset_supercell[0] result = sm.get_s2_like_s1(subset_supercell, s2) self.assertEqual(len(result), 6) for a, b in zip(subset_supercell, result): self.assertTrue(a.distance(b) < 0.08) self.assertEqual(a.species, b.species) self.assertTrue(sm.fit(subset_supercell, s2)) self.assertTrue(sm.fit(s2, subset_supercell)) self.assertFalse(sm_no_s.fit(subset_supercell, s2)) self.assertFalse(sm_no_s.fit(s2, subset_supercell)) rms = (0.053243049896333279, 0.059527539448807336) self.assertTrue(np.allclose(sm.get_rms_dist(subset_supercell, s2), rms)) self.assertTrue(np.allclose(sm.get_rms_dist(s2, subset_supercell), rms)) # test when s2 (once made a supercell) is a subset of s1 s2_missing_site = s2.copy() del s2_missing_site[1] result = sm.get_s2_like_s1(s1, s2_missing_site) for a, b in zip((s1[i] for i in (0, 2, 4, 5)), result): self.assertTrue(a.distance(b) < 0.08) self.assertEqual(a.species, b.species) self.assertTrue(sm.fit(s1, s2_missing_site)) self.assertTrue(sm.fit(s2_missing_site, s1)) self.assertFalse(sm_no_s.fit(s1, s2_missing_site)) self.assertFalse(sm_no_s.fit(s2_missing_site, s1)) rms = (0.029763769724403633, 0.029763769724403987) self.assertTrue(np.allclose(sm.get_rms_dist(s1, s2_missing_site), rms)) self.assertTrue(np.allclose(sm.get_rms_dist(s2_missing_site, s1), rms))
def simple_cubic_2x1x1(): lattice = Lattice.orthorhombic(2.0, 1.0, 1.0) coords = [[0.0, 0.0, 0.0], [0.5, 0.0, 0.0]] return IStructure(lattice=lattice, species=["H", "H"], coords=coords)