Beispiel #1
0
def generate_periodic_zgnr(
    width_n: int,
    bond_dist: float = DEFAULT_CC_DIST,
    vacuum_sep: float = 15,
    hydrogen: bool = True,
):
    assert width_n > 0
    # the way we count is a bit off, so subtract one here to fix it
    width_n -= 1

    # put vacuum separation in terms of the bond distance
    vacuum_sep /= bond_dist

    cell = zgnr_unit_cell(vacuum_sep=vacuum_sep)
    cell.make_supercell([1, width_n // 2 + 1, 1])
    if width_n % 2 == 0:
        # need to remove the two topmost atoms
        cell.remove_sites(np.argsort(cell.cart_coords[:, 1])[-2:])

    # add vacuum separation
    cell = add_vacuum_sep(cell, vy=vacuum_sep, vz=vacuum_sep)
    # center new structure
    cell = center_structure(cell)
    if hydrogen:
        add_hydrogen(cell, cutoff=1.05, dist=DEFAULT_CH_DIST / DEFAULT_CC_DIST)

    # scale to bond distances
    return Structure(
        lattice=Lattice(matrix=cell.lattice.matrix * bond_dist),
        species=cell.species,
        coords=cell.frac_coords,
    )
Beispiel #2
0
def generate_periodic_agnr(
    width_n: int,
    bond_dist: float = DEFAULT_CC_DIST,
    vacuum_sep: float = 15,
    hydrogen: bool = True,
):
    assert width_n >= 2

    # put vacuum separation in terms of the bond distance
    vacuum_sep /= bond_dist

    cell = agnr_unit_cell(vacuum_sep=vacuum_sep)
    if width_n % 2 == 0:
        cell.make_supercell([1, width_n // 2, 1])
    else:
        cell.make_supercell([1, width_n // 2 + 1, 1])
        # need to remove the two topmost atoms
        cell.remove_sites(np.argsort(cell.cart_coords[:, 1])[-2:])

    # add vacuum separation
    cell = add_vacuum_sep(cell, vy=vacuum_sep, vz=vacuum_sep)
    # center new structure
    cell = center_structure(cell)
    if hydrogen:
        add_hydrogen(cell, cutoff=1.05, dist=DEFAULT_CH_DIST / DEFAULT_CC_DIST)

    # scale to bond distances
    cell.lattice = Lattice(matrix=cell.lattice.matrix * bond_dist)
    return cell
Beispiel #3
0
def _generate_finite_agnr_from_periodic(
    periodic_gnr: Structure,
    length_m: int,
    bond_dist: float,
    vacuum_sep: float,
    hydrogen: bool,
):
    assert length_m >= 2
    cell = periodic_gnr

    if length_m % 2 == 0:
        cell.make_supercell([length_m // 2, 1, 1])
    else:
        num_to_remove = cell.num_sites // 2
        cell.make_supercell([length_m // 2 + 1, 1, 1])
        # remove rightmost atoms
        to_remove = np.argsort(cell.cart_coords[:, 0])[-num_to_remove:]
        cell.remove_sites(to_remove)

    # put vacuum separation in terms of the bond distance
    vacuum_sep /= bond_dist
    cell = add_vacuum_sep(cell, vx=vacuum_sep, vy=vacuum_sep, vz=vacuum_sep)
    # center new structure
    cell = center_structure(cell)

    # kill off any lone carbons or those with only 1 bond
    n_bonds = np.array([len(b) for b in calculate_bond_list(cell, cutoff=1.1)])
    cell.remove_sites(np.where(n_bonds <= 1)[0])

    if hydrogen:
        add_hydrogen(cell, cutoff=1.05, dist=DEFAULT_CH_DIST / DEFAULT_CC_DIST)

    # scale to bond distances
    cell.lattice = Lattice(matrix=cell.lattice.matrix * bond_dist)
    return cell
Beispiel #4
0
def run_gnr(args):
    if not args["periodic"] and not args["length"]:
        print("missing --length argument for finite gnr", file=sys.stderr)
        sys.exit(1)
    elif args["periodic"]:
        if args["zigzag"]:
            name = "z"
            func = generate_periodic_zgnr
        else:
            name = "a"
            func = generate_periodic_agnr

        if not args["output"]:
            args["output"] = f"periodic-{name}gnr-{args['width']}.vasp"

        os.chdir('output')

        gnr = func(args["width"], hydrogen=not args["no_hydrogen"])
        if args["length"]:
            gnr.make_supercell([args["length"], 1, 1])

        #For edge structures
        start = time.time()
        if args["zigzag"]:
            edge_combinations = zgnr_edge_types(gnr)
        else:
            edge_combinations = agnr_edge_types(gnr)
        print(len(edge_combinations))
        print(time.time() - start)

        for i, cell in enumerate(edge_combinations):
            add_hydrogen(cell,
                         cutoff=1.05,
                         dist=DEFAULT_CH_DIST / DEFAULT_CC_DIST)
            cell.lattice = Lattice(matrix=cell.lattice.matrix *
                                   DEFAULT_CC_DIST)
            cell.to(filename=
                    f"periodic-{name}gnr-w{args['width']}xl{args['length']}-" +
                    str(i) + ".vasp",
                    fmt="poscar")

        # gnr.to(filename=args["output"], fmt="poscar")
    else:
        if args["zigzag"]:
            print("only periodic zigzag GNR generation is supported",
                  file=sys.stderr)
            sys.exit(1)

        if not args["output"]:
            args[
                "output"] = f"finite-gnr-{args['width']}x{args['length']}.vasp"

        gnr = generate_finite_agnr(args["width"],
                                   args["length"],
                                   hydrogen=not args["no_hydrogen"])
        gnr.to(filename=args["output"], fmt="poscar")
Beispiel #5
0
 def process_structure(s: Structure):
     # kill off any lone carbons or those with only 1 bond
     from pyputil.structure.bonds import calculate_bond_list
     n_bonds = np.array([len(b) for b in calculate_bond_list(s)])
     s.remove_sites(np.where(n_bonds <= 1)[0])
     # add hydrogen atoms on the edges
     add_hydrogen(s, cutoff=1.05, dist=DEFAULT_CH_DIST / DEFAULT_CC_DIST)
     # scale coordinates to bond distance
     s.lattice = Lattice(matrix=s.lattice.matrix * bond_dist)
     return s