def read_struct(filename): """ Read lattice and atom positions from the crystal output file after a SLABCUT run. """ with open(filename, "r") as f: lignes = f.readlines() sectionCoord = False sites = list() for i, ligne in enumerate(lignes): if "DEFINITION OF THE NEW LATTICE VECTORS" in ligne: while "LATTICE PARAMETERS (ANGSTROM" not in ligne: i += 1 ligne = lignes[i] params = [float(val) for val in lignes[i + 2].split()] slab_lattice = mg.Lattice.from_lengths_and_angles( params[0:3], params[3:]) if "COORDINATES OF THE ATOMS BELONGING TO THE SLAB" in ligne: sectionCoord = True continue if sectionCoord: # on saute la premiere ligne if "LAB" in ligne: continue # si ligne blanche on sort if ligne.strip() == "": break z = int(ligne.split()[1]) valeurs = [float(val) for val in ligne[56:].split()] sites.append(mg.Site(z, valeurs)) return slab_lattice, sites
def make_hydrogen_capped_cluster_from_cif_3(outfilename, ciffile, numnearest, cappingdistances, bqchargemap, centeratom, sphereradius=6, supercell=6, bondlengthcutoff=2.5): '''Make hydrogen-capped cluster. Note: 3 means that this version is trying to accommodate inequivalent sites Supercell needs to be big enough that all atoms in sphere and neighbors thereof have full neighbors.''' print('Importing structure') struct = mg.Structure.from_file(ciffile) struct.make_supercell(supercell) # mol = mg.Molecule(struct.species, struct.cart_coords) mol = tag_sites_by_equivalency(struct) center_cluster_on_atom(mol, centeratom) # fixed 3.23.19 to add centeratom arg remove_oxidation_state_from_species(mol) print('Finding site inside/outside sphere.') innersites = mol.get_sites_in_sphere([0, 0, 0], sphereradius) inner = mg.Molecule.from_sites([s[0] for s in innersites]) neighboringmol = mg.Molecule([], []) for isite in inner: print('Checking neighbors of site {}'.format(mol.index(isite)), end='\r') neighbors = mol.get_neighbors(isite, bondlengthcutoff) for s, _ in neighbors: if s not in inner: if s not in neighboringmol: neighboringmol.append(s.specie, s.coords) try: neighboringmol[neighboringmol.index(s)].innerneighbors.append(isite) except AttributeError: neighboringmol[neighboringmol.index(s)].innerneighbors = [isite] hydrcoords = [] hydrneighbors = [] hydrreplace = [] for ns in neighboringmol: for n in ns.innerneighbors: hydrcoords.append(np.mean([ns.coords, n.coords], axis=0)) # create hydrogen halfway along bond hydrneighbors.append(n) # keep track of neighbor identity hydrreplace.append(ns) # keep track of identitiy of atom being replaced hydrsites = [mg.Site('H', c) for c in hydrcoords] hydr = mg.Molecule.from_sites(hydrsites) # add hydrogen neighbors and adjust bond lengths accordingly for hs, hn, hr in zip(hydrsites, hydrneighbors, hydrreplace): hydr[hydr.index(hs)].innerneighbor = hn hydr[hydr.index(hs)].replacing = hr for s in hydr: adjust_bond_length(s, s.innerneighbor, cappingdistances[str(s.innerneighbor.specie)]) capped = mg.Molecule.from_sites(hydr.sites + inner.sites) print('Writing capped cluster file: ', '{}.xyz'.format(outfilename)) capped.to('xyz', '{}.xyz'.format(outfilename)) print('Writing bq charge file: ', '{}.bq'.format(outfilename)) totalbqcharge = 0 with open('{}.bq'.format(outfilename), 'w') as file: for s in hydr: file.write('Bq {:>15.8f}{:>15.8f}{:>15.8f}{:>10.4f}\n'.format( *s.coords, bqchargemap[str(s.replacing.specie)][str(s.innerneighbor.specie)])) totalbqcharge += bqchargemap[str(s.replacing.specie)][str(s.innerneighbor.specie)] with open('{}.xyz'.format(outfilename), 'r') as file: oldlines = file.readlines() oldlines[1] = oldlines[1].strip() + '; Total bqcharge for capped cluster: {}\n'.format(totalbqcharge) with open('{}.xyz'.format(outfilename), 'w') as file: for line in oldlines: file.write(line) slightly_less_dumb_rename_center_atom('{}.xyz'.format(outfilename))
newLattice = mg.Lattice.from_lengths_and_angles( (a, b, newc), (90., 90., slab_lattice.gamma)) # -------------------------------------------- # decalage des coordonnees entre 0 et 1 dans (xy) # conversion de z en coordonnees reduites # -------------------------------------------- print(args) newSites = list() for site in sites: coords = site.coords coords[0] += .5 coords[1] += .5 if args.center: coords[2] = coords[2] / newLattice.c + .5 elif args.bottom: coords[2] = (coords[2] - zmin) / newLattice.c else: coords[2] = coords[2] / newLattice.c newSites.append(mg.Site(site.specie, coords)) # ----------------------------------- # make a structure and print POSCAR # ----------------------------------- struct = mg.Structure(newLattice, [site.specie for site in newSites], [site.coords for site in newSites]) struct.sort() Poscar(struct).write_file(args.poscar) print(struct)
def make_hydrogen_capped_cluster_from_cif_old_logic(outfilename, ciffile, numnearest, cappingdistances, bqchargemap, centeratom, sphereradius=6, supercell=6): '''Make hydrogen-capped cluster. Supercell needs to be big enough that all atoms in sphere and neighbors thereof have full neighbors.''' print('Importing structure') struct = mg.Structure.from_file(ciffile) struct.make_supercell(6) mol = mg.Molecule(struct.species, struct.cart_coords) center_cluster_on_atom(mol, centeratom) # fixed 3.23.19 to add centeratom arg print('Finding site inside/outside sphere.') innersites = mol.get_sites_in_sphere([0, 0, 0], sphereradius) inner = mg.Molecule.from_sites([s[0] for s in innersites]) SHELLDIST = 4 outersites = mol.get_neighbors_in_shell([0, 0, 0], sphereradius + SHELLDIST / 2, SHELLDIST / 2) outersiteindices = [] for site, _ in outersites: outersiteindices.append(mol.index(site)) neighboringsites = [] for osi in outersiteindices: print('Checking neighbors of site {}'.format(osi), end='\r') neighbors = get_nearest_sites_by_num_neighbors(mol, mol[osi], numnearest) for s, _ in neighbors: if s in inner: try: mol[osi].innerneighbors.append(s) except AttributeError: mol[osi].innerneighbors = [s] if osi not in neighboringsites: neighboringsites.append(osi) hydrcoords = [] hydrneighbors = [] hydrreplace = [] for ns in neighboringsites: ocoords = mol[ns].coords for n in mol[ns].innerneighbors: hydrcoords.append(np.mean([ocoords, n.coords], axis=0)) hydrneighbors.append(n) hydrreplace.append(mol[ns]) hydrsites = [mg.Site('H', c) for c in hydrcoords] hydr = mg.Molecule.from_sites(hydrsites) # add hydrogen neighbors and adjust bond lengths accordingly for hs, hn, hr in zip(hydrsites, hydrneighbors, hydrreplace): hydr[hydr.index(hs)].innerneighbor = hn hydr[hydr.index(hs)].replacing = hr for s in hydr: adjust_bond_length(s, s.innerneighbor, cappingdistances[str(s.innerneighbor.specie)]) capped = mg.Molecule.from_sites(hydr.sites + inner.sites) print('Writing capped cluster file: ', '{}.xyz'.format(outfilename)) capped.to('xyz', '{}.xyz'.format(outfilename)) print('Writing bq charge file: ', '{}.bq'.format(outfilename)) with open('{}.bq'.format(outfilename), 'w') as file: for s in hydr: file.write('Bq {:>15.8f}{:>15.8f}{:>15.8f}{:>10.4f}\n'.format( *s.coords, bqchargemap[str(s.replacing.specie)]))