Beispiel #1
0
def wilson_getBC(xcc, all_ics):
    numics = count_ics(all_ics)
    ics_st, ics_ab, ics_lb, ics_it, ics_pt = unmerge_ics(all_ics)
    # unit bond vectors
    natoms = fncs.howmanyatoms(xcc)
    bvecs = wilson_bvecs(xcc)
    # initialize matrices
    wilsonB = [[0.0 for row in range(numics)] for col in range(3 * natoms)]
    wilsonB, wilsonC = [], []
    # B and C: stretchings
    for atoms in ics_st:
        row_B, matrix_C = wilson_stretch(bvecs, atoms, natoms)
        wilsonB += row_B
        wilsonC += matrix_C
    # B and C: angular bendings
    for atoms in ics_ab:
        row_B, matrix_C = wilson_abend(bvecs, atoms, natoms)
        wilsonB += row_B
        wilsonC += matrix_C
    # B and C: linear  bendings
    for atoms in ics_lb:
        i, j, k = atoms
        r_m = np.array(fncs.xyz(xcc, i))
        r_o = np.array(fncs.xyz(xcc, j))
        r_n = np.array(fncs.xyz(xcc, k))
        row_B, matrix_C = wilson_lbend(r_m, r_o, r_n, atoms, natoms)
        wilsonB += row_B
        wilsonC += matrix_C
    # B and C: torsions (proper and improper)
    for atoms in ics_it + ics_pt:
        row_B, matrix_C = wilson_torsion(bvecs, atoms, natoms)
        wilsonB += row_B
        wilsonC += matrix_C
    return np.matrix(wilsonB), [np.matrix(ll) for ll in wilsonC]
Beispiel #2
0
def write_input(ifile, xcc, f="%+13.9f"):
    string = ""
    natoms = fncs.howmanyatoms(xcc)
    for atom in range(natoms):
        x = f % (fncs.x(xcc, atom))
        y = f % (fncs.y(xcc, atom))
        z = f % (fncs.z(xcc, atom))
        string += "  %s %s %s \n" % (x, y, z)
    ff.write_file(ifile, string)
Beispiel #3
0
def calculate_v1(xms,
                 v0,
                 Fms,
                 symbols,
                 masses,
                 mu,
                 d3,
                 spc_fnc,
                 spc_args,
                 parallel=False):
    natoms = fncs.howmanyatoms(xms)
    # Calculation of hessian at close structures
    xbw_3rd = fncs.ms2cc_x(sd_taylor(xms, d3, v0=-v0), masses, mu)
    xfw_3rd = fncs.ms2cc_x(sd_taylor(xms, d3, v0=+v0), masses, mu)
    t3rd_bw = (xbw_3rd, symbols, True, "thirdBw", spc_args)
    t3rd_fw = (xfw_3rd, symbols, True, "thirdFw", spc_args)
    # calculation with software
    if fncs.do_parallel(parallel):
        import multiprocessing
        pool = multiprocessing.Pool()
        out = [
            pool.apply_async(spc_fnc, args=args)
            for args in [t3rd_bw, t3rd_fw]
        ]
        #outbw, outfw = Parallel(n_jobs=-1)(delayed(spc_fnc)(*inp) for inp in [t3rd_bw,t3rd_fw])
        outbw = out[0].get()
        outfw = out[1].get()
        # clean up pool
        pool.close()
        pool.join()
    else:
        outbw = spc_fnc(*t3rd_bw)
        outfw = spc_fnc(*t3rd_fw)
    xcc_bw, atnums, ch, mtp, V0_bw, gcc_bw, Fcc_bw, dummy = outbw
    xcc_fw, atnums, ch, mtp, V0_fw, gcc_fw, Fcc_fw, dummy = outfw
    # In mass-scaled
    Fms_bw = fncs.cc2ms_F(fncs.lowt2matrix(Fcc_bw), masses, mu)
    Fms_fw = fncs.cc2ms_F(fncs.lowt2matrix(Fcc_fw), masses, mu)
    # Convert numpy matrices
    Fms = np.matrix(Fms)
    Fms_bw = np.matrix(Fms_bw)
    Fms_fw = np.matrix(Fms_fw)
    # Matriz of third derivatives
    m3der = (Fms_fw - Fms_bw) / (2.0 * d3)
    # Calculation of curvature, i.e. v^(1) (or small c)  A = B * c --> c = B^-1 * A
    LF = np.matrix([v0]).transpose()
    A = m3der * LF - float(LF.transpose() * m3der * LF) * LF
    B = 2.0 * float(LF.transpose() * Fms * LF) * np.identity(3 * natoms) - Fms
    v1 = np.linalg.inv(B) * A
    # Convert to (normal) array
    v1 = np.array(v1.transpose().tolist()[0])
    return v1
Beispiel #4
0
def pm_nextxms(xms, ds, gms, Fms, t0=None):
    '''
    Calculate next geometry using page-mciver method
    If fail in calculating t parameter, quadratic Taylor
    expasion is used.
    '''
    tmethod = "quad"  # ("quad" or "trap")
    natoms = fncs.howmanyatoms(xms)
    # to numpy arrays
    if xms is not None: xms = np.matrix(np.array([xms]).transpose())
    if gms is not None: gms = np.matrix(np.array([gms]).transpose())
    if Fms is not None: Fms = np.matrix(np.array(Fms))
    # Get Hessian eigenvalues and eigenvectors
    alpha, U = np.linalg.eigh(Fms)
    # Get projection of gradient
    gp = U.transpose() * gms
    # Put eigenvectors in diagonal matrix
    alpha = np.diag(alpha)
    # check dimensions
    if gms.shape != (3 * natoms, 1): exit("Problems in 'pm_nextxms'")
    if gp.shape != (3 * natoms, 1): exit("Problems in 'pm_nextxms'")
    if U.shape != (3 * natoms, 3 * natoms): exit("Problems in 'pm_nextxms'")
    # get t
    if t0 is None: t = pm_gett(ds, gp, alpha, tmethod)
    else: t = t0
    # apply taylor?
    if t is None:
        xms = np.array(xms.transpose().tolist()[0])
        gms = np.array(gms.transpose().tolist()[0])
        Fms = np.array(Fms.tolist())
        return sd_taylor(xms, ds, gms, Fms), None
    # Get Mn matrix
    M = np.identity(3 * natoms)
    for i in range(3 * natoms):
        M[i, i] = (np.exp(-alpha[i, i] * t) - 1.0) / alpha[i, i]
    # Get D(t)
    D = U * M * U.transpose()
    # Get dx vector
    dx_vector = D * gms
    # to normal array
    xms = np.array(xms.transpose().tolist()[0])
    dx_vector = np.array(dx_vector.transpose().tolist()[0])
    # Get new geom
    xms_next = xms + dx_vector
    return xms_next, t
Beispiel #5
0
def wilson_bvecs(xcc):
    '''
    This functions calculates the distance
    between each pair of atoms (dij) and also
    the unit bond vector eij = (rj - ri)/dij
    '''
    nat = fncs.howmanyatoms(xcc)
    bond_vectors = {}
    for ii in range(nat):
        ri = np.array(fncs.xyz(xcc, ii))
        for jj in range(ii + 1, nat):
            rj = np.array(fncs.xyz(xcc, jj))
            eij = rj - ri
            dij = np.linalg.norm(eij)
            eij = eij / dij
            bond_vectors[(ii, jj)] = (eij, dij)
            bond_vectors[(jj, ii)] = (-eij, dij)
    return bond_vectors
Beispiel #6
0
def get_adjmatrix(xcc, symbols, scale=1.2, mode="bool"):
    '''
    returns adjacency matrix (connection matrix);
    also distance matrix and number of bonds
    * mode = bool, int
    '''
    nbonds = 0
    nat = fncs.howmanyatoms(xcc)
    dmatrix = fncs.get_distmatrix(xcc)
    if mode == "bool": no, yes = False, True
    if mode == "int": no, yes = 0, 1
    cmatrix = [[no for ii in range(nat)] for jj in range(nat)]
    for ii in range(nat):
        cr_ii = dpt_s2cr[symbols[ii]]  # covalent radius
        for jj in range(ii + 1, nat):
            cr_jj = dpt_s2cr[symbols[jj]]
            dref = (cr_ii + cr_jj) * scale
            if dmatrix[ii][jj] < dref:
                nbonds += 1
                cmatrix[ii][jj] = yes
                cmatrix[jj][ii] = yes
    return cmatrix, dmatrix, nbonds
Beispiel #7
0
def puckering_coords(xvec, atoms_in_ring=None):
    '''
    Generalized Ring-Puckering Coordinates
    JACS 1975, 97:6, 1354-1358; eqs (12)-(14)
    '''
    nat = fncs.howmanyatoms(xvec)
    if atoms_in_ring is None: atoms_in_ring = range(nat)
    list_Rj, gc = puckering_rjs(xvec, atoms_in_ring)
    normal = puckering_normal(list_Rj)
    list_zj = puckering_zjs(list_Rj, normal)
    N = len(list_zj)
    if N % 2 != 0: mmax = (N - 1) / 2
    else: mmax = N / 2 - 1
    list_qm = []
    list_phim = []
    for m in range(2, mmax + 1, 1):
        qcos = 0.0
        qsin = 0.0
        for j in range(N):
            zj = list_zj[j]
            qcos += zj * np.cos(2 * np.pi * m * j / N)
            qsin += zj * np.sin(2 * np.pi * m * j / N)
        qcos *= +np.sqrt(2.0 / N)
        qsin *= -np.sqrt(2.0 / N)
        # Get q_m and phi_m
        phi_m = fncs.sincos2angle(qsin, qcos)
        q_m = qcos / np.cos(phi_m)
        list_qm.append(q_m)
        list_phim.append(phi_m)
    if N % 2 == 0:
        qNhalf = 0.0
        for j in range(N):
            zj = list_zj[j]
            qNhalf += ((-1)**j) * zj
        qNhalf *= np.sqrt(1.0 / N)
        list_qm.append(qNhalf)
    # total puckering amplitude
    Q = np.sqrt(sum([zj**2 for zj in list_zj]))
    return list_qm, list_phim, Q
Beispiel #8
0
def calculate_hessian(ifile, ofile, err, asurf=None):
    '''
    single point calculation (with numerical hessian)
    '''
    # name from ifile
    name = ".".join(ifile.split(".")[:-1])
    # ifile info
    xcc = read_input(ifile)
    natoms = fncs.howmanyatoms(xcc)
    # Energy and gradient
    E, gcc = calculate_gcc(ifile, ofile, err, asurf)
    # Hessian
    hessian = []
    for coord in range(len(xcc)):
        for idx in range(6):
            #----------------#
            # Left  geometry #
            #----------------#
            xcc_L = list(xcc)
            xcc_L[coord] = xcc_L[coord] - EPS_HESSDX
            # Left  file
            nameL, ifileL, ofileL, efileL = iofiles(name + ".L", folder=None)
            if idx == 0: write_input(ifileL, xcc_L, f="%+13.9f")
            if idx == 1: write_input(ifileL, xcc_L, f="%+13.8f")
            if idx == 2: write_input(ifileL, xcc_L, f="%+13.7f")
            if idx == 3: write_input(ifileL, xcc_L, f="%+13.6f")
            if idx == 4: write_input(ifileL, xcc_L, f="%+13.5f")
            if idx == 5: write_input(ifileL, xcc_L, f="%+13.4f")
            # Left  calculation
            E_L, gcc_L = calculate_gcc(ifileL, ofileL, efileL, asurf)
            #----------------#
            # Right geometry #
            #----------------#
            xcc_R = list(xcc)
            xcc_R[coord] = xcc_R[coord] + EPS_HESSDX
            # Right file
            nameR, ifileR, ofileR, efileR = iofiles(name + ".R", folder=None)
            if idx == 0: write_input(ifileR, xcc_R, f="%+13.9f")
            if idx == 1: write_input(ifileR, xcc_R, f="%+13.8f")
            if idx == 2: write_input(ifileR, xcc_R, f="%+13.7f")
            if idx == 3: write_input(ifileR, xcc_R, f="%+13.6f")
            if idx == 4: write_input(ifileR, xcc_R, f="%+13.5f")
            if idx == 5: write_input(ifileR, xcc_R, f="%+13.4f")
            # Right calculation
            E_R, gcc_R = calculate_gcc(ifileR, ofileR, efileR, asurf)

            #----------------#
            # Data 2 hessian #
            #----------------#
            row = [(gR - gL) / (2.0 * EPS_HESSDX)
                   for gR, gL in zip(gcc_R, gcc_L)]

            # Recalculate (any NaN in row?)
            newtry = False
            for rr in row:
                if math.isnan(float(rr)): newtry = True
            if newtry and idx < 6: continue

            # Append data
            hessian.append(row)
            break

    # Average hessian
    nrows = len(hessian)
    ncols = len(hessian[0])
    for i in range(1, nrows, 1):
        for j in range(i):
            Fij = hessian[i][j]
            Fji = hessian[j][i]
            average = 0.5 * (Fij + Fji)
            hessian[i][j] = average
            hessian[j][i] = average
    # Return
    return E, gcc, fncs.matrix2lowt(hessian)