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]
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)
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
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
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
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
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
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)