def get_numv1(drst): # list of point pts1 = sd.sorted_points(drst, hess=False) pts2 = sd.sorted_points(drst, hess=True) # get some lists from drst pts1 = sd.sorted_points(drst, hess=False) pts2 = sd.sorted_points(drst, hess=True) svals = [drst[label][0] for label in pts1] grads = [drst[label][3] for label in pts1] # positions in pts1 of points in pts2 hess_idxs = [idx for idx, label in enumerate(pts1) if label in pts2] hess_idxsBW = [ idx for idx, label in enumerate(pts1) if label in pts2 and drst[label][0] < 0.0 ] hess_idxsFW = [ idx for idx, label in enumerate(pts1) if label in pts2 and drst[label][0] > 0.0 ] # calculate list of numeric v^(1) vectors if False: dv1 = numv1_calcA(pts1, svals, grads, hess_idxsBW, hess_idxsFW) if True: dv1 = numv1_calcB(pts1, svals, grads, hess_idxs) # faster than numv1_calcA return dv1
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 manage_data_for_plot_mep(tsname,drst,Eref,VadiSpline): plotdata = {} # data for MEP plot data = [] mlabel = "%s_mep"%tsname points = sd.sorted_points(drst,hess=True) xx = [drst[point][0] for point in points] yy = [drst[point][1] for point in points] yy = [(yi-Eref)*pc.KCALMOL for yi in yy] title = "Minimum energy path" xlabel = "reaction coordinate s [bohr]" ylabel = "relative energy [kcal/mol]" data.append( (xx,yy,'k--o','low-level') ) plotdata[mlabel] = ("plot",data,title,xlabel,ylabel) # data for Vadi plot data = [] mlabel = "%s_vadi"%tsname xx = VadiSpline.xx() yy = [yi*pc.KCALMOL for yi in VadiSpline.yy()] xlabel = "reaction coordinate s [bohr]" ylabel = "relative energy [kcal/mol]" title = "Adiabatic Potential" data.append( (xx,yy,'k--o','') ) plotdata[mlabel] = ("plot",data,title,xlabel,ylabel) return plotdata
def calc_coefs(itarget, tcommon, drst, pathvars, ltemp, symmetry=None, plotfile=None): # initialize dcfs dcfs = {} # sorted points points = sd.sorted_points(drst, hess=True) # Calculate adiabatic potential dMols, Vadi, pathvars = obtain_adipot(tcommon, drst, pathvars, symmetry) # Calculate CVT correction factor if pathvars._cvt == "yes": dcfs, lscvt, gibbs, lnew = obtain_cvt(dMols, points, Vadi, ltemp, pathvars, dcfs=dcfs) else: lscvt = None # Calculate SCT correction factor if pathvars._sct == "yes": # v1 vector along MEP if pathvars._v1mode == "grad": dv1 = sct.get_numv1(drst) elif pathvars._v1mode == "hess": dv1 = {} # calculate SCT coefficient dcfs, tplot_sct, E0, VAG = obtain_sct(dMols, points, Vadi, ltemp, dv1, pathvars, dcfs=dcfs) # Calculate CAG correction factor dcfs = obtain_cag(Vadi, ltemp, E0, VAG, lscvt, dcfs=dcfs) # save data for plotting if plotfile is not None: plotdata = {} plotdata.update( manage_data_for_plot_mep(itarget, drst, pathvars._eref, Vadi)) if "cvt" in dcfs.keys(): plotdata.update( manage_data_for_plot_cvt(itarget, ltemp, Vadi.xx(), (gibbs, lnew), lscvt, dcfs["cvt"])) if "sct" in dcfs.keys() and tplot_sct is not None: plotdata.update( manage_data_for_plot_sct(itarget, dcfs["zct"], dcfs["sct"], *tplot_sct)) write_plotfile(plotfile, plotdata) # Delete variables palpha = Vadi.get_alpha() pomega = Vadi.get_omega() del dMols del Vadi # Return data return dcfs, pathvars, palpha, pomega
def find_label_in_rst(s_i,drst): # initialize output label label = None svalue = None # get all points allpoints = sorted_points(drst,hess=False) # as_i is indeed a label! if s_i in allpoints: return s_i, drst[s_i][0] # s_i is not a float number try : s_i = float(s_i) except: return label, s_i # go one by one for l_j in allpoints: s_j = drst[l_j][0] if abs(s_j-s_i) < EPS_MEPS: label = l_j svalue = s_j break return label, svalue
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 ispe(tcommon, drst, ispe_xy, tension): ''' V^LL --> V^HL ''' # points in rst points = sd.sorted_points(drst, hess=False) # Get imaginary frequency for TS (low-level) sTS, ETS_ll, xcc, gcc, Fcc = drst[sd.TSLABEL][0:5] ifreq, mu = get_ts_ifreq(xcc, gcc, Fcc, ETS_ll, tcommon) # convert x in ispe_xy to labels for idx, (l_i, V_i) in enumerate(ispe_xy): if l_i in points: s_i = drst[l_i][0] label_i = l_i else: s_i = float(l_i) label_i = None for point in points: if abs(drst[point][0] - s_i) < EPS_DLEVELS: label_i = point if label_i is None: raise Exc.DLEVELsthWrong(Exception) ispe_xy[idx] = (s_i, label_i, V_i) # sort points ispe_xy.sort() # only one point if len(ispe_xy) == 1: sx, lx, Ex_hl = ispe_xy[0] Ex_ll = drst[lx][1] # calculate energy difference diffE = Ex_ll - Ex_hl # points points = sd.sorted_points(drst, hess=False) # save old energies xx = [drst[point][0] for point in points] yyll = [drst[point][1] for point in points] # apply difference to all points for point in points: drst[point] = list(drst[point]) drst[point][1] = drst[point][1] - diffE drst[point] = tuple(drst[point]) # more than one point else: # reduce points of drst to those for DLEVEL s1, l1, E1_hl = ispe_xy[0] sn, ln, En_hl = ispe_xy[-1] drst = { point: drst[point] for point in points if in_interval(drst[point][0], s1, sn) } points = sd.sorted_points(drst, hess=False) # get s0 and L from lower level E1_ll, En_ll = drst[l1][1], drst[ln][1] s0, L = get_s0_L(E1_ll, ETS_ll, En_ll, mu, ifreq) # generate data for spline lxx, lyy = gen_data_for_spline(ispe_xy, drst, s0, L) # create spline spl = Spline(lxx, lyy, tension=tension) # save old energies xx = [drst[point][0] for point in points] yyll = [drst[point][1] for point in points] # modify drst for point in points: s, Vll = drst[point][0:2] z = s2z(s, s0, L) drst[point] = list(drst[point]) drst[point][1] = Vll - spl(z) drst[point] = tuple(drst[point]) # save new energies yyhl = [drst[point][1] for point in points] # return data return drst, points, xx, yyll, yyhl