Ejemplo n.º 1
0
def check_configs(structure_lmpdat, gas_lmpdat, verbose):
    atoms = Atoms.from_lammps_data(structure_lmpdat, use_comment_for_type_labels=True)
    gas_atoms = Atoms.from_lammps_data(gas_lmpdat, use_comment_for_type_labels=True)
    # check for charges
    num_zero_charges = np.count_nonzero(atoms.charges == 0.0)
    if num_zero_charges > 0:
        print("WARNING: %d/%d atoms in structure have 0 charges" % (num_zero_charges, len(atoms.charges)))

    num_zero_charges = np.count_nonzero(gas_atoms.charges == 0.0)
    if num_zero_charges > 0:
        print("WARNING: %d/%d atoms in gas have 0 charges" % (num_zero_charges, len(gas_atoms.charges)))

    # check for overlapped atom positions
    atoms.extend(gas_atoms)
    s_ss = distance.cdist(atoms.positions, atoms.positions, "sqeuclidean")
    min_dist_sq = s_ss[np.triu_indices_from(s_ss, k=1)].min()
    min_dist_indices = list(zip(*np.where(s_ss == min_dist_sq)))
    min_dist = min_dist_sq ** 0.5
    if verbose:
        print("min distance between atoms: %6.4f" % min_dist)

    if verbose:
        zero_indices = [(i1,i2) for i1, i2 in np.argwhere(s_ss < 0.1) if i1 < i2]
        for i1, i2 in zero_indices:
            print("WARNING: some atoms look like they are overlapped: %d %d (%s-%s) dist=%6.4f" %
                (i1+1, i2+1, atoms.elements[i1], atoms.elements[i2], s_ss[i1,i2] ** 0.5))
Ejemplo n.º 2
0
def checkdumpfile(lmpdatpath, dumppath, warns=True, verbose=False):
    atoms = Atoms.from_lammps_data(open(lmpdatpath, "r"),
                                   use_comment_for_type_labels=True)
    dumpatoms = ase.io.read(dumppath, format="lammps-dump-text")
    assert len(dumpatoms.positions) == len(atoms.positions)
    atoms.positions = dumpatoms.positions

    # check for overlapped atom positions
    s_ss = distance.cdist(atoms.positions, atoms.positions, "sqeuclidean")
    min_dist_sq = s_ss[np.triu_indices_from(s_ss, k=1)].min()
    min_dist_indices = list(zip(*np.where(s_ss == min_dist_sq)))
    min_dist = min_dist_sq**0.5
    if verbose:
        print("min distance between atoms: %6.4f" % min_dist)

    if verbose:
        zero_indices = [(i1, i2) for i1, i2 in np.argwhere(s_ss < 0.1)
                        if i1 < i2]
        for i1, i2 in zero_indices:
            print(
                "WARNING: some atoms look like they are overlapped: %d %d (%s-%s) dist=%6.4f"
                % (i1 + 1, i2 + 1, atoms.elements[i1], atoms.elements[i2],
                   s_ss[i1, i2]**0.5))

    # check for bond distances
    dumpatoms.set_pbc(True)
    bonddists = np.array(
        [dumpatoms.get_distance(b1, b2, mic=True) for b1, b2 in atoms.bonds])
    bonds_half_uc = (bonddists > dumpatoms.cell.lengths().min() / 2).any()
    if verbose:
        if bonds_half_uc:
            print(
                "WARNING: some bonds appear to have lengths > 1/2 the smallest UC dimension."
            )
            print(bonddists)
        else:
            print(
                "INFO: all bonds have lengths < 1/2 the smallest UC dimension."
            )
            print("maximum bond length is %.2f Å" % max(bonddists))
            print("min bond length is %.2f Å" % min(bonddists))
    else:
        if len(min_dist_indices) > 0:
            min_dist_indices_s = "(%4d %4d %2s - %-2s)" % (
                min_dist_indices[0][0] + 1, min_dist_indices[0][1] + 1,
                atoms.elements[min_dist_indices[0][0]],
                atoms.elements[min_dist_indices[0][1]])
        else:
            min_dist_indices_s = "(---- ----)"

        print("min_dist: %.2f %s; bonds: %.2f-%.2f" %
              (min_dist, min_dist_indices_s, min(bonddists), max(bonddists)),
              end='')
        if warns:
            if bonds_half_uc:
                print("; WARN: bonds > 1/2 UC", end='')
            if min_dist < 0.92 and min_dist < min(bonddists) - 1e-2:
                print("; WARN: atoms closer than shortest bond", end='')
def updatelmpdatpositions(lmpdatpath, dumppath, outputfile):
    atoms = Atoms.from_lammps_data(open(lmpdatpath, "r"), use_comment_for_type_labels=True)

    # update positions in original atoms file with new positions
    dumpatoms = ase.io.read(dumppath, format="lammps-dump-text")
    assert len(dumpatoms.positions) == len(atoms.positions)
    atoms.positions = dumpatoms.positions

    atoms.to_lammps_data(outputfile)
Ejemplo n.º 4
0
def packmol_gaslmpdat(structure_lmpdat, structure_xyz, gas_lmpdat, gas_xyz, num_molecules=1):
    """ packs gas into structure using packmol and converts the result into a LAMMPS lmpdat file.

    The resulting lmpdat file has only the gas molecules in it, according to the geometry and coeffs
    of the gas_lmpdat file. Note that it is redundant to have both an XYZ file input and LAMMPS
    file input but we have it this way because this method is used in large-scale screenings and
    both these files are generated at the beginning of the run.

    Args:
        structure_lmpdat: lmpdat file of structure; this is used to get the unit cell for packmol.
        structure_xyz: Path to xyz file of structure to pack the gas into.
        gas_lmpdat: lmpdat file with geometry and coeffs for gas we are packing.
        gas_xyz: xyz file of gas corresponding to the the gas_lmpdat. Atoms must be in the same order!
        num_molecules (int): number of gas molecules to pack into structure.

    """
    gas_name = Path(gas_lmpdat).stem
    structure_name = Path(structure_xyz).stem

    satoms = Atoms.from_lammps_data(structure_lmpdat, use_comment_for_type_labels=True)

    output_gas_xyz = "%s_%s_packed.xyz" % (structure_name, gas_name)
    packmol_input = packmol_config(structure_xyz, gas_xyz, output_gas_xyz, num_molecules=num_molecules,
        boundary_tolerance=1.5, a2a_tolerance=1.5, supercell=[*np.diag(satoms.cell), 90, 90, 90])

    with open("packmol.input", 'w') as f:
        f.write(packmol_input)
    subprocess.run("/Users/pboone/workspace/_prereqs/packmol/packmol < packmol.input", shell=True, check=True)
    gas_data = np.array(extract_gas_atoms_from_packmol_xyz(output_gas_xyz))

    # update the dummy positions in the template gas lmpdat file with real positions from packmol
    # and save in the current directory. Note that this should NOT overwrite the template, since you
    # should be in a different directory at this point.
    atoms = Atoms.from_lammps_data(open(gas_lmpdat,'r'), use_comment_for_type_labels=True)
    atoms.positions = np.array(gas_data[:, 1:], dtype=float)
    atoms.atom_types = np.tile(atoms.atom_types, num_molecules)
    atoms.charges = np.tile(atoms.charges, num_molecules)
    atoms.atom_groups = np.repeat(np.arange(num_molecules), len(gas_data) / num_molecules)
    atoms.cell = satoms.cell

    atoms.to_lammps_data(open("%s.lmpdat" % gas_name, 'w'))
    Path("tmp").mkdir(exist_ok=True)
    Path("packmol.input").rename("tmp/packmol.input")
    Path(output_gas_xyz).rename(Path("tmp/") / output_gas_xyz)
Ejemplo n.º 5
0
def lmpdat2cif(lmpdatpath, dumppath=None, outpath=None, framework_element=None):
    atoms = Atoms.from_lammps_data(open(lmpdatpath, "r"), use_comment_for_type_labels=True)
    if dumppath is not None:
        # update positions in original atoms file with new positions
        dumpatoms = ase.io.read(dumppath, format="lammps-dump-text")
        assert len(dumpatoms.positions) == len(atoms.positions)
        atoms.positions = dumpatoms.positions

    aseatoms = atoms.to_ase()
    if framework_element is not None:
        aseatoms.symbols[atoms.atom_groups == 0] = framework_element

    aseatoms.set_pbc(True)
    if outpath is None:
        aseatoms.write('-', format="cif")
    else:
        aseatoms.write(outpath)
Ejemplo n.º 6
0
def functionalize_structure_with_linkers(structure_path,
                                         linker_path,
                                         fnlinkers,
                                         output_dir=Path()):
    linker = Atoms.from_cml(Path(linker_path))
    structure = Atoms.from_cif(structure_path)
    output_dir = Path(output_dir)
    assign_pair_params_to_structure(structure)
    for fnlinker_path in fnlinkers:
        print("reading %s" % fnlinker_path)
        fnlinker = Atoms.from_lammps_data(open(fnlinker_path, "r"),
                                          use_comment_for_type_labels=True)
        try:
            new_structure = replace_pattern_in_structure(
                structure, linker, fnlinker)
            with open(
                    output_dir.joinpath(Path(fnlinker_path).stem + ".lmpdat"),
                    "w") as fd:
                new_structure.to_lammps_data(fd)
        except Exception as e:
            print("ERROR! ", e.args)