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 rst2xyz(rst, xyz, onlyhess=True, Eref=None): tpath, tcommon, drst = read_rst(rst) thelist = [(data[0], label) for (label, data) in drst.items()] thelist.sort() (ch, mtp, atonums, masses, mu) = tcommon symbols = fncs.atonums2symbols(atonums) natoms = len(symbols) string = "" for s_i, label in thelist: s_i, E_i, xms_i, gms_i, Fms_i, v0_i, v1_i, t_i = drst[label] if onlyhess and Fms_i is None: continue if Eref is not None: E_i = (E_i - Eref) * KCALMOL energy = "%+.4f kcal/mol" % E_i else: energy = "%+.6f hartree" % E_i string += " %i\n" % natoms string += " * E = %s ; s = %7.4f (%s)\n" % (energy, s_i, label) xcc_i = fncs.ms2cc_x(xms_i, masses, mu) for idx, symbol in enumerate(symbols): x, y, z = fncs.xyz(xcc_i, idx) x *= ANGSTROM y *= ANGSTROM z *= ANGSTROM string += " %2s %+12.8f %+12.8f %+12.8f\n" % (symbol, x, y, z) with open(xyz, 'w') as asdf: asdf.write(string)
def highlevel_mep(ctc, itc, keyHL_sp, software, dtesHL, dhighlvl, points): # key for dhighlvl keyHL_path = "%s.%s.path" % (ctc, itc) # initialize dictE dictE = {} # folder for calculation and file name TMP = PN.TMPHLi % PN.struckey(ctc, itc) # template and function for calculation tes = dtesHL.get(software, {}).get(ctc, None) spc_fnc = get_spc_fnc(software) # extra-arguments for spc_fnc clean = False # do not delete files bhess = False # do not calculate hessian (no needed actually) eargs = (tes, TMP, clean) # rst file rstfile = PN.get_rst(ctc, itc) tpath2, tcommon2, drst = ff.read_rst(rstfile) if drst == {}: yield None, keyHL_path, (None, None), None, "emptyrst" return ch, mtp, atonums, masses, mu = tcommon2 symbols = fncs.atonums2symbols(atonums) # define points allpoints = sorted_points(drst, hess=False) for point in points: if point.startswith("auto"): auto, nbw, nfw = point.split("_") points = auto_points(drst, allpoints, int(nbw), int(nfw)) break # loop in points for point_i in points: # name for files mname = "%s.%s.%s" % (ctc, itc, point_i) # get label label_i, s_i = find_label_in_rst(point_i, drst) # tuple for identify tuple_ID = (s_i, label_i) # not in drst? if label_i is None: yield point_i, keyHL_path, tuple_ID, None, "noinrst" # already calculated elif label_i in dhighlvl.get(keyHL_path, {}).keys(): yield point_i, keyHL_path, tuple_ID, dhighlvl[keyHL_path][ label_i], "already" # HL-calculation else: if s_i == 0.0: Ehl_sp = dhighlvl.get(keyHL_sp, None) if Ehl_sp is not None: yield point_i, keyHL_path, tuple_ID, Ehl_sp, "saddlefromsp" continue # get xcc from rst xms = drst[label_i][2] xcc = fncs.ms2cc_x(xms, masses, mu) # calculation try: out_spc = spc_fnc(xcc, symbols, bhess, mname, eargs) yield point_i, keyHL_path, tuple_ID, out_spc[4], "calculated" except: yield point_i, keyHL_path, tuple_ID, None, "fail"
def path2vadi(tcommon,drst,Eref=None,ics=None,boolint=False,lowfq={},freqscal=1.0,icsbw=None,icsfw=None,symmetry=None): ''' lowfq: in case of imaginary frequencies ''' # boolint as boolean if boolint in [False,"no","No","n","N",None]: boolint = False elif boolint in [True,"yes","YES","y","Y"] : boolint = True # check there are internal coordinates if required if boolint and ics in [None,False,[]]: raise Exc.NoICS(Exception) # expand data in tcommon ch,mtp,atnums,masses,mu = tcommon # Sorted labels (by s) slabels = sd.sorted_points(drst,hess=True) # Reference energy if Eref is None: lbw, lfw, sbw, sfw, Eref, Efw = sd.rstlimits(drst) # Independent variable data_x = [drst[label][0] for label in slabels] # mep energy (relative value) listV0 = [drst[label][1]-Eref for label in slabels] # Initializing data lcc_tzpe, lcc_frqs, lcc_Vadi = [], [], [] lic_tzpe, lic_frqs, lic_Vadi = [], [], [] dMols = {} # Updating data for label in slabels: # data in drst s_i, E_i, xms_i,gms_i,Fms_i,v0_i,v1_i,t_i = drst[label] # project gradient if s_i == 0.0: bool_pg = False else : bool_pg = True # lowfq if s_i == 0.0: dlowfq = {} elif s_i < 0.0: dlowfq = lowfq.get("bw",{}) elif s_i > 0.0: dlowfq = lowfq.get("fw",{}) # mass-scaled --> Cartesian coords xcc = fncs.ms2cc_x(xms_i,masses,mu) gcc = fncs.ms2cc_g(gms_i,masses,mu) Fcc = fncs.ms2cc_F(Fms_i,masses,mu) # create Molecule instance mol = Molecule() mol.setvar(xcc=xcc,gcc=gcc,Fcc=Fcc) mol.setvar(atonums=atnums,masses=masses) mol.setvar(ch=ch,mtp=mtp,V0=E_i) mol.setvar(fscal=freqscal) if symmetry is not None: mol.setvar(pgroup=symmetry[0]) mol.setvar(rotsigma=symmetry[1]) mol.prepare() mol.setup(mu,projgrad=bool_pg) mol.clean_freqs("cc") # it may be needed with orca mol.deal_lowfq(dlowfq,"cc") # deal with low frequencies mol.ana_freqs("cc") # calculate zpe # append data lcc_tzpe.append(float(mol._cczpe) ) lcc_Vadi.append(mol._ccV1 - Eref ) lcc_frqs.append(list(mol._ccfreqs)) # internal coordinates if boolint: if s_i < 0.0 and icsbw is not None: mol.icfreqs(icsbw,bool_pg) elif s_i > 0.0 and icsfw is not None: mol.icfreqs(icsfw,bool_pg) else : mol.icfreqs(ics ,bool_pg) mol.deal_lowfq(dlowfq,"ic") mol.ana_freqs("ic") # append data lic_tzpe.append(float(mol._iczpe) ) lic_Vadi.append(mol._icV1 - Eref ) lic_frqs.append(list(mol._icfreqs)) # save instance dMols[label] = (s_i,mol) # package data tuple_cc = (data_x,lcc_frqs,lcc_tzpe) tuple_ic = (data_x,lic_frqs,lic_tzpe) # Generate splines Vadi_cc = VadiSpline(data_x,lcc_Vadi) if boolint: Vadi_ic = VadiSpline(data_x,lic_Vadi) else : Vadi_ic = None # Return data return dMols, Vadi_cc, Vadi_ic, tuple_cc, tuple_ic, listV0
def steepest(xcc0,s0,symbols,masses,pathdata,spc_fnc,spc_args,drst={},lFms=None,pf="%i"): ''' x0 should not be a saddle point pathdata: tuple made of: * method pm for Page-McIver es for Euler * mu * ds * nsteps * hsteps * epse * epsg pf: point format ''' # expand pathdata method,mu,ds,sfinal,hsteps,epse,epsg = pathdata nsteps = int(round(abs(sfinal/ds))) # Check some staff if lFms is None and method == "pm": raise Exc.SDpmNoHess(Exception) # loop s_i = s0 xcc_i = xcc0 listE = [] listg = [] for step in range(1,nsteps+1): point = pf%step # calculate hessian? if step%hsteps == 0: bhessian = True else : bhessian = False # previously calculated vs single-point calculation if point in drst.keys(): s_ii, E_i, xms_i, gms_i, Fms_i, v0, v1, t_i = drst[point] # in cc gcc_i = fncs.ms2cc_g(gms_i,masses,mu) # compare geometry exception = Exc.RstDiffPoint(Exception) exception._var = (point,s_i) if abs(s_ii-s_i) > EPS_MEPS: raise exception same = fncs.same_geom(fncs.cc2ms_x(xcc_i,masses,mu),xms_i) if not same: raise exception else: spc_data = spc_fnc(xcc_i,symbols,bhessian,point,spc_args) xcc_i, atnums, ch, mtp, E_i, gcc_i, Fcc_i, dummy = spc_data # Data in mass-scaled and correct format Fcc_i = fncs.lowt2matrix(Fcc_i) xms_i = fncs.cc2ms_x(xcc_i,masses,mu) gms_i = fncs.cc2ms_g(gcc_i,masses,mu) Fms_i = fncs.cc2ms_F(Fcc_i,masses,mu) t_i = None # keep data for eps listE.append(E_i) listg.append(fncs.norm(gcc_i)) # Last Fms if Fms_i not in [[],None]: lFms = Fms_i # Calculate new geometry (step+1) if method == "es": xms_j, t_i = sd_taylor(xms_i,ds,gms=gms_i), None # to check format elif method == "pm": xms_j, t_i = pm_nextxms(xms_i,ds,gms=gms_i,Fms=lFms,t0=t_i) # check real ds value diff_ds2 = sum([(ii-jj)**2 for (ii,jj) in zip(xms_j,xms_i)]) - ds**2 if diff_ds2 > EPS_FLOAT: raise Exc.SDdiffds(Exception) # Yield updated data for step yield (point,s_i), E_i, xms_i, gms_i, Fms_i, t_i # update xcc_i = fncs.ms2cc_x(xms_j,masses,mu) if s_i >= 0.0: s_i += ds else : s_i -= ds # Check eps if len(listE) > 2 and step > 2*hsteps: diffE = abs(listE[-1]-listE[-2]) #diffg = abs(listg[-1]-listg[-2]) crit1 = diffE < epse crit2 = listg[-1] < epsg if crit1 and crit2: break
def obtain_mep(target, gtsTS, pathvars, tsoftware, TMP): ctc, itc = PN.name2data(target) # create folder now and not in the parallel process if not os.path.exists(TMP): try: os.mkdir(TMP) except: pass # Files rstfile = PN.get_rst(ctc, itc) xyzfile = PN.get_rstxyz(ctc, itc) # print software, tes = tsoftware fncs.print_string(PS.smep_init(target,software,pathvars._paral,pathvars.tuple_first(),\ pathvars.tuple_sdbw(),pathvars.tuple_sdfw()),4) fncs.print_string(PS.smep_ff(TMP, PN.DIR4, PN.DIR5, rstfile, xyzfile), 4) # read rst try: tpath2, tcommon2, drst = ff.read_rst(rstfile) except: exception = Exc.RstReadProblem(Exception) exception._var = rstfile raise exception fncs.print_string(PS.smep_rst(rstfile, drst), 4) # correct MEP direction? if TSLABEL in drst.keys(): ii_s, ii_V, ii_x, ii_g, ii_F, ii_v0, ii_v1, ii_t = drst[TSLABEL] ii_ic, ii_sign = pathvars._fwdir if not intl.ics_correctdir(ii_x, ii_v0, ii_ic, ii_sign, tcommon2[3], tcommon2[4]): fncs.print_string( "'fwdir' variable differs from MEP direction in rst file!", 4) fncs.print_string("* modifying rst internal dictionary...", 8) new_drst = {} for key in drst.keys(): ii_s, ii_V, ii_x, ii_g, ii_F, ii_v0, ii_v1, ii_t = drst[key] ii_s = -ii_s if ii_v0 is not None: ii_v0 = [-ii for ii in ii_v0] if ii_v1 is not None: ii_v1 = [-ii for ii in ii_v1] if "bw" in key: newkey = key.replace("bw", "fw") else: newkey = key.replace("fw", "bw") new_drst[newkey] = (ii_s, ii_V, ii_x, ii_g, ii_F, ii_v0, ii_v1, ii_t) drst = new_drst del new_drst fncs.print_string("* rewriting rst file...", 8) ff.write_rst(rstfile, tpath2, tcommon2, drst) # Extension of MEP in rst is bigger if drst != {}: lbw, lfw, sbw, sfw, V0bw, V0fw = sd.rstlimits(drst) pathvars._sbw = min(pathvars._sbw, sbw) pathvars._sfw = max(pathvars._sfw, sfw) # Read gts ts = Molecule() ts.set_from_gts(gtsTS) # scaling of frequencies ts.setvar(fscal=pathvars._freqscal) # apply iso mod if pathvars._masses is not None: ts.mod_masses(pathvars._masses) # setup ts.setup(mu=pathvars._mu) ts.ana_freqs(case="cc") fncs.print_string(PS.smep_ts(ts), 4) tcommon = (ts._ch, ts._mtp, ts._atnums, ts._masses, ts._mu) compare_tpath(pathvars.tuple_rst(), tpath2, rstfile) compare_tcommon(tcommon, tcommon2, rstfile) # data for single-point calculation frozen = RW.read_frozen(gtsTS + ".frozen") oniom_layers = (list(pathvars._oniomh), list(pathvars._oniomm), list(pathvars._onioml)) spc_args = (tes, TMP, False, frozen, oniom_layers) spc_fnc = get_spc_fnc(software) #------------# # First step # #------------# print("") fncs.print_string("Performing first step of MEP...", 4) print("") inputvars = (ts._xcc,ts._gcc,ts._Fcc,ts._symbols,ts._masses,pathvars.tuple_first(),\ spc_fnc,spc_args,drst,pathvars._paral) (xms, gms, Fms), (v0, v1), (xms_bw, xms_fw) = sd.mep_first(*inputvars) s1bw = -float(pathvars._ds) s1fw = +float(pathvars._ds) # oniom layers? oniom_ok = pathvars.isONIOMok(ts._natoms, software) layers = pathvars.get_layers() fncs.print_string(PS.smep_oniom(layers, ts._natoms, software), 8) if not oniom_ok: raise Exc.WrongONIOMlayers(Exception) # Print MEP info fncs.print_string(PS.smep_first(ts._symbols, ts._xms, v0, v1, layers), 8) # write rst file if TSLABEL not in drst.keys(): drst[TSLABEL] = (0.0, ts._V0, xms, gms, Fms, v0, v1, None) ff.write_rst_head(rstfile, pathvars.tuple_rst(), tcommon) ff.write_rst_add(rstfile, TSLABEL, drst[TSLABEL]) #------------# # The MEP # #------------# print("") fncs.print_string("Calculating MEP...", 4) print("") fncs.print_string( "* REMEMBER: data of each step will be saved at %s" % rstfile, 7) fncs.print_string(" a summary will be printed when finished", 7) # preparation xcc_bw = fncs.ms2cc_x(xms_bw, ts._masses, pathvars._mu) xcc_fw = fncs.ms2cc_x(xms_fw, ts._masses, pathvars._mu) args_bw = ((xcc_bw,s1bw,ts._symbols,ts._masses,pathvars.tuple_sdbw(),\ spc_fnc,spc_args,drst,ts._Fms,"bw%i") , rstfile,drst) args_fw = ((xcc_fw,s1fw,ts._symbols,ts._masses,pathvars.tuple_sdfw(),\ spc_fnc,spc_args,drst,ts._Fms,"fw%i") , rstfile,drst) # execution if pathvars._paral: import multiprocessing pool = multiprocessing.Pool() out = [ pool.apply_async(onesidemep, args=args) for args in [args_bw, args_fw] ] drstbw, pointsbw, convbw = out[0].get() drstfw, pointsfw, convfw = out[1].get() del out # clean up pool pool.close() pool.join() else: drstbw, pointsbw, convbw = onesidemep(*args_bw) drstfw, pointsfw, convfw = onesidemep(*args_fw) # update drst fncs.print_string("* FINISHED!", 7) print("") drst.update(drstbw) drst.update(drstfw) points = [TSLABEL] + pointsbw + pointsfw # empty variables del drstbw, pointsbw del drstfw, pointsfw # Rewrite rst fncs.print_string("* (re)writing file: %s (sorted version)" % rstfile, 7) ff.write_rst(rstfile, pathvars.tuple_rst(), tcommon, drst) print("") ## restrict drst to points #if restrict: drst = {point:drst[point] for point in points} # Get limits of rst lbw, lfw, sbw, sfw, V0bw, V0fw = sd.rstlimits(drst) convbw, l1bw, l2bw = convbw convfw, l1fw, l2fw = convfw if l1bw + l1fw != "": fncs.print_string("* MEP convergence criteria (epse and epsg):", 7) print("") if l1bw != "": fncs.print_string("%s" % l1bw, 9) if l2bw != "": fncs.print_string("%s" % l2bw, 9) if l1fw != "": fncs.print_string("%s" % l1fw, 9) if l2fw != "": fncs.print_string("%s" % l2fw, 9) print("") if convbw: pathvars.converged_in_bw(sbw) fncs.print_string("CRITERIA FULFILLED in backward dir.!", 9) fncs.print_string("path stopped at sbw = %+8.4f bohr" % sbw, 9) print("") if convfw: pathvars.converged_in_fw(sfw) fncs.print_string("CRITERIA FULFILLED in forward dir.!", 9) fncs.print_string("path stopped at sfw = %+8.4f bohr" % sfw, 9) print("") # write molden file fncs.print_string("* writing file: %s" % xyzfile, 7) ff.rst2xyz(rstfile, xyzfile, onlyhess=True) print("") # reference energy if pathvars._eref is None: pathvars._eref = V0bw # return data return tcommon, drst, pathvars