def repeatgen(infile, repeats, options): '''Repeats geometry from gen files. Args: infile: File containing the gen-formatted geometry. repeats: (n1, n2, n3) integer tuple containing the repetitions along each lattice vector. options: Options (e.g. as returned by the command line parser). ''' gen = Gen.fromfile(infile) geo = gen.geometry latvecs = geo.latvecs if options.latticefile: latvecs = np.fromfile(options.latticefile, sep=' ') if len(latvecs) != 9: msg = ('Invalid number of lattice vector components in ' + options.latticefile) raise ScriptError(msg) latvecs.shape = (3, 3) if latvecs is None: msg = 'No lattice vectors found (neither in gen nor in external file)' raise ScriptError(msg) newgeo = _repeatgeo(geo, latvecs, repeats) newgen = Gen(newgeo, gen.fractional) outfile = options.output if outfile == '-': outfile = sys.stdout newgen.tofile(outfile)
def xyz2gen(args): '''Converts the given INPUT file in XYZ format to DFTB+ GEN format. Args: args: Namespace of command line arguments ''' infile = args.infile try: xyz = Xyz.fromfile(infile) except OSError: raise ScriptError('You must enter a valid path to the input file.') geo = xyz.geometry if args.lattfile: fp = open(args.lattfile, "r") tmp = np.fromfile(fp, count=9, dtype=float, sep=" ") latvecs = tmp.reshape((3, 3)) fp.close() geo.setlattice(latvecs) gen = Gen(geo, fractional=args.fractional) if args.output: if args.output == "-": outfile = sys.stdout else: outfile = args.output else: if infile.endswith(".xyz"): outfile = infile[:-4] + ".gen" else: outfile = infile + ".gen" gen.tofile(outfile)
def gen_file_equals(current, reference): '''Checks whether contents of a gen file equals another one. Args: current (str): Name of gen file to check. reference (str): Name of reference gen file. ''' curgen = Gen.fromfile(current) refgen = Gen.fromfile(reference) return curgen.equals(refgen)
def gen2cif(args): '''Converts the given INPUT file in DFTB+ GEN format to CIF format. Args: args: Namespace of command line arguments ''' infile = args.infile try: gen = Gen.fromfile(infile) except OSError: raise ScriptError('You must enter a valid path to the input file.') geometry = gen.geometry if not geometry.periodic: geometry.setlattice(args.cellsize * np.eye(3)) cif = Cif(gen.geometry) if args.output: if args.output == "-": outfile = sys.stdout else: outfile = args.output else: if infile.endswith(".gen"): outfile = infile[:-4] + ".cif" else: outfile = infile + ".cif" cif.tofile(outfile)
def gen2xyz(args): '''Converts the given INPUT file in DFTB+ GEN format to XYZ format. Args: args: Namespace of command line arguments ''' infile = args.infile try: gen = Gen.fromfile(infile) except OSError: raise ScriptError('You must enter a valid path to the input file.') xyz = Xyz(gen.geometry, args.comment) if args.output: if args.output == "-": outfile = sys.stdout else: outfile = args.output else: if infile.endswith(".gen"): outfile = infile[:-4] + ".xyz" else: outfile = infile + ".xyz" xyz.tofile(outfile) if gen.geometry.periodic and args.lattfile: fp = open(args.lattfile, "w") for vec in gen.geometry.latvecs: fp.write("{0:18.10E} {1:18.10E} {2:18.10E}\n".format(*vec)) fp.close()
def straingen(args, strain): '''Strains a geometry from a gen file. Args: args: Namespace of command line arguments strain: Strain to apply ''' infile = args.infile try: gen = Gen.fromfile(infile) except OSError: raise ScriptError('You must enter a valid path to the input file.') geometry = gen.geometry strainmtx = np.zeros((3, 3), dtype=float) for jj in range(3): strainmtx[jj][jj] = 1.0 components = LABELS[args.component.lower()] for ii in components: strainmtx[VOIGHT[ii][0]][VOIGHT[ii][1]] += 0.005 * strain strainmtx[VOIGHT[ii][1]][VOIGHT[ii][0]] += 0.005 * strain if geometry.latvecs is not None: geometry.latvecs = np.dot(geometry.latvecs, strainmtx) geometry.coords = np.dot(geometry.coords, strainmtx) if args.output: if args.output == "-": outfile = sys.stdout else: outfile = args.output else: if infile.endswith(".gen"): outfile = infile else: outfile = infile + ".gen" gen = Gen(geometry, fractional=gen.fractional) gen.tofile(outfile)
def straingen(infile, strain, options): '''Strains a geometry from a gen file. Args: infile: File containing the gen-formatted geometry strain: Strain to apply options: Options (e.g. as returned by the command line parser) ''' gen = Gen.fromfile(infile) geometry = gen.geometry strainmtx = np.zeros((3, 3), dtype=float) for jj in range(3): strainmtx[jj][jj] = 1.0 components = LABELS[options.component.lower()] for ii in components: strainmtx[VOIGHT[ii][0]][VOIGHT[ii][1]] += 0.005 * strain strainmtx[VOIGHT[ii][1]][VOIGHT[ii][0]] += 0.005 * strain if geometry.latvecs is not None: geometry.latvecs = np.dot(geometry.latvecs, strainmtx) geometry.coords = np.dot(geometry.coords, strainmtx) if options.output: if options.output == "-": outfile = sys.stdout else: outfile = options.output else: if infile.endswith(".gen"): outfile = infile else: outfile = infile + ".gen" gen = Gen(geometry, fractional=gen.fractional) gen.tofile(outfile)
def test_interaction(filename, i_contacts, r_interactions, principle_layers): '''Tests if every principle layer only interacts with adjacent layers. Also checks that contacts only interact with one layer. Does not check if contacts are interacting.''' geo = Gen.fromfile(filename).geometry interaction_mtrx = _create_interaction_mtrx(r_interactions) test_passed = True # Check layers print('Starting interaction test:') for layer_index, layer in enumerate(principle_layers): interacting_layers = set() for currentlayeratom in layer: for otherlayer_index, otherlayer in enumerate(principle_layers): for otheratom in otherlayer: distance = np.linalg.norm(geo.coords[otheratom] - geo.coords[currentlayeratom]) species = (geo.indexes[currentlayeratom], geo.indexes[otheratom]) if distance <= interaction_mtrx[species[0]][species[1]]: interacting_layers.add(otherlayer_index) if (min(interacting_layers) < layer_index - 1 or max(interacting_layers) > layer_index + 1): shifted_layers = {elem + 1 for elem in interacting_layers} print('Principle layers were not sorted right! Atom ' + str(currentlayeratom + 1) + ' in layer ' + str(layer_index + 1) + ' might be interacting with non adjacent layer: ' + str(shifted_layers)) test_passed = False # Checks if every contact only interacts with one layer i_contacts.append(geo.natom) for contact in range(len(i_contacts) - 1): contactatoms = set(range(i_contacts[contact], i_contacts[contact + 1])) interacting_layers = set() for atom in contactatoms: for layerindex, layer in enumerate(principle_layers): for layeratom in layer: distance = np.linalg.norm(geo.coords[atom] - geo.coords[layeratom]) species = (geo.indexes[atom], geo.indexes[layeratom]) if distance <= interaction_mtrx[species[0]][species[1]]: interacting_layers.add(layerindex) if len(interacting_layers) > 1: shifted_layers = {elem + 1 for elem in interacting_layers} print('Principle layers were not sorted right! Atom ' + str(atom + 1) + ' in contact ' + str(contact + 1) + ' is interacting with more than one layer: ' + str(shifted_layers)) test_passed = False if test_passed: print('Principle layers passed interaction test') return test_passed
def repeatgen(args): '''Repeats geometry from gen files. Args: args: Namespace of command line arguments ''' infile = args.infile repeats = [args.n1, args.n2, args.n3] try: gen = Gen.fromfile(infile) except OSError: raise ScriptError('You must enter a valid path to the input file.') geo = gen.geometry latvecs = geo.latvecs if args.latticefile: latvecs = np.fromfile(args.latticefile, sep=' ') if len(latvecs) != 9: msg = ('Invalid number of lattice vector components in ' + args.latticefile) raise ScriptError(msg) latvecs.shape = (3, 3) if latvecs is None: msg = 'No lattice vectors found (neither in gen nor in external file)' raise ScriptError(msg) if args.phonons: newgeo = _repeatgeo2(geo, latvecs, repeats) else: newgeo = _repeatgeo(geo, latvecs, repeats) newgen = Gen(newgeo, gen.fractional) outfile = args.output if outfile == '-': outfile = sys.stdout newgen.tofile(outfile)
def partition(filename, i_contacts, r_interactions, maxiterations): '''Creates principle layers. Atom indexes starting with 0. Algorithm first creates chains starting from every contact. Each chain element is called a bin and every bin only interacts with adjacent bins or contacts (Not a principle layer yet). Chains (and also dead ends) are merged until only two chains are left. Those two chains will be resorted to create the principle layers.''' bin_index = 0 geo = Gen.fromfile(filename).geometry interaction_mtrx = _create_interaction_mtrx(r_interactions) allchains = _create_starting_chains(i_contacts, geo.natom) unsorted_atoms = set(range(min(i_contacts))) print('Starting to create chains from every contact:') while unsorted_atoms: if bin_index >= maxiterations: print('Maximum iterations reached:', maxiterations) print('Exiting program') sys.exit() bin_index += 1 _create_next_bins(allchains, unsorted_atoms, geo, interaction_mtrx) chains_merged = False if len(allchains) > 2: chains_merged = _merge_interacting_chains(allchains, geo, interaction_mtrx) print('Bins for iteration', bin_index, 'created. Chains merged:', chains_merged) if (len(allchains) == 2 and _chains_interact( allchains[0], allchains[1], geo, interaction_mtrx)): if len(allchains[1]) > 1 and _bins_interact( allchains[0][-1], allchains[1][-2], geo, interaction_mtrx): allchains[0][-1] = allchains[0][-1].union(allchains[1][-1]) del allchains[1][-1] print('Merged last bin of chain1 and chain2') if unsorted_atoms: _sort_remaining(allchains, unsorted_atoms, geo, interaction_mtrx) print('Sorted remaining atoms') print('All atoms sorted') principle_layers = _create_finalchain(allchains) print('Principle layers created (Last two chains combined)') return principle_layers