示例#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 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)
示例#3
0
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"
示例#4
0
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
示例#5
0
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
示例#6
0
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