Пример #1
0
def calculate_QMSHO_for_ctc(Cluster, ltemp, dimasses={}, tupleHL=None):
    global WARNINGS
    # expand data
    ctc = Cluster._ctc
    itcs = Cluster._itcs
    eslist = Cluster._es
    sptype = Cluster._type
    fscal = Cluster._fscal
    diso = Cluster._diso
    if tupleHL is None: dlevel, dhighlvl = False, {}
    else: dlevel, dhighlvl = tupleHL
    # get list of gts files and check existency
    gtsfiles = Cluster.gtsfiles()
    exception = Exc.LackOfGts(Exception)
    for gts in gtsfiles:
        if not os.path.exists(gts):
            exception._var = gts
            raise exception

    # Generate Molecule instances
    molecules = []
    mass = None
    V0LLs = []

    for idx, gts in enumerate(gtsfiles):
        itc, weight = itcs[idx]
        # tuple with isotopic
        if itc in diso.keys(): iso = diso[itc]
        elif "*" in diso.keys(): iso = diso["*"]
        else: iso = None
        tiso = (iso, dimasses)
        # prepare and add molecule
        molecule = molecule_prep(gts, eslist, tiso, fscal)
        # save low-level
        V0LLs.append(float(molecule._V0))
        # save molecule
        molecules.append(molecule)

    # String
    string = ""

    #----------------------------------------------------#
    #             APPLY DUAL LEVEL  (DLEVEL)             #
    #----------------------------------------------------#
    if dlevel:
        # get HL energies
        V0HLs = get_V0HL_list(Cluster, dhighlvl)

        # only one conformer?? Keep LL relative energy
        num_nones = V0HLs.count(None)
        if len(V0HLs) == num_nones + 1:
            dlevel_ok = True
            IDX = [
                idx for idx, V0HL_i in enumerate(V0HLs) if V0HL_i is not None
            ][0]
            deltaE = V0HLs[IDX] - V0LLs[IDX]
            V0HLs = [V0LL_i + deltaE for V0LL_i in V0LLs]
        elif num_nones == 0:
            dlevel_ok, IDX = True, None
        else:
            dlevel_ok, IDX = False, None

        # add to string
        string += "    keyword --dlevel activated: applying High-Level energies to this STRUC\n"
        string += "\n"
        string += "        * Low-level (LL) and high-level (HL) energies (in hartree):\n"
        string += "\n"
        string += "          ---------------------------------------------------\n"
        string += "           conformer |     LL energy     |     HL energy     \n"
        string += "          ---------------------------------------------------\n"
        for idx, (itc, weight) in enumerate(itcs):
            if V0HLs[idx] is None: V0HL = "        -        "
            else: V0HL = "%+17.8f" % V0HLs[idx]
            string += "           %-9s | %+17.8f | %s " % (itc, V0LLs[idx],
                                                           V0HL)
            if idx == IDX: string += "*"
            string += "\n"
        string += "          ---------------------------------------------------\n"
        if IDX is not None:
            string += "           * conformer for which the HL energy was found\n"
        string += "\n"

        # apply HL to each conformer
        if dlevel_ok:
            for idx, molecule in enumerate(molecules):
                molecule._V0 = float(V0HLs[idx])
                molecule._ccV1 = molecule._V0 + float(molecule._cczpe)
        else:
            string += "        * FAIL!! Not enough data... DUAL-LEVEL will be omitted!\n"
            string += "\n"
            WARNINGS.append("Dual-level was not applied to %s..." % ctc)
    #----------------------------------------------------#

    # Get min of V0 and V1
    V0 = min([molecule._V0 for molecule in molecules])
    V1 = min([molecule._ccV1 for molecule in molecules])

    string += add_iblank(PS.getstring_ctc(sptype, molecules, itcs, V0, V1), 4)
    # Compare masses
    for molecule in molecules:
        if mass is None: mass = molecule._mass
        # compare masses
        if abs(mass - molecule._mass) * AMU > EPS_AMU:
            WARNINGS.append("Mass inconsistences in %s" % ctc)
            exception = Exc.DiffMassConf(Exception)
            exception._var = string
            raise exception
    # get partition functions for each molecule (and for CTC)
    dctr = {}
    dpfn = {}
    dgibbs1cm3 = {}
    dgibbs1bar = {}
    pfn_tot = [0.0 for T in ltemp]
    #pfn_gibbs  = [0.0 for T in ltemp] # goes without sigma_rot
    for idx, molecule in enumerate(molecules):
        itc, weight = itcs[idx]
        V0_i, V1_i, pf_i, tuple_i = molecule_pfns(molecule, ltemp, sptype)
        key = PN.struckey(ctc, itc)
        # save individual pfn and gibbs free energy
        rotsigma = molecule._rotsigma
        # Considering volume --> 1 particle per cc
        gibbs1cm3_i = [
            V1_i - KB * T * np.log(q_j * VOL0) for T, q_j in zip(ltemp, pf_i)
        ]
        # Considering pression --> 1bar
        gibbs1bar_i = [
            V1_i - KB * T * np.log(q_j * pressure2vol(PRE0, T))
            for T, q_j in zip(ltemp, pf_i)
        ]
        # save data
        dpfn[key] = (V0_i, V1_i, pf_i)
        dgibbs1cm3[key] = gibbs1cm3_i
        dgibbs1bar[key] = gibbs1bar_i
        # update MSHO values
        rel_V1 = V1_i - V1
        for idx, T in enumerate(ltemp):
            beta = 1.0 / (T * KB)
            pfn_tot[idx] += weight * pf_i[idx] * exp128(-rel_V1 * beta)
            #pfn_gibbs[idx] += weight*pf_i[idx]*exp128(-rel_V1*beta)*rotsigma
        # add to string
        pf_PIB, pf_RR, pf_HO, pf_ele = tuple_i
        pf_RRHO = [aa * bb for aa, bb in zip(pf_RR, pf_HO)]
        dctr[key] = (pf_PIB, pf_RRHO, pf_ele)
        string += "    " + "-" * len("Conformation: %s " % itc) + "\n"
        string += "    Conformation: %s\n" % itc
        string += "    " + "-" * len("Conformation: %s " % itc) + "\n"
        for line in molecule.info_string().split("\n"):
            string += "     | " + line + "\n"
        #string += add_iblank(molecule.info_string(),5)
        string += "     | Partition functions (pfns):\n"
        table_1a = PS.getstring_pfn1a(ltemp, pf_PIB, pf_RR, pf_HO, pf_ele,
                                      V0_i, V1_i)
        table_1b = PS.getstring_pfn1b(ltemp, pf_i, V0_i, V1_i)
        for line in table_1a.split("\n") + table_1b.split("\n"):
            string += "     | " + line + "\n"
    #string += add_iblank(PS.getstring_pfn1(ltemp,pf_i,pf_PIB,pf_RR,pf_HO,pf_ele),7)
        string += "     | Gibbs free energy (hartree):\n"
        for line in PS.spfn_igibbs(ltemp, gibbs1cm3_i,
                                   gibbs1bar_i).split("\n"):
            string += "     | " + line + "\n"
    #string += add_iblank(PS.spfn_igibbs(ltemp,gibbs1cm3_i,gibbs1bar_i),7)
    # generate molden file
        molden = PN.get_gtsmolden(ctc, itc)
        if not os.path.exists(molden):
            if not os.path.exists(PN.DIR5): os.mkdir(PN.DIR5)
            #molecule.genfile_xyz(molden)
            molecule.genfile_molden(molden)
            string += "     | file %s was generated\n" % molden
            string += "\n"
        string += "\n"
    # save Q_MSHO
    dpfn[PN.struckey(ctc, "msho")] = (V0, V1, pfn_tot)
    pf_PIBele = [aa * bb for aa, bb in zip(pf_PIB, pf_ele)]
    pf_RRHO = [aa / bb for aa, bb in zip(pfn_tot, pf_PIBele)]
    dctr[ctc] = (pf_PIB, pf_RRHO, pf_ele)
    # save Gibbs_MSHO
    gibbs1cm3_tot = [
        V1 - KB * T * np.log(q_j * VOL0) for T, q_j in zip(ltemp, pfn_tot)
    ]
    gibbs1bar_tot = [
        V1 - KB * T * np.log(q_j * pressure2vol(PRE0, T))
        for T, q_j in zip(ltemp, pfn_tot)
    ]
    dgibbs1cm3[PN.struckey(ctc, "msho")] = gibbs1cm3_tot
    dgibbs1bar[PN.struckey(ctc, "msho")] = gibbs1bar_tot
    # Add to string
    nconfs = sum([weight for name, weight in itcs])
    if nconfs > 1:
        dchi = conformer_contributions(ltemp, dpfn, ctc, itcs)
        string += "\n"
        string += "    Total multi-structural HO pfn (QMS_HO):\n"
        string += add_iblank(PS.getstring_pfn2a(ltemp, pfn_tot, V0, V1), 5)
        string += "    Total HO Gibbs free energies (GFE):\n"
        string += add_iblank(
            PS.getstring_pfn2b(ltemp, gibbs1cm3_tot, gibbs1bar_tot), 5)
        string += "    Individual contributions to the partition function:\n"
        string += add_iblank(PS.string_contributions(itcs, ltemp, dchi), 5)
    else:
        dchi = {}
    return dpfn, dgibbs1cm3, dgibbs1bar, string, dchi, dctr
Пример #2
0
def calculate_QMSHO_for_ctc(Cluster, ltemp, dimasses={}, tupleHL=None):
    # expand data
    ctc = Cluster._ctc
    itcs = Cluster._itcs
    eslist = Cluster._es
    sptype = Cluster._type
    fscal = Cluster._fscal
    diso = Cluster._diso
    if tupleHL is None: dlevel, dhighlvl = False, {}
    else: dlevel, dhighlvl = tupleHL
    # get list of gts files and check existency
    gtsfiles = Cluster.gtsfiles()
    exception = Exc.LackOfGts(Exception)
    for gts in gtsfiles:
        if not os.path.exists(gts):
            exception._var = gts
            raise exception
    # DLEVEL
    if dlevel: V0HLs = get_V0HL_list(Cluster._root, itcs, dhighlvl)
    else: V0HLs = [None for itc, weight in itcs]
    # Generate Molecule instances
    molecules = []
    mass = None
    V0LLs = []
    for idx, gts in enumerate(gtsfiles):
        itc, weight = itcs[idx]
        # tuple with isotopic
        if itc in diso.keys(): iso = diso[itc]
        elif "*" in diso.keys(): iso = diso["*"]
        else: iso = None
        tiso = (iso, dimasses)
        # prepare and add molecule
        molecule = molecule_prep(gts, eslist, tiso, fscal)
        # save low-level
        V0LLs.append(float(molecule._V0))
        # apply dlevel
        if V0HLs[idx] is not None:
            molecule._V0 = V0HLs[idx]
            molecule._ccV1 = molecule._V0 + molecule._cczpe
        # save molecule
        molecules.append(molecule)
    # Get min of V0 and V1
    V0 = min([molecule._V0 for molecule in molecules])
    V1 = min([molecule._ccV1 for molecule in molecules])
    # String
    string = ""
    if dlevel:
        string += "    keyword --dlevel activated: applying High-Level energies to this STRUC\n"
        string += "\n"
        string += "        * Low-level (LL) and high-level (HL) energies (in hartree):\n"
        string += "\n"
        string += "          ---------------------------------------------------\n"
        string += "           conformer |     LL energy     |     HL energy     \n"
        string += "          ---------------------------------------------------\n"
        for idx, (itc, weight) in enumerate(itcs):
            if V0HLs[idx] is None: V0HL = "        -        "
            else: V0HL = "%+17.8f" % V0HLs[idx]
            string += "           %-9s | %+17.8f | %s \n" % (itc, V0LLs[idx],
                                                             V0HL)
        string += "          ---------------------------------------------------\n"
        string += "\n"
        if None in V0HLs:
            string += "        * FAIL!! Not enough data... DUAL-LEVEL will be omitted!\n"
            string += "\n"
            global WARNINGS
            WARNINGS.append("Dual-level was not applied to %s..." % ctc)
    string += add_iblank(PS.getstring_ctc(sptype, molecules, itcs, V0, V1), 4)
    # Compare masses
    for molecule in molecules:
        if mass is None: mass = molecule._mass
        # compare masses
        if abs(mass - molecule._mass) * AMU > EPS_AMU:
            global WARNINGS
            WARNINGS.append("Mass inconsistences in %s" % ctc)
            exception = Exc.DiffMassConf(Exception)
            exception._var = string
            raise exception
    # get partition functions for each molecule (and for CTC)
    dpfn = {}
    dgibbs = {}
    pfn_tot = [0.0 for T in ltemp]
    pfn_gibbs = [0.0 for T in ltemp]  # goes without sigma_rot
    for idx, molecule in enumerate(molecules):
        itc, weight = itcs[idx]
        V0_i, V1_i, pf_i, tuple_i = molecule_pfns(molecule, ltemp, sptype)
        key = PN.struckey(ctc, itc)
        # save individual pfn and gibbs free energy
        rotsigma = molecule._rotsigma
        gibbs_i = [
            V1_i - KB * T * np.log(q_j * rotsigma)
            for T, q_j in zip(ltemp, pf_i)
        ]
        dpfn[key] = (V0_i, V1_i, pf_i)
        dgibbs[key] = gibbs_i
        # update MSHO values
        rel_V1 = V1_i - V1
        for idx, T in enumerate(ltemp):
            beta = 1.0 / (T * KB)
            pfn_tot[idx] += weight * pf_i[idx] * np.exp(-rel_V1 * beta)
            pfn_gibbs[idx] += weight * pf_i[idx] * np.exp(
                -rel_V1 * beta) * rotsigma
        # add to string
        pf_PIB, pf_RR, pf_HO, pf_ele = tuple_i
        string += "    Conformation: %s\n" % itc
        string += add_iblank(molecule.info_string(), 7)
        string += "       partition functions (with regards electronic energy + ZPE):\n"
        string += add_iblank(
            PS.getstring_pfn1(ltemp, pf_i, pf_PIB, pf_RR, pf_HO, pf_ele), 7)
    # save Q_MSHO
    dpfn[PN.struckey(ctc, "msho")] = (V0, V1, pfn_tot)
    # save Gibbs_MSHO
    gibbs_tot = [V1 - KB * T * np.log(q_j) for T, q_j in zip(ltemp, pfn_gibbs)]
    dgibbs[PN.struckey(ctc, "msho")] = gibbs_tot
    # Add to string
    nconfs = sum([weight for name, weight in itcs])
    if nconfs > 1:
        dchi = conformer_contributions(ltemp, dpfn, ctc, itcs)
        string += "    MSHO partition function (QMSHO) with regard to min(V1):\n"
        string += "\n"
        string += add_iblank(PS.getstring_pfn2(ltemp, pfn_tot), 10)
        string += "    Individual contributions to QMSHO:\n"
        string += "\n"
        string += add_iblank(PS.string_contributions(itcs, ltemp, dchi), 10)
    else:
        dchi = {}
    return dpfn, dgibbs, string, dchi