def test_basic_atoms(): box = [[2.715, 2.715, 0], [0, 2.715, 2.715], [2.715, 0, 2.715]] coords = [[0, 0, 0], [0.25, 0.2, 0.25]] elements = ["Si", "Si"] Si = Atoms(lattice_mat=box, coords=coords, elements=elements) dim = get_supercell_dims(Si) assert dim == [3, 3, 3] polar = Si.check_polar Si.props = ["a", "a"] vac_pad = VacuumPadding(Si) den_2d = round(vac_pad.get_effective_2d_slab().density, 2) den_0d = round(vac_pad.get_effective_molecule().density, 2) den_lll_red = round(Si.get_lll_reduced_structure().density, 2) strng = Si.get_string() scell_nat = Si.make_supercell([2, 2, 2]).num_atoms scell_nat2 = Si.make_supercell_matrix([[2, 0, 0], [0, 2, 0], [0, 0, 2]]).num_atoms # print("scell_nat,scell_nat2", scell_nat, scell_nat2) # print(Si.make_supercell([2, 2, 2])) # print() # print(Si.make_supercell_matrix([[2, 0, 0], [0, 2, 0], [0, 0, 2]])) com = round(Si.get_center_of_mass()[0], 3) rem = (Si.make_supercell([2, 2, 2]).remove_site_by_index(site=0)).num_atoms prim = Si.get_primitive_atoms print(prim.cart_coords) assert round(prim.cart_coords[0][0], 2) == round(4.37815150, 2) # print ('raw_distance_matrix', prim.raw_distance_matrix) # print ('raw_distance_matrix', Si.raw_distance_matrix) # print ('distance_matrix', Si.pymatgen_converter().distance_matrix) assert round(prim.raw_distance_matrix[0][1], 2) == round(4.42386329832851, 2) print(prim.raw_angle_matrix) d = Si.to_dict() new_at = Atoms.from_dict(d) angs_a = d["angles"][0] Si_2_den = Atoms( lattice_mat=d["lattice_mat"], coords=d["coords"], elements=d["elements"], ).density Si_xyz = Si.get_xyz_string Si.write_xyz(filename="atoms.xyz") tmp = Atoms.from_xyz(filename="atoms.xyz") cmd = 'rm atoms.xyz' os.system(cmd) Si.center_around_origin() # print ('scell_nat', Si_2) assert ( round(Si.volume, 2), Si.atomic_numbers, Si.num_atoms, Si.frac_coords[0][0], Si.cart_coords[0][0], round(Si.density, 2), Si.spacegroup(), Si.pymatgen_converter() != {}, polar, Si.props[0], den_2d, den_0d, round(Si.packing_fraction, 2), Si.composition.to_dict(), strng != "", den_lll_red, scell_nat, com, rem, angs_a, round(Si_2_den, 2), ) == ( 40.03, [14, 14], 2, 0, 0.0, 2.33, "C2/m (12)", True, False, "a", 0.35, 0.01, 0.28, { "Si": 2 }, True, 2.33, 16, 0.679, 15, 60.0, 2.33, ) cc = Si.center() cc = Si.center(axis=[0, 0, 1]) m1 = Atoms.from_dict(get_jid_data("JVASP-6640")["atoms"]) assert m1.check_polar == True print("Strain test") print(m1) m1.apply_strain(0.1) print(m1) assert m1.lattice_mat[2][2] == 32.8717576 m1.apply_strain([0, 0, 0.1]) assert m1.lattice_mat[2][2] == 36.158933360000006 filename = "atoms.cif" m1.write_cif(filename) a = Atoms.from_cif(filename) filename = "POSCAR" m1.write_poscar(filename) m2 = Atoms.from_poscar(filename) filename = "atoms.xyz" m1.write_xyz(filename) m3 = Atoms.from_xyz(filename) cmd = "rm atoms.xyz POSCAR atoms.cif" os.system(cmd)
def make_surface(self): """Generate specified surface. Modified from ase package.""" atoms = self.atoms h_index, k_index, l_index = self.indices h0, k0, l0 = self.indices == 0 if h0 and k0 or h0 and l0 or k0 and l0: # if two indices are zero if not h0: c1, c2, c3 = [(0, 1, 0), (0, 0, 1), (1, 0, 0)] if not k0: c1, c2, c3 = [(0, 0, 1), (1, 0, 0), (0, 1, 0)] if not l0: c1, c2, c3 = [(1, 0, 0), (0, 1, 0), (0, 0, 1)] else: p, q = ext_gcd(k_index, l_index) a1, a2, a3 = self.atoms.lattice_mat # .lat_lengths() # constants describing the dot product of basis c1 and c2: # dot(c1,c2) = k1+i*k2, i in Z k1 = np.dot( p * (k_index * a1 - h_index * a2) + q * (l_index * a1 - h_index * a3), l_index * a2 - k_index * a3, ) k2 = np.dot( l_index * (k_index * a1 - h_index * a2) - k_index * (l_index * a1 - h_index * a3), l_index * a2 - k_index * a3, ) if abs(k2) > self.tol: i = -int(round(k1 / k2)) p, q = p + i * l_index, q - i * k_index a, b = ext_gcd(p * k_index + q * l_index, h_index) c1 = (p * k_index + q * l_index, -p * h_index, -q * h_index) c2 = np.array((0, l_index, -k_index)) // abs(gcd(l_index, k_index)) c3 = (b, a * p, a * q) lattice = atoms.lattice_mat # .lat_lengths() basis = np.array([c1, c2, c3]) scaled = np.linalg.solve(basis.T, np.array(atoms.frac_coords).T).T scaled -= np.floor(scaled + self.tol) new_coords = scaled tmp_cell = np.dot(basis, lattice) M = np.linalg.solve(lattice, tmp_cell) cart_coords = np.dot(scaled, lattice) new_coords = np.dot(cart_coords, M) new_atoms = Atoms( lattice_mat=tmp_cell, coords=new_coords, elements=atoms.elements, cartesian=True, ) surf_atoms = new_atoms.make_supercell_matrix([1, 1, self.layers]) # print("supercell_cart_coords", surf_atoms.frac_coords) new_lat = surf_atoms.lattice_mat # lat_lengths() a1 = new_lat[0] a2 = new_lat[1] a3 = new_lat[2] new_lat = np.array([ a1, a2, np.cross(a1, a2) * np.dot(a3, np.cross(a1, a2)) / norm(np.cross(a1, a2))**2, ]) a1 = new_lat[0] a2 = new_lat[1] a3 = new_lat[2] # print("a1,a2,a3", new_lat) latest_lat = np.array([ (np.linalg.norm(a1), 0, 0), ( np.dot(a1, a2) / np.linalg.norm(a1), np.sqrt( np.linalg.norm(a2)**2 - (np.dot(a1, a2) / np.linalg.norm(a1))**2), 0, ), (0, 0, np.linalg.norm(a3)), ]) M = np.linalg.solve(new_lat, latest_lat) new_cart_coords = surf_atoms.cart_coords # np.dot(scaled,lattice) new_coords = np.dot(new_cart_coords, M) new_atoms = Atoms( lattice_mat=latest_lat, elements=surf_atoms.elements, coords=new_coords, cartesian=True, ).center_around_origin() frac_coords = new_atoms.frac_coords frac_coords[:] = frac_coords[:] % 1 new_atoms = Atoms( lattice_mat=latest_lat, elements=surf_atoms.elements, coords=frac_coords, cartesian=False, ) new_lat = new_atoms.lattice_mat new_cart_coords = new_atoms.cart_coords elements = new_atoms.elements new_lat[2][2] = new_lat[2][2] + self.vacuum with_vacuum_atoms = Atoms( lattice_mat=new_lat, elements=elements, coords=new_cart_coords, cartesian=True, ) # new_atoms.center() # print (with_vacuum_atoms) return with_vacuum_atoms