Exemple #1
0
def execute_pfn(itargets, dchem, idata, status, case):
    reactions = set([])
    for target in itargets:
        ctc1, itc1 = PN.name2data(target)
        the_reaction = None
        for reaction, (Rs, TS, Ps) in dchem.items():
            try:
                ctc2, itc2 = PN.name2data(TS)
            except:
                continue
            if ctc1 == ctc2:
                the_reaction = reaction
                if itc1 == itc2: break
        if the_reaction is not None: reactions.add(the_reaction)
    if len(reactions) == 0: return
    reactions = sorted(list(reactions))

    print "   The selected transitions states are involved in defined reactions!"
    pfn_targets = set([])
    for reaction in reactions:
        print "      * %s" % reaction
        Rs, TS, Ps = dchem[reaction]
        for xx in Rs + [TS] + Ps:
            pfn_targets.add(PN.name2data(xx)[0])
    if len(pfn_targets) == 0: return
    pfn_targets = sorted(list(pfn_targets))
    print

    import opt_pfn as pfn
    print "   Calculating partition functions for the next targets:"
    for target in pfn_targets:
        print "      * %s" % target
    print
    pfn.main(idata, status, case, targets=pfn_targets)
Exemple #2
0
def data_target(target, dall, ltemp):
    # convert to list
    target = target2list(target)
    # initialize
    tot_V0 = 0.0
    tot_V1 = 0.0
    tot_Q = [1.0 for T in ltemp]
    tot_ANH = [1.0 for T in ltemp]
    trg_ANH = []
    # everything ok?
    if target is None: return None, None, None, tot_ANH, trg_ANH
    # read data
    for trg in target:
        ctc, itc = PN.name2data(trg)
        # Get key
        if itc is None: key = PN.struckey(ctc, "msho")
        else: key = PN.struckey(ctc, itc)
        # look for data
        try:
            V0, V1, pfns = dall["pfn"][key]
        except:
            raise Exc.NoData
        # add energies to total
        tot_V0 += V0
        tot_V1 += V1
        # update total partition function
        tot_Q = [q_i * q_j for q_i, q_j in zip(tot_Q, pfns)]
        # anharmonicity
        if ctc in dall["anh"].keys():
            anh = dall["anh"][ctc]
            tot_ANH = [r1 * r2 for r1, r2 in zip(tot_ANH, anh)]
            trg_ANH.append(trg)
    # return data
    return tot_V0, tot_V1, tot_Q, tot_ANH, trg_ANH
Exemple #3
0
def get_itargets(targets, dpath, dctc):
    '''
    get individual targets
    '''
    # Targets?
    if (len(targets) == 0) or ("*" in targets): targets = dpath.keys()

    # generate list of individual targets
    itargets = []
    for target in targets:
        ctc, itc = PN.name2data(target)
        # check ctc
        if ctc not in dctc.keys():
            print "   * '%s' not in '%s'" % (target, PN.IFILE1)
            print
            continue
        if ctc not in dpath.keys():
            print "   * '%s' not in '%s'" % (target, PN.IFILE3)
            print
            continue
        # list of itcs for the ctc
        itclist = [itc_i for itc_i, weight_i in dctc[ctc]._itcs]
        # add itc
        if itc is None:
            itargets += [
                PN.struckey(ctc, itc) for itc, weight in dctc[ctc]._itcs
            ]
        elif itc in itclist:
            itargets += [PN.struckey(ctc, itc)]
    return sorted(itargets)
Exemple #4
0
def calc_mep(itarget, gtsTS, pathvars, tsoftware, TMP, decrease=False):
    '''
     if decrease = True, MEP is reduced hsteps steps
    '''
    # data in name
    ctc, itc = PN.name2data(itarget)
    # calculate path
    tcommon, drst, pathvars = obtain_mep(itarget, gtsTS, pathvars, tsoftware,
                                         TMP)
    # decrease mep??
    if decrease:
        sbw1, sfw1 = pathvars._sbw, pathvars._sfw
        pathvars.decrease_svals()
        sbw2, sfw2 = pathvars._sbw, pathvars._sfw
        print "    MEP will be reduced to check SCT convergence:"
        print
        print "        sbw: %+8.4f --> %+8.4f bohr" % (sbw1, sbw2)
        print "        sfw: %+8.4f --> %+8.4f bohr" % (sfw1, sfw2)
        print
        drst = {
            label: data
            for label, data in drst.items()
            if in_interval(data[0], sbw2, sfw2)
        }
    # DLEVEL??
    if pathvars._dlevel is not None:
        print "    Applying Dual-Level..."
        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]
            print "             %+8.4f bohr (%-6s) --> %.7f hartree" % (
                s_i, xx_i, yy_i)
        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)
    else:
        # Print table
        fncs.print_string(PS.smep_table(drst, pathvars._eref), 4)
    return tcommon, drst, pathvars
Exemple #5
0
def get_masses(target, dctc, dimasses):
    ctc, itc = PN.name2data(target)
    diso = dctc[ctc]._diso
    if itc in diso.keys(): imod = diso[itc]
    elif "*" in diso.keys(): imod = diso["*"]
    else: imod = None
    if imod is None: return None
    gtsTS = dctc[ctc].gtsfile(itc)
    TS = Molecule()
    TS.set_from_gts(gtsTS)
    TS.apply_imods(imod, dimasses)
    masses = list(TS._masses)
    return masses
Exemple #6
0
 def set_eref_from_reaction(self, tsname, dchem, dof):
     thebool = self._eref in [None, "auto", "default"]
     ctc, itc = PN.name2data(tsname)
     # Get data from reactions
     rname, V0R, V0P, V1R, V1P, GibbsR = get_reaction_energies(
         tsname, dchem, dof)
     self._V1R = V1R
     self._V1P = V1P
     # save GibbsR for CVT gibbs
     self._GibbsR = GibbsR
     # go case by case
     if thebool and V0R is not None: self._eref = V0R
     # save reaction name and check if beyond mep
     self._reaction = rname
     if self._eref in [None, "auto", "default"]: self._beyondmep = False
Exemple #7
0
def factors_from_TS(TS, V1TS, QTS, ltemp, dctc, dall):
    # list of itcs
    ctc, itc = PN.name2data(TS)
    if itc is None: itcs = dctc[ctc]._itcs
    else: itcs = [(itc, 1)]
    # get TST ratios
    tst_ratios = get_TSratios(ctc, itcs, V1TS, QTS, ltemp, dall)
    # print TST ratios
    print_string(PS.srcons_tstratios(ltemp, tst_ratios), 7)
    # get total correction factors
    corrfactors = get_corrfactors(ltemp, ctc, itcs, dall, tst_ratios)
    # print correction factors
    print_string(PS.string_corrfactors(ltemp, corrfactors), 7)
    # print VTST contributions
    print_string(PS.srcons_vtstratios(ltemp, tst_ratios, corrfactors), 7)
    return tst_ratios, corrfactors
Exemple #8
0
 def prepare_qrc(self, dchem, dctc, dimasses):
     # Will qrc be used?
     if self._reaction is None: return
     if self._qrc is None: return
     reactants = dchem[self._reaction][0]
     if len(reactants) != 1: return
     # generate Molecule instance
     reactant = reactants[0]
     ctc, itc = PN.name2data(reactant)
     if ctc not in dctc.keys(): return
     cluster = dctc[ctc]
     if itc is None: itc = cluster._itcs[0][0]
     if itc in cluster._diso.keys(): imods = cluster._diso[itc]
     elif "*" in cluster._diso.keys(): imods = cluster._diso["*"]
     else: imods = None
     gtsfile = PN.get_gts(ctc, itc)
     if not os.path.exists(gtsfile): raise Exception
     # Generate Molecule instance
     reactant = Molecule()
     reactant.set_from_gts(gtsfile)
     # apply fscal
     reactant.set_fscal(fscal=cluster._fscal)
     # apply isotopic masses
     if imods is not None:
         reactant.apply_imods(imods, dimasses)
     # calculate frequencies
     reactant.setup()
     mode, nE = self._qrc
     Vadi = reactant._V0
     for idx, afreq in enumerate(reactant._ccfreqs):
         if idx == mode: continue
         Vadi += afreq2zpe(afreq)
     afreq = reactant._ccfreqs[mode]
     listE = [
         Vadi + (n + 0.5) * HBAR * afreq - self._eref for n in range(nE)
     ]
     self._qrclE = listE
     self._qrcafreq = afreq
Exemple #9
0
    fstatus = ffchecking(mustexist, tocreate)
    if fstatus == -1: exit()
    # expand case
    (dof, hlf, plotfile), dlevel, software = case
    #-------------------------------------------------------#

    print "   Selected software: %s" % software
    print

    targets = get_targets(targets, dctc)
    # Print targets
    if len(targets) != 0:
        print "   High-level (HL) calculations will be carried out for:"
        ml = max([len(target) for target in targets] + [1])
        for target in targets:
            ctc, itc = PN.name2data(target)
            TMP = PN.TMPHLi % PN.struckey(ctc, itc)
            print "       %s (TMP folder: %s)" % ("%%-%is" % ml % target, TMP)
        print
    else:
        print "   No valid target(s) for High-level (HL) calculations"
        print
        return

    # read high-level output file
    dhighlvl = RW.read_highlevelfile(hlf)

    # loop over each target
    print "   Carrying out HL-calculations:"
    print
    ml = max([len(target) for target in targets])
Exemple #10
0
def get_reaction_energies(TS, dchem, dof):
    '''
    * checks the reactions which involved the target transition
      state (TS) in order to extract V0 and V1 for reactants
      and products 
    '''
    # initialize variables
    reaction = None
    Eref = None
    V0R = None
    V0P = None
    V1R = None
    V1P = None
    GibbsR = None
    # select reaction
    ctc, itc = PN.name2data(TS)
    for rname in dchem.keys():
        Rs, ts, Ps = dchem[rname]
        ctc2, itc2 = PN.name2data(ts)
        if ctc == ctc2:
            reaction = rname
            if itc == itc2: break
    # no reaction?
    if reaction is None: return reaction, V0R, V0P, V1R, V1P, GibbsR
    # read dof
    dall = RW.read_alldata(dof)[0]
    # get energy from reaction
    Rs = dchem[reaction][0]
    Ps = dchem[reaction][2]
    # reactants
    if len(Rs) != 0:
        V0R, V1R = 0.0, 0.0
        for R in Rs:
            ctc, itc = PN.name2data(R)
            if itc is None: key = PN.struckey(ctc, "msho")
            else: key = R
            data = dall["pfn"].get(key, None)
            if data is None:
                V0R, V1R = None, None
                break
            V0, V1, pfns = data
            V0R += V0
            V1R += V1
            # Gibbs energy
            if key in dall["gibbs"].keys():
                gibbs = dall["gibbs"][key]
                if GibbsR is None: GibbsR = gibbs
                else: GibbsR = [gi + gj for gi, gj in zip(GibbsR, gibbs)]
    # products
    if len(Ps) != 0:
        V0P, V1P = 0.0, 0.0
        for P in Ps:
            ctc, itc = PN.name2data(P)
            if itc is None: key = PN.struckey(ctc, "msho")
            else: key = P
            data = dall["pfn"].get(key, None)
            if data is None:
                V0P, V1P = None, None
                break
            V0, V1, pfns = data
            V0P += V0
            V1P += V1
    # Output
    return reaction, V0R, V0P, V1R, V1P, GibbsR
Exemple #11
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)
    # temporal folder
    TMP = PN.TMPi % (target)
    # if exists,remove content
    # (to avoid reading old files from different levels of calculation)
    if os.path.exists(TMP): 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
    dics = dctc[ctc]._dics
    if itc in dics.keys(): ics = dics[itc]
    elif "*" in dics.keys(): ics = dics["*"]
    else: ics = None
    # path variables
    pathvars.set_ics(ics)  # 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._sctmns = 0
        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)
    #string
    fncs.print_string(PS.smep_title(target, pathvars, pof), 2)
    #----------------#
    # calculate path #
    #----------------#
    # 1. MEP
    if not pathvars._beyondmep:
        common, drst, pathvars = calc_mep(target,
                                          gtsTS,
                                          pathvars,
                                          tsoftw,
                                          TMP,
                                          decrease=False)
        dcoefs = {}
        del drst
        # raise error
        raise Exc.OnlyMEP(Exception)
    # 2. MEP + coefs
    else:
        # 2.1 MEP expanded till SCT convergence
        if pathvars.sct_convergence():
            dcoefs = get_path_sctconv(target, gtsTS, pathvars, tsoftw, ltemp,
                                      TMP, plotfile)
        # 2.2 Coefs with the current MEP extension
        else:
            tcommon, drst, pathvars = calc_mep(target,
                                               gtsTS,
                                               pathvars,
                                               tsoftw,
                                               TMP,
                                               decrease=False)
            dcoefs, pathvars = calc_coefs(target, tcommon, drst, pathvars,
                                          ltemp, plotfile)
            del drst
    # print summary with the coefficients
    fncs.print_string(PS.spath_allcoefs(ltemp, dcoefs), 3)
    # return data
    return dcoefs, pathvars
Exemple #12
0
def obtain_mep(target, gtsTS, pathvars, tsoftware, TMP):
    ctc, itc = PN.name2data(target)

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

    # data for single-point calculation
    spc_args = (tes, TMP, False)
    spc_fnc = get_spc_fnc(software)

    # read rst
    tpath2, tcommon2, drst = ff.read_rst(rstfile)
    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]):
            print "    'fwdir' variable differs from MEP direction in rst file!"
            print "        * modifying rst internal dictionary..."
            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
            print "        * rewriting rst file..."
            ff.write_rst(rstfile, tpath2, tcommon2, drst)

    # Extension of MEP in rst is bigger
    if drst != {}:
        lbw, lfw, sbw, sfw, Ebw, Efw = 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.set_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)

    #------------#
    # First step #
    #------------#
    print
    print "    Performing first step of MEP..."
    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)
    fncs.print_string(PS.smep_first(ts._symbols, ts._xms, v0, v1), 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
    print "    Calculating MEP..."
    print
    print "       * REMEMBER: data of each step will be saved at %s" % rstfile
    print "                   a summary will be printed when finished"
    # 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
    print "       * FINISHED!"
    print
    drst.update(drstbw)
    drst.update(drstfw)
    points = [TSLABEL] + pointsbw + pointsfw
    # empty variables
    del drstbw, pointsbw
    del drstfw, pointsfw
    # Rewrite rst
    print "       * (re)writing file: %s (sorted version)" % rstfile
    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, Ebw, Efw = sd.rstlimits(drst)
    convbw, l1bw, l2bw = convbw
    convfw, l1fw, l2fw = convfw
    if l1bw + l1fw != "":
        print "       * EPS criteria (epse and epsg):"
        print
        if l1bw != "": print "         %s" % l1bw
        if l2bw != "": print "         %s" % l2bw
        if l1fw != "": print "         %s" % l1fw
        if l2fw != "": print "         %s" % l2fw
        print
        if convbw:
            pathvars.converged_in_bw(sbw)
            print "         CRITERIA FULFILLED in backward dir.!"
            print "         path stopped at sbw = %+8.4f bohr" % sbw
            print
        if convfw:
            pathvars.converged_in_fw(sfw)
            print "         CRITERIA FULFILLED in forward dir.!"
            print "         path stopped at sfw = %+8.4f bohr" % sfw
            print
    # write molden file
    print "       * writing file: %s" % xyzfile
    ff.rst2xyz(rstfile, xyzfile, onlyhess=True)
    print
    # reference energy
    if pathvars._eref is None: pathvars._eref = Ebw
    # return data
    return tcommon, drst, pathvars