def test_disordered_formula(self): disordered_struct = Structure( [[10, 0, 0], [0, 10, 0], [0, 0, 10]], [{"Cu": 0.25, "Au": 0.75}], [[0, 0, 0]], ) formula_plain = disordered_formula(disordered_struct, fmt="plain") formula_latex = disordered_formula(disordered_struct, fmt="LaTeX") formula_html = disordered_formula(disordered_struct, fmt="HTML") self.assertEqual(formula_plain, "CuxAu1-x x=0.25") self.assertEqual(formula_latex, "Cu_{x}Au_{1-x} x=0.25") self.assertEqual(formula_html, "Cu<sub>x</sub>Au<sub>1-x</sub> x=0.25")
def test_to_istructure(self): cscl = Structure( Lattice([[4.209, 0, 0], [0, 4.209, 0], [0, 0, 4.209]]), ["Cl", "Cs"], [[0.45, 0.5, 0.5], [0, 0, 0]]) df = DataFrame({"structure": [cscl]}) # Run the conversion sti = StructureToIStructure() df = sti.featurize_dataframe(df, 'structure') # Make sure the new structure is an IStructure, and equal # to the original structure self.assertIsInstance(df["istructure"][0], IStructure) self.assertEqual(df["istructure"][0], df["structure"][0])
def test_get_supercell_size(self): l = Lattice.cubic(1) l2 = Lattice.cubic(0.9) s1 = Structure(l, ['Mg', 'Cu', 'Ag', 'Cu', 'Ag'], [[0]*3]*5) s2 = Structure(l2, ['Cu', 'Cu', 'Ag'], [[0]*3]*3) sm = StructureMatcher(supercell_size='volume') result = sm._get_supercell_size(s1, s2) self.assertEqual(result[0], 1) self.assertEqual(result[1], True) result = sm._get_supercell_size(s2, s1) self.assertEqual(result[0], 1) self.assertEqual(result[1], True) sm = StructureMatcher(supercell_size='num_sites') result = sm._get_supercell_size(s1, s2) self.assertEqual(result[0], 2) self.assertEqual(result[1], False) result = sm._get_supercell_size(s2, s1) self.assertEqual(result[0], 2) self.assertEqual(result[1], True)
def test_disordered_formula(self): disordered_struct = Structure([[10, 0, 0], [0, 10, 0], [0, 0, 10]], [{ 'Cu': 0.25, 'Au': 0.75 }], [[0, 0, 0]]) formula_plain = disordered_formula(disordered_struct, fmt='plain') formula_latex = disordered_formula(disordered_struct, fmt='LaTeX') formula_html = disordered_formula(disordered_struct, fmt='HTML') self.assertEqual(formula_plain, 'CuxAu1-x x=0.25') self.assertEqual(formula_latex, 'Cu_{x}Au_{1-x} x=0.25') self.assertEqual(formula_html, 'Cu<sub>x</sub>Au<sub>1-x</sub> x=0.25')
def test_paramdict(self): coords = [[0.0, 0.0, 0.0], [0.75, 0.5, 0.75]] lattice = Lattice.from_parameters(a=3.84, b=3.84, c=3.84, alpha=120, beta=90, gamma=60) struct = Structure(lattice, ["Si", "Si"], coords) paradir = { "grst": { "do": "fromscratch", "ngridk": "8 8 8", "xctype": "GGA_PBE_SOL", "gmaxvr": "14.0", }, "xs": { "xstype": "BSE", "ngridk": "4 4 4", "ngridq": "4 4 4", "nempty": "30", "gqmax": "3.0", "broad": "0.07", "tevout": "true", "energywindow": { "intv": "0.0 1.0", "points": "1200" }, "screening": { "screentype": "full", "nempty": "100" }, "BSE": { "bsetype": "singlet", "nstlbse": "1 5 1 4" }, }, } test_input = ExcitingInput(struct) test_string = test_input.write_string("unchanged", **paradir) # read reference file filepath = os.path.join(PymatgenTest.TEST_FILES_DIR, "input_exciting2.xml") tree = ET.parse(filepath) root = tree.getroot() ref_string = ET.tostring(root, encoding="unicode") self.assertEqual(ref_string.strip(), test_string.strip())
def test_from_edges(self): edges = { (0, 0, (0, 0, 0), (1, 0, 0)): None, (0, 0, (0, 0, 0), (-1, 0, 0)): None, (0, 0, (0, 0, 0), (0, 1, 0)): None, (0, 0, (0, 0, 0), (0, -1, 0)): None, } structure = Structure(Lattice.tetragonal(5.0, 50.0), ["H"], [[0, 0, 0]]) sg = StructureGraph.with_edges(structure, edges) self.assertEqual(sg, self.square_sg)
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 read_cfgs(self, filename="output.data"): """ Read the configuration file. Args: filename (str): The configuration file to be read. """ data_pool = [] with zopen(filename, "rt") as f: lines = f.read() block_pattern = re.compile("begin\n(.*?)end", re.S) lattice_pattern = re.compile("lattice(.*?)\n") position_pattern = re.compile("atom(.*?)\n") energy_pattern = re.compile("energy(.*?)\n") for block in block_pattern.findall(lines): d = {"outputs": {}} lattice_str = lattice_pattern.findall(block) lattice = Lattice( np.array([latt.split() for latt in lattice_str], dtype=np.float64) * self.bohr_to_angstrom) position_str = position_pattern.findall(block) positions = pd.DataFrame([pos.split() for pos in position_str]) positions.columns = [ "x", "y", "z", "specie", "charge", "atomic_energy", "fx", "fy", "fz" ] coords = np.array(positions.loc[:, ["x", "y", "z"]], dtype=np.float64) coords = coords * self.bohr_to_angstrom species = np.array(positions["specie"]) forces = np.array(positions.loc[:, ["fx", "fy", "fz"]], dtype=np.float64) forces = forces / self.eV_to_Ha / self.bohr_to_angstrom energy_str = energy_pattern.findall(block)[0] energy = float(energy_str.lstrip()) / self.eV_to_Ha struct = Structure(lattice=lattice, species=species, coords=coords, coords_are_cartesian=True) d["structure"] = struct.as_dict() d["outputs"]["energy"] = energy d["outputs"]["forces"] = forces d["num_atoms"] = len(struct) data_pool.append(d) _, df = convert_docs(docs=data_pool) return data_pool, df
def test_interstice_distribution_of_glass(self): cuzr_glass = Structure(Lattice([[25, 0, 0], [0, 25, 0], [0, 0, 25]]), [ "Cu", "Cu", "Cu", "Cu", "Cu", "Zr", "Cu", "Zr", "Cu", "Zr", "Cu", "Zr", "Cu", "Cu" ], [[11.81159679, 16.49480537, 21.69139442], [11.16777208, 17.87850033, 18.57877144], [12.22394796, 15.83218325, 19.37763412], [13.07053548, 14.34025424, 21.77557646], [10.78147725, 19.61647494, 20.77595531], [10.87541011, 14.65986432, 23.61517624], [12.76631002, 18.41479521, 20.46717947], [14.63911675, 16.47487037, 20.52671362], [14.2470256, 18.44215167, 22.56257566], [9.38050168, 16.87974592, 20.51885879], [10.66332986, 14.43900833, 20.545186], [11.57096832, 18.79848982, 23.26073408], [13.27048138, 16.38613795, 23.59697472], [9.55774984, 17.09220537, 23.1856528]], coords_are_cartesian=True) df_glass = pd.DataFrame({'struct': [cuzr_glass], 'site': [0]}) interstice_distribution = IntersticeDistribution() intersticefp = interstice_distribution.featurize_dataframe( df_glass, ['struct', 'site']) self.assertAlmostEqual(intersticefp['Interstice_vol_mean'][0], 0.28905, 5) self.assertAlmostEqual(intersticefp['Interstice_vol_std_dev'][0], 0.04037, 5) self.assertAlmostEqual(intersticefp['Interstice_vol_minimum'][0], 0.21672, 5) self.assertAlmostEqual(intersticefp['Interstice_vol_maximum'][0], 0.39084, 5) self.assertAlmostEqual(intersticefp['Interstice_area_mean'][0], 0.16070, 5) self.assertAlmostEqual(intersticefp['Interstice_area_std_dev'][0], 0.05245, 5) self.assertAlmostEqual(intersticefp['Interstice_area_minimum'][0], 0.07132, 5) self.assertAlmostEqual(intersticefp['Interstice_area_maximum'][0], 0.26953, 5) self.assertAlmostEqual(intersticefp['Interstice_dist_mean'][0], 0.08154, 5) self.assertAlmostEqual(intersticefp['Interstice_dist_std_dev'][0], 0.14778, 5) self.assertAlmostEqual(intersticefp['Interstice_dist_minimum'][0], -0.04668, 5) self.assertAlmostEqual(intersticefp['Interstice_dist_maximum'][0], 0.37565, 5)
def get_drift_corrected_structures(self): """ Returns an iterator for the drift-corrected structures. Use of iterator is to reduce memory usage as # of structures in MD can be huge. You don't often need all the structures all at once. """ coords = np.array(self.structure.cart_coords) species = self.structure.species_and_occu latt = self.structure.lattice nsites, nsteps, dim = self.corrected_displacements.shape for i in range(nsteps): yield Structure(latt, species, coords + self.corrected_displacements[:, i, :], coords_are_cartesian=True)
def test_from_seed(self): coords = [[0, 0, 0], [0.75, 0.5, 0.75]] lattice = pmg_Lattice.from_parameters(a=3.84, b=3.84, c=3.84, alpha=120, beta=90, gamma=60) struct = Structure(lattice, ["Si", "C"], coords) s1 = pyxtal() s1.from_seed(struct) s2 = s1.subgroup_once(eps=0) pmg_s1 = s1.to_pymatgen() pmg_s2 = s2.to_pymatgen() self.assertTrue(sm.StructureMatcher().fit(pmg_s1, pmg_s2))
async def calculate(): futures = [] for angle in angles: coord_a = (lattice.a*0.5 + separation, lattice.b*0.5, lattice.c*0.5) coord_b = (lattice.a*0.5, lattice.b*0.5, lattice.c*0.5) # b in center coord_c = (lattice.a*0.5 + (math.cos(angle) * separation), lattice.b*0.5 + (math.sin(angle) * separation), lattice.c*0.5) structure = Structure( lattice, [element_b, element_a, element_b], [coord_a, coord_b, coord_c], coords_are_cartesian=True) futures.append(await self.calculator.submit( structure, potential, properties={'energy'}, **kwargs)) return await asyncio.gather(*futures)
def test_get_Q_from_struct(self): q = get_Q_from_struct(self.gnd_test, self.exd_test, self.sct_test) self.assertAlmostEqual(q, 0.5 * 0.86945, places=4) q = get_Q_from_struct(self.gnd_real, self.exd_real, str(TEST_FILES / 'POSCAR.C0.gz')) self.assertAlmostEqual(q, 0., places=4) gs, es = get_cc_structures(self.gnd_real, self.exd_real, np.linspace(-0.5, 0.5, 100), remove_zero=False) Q = 1.68587 * np.linspace(-0.5, 0.5, 100) for s, q in zip(gs, Q): tq = get_Q_from_struct(self.gnd_real, self.exd_real, s) self.assertAlmostEqual(tq, q, places=4) for s, q in zip(es, Q + 1.68587): tq = get_Q_from_struct(self.gnd_real, self.exd_real, s) self.assertAlmostEqual(tq, q, places=4) # test when one of the coordinates stays the same sg = Structure(np.eye(3), ['H'], [[0.0, 0.0, 0.0]]) sq = Structure(np.eye(3), ['H'], [[0.1, 0.0, 0.1]]) se = Structure(np.eye(3), ['H'], [[0.2, 0.0, 0.2]]) dQ = get_dQ(sg, se) self.assertAlmostEqual(get_Q_from_struct(sg, se, sq) / dQ, 0.5)
def _get_structure(optimade_structure: OptimadeStructure) -> Structure: """Create pymatgen Structure from OPTIMADE structure""" attributes = optimade_structure.attributes return Structure( lattice=attributes.lattice_vectors, species=_pymatgen_species( nsites=attributes.nsites, species=attributes.species, species_at_sites=attributes.species_at_sites, ), coords=attributes.cartesian_site_positions, coords_are_cartesian=True, )
def test_potcar_symbols(self): coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) coords.append([0.75, 0.25, 0.75]) lattice = Lattice([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]]) structure = Structure(lattice, ["P", "Fe", "O"], coords) mitparamset = MITRelaxSet(structure) syms = mitparamset.potcar_symbols self.assertEqual(syms, ['Fe', 'P', 'O']) paramset = MPRelaxSet(structure, sort_structure=False) syms = paramset.potcar_symbols self.assertEqual(syms, ['P', 'Fe_pv', 'O'])
def test_add_interstitial_not_primitive_error(cubic_supercell_info_wo_int): conventional_cell = Structure(Lattice.cubic(10), species=["H"] * 4 + ["He"] * 4, 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], ]) with pytest.raises(NotPrimitiveError): append_interstitial(cubic_supercell_info_wo_int, conventional_cell, [[1/4, 1/4, 1/4]], ["test1"])
def test_structure_to_composition(self): coords = [[0, 0, 0], [0.75, 0.5, 0.75]] lattice = Lattice([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]]) struct = Structure(lattice, ["Si"] * 2, coords) df = DataFrame(data={'structure': [struct]}) stc = StructureToComposition() df = stc.featurize_dataframe(df, 'structure') self.assertEqual(df["composition"].tolist()[0], Composition("Si2")) stc = StructureToComposition(reduce=True, target_col_id='composition_red') df = stc.featurize_dataframe(df, 'structure') self.assertEqual(df["composition_red"].tolist()[0], Composition("Si"))
async def calculate(): futures = [] for sep in separations: coord_a = (lattice.a * 0.5 - (sep / 2), lattice.b * 0.5, lattice.c * 0.5) coord_b = (lattice.a * 0.5 + (sep / 2), lattice.b * 0.5, lattice.c * 0.5) structure = Structure(lattice, [specie_a, specie_b], [coord_a, coord_b], coords_are_cartesian=True) futures.append(await self.calculator.submit(structure, potential, properties={'energy'}, **kwargs)) return await asyncio.gather(*futures)
def read_cfgs(self, filename='output.data'): """ Read the configuration file. Args: filename (str): The configuration file to be read. """ data_pool = [] with zopen(filename, 'rt') as f: lines = f.read() block_pattern = re.compile('begin\n(.*?)end', re.S) lattice_pattern = re.compile('lattice(.*?)\n') position_pattern = re.compile('atom(.*?)\n') energy_pattern = re.compile('energy(.*?)\n') for block in block_pattern.findall(lines): d = {'outputs': {}} lattice_str = lattice_pattern.findall(block) lattice = Lattice( np.array([latt.split() for latt in lattice_str], dtype=np.float) * self.bohr_to_angstrom) position_str = position_pattern.findall(block) positions = pd.DataFrame([pos.split() for pos in position_str]) positions.columns = \ ['x', 'y', 'z', 'specie', 'charge', 'atomic_energy', 'fx', 'fy', 'fz'] coords = np.array(positions.loc[:, ['x', 'y', 'z']], dtype=np.float) coords = coords * self.bohr_to_angstrom species = np.array(positions['specie']) forces = np.array(positions.loc[:, ['fx', 'fy', 'fz']], dtype=np.float) forces = forces / self.eV_to_Ha / self.bohr_to_angstrom energy_str = energy_pattern.findall(block)[0] energy = float(energy_str.lstrip()) / self.eV_to_Ha struct = Structure(lattice=lattice, species=species, coords=coords, coords_are_cartesian=True) d['structure'] = struct.as_dict() d['outputs']['energy'] = energy d['outputs']['forces'] = forces d['num_atoms'] = len(struct) data_pool.append(d) _, df = convert_docs(docs=data_pool) return data_pool, df
def gen_child(self, struc): ''' generate child struture # ---------- return (if success) self.child: (if fail) None: ''' # ---------- init cnt = 0 lat_mat = struc.lattice.matrix.T # lattice vector as matrix # ---------- generate strained structure while True: # ------ strain matrix strain_matrix = np.empty([3, 3]) for i in range(3): for j in range(3): if i <= j: if i == j: strain_matrix[i][j] = 1.0 + np.random.normal( loc=0.0, scale=self.sigma) else: strain_matrix[i][j] = np.random.normal( loc=0.0, scale=self.sigma) / 2.0 strain_matrix[j][i] = strain_matrix[i][j] # ------ strained lattice strained_lattice = np.dot(strain_matrix, lat_mat).T # ------ child self.child = Structure(strained_lattice, struc.species, struc.frac_coords) # ------ scale lattice self.child.scale_lattice(struc.volume) # ------ check distance success, mindist_ij, dist = check_distance(self.child, self.atype, self.mindist) if success: self.child = sort_by_atype(self.child, self.atype) return self.child else: sys.stderr.write( 'mindist in permutation: {} - {}, {}. retry.\n'.format( self.atype[mindist_ij[0]], self.atype[mindist_ij[1]], dist)) cnt += 1 if cnt >= self.maxcnt_ea: self.child = None return None # change parent
def get_struc_step_vasp(struc_step_data, current_id, filename): # ---------- get struc step from vasprun try: # ------ read file tree = ET.parse(filename) root = tree.getroot() # ------ get atom list atoms = root.findall("atominfo/array[@name='atoms']/set/rc") atomlist = [] for atom in atoms: atomlist.append(atom.find('c').text) # ------ children nodes: calculation cals = root.findall('calculation') # ------ init. struc_step = [] # ------ loop for relaxation step for cal in cals: # -- lattice basis = cal.findall("structure/crystal/varray[@name='basis']/v") lattice = [] for a in basis: lattice.append([float(x) for x in a.text.split()]) # -- positions positions = cal.findall("structure/varray/[@name='positions']/v") incoord = [] for a in positions: incoord.append([float(x) for x in a.text.split()]) # -- structure in pymatgen format struc = Structure(lattice, atomlist, incoord) # -- append struc_step.append(struc) except: struc_step = None print('\n#### ID: {0}: failed to parse vasprun.xml\n\n'.format( current_id)) # ---------- append struc_step if struc_step_data.get(current_id) is None: struc_step_data[current_id] = [] # initialize struc_step_data[current_id].append(struc_step) # ---------- save struc_step_data pkl_data.save_struc_step(struc_step_data) # ---------- return return struc_step_data
def test_check_structures(self): s = Structure( Lattice( np.array([[3.16, 0.1, 0.2], [0.1, 3.17, 0.3], [0.1, 0.2, 3]])), ["Mo", "Mo"], [[0, 0, 0], [0.13, 0.4, 0.2]], ) forces = np.array([[0.04844841, 0.08648062, 0.07070806], [-0.04844841, -0.08648062, -0.07070806]]) stress = np.array([ -0.22279327, -1.2809575, -0.44279698, -0.23345818, -0.37798718, -0.17676364 ]) checked_force = np.array([[0.05552151, 0.09063424, 0.05940176], [-0.05552151, -0.09063424, -0.05940176]]) checked_stress = np.array([ -0.26319715, -1.3219795, -0.3613719, -0.30627516, -0.27276486, -0.17306383 ]) new_structures, new_forces, new_stresses = check_structures_forces_stresses( [s], [forces], [stress]) # print(np.linalg.norm(checked_stress - new_stresses[0])) print(new_stresses[0], checked_stress) self.assertTrue(np.linalg.norm(checked_force - new_forces[0]) < 1e-4) self.assertTrue( np.linalg.norm(checked_stress - new_stresses[0]) < 1e-4) new_structures = check_structures_forces_stresses(structures=[s], return_none=False) self.assertTrue(len(new_structures) == 1) self.assertTrue(isinstance(new_structures[0], Structure)) new_structures, new_forces, new_stresses = check_structures_forces_stresses( structures=[s, s], return_none=True) self.assertTrue(len(new_forces) == 2) self.assertTrue(new_forces[0] is None) self.assertTrue(len(new_stresses) == 2) self.assertTrue(new_stresses[0] is None)
def set_vacuum(self, thick=20): self.reset_loc() new_lattice = self.poscar.structure.lattice new_c = new_lattice.c - self.vacuum_thick + thick new_lattice = Lattice.from_parameters(new_lattice.a, new_lattice.b, new_c, new_lattice.alpha, new_lattice.beta, new_lattice.gamma) min = np.mean(self.poscar.structure.frac_coords[:, 2]) newcoor = self.poscar.structure.frac_coords - [0, 0, min] newcoor[:, 2] = newcoor[:, 2] * self.poscar.structure.lattice.c / new_c new_structure = Structure(new_lattice, self.poscar.structure.species, newcoor, coords_are_cartesian=False) self.poscar = Poscar(new_structure) self.reset_loc()
def test_rdf_coordination_number(self): # create a simple cubic lattice coords = np.array([[0.5, 0.5, 0.5]]) atom_list = ['S'] lattice = Lattice.from_parameters(a=1.0, b=1.0, c=1.0, alpha=90, beta=90, gamma=90) structure = Structure(lattice, atom_list, coords) rdf = RadialDistributionFunctionFast(structures=[structure], rmax=5.0, sigma=0.01, ngrid=500) self.assertEqual( np.round(rdf.get_coordination_number('S', 'S')[1][110], 2), 6.0)
def gen_phband(file_primitive): qeobj = QEParser() qeobj.load_initial_structure(file_primitive) structure = Structure(qeobj.lattice_vector.transpose(), qeobj.kd_in_str, qeobj.x_fractional) path_info = gen_bzpath(structure) prefix0 = 'supercell' gen_anphon_input('phband.in', prefix0, 'phonons', structure, path_info) command = ("%s/anphon/anphon phband.in > phband.log" % ALAMODE_root) os.system(command)
def test_rdf_coordination_number(self): # create a simple cubic lattice coords = np.array([[0.5, 0.5, 0.5]]) atom_list = ["S"] lattice = Lattice.from_parameters(a=1.0, b=1.0, c=1.0, alpha=90, beta=90, gamma=90) structure = Structure(lattice, atom_list, coords) rdf = RadialDistributionFunction.from_species(structures=[structure], species=["S"], rmax=5.0, sigma=0.1, ngrid=500) self.assertEqual(rdf.coordination_number[100], 6.0)
def pose(self): species = self.host.species + self.guest.species coords = np.concatenate( [self.host.cart_coords, self.guest.cart_coords], axis=0) host_props = self.host.site_properties.get("label", ["host"] * len(self.host)) guest_props = self.guest.site_properties.get("label", ["guest"] * len(self.guest)) props = {"label": host_props + guest_props} return Structure( species=species, coords=coords, coords_are_cartesian=True, lattice=self.host.lattice.matrix, site_properties=props, )
def test_model_load(self): model = MEGNetDescriptor(model_name=DEFAULT_MODEL) self.assertTrue(model.model, Model) s = Structure(Lattice.cubic(3.6), ["Mo", "Mo"], [[0.5, 0.5, 0.5], [0, 0, 0]]) atom_features = model.get_atom_features(s) bond_features = model.get_bond_features(s) glob_features = model.get_global_features(s) atom_set2set = model.get_set2set(s, ftype="atom") bond_set2set = model.get_set2set(s, ftype="bond") s_features = model.get_structure_features(s) self.assertListEqual(list(atom_features.shape), [2, 32]) self.assertListEqual(list(bond_features.shape), [28, 32]) self.assertListEqual(list(glob_features.shape), [1, 32]) self.assertListEqual(list(atom_set2set.shape), [1, 32]) self.assertListEqual(list(bond_set2set.shape), [1, 32]) self.assertListEqual(list(s_features.shape), [1, 96])
def repeat_uc_edge_atoms(structure, tol=1e-7): # Repeats atoms that touch any of the unit cell edges or corners (i.e, have a 0 or 1 fractional coordinate) struct = structure.copy() frac_coords = struct.frac_coords.tolist() border_species = [] border_coords = [] for s in struct: zero_ind = [] for ind, fc in enumerate(s.frac_coords): if fc < tol or fc > 1 - tol: zero_ind.append(ind) if len(zero_ind) > 0: comb = [ list(c) for c in itertools.product([0, 1], repeat=len(zero_ind)) ] for c in comb: c = [float(k) for k in c] if len(c) == 3: if not any(li == c for li in frac_coords + border_coords): border_coords.append(c) border_species.append(s.specie) elif len(c) == 2: new_coord = [sfc for sfc in s.frac_coords] new_coord[zero_ind[0]] = c[0] new_coord[zero_ind[1]] = c[1] if not any(li == new_coord for li in frac_coords + border_coords): border_coords.append(new_coord) border_species.append(s.specie) else: new_coord = [sfc for sfc in s.frac_coords] new_coord[zero_ind[0]] = c[0] if not any(li == new_coord for li in frac_coords + border_coords): border_coords.append(new_coord) border_species.append(s.specie) # Fractional coords 0 and 1 may often get replaced with one another (during conversion to cart_coords), # hence adding/subtracting a tol value in these cases final_coords = [[ tol if f < tol else 1 - tol if f > 1 - tol else f for f in fc ] for fc in struct.frac_coords.tolist() + border_coords] return Structure(struct.lattice, struct.species + border_species, final_coords)
def test_structure_info(mocker): args = Namespace(poscar="POSCAR", symprec=0.1, angle_tolerance=5, show_conventional=False) lattice = [[10.0, 0.0, 0.0], [0.0, 10.0, 0.0], [-2.0, 0.0, 10.0]] coords = [[0.0, 0.0, 0.0], [0.5, 0.5, 0.0]] s = Structure(lattice=lattice, species=["H"] * 2, coords=coords) mock = mocker.patch("vise.cli.main_functions.Structure") mock.from_file.return_value = s structure_info(args) args = Namespace(poscar="POSCAR", symprec=0.1, angle_tolerance=5, show_conventional=True) structure_info(args)