Example #1
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"
Example #2
0
def calc_mep(itarget, gtsTS, pathvars, tsoftware, TMP):
    # data in name
    ctc, itc = PN.name2data(itarget)
    # Low-Level
    if pathvars._dlevel is None:
        tcommon, drst, pathvars = obtain_mep(itarget, gtsTS, pathvars,
                                             tsoftware, TMP)
        fncs.print_string(PS.smep_table(drst, pathvars._eref), 4)
    # Dual-Level
    else:
        rstfile = PN.get_rst(ctc, itc)
        xyzfile = PN.get_rstxyz(ctc, itc)
        software, tes = tsoftware
        fncs.print_string(PS.smep_init(itarget,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
        tpath, tcommon, drst = ff.read_rst(rstfile)
        fncs.print_string(PS.smep_rst(rstfile, drst), 4)

        fncs.print_string("Applying Dual-Level...", 4)
        print("")
        dlevel_xy = [(find_label_in_rst(x, drst)[0], y)
                     for x, y in pathvars._dlevel.items()]
        dlevel_xy = [(x, y) for x, y in dlevel_xy if x is not None]
        # Print points (sorted by s value)
        dummy = [(drst[xx][0], idx) for idx, (xx, yy) in enumerate(dlevel_xy)]
        dummy.sort()
        for s_i, idx_i in dummy:
            xx_i, yy_i = dlevel_xy[idx_i]
            fncs.print_string(
                "%+8.4f bohr (%-6s) --> %.7f hartree" % (s_i, xx_i, yy_i), 13)
        print("")
        # interpolation
        drst, points, xx, yyll, yyhl = ispe.ispe(tcommon,
                                                 drst,
                                                 dlevel_xy,
                                                 tension=0.0)
        tdleveldata = (points, xx, yyll, yyhl)
        # table new values
        fncs.print_string(
            PS.smep_tableDLEVEL(drst, tdleveldata, pathvars._eref), 4)
    return tcommon, drst, pathvars
Example #3
0
def deal_with_path(target, dlevel, software, ltemp, dctc, pathvars, dtes,
                   dchem, dhighlvl, dimasses):
    dof = PN.get_dof(dlevel)
    plotfile = PN.get_plf(dlevel)
    # gts file for this TS
    ctc, itc = PN.name2data(target)
    gtsTS = dctc[ctc].gtsfile(itc)
    # rotational symmetry
    moleculeTS = Molecule()
    moleculeTS.set_from_gts(gtsTS)
    symmetry = str(moleculeTS._pgroup), int(moleculeTS._rotsigma)
    # temporal folder
    TMP = PN.TMPi % (target)
    # if exists,remove content (unless keeptmp is activated)
    # (to avoid reading old files from different levels of calculation)
    if os.path.exists(TMP) and not pathvars._keeptmp:
        shutil.rmtree(TMP, ignore_errors=True)
    # split target
    ctc, itc = PN.name2data(target)
    # name of rst file
    rstfile = PN.get_rst(ctc, itc)
    # tuple software
    tes = dtes.get(software, {}).get(ctc, None)
    tsoftw = (software, tes)
    # internal coordinates
    if itc in dctc[ctc]._dics.keys(): ics = dctc[ctc]._dics[itc]
    elif "*" in dctc[ctc]._dics.keys(): ics = dctc[ctc]._dics["*"]
    else: ics = None
    if itc in dctc[ctc]._dicsbw.keys(): icsbw = dctc[ctc]._dicsbw[itc]
    elif "*" in dctc[ctc]._dicsbw.keys(): icsbw = dctc[ctc]._dicsbw["*"]
    else: icsbw = None
    if itc in dctc[ctc]._dicsfw.keys(): icsfw = dctc[ctc]._dicsfw[itc]
    elif "*" in dctc[ctc]._dicsfw.keys(): icsfw = dctc[ctc]._dicsfw["*"]
    else: icsfw = None
    # path variables
    pathvars.set_ics(ics, icsbw, icsfw)  # before setup3!!
    pathvars.apply_specific(itc)
    pathvars.setup1()
    pathvars.setup2()
    pathvars.setup3()
    # Set Eref (from reaction)
    pathvars.set_eref_from_reaction(target, dchem, dof)
    # Quantum reaction coordinate qrc
    pathvars.prepare_qrc(dchem, dctc, dimasses)
    # frequency scaling factor
    pathvars._freqscal = float(dctc[ctc]._fscal)
    # if dlevel --> no convergence and dlevel data
    if dlevel:
        exception = Exc.NoDLEVELdata(Exception)
        pathvars._scterr = None
        keydhl = "%s.%s.path" % (ctc, itc)
        if keydhl not in dhighlvl.keys():
            # maybe only TS
            keydhl = "%s.%s" % (dctc[ctc]._root, itc)
            if keydhl in dhighlvl.keys():
                dictE = {0.0: dhighlvl[keydhl]}
            else:
                global WARNINGS
                WARNINGS.append("No high-level data for %s" % target)
                raise exception
        else:
            dictE = dhighlvl[keydhl]
        pathvars._dlevel = dictE
    # LOGGER
    pof = PN.get_pof(dlevel, "path", target)
    sys.stdout = Logger(pof, "w", True)
    sys.stdout.writeinfile(PS.init_txt())
    #string
    fncs.print_string(PS.smep_title(target, pathvars, pof), 2)
    # Was previously converged???
    ffloat = "%.3f"
    drstconv = RW.read_rstconv()
    if target in drstconv.keys() and not dlevel and os.path.exists(rstfile):
        lowtemp, useics, scterr, converged = drstconv[target]
        b0 = (converged == "yes")
        b1 = (pathvars._useics == useics)
        b2 = (ffloat % pathvars._scterr == ffloat % scterr)
        b3 = (ffloat % min(ltemp) == ffloat % lowtemp)
        if b0 and b1 and b2 and b3:
            pathvars._scterr = None
            fncs.print_string("THIS PATH IS STORED AS CONVERGED!\n", 4)
            tpath, tcommon, drst = ff.read_rst(rstfile)
            lbw, lfw, sbw, sfw, V0bw, V0fw = sd.rstlimits(drst)
            pathvars._sbw = sbw
            pathvars._sfw = sfw
            del drst
    #----------------#
    # calculate path #
    #----------------#

    # 1. Only MEP
    if not pathvars._beyondmep:
        common, drst, pathvars = calc_mep(target, gtsTS, pathvars, tsoftw, TMP)
        dcoefs = {}
        del drst
        # raise error
        raise Exc.OnlyMEP(Exception)

    # 2. MEP expanded till SCT convergence
    elif pathvars.sct_convergence():
        dcoefs, converged = get_path_sctconv(target, gtsTS, pathvars, tsoftw,
                                             ltemp, TMP, symmetry, plotfile)
        # save convergence in file!
        drstconv = RW.read_rstconv()
        if converged:
            drstconv[target] = (min(ltemp), pathvars._useics, pathvars._scterr,
                                "yes")
        else:
            drstconv[target] = (min(ltemp), pathvars._useics, pathvars._scterr,
                                "no")
        RW.write_rstconv(drstconv)

    # 3. Coefs with the current MEP extension
    else:
        tcommon, drst, pathvars = calc_mep(target, gtsTS, pathvars, tsoftw,
                                           TMP)
        dcoefs, pathvars, palpha, pomega = calc_coefs(target, tcommon, drst,
                                                      pathvars, ltemp,
                                                      symmetry, plotfile)
        del drst

    # print summary with the coefficients
    fncs.print_string(PS.spath_allcoefs(ltemp, dcoefs), 3)
    # return data
    return dcoefs, pathvars
Example #4
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