Esempio n. 1
0
def get_lindh_k(atoms, coords3d, bonds=None, angles=None, torsions=None):
    if bonds is None:
        bonds = list()
    if angles is None:
        angles = list()
    if torsions is None:
        torsions = list()

    atoms = [a.lower() for a in atoms]

    alphas = [get_lindh_alpha(a1, a2) for a1, a2 in it.combinations(atoms, 2)]
    pair_cov_radii = get_pair_covalent_radii(atoms)
    cdm = pdist(coords3d)
    rhos = squareform(np.exp(alphas * (pair_cov_radii**2 - cdm**2)))

    k_dict = {
        2: 0.45,  # Stretches/bonds
        3: 0.15,  # Bends/angles
        4: 0.005,  # Torsions/dihedrals
    }
    ks = list()
    for inds in it.chain(bonds, angles, torsions):
        rho_product = 1
        for i in range(len(inds) - 1):
            i1, i2 = inds[i:i + 2]
            rho_product *= rhos[i1, i2]
        ks.append(k_dict[len(inds)] * rho_product)
    return ks
Esempio n. 2
0
def fischer_guess(geom):
    cdm = pdist(geom.coords3d)
    pair_cov_radii = get_pair_covalent_radii(geom.atoms)

    dihedrals = geom.internal.dihedrals
    # For the dihedral force constants we also have to count the number
    # of bonds formed with the centrals atoms of the dihedral.
    central_atoms = [dh.inds[1:3] for dh in dihedrals]
    bond_factor = geom.internal.bond_factor
    bond_mat = squareform(cdm <= (pair_cov_radii * bond_factor))
    tors_atom_bonds = dict()
    for a, b in central_atoms:
        # Substract 2, as we don't want the bond between a and b,
        # but this bond will be in both rows of the bond_mat.
        bond_sum = bond_mat[a].sum() + bond_mat[b].sum() - 2
        tors_atom_bonds[(a, b)] = bond_sum

    dist_mat = squareform(cdm)
    pair_cov_radii_mat = squareform(pair_cov_radii)

    def h_bond(bond):
        a, b = bond.indices
        r_ab = dist_mat[a, b]
        r_ab_cov = pair_cov_radii_mat[a, b]
        return 0.3601 * exp(-1.944 * (r_ab - r_ab_cov))

    def h_bend(bend):
        b, a, c = bend.indices
        r_ab = dist_mat[a, b]
        r_ac = dist_mat[a, c]
        r_ab_cov = pair_cov_radii_mat[a, b]
        r_ac_cov = pair_cov_radii_mat[a, c]
        return (0.089 + 0.11 / (r_ab_cov * r_ac_cov)**(-0.42) *
                exp(-0.44 * (r_ab + r_ac - r_ab_cov - r_ac_cov)))

    def h_dihedral(dihedral):
        # import pdb; pdb.set_trace()
        c, a, b, d = dihedral.indices
        r_ab = dist_mat[a, b]
        r_ab_cov = pair_cov_radii_mat[a, b]
        bond_sum = max(tors_atom_bonds[(a, b)], 0)
        return (0.0015 + 14.0 * bond_sum**0.57 /
                (r_ab * r_ab_cov)**4.0 * exp(-2.85 * (r_ab - r_ab_cov)))

    h_funcs = {
        2: h_bond,
        3: h_bend,
        4: h_dihedral,
    }

    h_diag = list()
    for primitive in geom.internal.primitives:
        f = h_funcs[len(primitive.indices)]
        h_diag.append(f(primitive))
    H = np.array(np.diagflat(h_diag))
    return H
Esempio n. 3
0
def swart_guess(geom):
    pair_cov_radii = get_pair_covalent_radii(geom.atoms)
    cdm = pdist(geom.coords3d)
    rhos = squareform(np.exp(-cdm / pair_cov_radii + 1))
    k_dict = {
        2: 0.35,
        3: 0.15,
        4: 0.005,
    }
    k_diag = list()
    for primitive in geom.internal.primitives:
        rho_product = 1
        for i in range(len(primitive.indices) - 1):
            i1, i2 = primitive.indices[i:i + 2]
            rho_product *= rhos[i1, i2]
        k_diag.append(k_dict[len(primitive.indices)] * rho_product)
    return np.diagflat(k_diag)
Esempio n. 4
0
def lindh_guess(geom):
    """Slightly modified Lindh model hessian as described in [1].

    Instead of using the tabulated r_ref,ij values from [1] we will use the
    'true' covalent radii as pyberny. The tabulated r_ref,ij value for two
    carbons (2nd period) is 2.87 Bohr. Carbons covalent radius is ~ 1.44 Bohr,
    so 2*1.44 Bohr = 2.88 Bohr which fits nicely with the tabulate value.
    If values for elements > 3rd are requested the alpha values for the 3rd
    period will be (re)used.
    """
    first_period = "h he".split()

    def get_alpha(atom1, atom2):
        if (atom1 in first_period) and (atom2 in first_period):
            return 1.
        elif (atom1 in first_period) or (atom2 in first_period):
            return 0.3949
        else:
            return 0.28

    atoms = [a.lower() for a in geom.atoms]
    alphas = [get_alpha(a1, a2) for a1, a2 in it.combinations(atoms, 2)]
    pair_cov_radii = get_pair_covalent_radii(geom.atoms)
    cdm = pdist(geom.coords3d)
    rhos = squareform(np.exp(alphas * (pair_cov_radii**2 - cdm**2)))

    k_dict = {
        2: 0.45,  # Stretches/bonds
        3: 0.15,  # Bends/angles
        4: 0.005,  # Torsions/dihedrals
    }
    k_diag = list()
    for prim_int in geom.internal.prim_internals:
        rho_product = 1
        for i in range(len(prim_int.inds) - 1):
            i1, i2 = prim_int.inds[i:i + 2]
            rho_product *= rhos[i1, i2]
        k_diag.append(k_dict[len(prim_int.inds)] * rho_product)
    H = np.diagflat(k_diag)
    return H
Esempio n. 5
0
 def atoms_are_too_close(self, geom, factor=.7):
     """Determine if atoms are too close."""
     dist_mat = pdist(geom.coords3d)
     cov_rad_mat = get_pair_covalent_radii(geom.atoms)
     too_close = dist_mat < factor*cov_rad_mat
     return any(too_close)