예제 #1
0
def parse_inputs(name="config"):
    """Convert the string values of the diciontary to the appropriate types"""

    inputs = complete_config(name)

    inputs["bond_thresh"] = float(inputs["bond_thresh"])
    if type(inputs["atom_label"]) == str:
        inputs["atom_label"] = [int(inputs["atom_label"]) - 1]
    else:
        inputs["atom_label"] = [int(i) - 1 for i in inputs["atom_label"]]
    inputs["ewald"] = bool_cast(inputs["ewald"])
    inputs["nchk"] = int(inputs["nchk"])
    inputs["nat"] = int(inputs["nat"])
    inputs["an"] = int(inputs["an"])
    inputs["bn"] = int(inputs["bn"])
    inputs["cn"] = int(inputs["cn"])
    inputs["clust_rad"] = float(inputs["clust_rad"])
    inputs["traan"] = int(inputs["traan"])
    inputs["trabn"] = int(inputs["trabn"])
    inputs["tracn"] = int(inputs["tracn"])
    inputs["self_consistent"] = bool_cast(inputs["self_consistent"])
    inputs["dev_tol"] = float(inputs["dev_tol"])
    inputs["a_vec"] = np.array([float(i) for i in inputs["a_vec"]])
    inputs["b_vec"] = np.array([float(i) for i in inputs["b_vec"]])
    inputs["c_vec"] = np.array([float(i) for i in inputs["c_vec"]])
    inputs["damping"] = float(inputs["damping"])
    inputs["print_tweak"] = bool_cast(inputs["print_tweak"])
    # specified in config
    inputs["vectors"] = np.zeros((3, 3))
    if all(
            len(i) == 3
            for i in [inputs["a_vec"], inputs["b_vec"], inputs["c_vec"]]):
        a_vec = inputs["a_vec"]
        b_vec = inputs["b_vec"]
        c_vec = inputs["c_vec"]
        inputs["vectors"][0] = a_vec
        inputs["vectors"][1] = b_vec
        inputs["vectors"][2] = c_vec
    else:  # from external file
        inputs["vectors"] = rf.read_vectors(inputs["vectors_file"])

    return inputs
예제 #2
0
def main(args):
    # read input file
    all_atoms = fro.mol_from_file(args.input)
    # specify bonding
    all_atoms.set_bonding(bonding=args.bonding, thresh=args.thresh)
    # if the bonding is specified all in one string
    if args.bonding_string:
        all_atoms.set_bonding_str(args.bonding_string)

    # if periodic
    if args.vectors:
        prints("Vectors detected")
        vectors = rf.read_vectors(args.vectors)
        all_atoms.vectors = vectors
        # if we are forbidding some atoms
        if args.no_atom_label:
            forbidden_kinds = []
            # for each atom to forbid
            for label in args.no_atom_label:
                mol_of_interest = all_atoms.per_select(label - 1)
                mol_of_interest.set_connectivity()
                for atom in mol_of_interest:
                    if atom == all_atoms[label - 1]:
                        forbidden_kinds.append(atom.kind)
        all_atoms, molecules = all_atoms.complete_cell()
        prints("{} molecules detected after reconstitution".format(
            len(molecules)))
    else:
        # if we are forbidding some atoms
        if args.no_atom_label:
            forbidden_kinds = []
            # for each atom to forbid
            for label in args.no_atom_label:
                mol_of_interest = all_atoms.select(label - 1)
                mol_of_interest.set_connectivity()
                for atom in mol_of_interest:
                    if atom == all_atoms[label - 1]:
                        forbidden_kinds.append(atom.kind)
        # separate into molecules
        molecules = all_atoms.segregate(diff_mols=False)
        prints("{} molecules detected".format(len(molecules)))

    # ignore hydrogens
    if args.no_hydrogens:
        for mol in molecules:
            mol.geom.ignore_hydrogens = True

    # ignore certain atoms
    if args.no_atom_label:
        zero_vectors = np.array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
        for mol in molecules:
            mol.vectors = zero_vectors
            mol.set_connectivity()
            mol.geom.ignore_kinds = forbidden_kinds

    # get dimers
    dimers_raw = all_dimers(molecules)
    prints("{} dimers in the input geometry".format(len(dimers_raw)))

    # if periodic
    if args.vectors:
        # get all the dimers generated by extra periodic images
        dimers_per = []
        for dimer in dimers_raw:
            images = dimer.images(vectors)
            dimers_per.extend(images)
        dimers_raw = dimers_per
        prints("{} dimers considering periodicity".format(len(dimers_raw)))

    if args.linear:
        for dimer in dimers_raw:
            dimer.mols_are_linear()
    # filter out dimers
    if args.dimtype == 'centroid':
        method = 'centroid'
        mode = 'dis'
    else:
        method = 'atomic'
    if args.dimtype == 'dis':
        mode = 'dis'
    elif args.dimtype == 'cov':
        mode = 'cov'
    elif args.dimtype == 'vdw':
        mode = 'vdw'

    selected_dimers = []
    for dimer in dimers_raw:
        if dimer.inter_distance(method=method, mode=mode) <= args.dist:
            selected_dimers.append(dimer)
    prints("{} dimers selected from distance criterion".format(
        len(selected_dimers)))

    # remove repeated dimers
    keep_these = []
    for i, dimer_i in enumerate(selected_dimers[:-1]):
        keep = True
        for dimer_j in selected_dimers[i + 1:]:
            if dimer_i.same_geom(dimer_j, tol=args.tol_duplicate):
                keep = False
                break
        if keep:
            keep_these.append(dimer_i)
    # don't forget that the last one was not included in the parent loop
    keep_these.append(selected_dimers[-1])
    selected_dimers = keep_these
    prints("{} dimers remaining after removing duplicates".format(
        len(selected_dimers)))

    if args.output_geometry_data:
        data_file = open(args.output_geometry_data, "w")
        header_str = "{:>13}{:>10}{:>10}{:>10}{:>17}{:>13}{:>11}\n".format(
            "Dimer number", "Alpha", "Beta", "Gamma", "Centroid dist",
            "Slip angle", "Category")
        data_file.write(header_str)
    for i, dimer in enumerate(selected_dimers):

        if args.output_geometry_data:
            cen_dist = dimer.inter_distance(method='centroid')
            angles = dimer.angles()
            slip_angle = dimer.slip_angle()
            # classify
            if 20 < angles[2] < 160:
                category = "E-F"
            elif slip_angle > 60:
                category = "S-S"
            else:
                category = "F-F"
            data_file.write(
                "{:>7}{:17.3f}{:10.3f}{:10.3f}{:12.3f}{:15.3f}{:>10}\n".format(
                    i + 1, angles[0], angles[1], angles[2], cen_dist,
                    slip_angle, category))
        if args.print_dimers:
            out_name = str(args.input[:-4]) + "_dimer_" + str(i + 1) + ".xyz"
            dimer.write_xyz(out_name)
    if args.output_geometry_data:
        data_file.close()
예제 #3
0
def pery_cell():
    """Return a Mol object of the uncharged perylene cell"""
    out_cell = rf.mol_from_file("perylene_cell.xyz")
    out_cell.vectors = rf.read_vectors("perylene_vectors")
    return out_cell
예제 #4
0
def main(in_xyz, vectors_file, complete, confine, frac, dupli, output, bonding,
         thresh, bonding_str, print_mono, trans, clust_rad, inclusivity,
         center_label):
    vectors = rf.read_vectors(vectors_file)
    atoms = rf.mol_from_file(in_xyz, vectors=vectors)

    if thresh == 999:
        thresh = None
    atoms.set_bonding(bonding=bonding, thresh=thresh)
    # if the bonding is specified all in one string
    if bonding_str:
        atoms.set_bonding_str(bonding_str)

    if print_mono and not complete:
        print("-c is required for -m")
        return

    if sum([complete, confine, frac]) > 1:
        print("-c, -C and -f are mutually exclusive")
        return

    print_now = True
    centered = False
    if center_label:
        central_mol, atoms = atoms.centered_mols(center_label -
                                                 1)  # -1 for Python index
        centered = True
    if complete:
        # get the modified (uncropped) unit cell
        mod_cell, mols = atoms.complete_cell()
    elif confine:
        # get the cell confined to primitive
        mod_cell = atoms.confined()
    elif frac:
        # get the cell in fractional coordinates
        mod_cell = atoms.dir_to_frac_pos()
    elif centered:
        mod_cell = atoms.copy()
    else:
        mod_cell = deepcopy(atoms)
        print_now = False

    if dupli:
        # purge duplicate atoms
        mod_cell.remove_duplicates()
        print_now = True

    if print_now:
        mod_cell.write_xyz(output)

    if trans:
        translation = np.array(trans)
        new_atoms = mod_cell.supercell(translation)
        new_vec = (vectors.T * translation.transpose()).T
        new_atoms.write_xyz("supercell_out.xyz")
        ef.write_lat_vec("supercell_vectors", new_vec)

    if clust_rad > 0.0:
        clust = atoms.make_cluster(clust_rad, mode=inclusivity)
        clust.write_xyz("cluster_out.xyz")

    if print_mono:
        identities = []
        # for each molecule of the modified unit cell
        for mol_i in mols:
            # get the rest of the molecules
            rest = []
            for mol_j in mols:
                if mol_j != mol_i:
                    rest.append(mol_j)
            identity = []
            # for each dimer including the selected molecule
            for mol_j in rest:
                dimer_distances = []
                # get all of the interatomic distances across the dimer using the
                # shortest lattice distance
                for at_i in mol_i:
                    for at_j in mol_j:
                        dimer_distances.append(at_i.per_dist(at_j, vectors))
                        dimer_distances.sort()
                identity.append(dimer_distances)
                identity.sort()
            identities.append(identity)
        identities = np.array(identities)

        # list of each molecules paired with its identity
        # in Python 2 we could just use a zip but for compatibility with Python3
        # we need a list of tuples
        mols_ids = [(mol_i, iden_i) for mol_i, iden_i in zip(mols, identities)]

        # list of each molecule paired with its identity separated by equivalent
        # molecule
        sep_mols_ids = []
        while len(mols_ids) > 0:
            sep_mol_id = [mols_ids[0]]
            for mol_i, id_i in mols_ids[1:]:
                comp = compare_id(mols_ids[0][1], id_i)
                # if the identities being compared don't have the same dimension,
                # the comparison will return None. This implies that the molecules
                # are not equivalent. This case only happens in crystals with
                # different monomers
                if comp:
                    if comp < 0.001:
                        sep_mol_id.append((mol_i, id_i))
                        mols_ids.remove((mol_i, id_i))
            del mols_ids[0]
            sep_mols_ids.append(sep_mol_id)

        for counter, equimols in enumerate(sep_mols_ids):
            # only the list of lists of atoms i.e. list of molecules which are
            # equivalent
            fequimols = [i[0] for i in equimols]
            # make it a flat list
            fequimols = [inner for outer in fequimols for inner in outer]
            ef.write_xyz("mono_" + str(counter + 1) + ".xyz", fequimols)
    return