def get_targets(targets, dctc): # No targets selected if targets == [] or targets == "*": targets = [ PN.struckey(ctc, itc) for ctc in dctc.keys() for itc, weight in dctc[ctc]._itcs ] targets.sort() return targets # Check targets itargets = [] for target in targets: np = target.count(".") # a whole ctc is selected if np == 0: ctc = target if ctc not in dctc.keys(): continue itargets += [ PN.struckey(ctc, itc) for itc, weight in dctc[ctc]._itcs ] # a specific itc elif np == 1: ctc, itc = target.split(".") if ctc not in dctc.keys(): continue itcs = [itc_i for itc_i, weight_i in dctc[ctc]._itcs] if itc not in itcs: continue itargets += [target] return itargets
def get_contributions(ctc, dall, dctc, ltemp): if ctc not in dctc.keys(): return None # Only one conformer? if len(dctc[ctc]._itcs) == 1: itc, weight = dctc[ctc]._itcs[0] dchi = {itc: [1.0 for T in ltemp]} return dchi # Get total partition function V0, V1, PFN = dall["pfn"]["%s.msho" % ctc] # Get ratios dchi = {} for itc, weight in dctc[ctc]._itcs: # Get individual partition functions try: V0i, V1i, PFNi = dall["pfn"][PN.struckey(ctc, itc)] # Calculate contribution dE = (V1i - V1) exp_arg = [-dE / pc.KB / T for T in ltemp] ratio_pfn = [weight * pfi / pftot for pfi, pftot in zip(PFNi, PFN)] chi_i = [ aa * fncs.exp128(bb) for aa, bb in zip(ratio_pfn, exp_arg) ] dchi[itc] = np.array(chi_i) except: exception = Exc.LostConformer(Exception) exception._var = PN.struckey(ctc, itc) raise exception # Return data return dchi
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(): fncs.print_string("* '%s' not in '%s'" % (target, PN.IFILE1), 3) print("") continue if ctc not in dpath.keys(): fncs.print_string("* '%s' not in '%s'" % (target, PN.IFILE3), 3) 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)
def conformer_contributions(ltemp, dpfn, ctc, itcs): # get contributions dchi = {} for itc, weight in itcs: V0i, V1i, Qi = dpfn[PN.struckey(ctc, itc)] V0, V1, Q = dpfn[PN.struckey(ctc, "msho")] # calculate contribution expvec = [exp128(-(V1i - V1) / KB / T) for T in ltemp] chi = weight * np.array(Qi) / np.array(Q) * np.array(expvec) # save data dchi[itc] = chi return dchi
def obtain_pfns(self): # (a) reactants for target in self._reacts: self.calculate_chi0(target) V0, V1, pfns, anh = self.return_pfns(target) self._V0R += V0 self._V1R += V1 self._QtR *= pfns self._ANHR *= anh self._FMSQH *= self._chi0[target][1] # (b) products for target in self._prods: V0, V1, pfns, anh = self.return_pfns(target) self._V0P += V0 self._V1P += V1 self._QtP *= pfns self._ANHP *= anh # (c) transition state if self._ts is None: return # (c.1) get partition functions self.calculate_chi0(self._ts) self._V0TS, self._V1TS, self._QtTS, self._ANHTS = self.return_pfns( self._ts) # (c.2) Conversion betweem SS-QH and MS-QH rate constants self._FMSQH /= self._chi0[self._ts][1] # (c.2) get individual contributions of TS and itc of min(V0) ctc, itcs, ms = self._itcs[self._ts] if ms: V0, V1, PFN = self._dall["pfn"][PN.struckey(ctc, "msho")] # save most stable conformer self._tsitc0 = self._chi0[self._ts][0] # calculate chi for each conformer of the ts for itc, weight in itcs: # see pfn V0i, V1i, PFNi = self._dall["pfn"][PN.struckey(ctc, itc)] dE = (V1i - V1) exp_arg = [-dE / KB / T for T in self._ltemp] ratio_pfn = [ weight * pfi / pftot for pfi, pftot in zip(PFNi, PFN) ] chi_i = [ aa * fncs.exp128(bb) for aa, bb in zip(ratio_pfn, exp_arg) ] # save data self._tschi["tst"][itc] = np.array(chi_i) else: itc, weight = itcs[0] self._tschi["tst"][itc] = np.array([1.0 for T in self._ltemp]) self._tsitc0 = None
def return_pfns(self,target): ctc,itcs,ms = self._itcs[target] itc0,weight0 = itcs[0] # key for partition functions & anharmonicity if ms: key = PN.struckey(ctc,"msho") anh = self._dall["anh"].get(ctc,None) else: key = PN.struckey(ctc,itc0) anh = None V0,V1,pfns = self._dall["pfn"][key] if anh is None: anh = np.array([1.0 for t in self._ltemp]) else : self._anhctcs.add(ctc) return V0, V1, pfns, anh
def return_pfns(self, target): ctc, itcs, ms = self._itcs[target] # key for partition functions if ms: key = PN.struckey(ctc, "msho") else: key = PN.struckey(ctc, itcs[0][0]) # Energies and partition functions from data V0, V1, pfns = self._dall["pfn"][key] # anharmonicity (if commented in pif.struc --> not include it) anh = None if ms and self._anhfile[ctc] is not None: anh = self._dall["anh"].get(ctc, None) # Save data if anh is None: anh = np.array([1.0 for t in self._ltemp]) else: self._anhctcs.add(ctc) return V0, V1, pfns, anh
def get_V0HL_list(ctc, itcs, dhighlvl): list_V0HL = [] for itc, weight in itcs: key = PN.struckey(ctc, itc) V0HL = dhighlvl.get(key, None) list_V0HL.append(V0HL) return list_V0HL
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 calculate_transcoeffs(self): if self._ts is None: return ctc, itcs, ms = self._itcs[self._ts] # Get individual transmission coefficients for itc, weight in itcs: tsname = PN.struckey(ctc, itc) cvt = self._dall.get("cvt", {}).get(tsname, None) zct = self._dall.get("zct", {}).get(tsname, None) sct = self._dall.get("sct", {}).get(tsname, None) cagtst = self._dall.get("cagtst", {}).get(tsname, None) cagcvt = self._dall.get("cagcvt", {}).get(tsname, None) # now total transmission coefficients try: tc_tstzct = np.array(fncs.prod_list((zct, cagtst))) except: tc_tstzct = None try: tc_tstsct = np.array(fncs.prod_list((sct, cagtst))) except: tc_tstsct = None try: tc_cvt = np.array(fncs.prod_list((cvt, ))) except: tc_cvt = None try: tc_cvtzct = np.array(fncs.prod_list((zct, cvt, cagcvt))) except: tc_cvtzct = None try: tc_cvtsct = np.array(fncs.prod_list((sct, cvt, cagcvt))) except: tc_cvtsct = None # save self._dtcoef["tstzct"][itc] = tc_tstzct self._dtcoef["tstsct"][itc] = tc_tstsct self._dtcoef["cvt"][itc] = tc_cvt self._dtcoef["cvtzct"][itc] = tc_cvtzct self._dtcoef["cvtsct"][itc] = tc_cvtsct # Calculate contributions to other methods for X in self._dtcoef.keys(): # calculate numerator of contribution for itc, weight in itcs: chi_i = self._tschi["tst"][itc] tc_i = self._dtcoef[X][itc] if tc_i is not None: self._tschi[X][itc] = chi_i * tc_i else: self._tschi[X][itc] = None # averaged transmission coefficient chis_X = [chi_i_X for chi_i_X in self._tschi[X].values()] try: self._dtcoef[X]["averaged"] = sum(chis_X) except: self._dtcoef[X]["averaged"] = None # calculate contribution averaged = self._dtcoef[X]["averaged"] for itc, weight in itcs: chi_i = self._tschi["tst"][itc] tc_i = self._dtcoef[X][itc] if averaged is None or tc_i is None: self._tschi[X][itc] = None else: self._tschi[X][itc] /= averaged
def get_V0HL_list(Cluster, dhighlvl): list_V0HL = [] for itc, weight in Cluster._itcs: key = PN.struckey(Cluster._root, itc) V0HL = dhighlvl.get(key, None) list_V0HL.append(V0HL) return list_V0HL
def calculate_chi0(self, target): ctc, itcs, ms = self._itcs[target] # Get total partition function key = PN.struckey(ctc, "msho") V0, V1, PFN = self._dall["pfn"][key] # Get contribution of each conformer itc0, V0_0, V1_0, PFN_0 = None, float("inf"), float("inf"), None for itc, weight_i in itcs: # individual partition function key_i = PN.struckey(ctc, itc) V0_i, V1_i, PFN_i = self._dall["pfn"][key_i] if V0_i < V0_0: itc0, V0_0, V1_0, PFN_0 = itc, V0_i, V1_i, PFN_i # contribution of most stable conformer (wo considering weight) dE = (V1_0 - V1) exp_arg = [-dE / KB / T for T in self._ltemp] ratio_pfn = [pfi / pftot for pfi, pftot in zip(PFN_0, PFN)] chi_i = [aa * fncs.exp128(bb) for aa, bb in zip(ratio_pfn, exp_arg)] self._chi0[target] = (itc0, np.array(chi_i))
def get_transmissioncoeffs(ctc, dall, dctc, ltemp): # Get contributions dchi = get_contributions(ctc, dall, dctc, ltemp) if ctc not in dctc.keys(): return None, dchi # Get individual transmission coefficients dtc = {X: {} for X in "tst,tstzct,tstsct,cvt,cvtzct,cvtsct".split(",")} # Get transmission coefficients for itc, weight in dctc[ctc]._itcs: tsname = PN.struckey(ctc, itc) cvt = dall.get("cvt", {}).get(tsname, None) zct = dall.get("zct", {}).get(tsname, None) sct = dall.get("sct", {}).get(tsname, None) cagtst = dall.get("cagtst", {}).get(tsname, None) cagcvt = dall.get("cagcvt", {}).get(tsname, None) # now total transmission coefficients try: tc_tstzct = np.array(fncs.prod_list((zct, cagtst))) except: tc_tstzct = None try: tc_tstsct = np.array(fncs.prod_list((sct, cagtst))) except: tc_tstsct = None try: tc_cvt = np.array(fncs.prod_list((cvt, ))) except: tc_cvt = None try: tc_cvtzct = np.array(fncs.prod_list((zct, cvt, cagcvt))) except: tc_cvtzct = None try: tc_cvtsct = np.array(fncs.prod_list((sct, cvt, cagcvt))) except: tc_cvtsct = None # save dtc["tst"][itc] = np.array([1.0 for T in ltemp]) dtc["tstzct"][itc] = tc_tstzct dtc["tstsct"][itc] = tc_tstsct dtc["cvt"][itc] = tc_cvt dtc["cvtzct"][itc] = tc_cvtzct dtc["cvtsct"][itc] = tc_cvtsct # Get averaged transmission coefficient for X in dtc.keys(): # Initializing averaged value dtc[X]["averaged"] = np.array([0.0 for T in ltemp]) # Calculating averaged coef for itc, weight in dctc[ctc]._itcs: # No data for this method? if dtc[X][itc] is None: dtc[X]["averaged"] = None break # update averaged transmission coeff else: dtc[X]["averaged"] += dchi[itc] * dtc[X][itc] return dtc, dchi
def obtain_pfns(self): # (a) reactants for target in self._reacts: V0, V1, pfns, anh = self.return_pfns(target) self._V0R += V0 self._V1R += V1 self._QtR *= pfns self._ANHR *= anh # (b) products for target in self._prods: V0, V1, pfns, anh = self.return_pfns(target) self._V0P += V0 self._V1P += V1 self._QtP *= pfns self._ANHP *= anh # (c) transition state if self._ts is None: return self._V0TS, self._V1TS, self._QtTS, self._ANHTS = self.return_pfns(self._ts) # (c.1) get individual contributions of TS and itc of min(V0) ctc, itcs, ms = self._itcs[self._ts] if ms: minV0 = float("inf") V0,V1,PFN = self._dall["pfn"][PN.struckey(ctc,"msho")] for itc,weight in itcs: # see pfn V0i,V1i,PFNi = self._dall["pfn"][PN.struckey(ctc,itc)] dE = (V1i-V1) exp_arg = [-dE/KB/T for T in self._ltemp] ratio_pfn = [weight*pfi/pftot for pfi,pftot in zip(PFNi,PFN)] chi_i = [aa*fncs.exp128(bb) for aa,bb in zip(ratio_pfn,exp_arg)] # see most stable if V0i < minV0: minV0, self._tsitc0 = V0i, itc # save data self._tschi["tst"][itc] = np.array(chi_i) else : itc,weight = itcs[0] self._tschi["tst"][itc] = np.array( [1.0 for T in self._ltemp] ) self._tsitc0 = None
except Exception as exception: WARNINGS.append("Problem with %s" % ctc) if type(exception) == Exc.DiffMassConf: print_string(exception._var, NBS) continue if type(exception) == Exc.LackOfGts: error_line = "ERROR: Unable to find '%s'" % exception._var print_string(error_line, 7) print("") continue raise exception # print info print_string(string, NBS) # anharmonicity?? anhfile = dctc[ctc]._anh V0, V1, QMSHO = dpfn_i[PN.struckey(ctc, "msho")] ZPEMSHO = V1 - V0 RATIO, string = deal_with_anh(anhfile, ltemp, ZPEMSHO, QMSHO) if string != "": print_string(string, 7) if RATIO is None: WARNINGS.append("Anharmonicity IGNORED for %s" % ctc) # add data of weights to plot if plotfile is not None and dchi != {}: plotdata = {} plotdata.update(manage_data_for_plot_weights(ctc, ltemp, dchi)) write_plotfile(plotfile, plotdata) # update dictionary dpfn.update(dpfn_i) dgibbs1cm3.update(dgibbs1cm3_i) dgibbs1bar.update(dgibbs1bar_i)
def return_V0V1(self, ctc, itc): key = PN.struckey(ctc, itc) V0, V1, pfns = self._dall["pfn"][key] return V0, V1
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["gibbs1cm3"].keys(): gibbs = dall["gibbs1cm3"][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
# 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]) cols = ("target","point identifier","s value (bohr)","E_HL (hartree)")
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