Beispiel #1
0
    def bindCN(self,
               site_index,
               molecule,
               v,
               CN_bond_length=1.16,
               catC_bond_length=1.49):
        """
        input:
            molecule: (molSimplify mol class) molecule to modify in-place with O2
            v: (np.array) coordinates to displace first O
        output:
            molecule modified with functional group OH
        """

        site_coords = molecule.atoms[site_index].coords()
        v_C = self.scale_vector(v, catC_bond_length)
        v_N = self.scale_vector(v, catC_bond_length + CN_bond_length)
        site_coords = molecule.atoms[site_index].coords()

        molecule.addAtom(
            mol3D.atom3D(
                Sym='C',
                xyz=[site_coords[c] + v_C[c]
                     for c in range(len(site_coords))]))
        molecule.addAtom(
            mol3D.atom3D(
                Sym='N',
                xyz=[site_coords[c] + v_N[c]
                     for c in range(len(site_coords))]))
        #structgen.ffopt('MMFF94', molecule, [], 1, [], False, [], 200, False) # keeps failing
        return molecule
Beispiel #2
0
    def bindO2H(self,
                site_index,
                molecule,
                v,
                bond_angle=111.,
                OO_bond_length=1.32,
                catO_bond_length=1.55):
        """
        input:
            molecule: (molSimplify mol class) molecule to modify in-place with O2
            v: (np.array) coordinates to displace first O
        output:
            molecule modified with functional group O2H
        """

        site_coords = molecule.atoms[site_index].coords()
        v_O1 = self.scale_vector(v, catO_bond_length)
        v_O2 = self.scale_vector(
            v, catO_bond_length +
            OO_bond_length * math.cos(math.pi - math.radians(bond_angle)))
        v_H = self.scale_vector(v, self.OH_bond_length)
        theta_0 = 0  # arbitrarily chosen
        v_perp = self.vec3_perp(
            self.scale_vector(
                v,
                self.OO_bond_length *
                math.sin(math.pi - math.radians(bond_angle))), theta_0)
        if v_perp == None:  # shouldn't happen
            return None
        site_coords = molecule.atoms[site_index].coords()

        molecule.addAtom(
            mol3D.atom3D(Sym='O',
                         xyz=[
                             site_coords[c] + v_O1[c]
                             for c in range(len(site_coords))
                         ]))
        molecule.addAtom(
            mol3D.atom3D(Sym='O',
                         xyz=[
                             site_coords[c] + v_O2[c] + v_perp[c]
                             for c in range(len(site_coords))
                         ]))
        molecule.addAtom(
            mol3D.atom3D(Sym='H',
                         xyz=[
                             site_coords[c] + v_O2[c] + (v_perp[c] + v_H[c])
                             for c in range(len(site_coords))
                         ]))
        #structgen.ffopt('MMFF94', molecule, [], 1, [], False, [], 200, False) # keeps failing
        return molecule
Beispiel #3
0
def bind_OOH(infile, molecule, site_index, catO_bond_length, catOO_bond_angle,
             OO_bond_length, OH_bond_length):
    molecule_copy = mol3D.mol3D()
    molecule_copy.copymol3D(molecule)

    v = get_normal_vec(molecule_copy, site_index)
    v_O1 = scale_vector(v, catO_bond_length)
    v_O2 = scale_vector(
        v, catO_bond_length +
        OO_bond_length * math.cos(math.pi - math.radians(catOO_bond_angle)))
    theta_0 = 0
    v_perp = vec3_perp(
        scale_vector(
            v,
            OO_bond_length *
            math.sin(math.pi - math.radians(catOO_bond_angle))), theta_0)
    if v_perp == None:  # shouldn't happen
        return None
    v_H = scale_vector(v, OH_bond_length)

    site_coords = molecule_copy.atoms[site_index].coords()

    molecule_copy.addAtom(
        mol3D.atom3D(
            Sym='O',
            xyz=[site_coords[c] + v_O1[c] for c in range(len(site_coords))]))
    molecule_copy.addAtom(
        mol3D.atom3D(Sym='O',
                     xyz=[
                         site_coords[c] + v_O2[c] + v_perp[c]
                         for c in range(len(site_coords))
                     ]))
    molecule_copy.addAtom(
        mol3D.atom3D(Sym='H',
                     xyz=[
                         site_coords[c] + v_O2[c] + v_perp[c] + v_H[c]
                         for c in range(len(site_coords))
                     ]))

    file_name = infile.split('.')[0] + "OOH"
    if not is_metal_catalyst:  # metal catalysts assumed to have one active site
        file_name += "-" + str(site_index)  # still zero-indexed
    molecule_copy.writexyz(file_name)
Beispiel #4
0
def bind_O(infile, molecule, site_index, catO_bond_length):
    molecule_copy = mol3D.mol3D()
    molecule_copy.copymol3D(molecule)

    v = get_normal_vec(molecule_copy, site_index)
    v_O = scale_vector(v, catO_bond_length)

    site_coords = molecule_copy.atoms[site_index].coords()

    molecule_copy.addAtom(
        mol3D.atom3D(
            Sym='O',
            xyz=[site_coords[c] + v_O[c] for c in range(len(site_coords))]))

    file_name = infile.split('.')[0] + "O"
    if not is_metal_catalyst:  # metal catalysts assumed to have one active site
        file_name += "-" + str(site_index)  # still zero-indexed
    molecule_copy.writexyz(file_name)
 oxo = mymol.getAtom(-1)
 oxo_coord = oxo.coords()
 metal_coord = mymol.getAtom(metalval[0]).coords()
 bond1_coord = mymol.getAtom(bondedatoms[0]).coords()
 bond2_coord = mymol.getAtom(bondedatoms[1]).coords()
 oxo, dxyz = setPdistance(oxo, oxo_coord, metal_coord, 1.84)
 metaloxo = np.array(oxo_coord) - np.array(metal_coord)
 extra = getPointu(oxo_coord, 1.2, metaloxo)
 moveup = np.array(extra) - metal_coord
 val = midpt(bond1_coord, bond2_coord)
 movevect = np.array(
     normalize(
         np.array(val) + moveup -
         np.array(oxo_coord))) + oxo_coord
 p = list(movevect)
 newH = atom3D('H', p)
 mymol.addAtom(newH)
 hydrogen = mymol.getAtom(-1)
 hydrogen, dxyz = setPdistance(hydrogen, hydrogen.coords(),
                               oxo.coords(), 1)
 if not dry_run:
     if not os.path.exists(
             path_dictionary["initial_geo_path"] + modgeo1
     ) and (upperspin
            in metal_spin_dictionary[metal][hydroxyl_ox]):
         mymol.writexyz(
             path_dictionary["initial_geo_path"] + modgeo1)
     elif (upperspin not in metal_spin_dictionary[metal]
           [hydroxyl_ox]):
         print((str(upperspin) +
                ' spin not in dictionary for ' +
Beispiel #6
0
    def bind_O2(self,
                site_index,
                catO_bond_length=1.8,
                bond_angle=120,
                OO_bond_length=1.3,
                reposition_O2=False):
        # binds O2 perpendicular to catalyst plane, then makes .xyz file
        # does not modify input molecule
        # bond lengths in angstroms, angle in degrees. Variables set to parameters for Fe
        molecule_copy = mol3D.mol3D()
        molecule_copy.copymol3D(self.molecule)

        connection_list = molecule_copy.getBondedAtomsSmart(site_index,
                                                            oct=False)
        #print("Active Site: %s       Neighbors: %s" %(str(site_index), str(connection_list))) # for debugging
        try:
            v1 = molecule_copy.atoms[connection_list[0]].distancev(
                molecule_copy.atoms[connection_list[1]])
            v2 = molecule_copy.atoms[connection_list[0]].distancev(
                molecule_copy.atoms[connection_list[2]])
            v = np.cross(v1, v2)
        except:
            print("Error finding plane of catalyst.")
            return None

        v_O1 = self.scale_vector(v, catO_bond_length)
        v_O2 = self.scale_vector(
            v, catO_bond_length +
            OO_bond_length * math.cos(math.pi - math.radians(bond_angle)))
        theta_0 = 0  # arbitrarily chosen
        v_perp = self.vec3_perp(
            self.scale_vector(
                v,
                OO_bond_length * math.sin(math.pi - math.radians(bond_angle))),
            theta_0)
        if v_perp == None:  # shouldn't happen
            return None
        site_coords = molecule_copy.atoms[site_index].coords()

        molecule_copy.addAtom(
            mol3D.atom3D(Sym='O',
                         xyz=[
                             site_coords[c] + v_O1[c]
                             for c in range(len(site_coords))
                         ]))
        molecule_copy.addAtom(
            mol3D.atom3D(Sym='O',
                         xyz=[
                             site_coords[c] + v_O2[c] + v_perp[c]
                             for c in range(len(site_coords))
                         ]))
        #structgen.ffopt('MMFF94', molecule_copy, [], 1, [], False, [], 200, False) # keeps failing

        if reposition_O2:  # workaround for ffopt() failing to set up; nonmetal catalysts
            theta = theta_0 + self.dtheta
            position_OK = False
            while not position_OK:
                position_OK = True
                for atom in molecule_copy.getAtoms():
                    if atom == molecule_copy.getAtoms(
                    )[-1] or atom == molecule_copy.getAtoms()[-2]:
                        continue
                    if atom.symbol() in self.bond_length_cutoffs:
                        cutoff = self.bond_length_cutoffs[atom.symbol()]
                    else:  # won't happen if bond_length_cutoffs is kept up to date
                        cutoff = self.bond_length_cutoffs[max(
                            self.bond_length_cutoffs,
                            key=lambda key: self.bond_length_cutoffs[key])]
                        print("Using %f A as the bond length cutoff for %s" %
                              (cutoff, atom.symbol()))
                    if molecule_copy.getAtoms()[-1].distance(atom) < cutoff:
                        position_OK = False
                        break
                if not position_OK:
                    if theta >= 360:
                        print("%s may have geometry issues after O2-binding." %
                              infile)
                        break
                    v_perp = self.vec3_perp(
                        self.scale_vector(
                            v,
                            OO_bond_length *
                            math.sin(math.pi - math.radians(bond_angle))),
                        theta)
                    if v_perp == None:  # shouldn't happen
                        return None
                    molecule_copy.getAtoms()[-1].setcoords([
                        site_coords[c] + v_O2[c] + v_perp[c]
                        for c in range(len(site_coords))
                    ])
                    theta += self.dtheta

        file_name = self.infile.split('.')[0] + "O2"
        if len(self.active_sites
               ) > 1:  #only add active site in name if more than 1
            file_name += "-" + str(site_index)  # still zero-indexed
        molecule_copy.writexyz(file_name)
Beispiel #7
0
def bind_XY(infile, molecule, site_index, X, Y, catX_bond_length, bond_angle,
            XY_bond_length, reposition_XY, fn_suffix):
    # XY is any diatomic species, with X closer to the active site
    # positions XY perpendicular to catalyst plane, then makes .xyz file
    # does not modify input molecule
    # bond lengths in angstroms, angle in degrees
    molecule_copy = mol3D.mol3D()
    molecule_copy.copymol3D(molecule)

    v = get_normal_vec(molecule_copy, site_index)
    v_X = scale_vector(v, catX_bond_length)
    v_Y = scale_vector(
        v, catX_bond_length +
        XY_bond_length * math.cos(math.pi - math.radians(bond_angle)))
    theta_0 = 0  # arbitrarily chosen
    v_perp = vec3_perp(
        scale_vector(
            v, XY_bond_length * math.sin(math.pi - math.radians(bond_angle))),
        theta_0)
    if v_perp == None:  # shouldn't happen
        return None

    site_coords = molecule_copy.atoms[site_index].coords()

    molecule_copy.addAtom(
        mol3D.atom3D(
            Sym=X,
            xyz=[site_coords[c] + v_X[c] for c in range(len(site_coords))]))
    molecule_copy.addAtom(
        mol3D.atom3D(Sym=Y,
                     xyz=[
                         site_coords[c] + v_Y[c] + v_perp[c]
                         for c in range(len(site_coords))
                     ]))
    #structgen.ffopt('MMFF94', molecule_copy, [], 1, [], False, [], 200, False) # keeps failing

    if reposition_XY:  # workaround for ffopt() failing to set up; nonmetal catalysts
        bond_length_cutoffs = {
            'C': 1.953,
            'H': 1.443,
            'I': 2.543,
            'Cl': 2.154,
            'B': 2.027,
            'N': 1.834,
            'F': 1.707,
            'Br': 2.423,
            'P': 2.297,
            'S': 2.198,
            'O': 1.810
        }  # X-O (angstroms)
        dtheta = 5  # change this if you want to
        theta = theta_0 + dtheta
        position_OK = False
        while not position_OK:
            position_OK = True
            for atom in molecule_copy.getAtoms():
                if atom == molecule_copy.getAtoms(
                )[-1] or atom == molecule_copy.getAtoms()[-2]:
                    continue
                if atom.symbol() in bond_length_cutoffs:
                    cutoff = bond_length_cutoffs[atom.symbol()]
                else:  # won't happen if bond_length_cutoffs is kept up to date
                    cutoff = bond_length_cutoffs[max(
                        bond_length_cutoffs,
                        key=lambda key: bond_length_cutoffs[key])]
                    print("Using %f A as the bond length cutoff for %s" %
                          (cutoff, atom.symbol()))
                if molecule_copy.getAtoms()[-1].distance(atom) < cutoff:
                    position_OK = False
                    break
            if not position_OK:
                if theta >= 360:
                    print("%s may have geometry issues after O2-binding." %
                          infile)
                    break
                v_perp = vec3_perp(
                    scale_vector(
                        v,
                        XY_bond_length *
                        math.sin(math.pi - math.radians(bond_angle))), theta)
                if v_perp == None:  # shouldn't happen
                    return None
                molecule_copy.getAtoms()[-1].setcoords([
                    site_coords[c] + v_Y[c] + v_perp[c]
                    for c in range(len(site_coords))
                ])
                theta += dtheta

    file_name = infile.split('.')[0] + fn_suffix
    if not is_metal_catalyst:  # metal catalysts assumed to have one active site
        file_name += "-" + str(site_index)  # still zero-indexed
    molecule_copy.writexyz(file_name)