Example #1
0
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 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)
Example #3
0
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)
Example #4
0
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()
Example #5
0
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
Example #6
0
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)
Example #7
0
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
Example #8
0
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)
Example #9
0
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)