Пример #1
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
Пример #2
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] = (fncs.exp128(- 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
Пример #3
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