V_zc = (V_cathode + V_anode) / 2 V_Q_electrode[V_zc] = 0 else: q_cathode = df.rho_q[ args.cathode] * dz / NANO**2 * ELEMENTARY_CHARGE / MILLI # mC/m^2 q_anode = df.rho_q[ args.anode] * dz / NANO**2 * ELEMENTARY_CHARGE / MILLI # mC/m^2 if abs(q_cathode + q_anode) > 1E6: print('WARNING: charges on cathode and anode do not equal: %s' % inp) V_Q_electrode[V_cathode] = q_cathode V_Q_electrode[V_anode] = q_anode V_Q_cell[V_drop] = q_cathode V_list, Q_list = zip(*sorted(V_Q_electrode.items())) coeff4, score4 = polyfit(V_list, Q_list, 4) coeff5, score5 = polyfit(V_list, Q_list, 5) print('Zero charge voltage: %.4f V' % V_zc) print('RSQ for 4th and 5th polynomial fitting Cdiff: %.4f %.4f' % (score4, score5)) print('%10s %10s %10s %10s %10s %10s' % ('electrode', 'V', 'Q', 'Cint', 'Cdiff-4th', 'Cdiff-5th')) for V, Q in sorted(V_Q_electrode.items()): Cdiff4 = polyval_derivative(V, coeff4)[1] Cdiff5 = polyval_derivative(V, coeff5)[1] Cint = Q / (V - V_zc) if V != V_zc else 0 print('%10s %10.4f %10.4f %10.4f %10.4f %10.4f' % ('', V, Q, Cint, Cdiff4, Cdiff5)) print('%10s %10s %10s %10s' % ('cell', 'V', 'Q', 'Cint')) for V, Q in sorted(V_Q_cell.items()):
def post_process(T_list, P_list, result_list, n_mol_list, **kwargs) -> (dict, str): t_set = set(T_list) p_set = set(P_list) if len(t_set) < 5 or len(p_set) < 5: return None, 'T or P points less than 5' from mstools.analyzer.fitting import polyfit_2d, polyfit def round3(x): return float('%.3e' % x) ### einter divided by number of molecules dens_stderr_list = [ list(map(round3, result['density'])) for result in result_list ] eint_stderr_list = [ list(map(lambda x: round3(x / n_mol_list[0]), result['einter'])) for result in result_list ] comp_stderr_list = [ list(map(round3, result['compress'])) for result in result_list ] dens_list = [i[0] for i in dens_stderr_list] eint_list = [i[0] for i in eint_stderr_list] comp_list = [i[0] for i in comp_stderr_list] ### Fit against T, P with poly4 coeff_dens, score_dens = polyfit_2d(T_list, P_list, dens_list, 4) coeff_eint, score_eint = polyfit_2d(T_list, P_list, eint_list, 4) ### Fit against only T with poly3 t_p_dens_list = list(map(list, zip(T_list, P_list, dens_list))) t_p_dens_list.sort(key=lambda x: (x[1], x[0])) # sorted by P, then T t_p_eint_list = list(map(list, zip(T_list, P_list, eint_list))) t_p_eint_list.sort(key=lambda x: (x[1], x[0])) # sorted by P, then T t_p_comp_list = list(map(list, zip(T_list, P_list, comp_list))) t_p_comp_list.sort(key=lambda x: (x[1], x[0])) # sorted by P, then T t_p_dens_stderr_list = list( map(list, zip(T_list, P_list, dens_stderr_list))) t_p_dens_stderr_list.sort(key=lambda x: (x[1], x[0])) # sorted by P, then T t_p_eint_stderr_list = list( map(list, zip(T_list, P_list, eint_stderr_list))) t_p_eint_stderr_list.sort(key=lambda x: (x[1], x[0])) # sorted by P, then T t_p_comp_stderr_list = list( map(list, zip(T_list, P_list, comp_stderr_list))) t_p_comp_stderr_list.sort(key=lambda x: (x[1], x[0])) # sorted by P, then T t_dens_poly3 = {} t_eint_poly3 = {} t_comp_poly3 = {} for p in sorted(p_set): _t_list = [ element[0] for element in t_p_dens_list if element[1] == p ] _dens_list = [ element[2] for element in t_p_dens_list if element[1] == p ] _eint_list = [ element[2] for element in t_p_eint_list if element[1] == p ] _comp_list = [ element[2] for element in t_p_comp_list if element[1] == p ] if len(_t_list) < 5: continue # density-T relation is fitted by 3-order polynomial function _t_dens_coeff, _t_dens_score = polyfit(_t_list, _dens_list, 3) _t_eint_coeff, _t_eint_score = polyfit(_t_list, _eint_list, 3) _t_comp_coeff, _t_comp_score = polyfit(_t_list, _comp_list, 3) t_dens_poly3[p] = [ list(map(round3, _t_dens_coeff)), round3(_t_dens_score), min(_t_list), max(_t_list) ] t_eint_poly3[p] = [ list(map(round3, _t_eint_coeff)), round3(_t_eint_score), min(_t_list), max(_t_list) ] t_comp_poly3[p] = [ list(map(round3, _t_comp_coeff)), round3(_t_comp_score), min(_t_list), max(_t_list) ] post_result = { 'density': t_p_dens_stderr_list, 'einter': t_p_eint_stderr_list, 'compress': t_p_comp_stderr_list, 'density-poly4': [list(map(round3, coeff_dens)), round3(score_dens)], 'einter-poly4': [list(map(round3, coeff_eint)), round3(score_eint)], 'density-t-poly3': t_dens_poly3, 'einter-t-poly3': t_eint_poly3, 'compress-t-poly3': t_comp_poly3, } return post_result, 'density-poly4-score %.4f einter-poly4-score %.4f' % ( score_dens, score_eint)
def get_post_data(post_result, T, P, smiles_list, **kwargs) -> dict: from mstools.analyzer.fitting import polyval_derivative_2d, polyval, polyval_derivative, polyfit ### Calculate with T,P-poly4. Not accurate enough, especially for expansion and compressibility coeff_dens, score_dens = post_result['density-poly4'] coeff_eint, score_eint = post_result['einter-poly4'] density4, dDdT4, dDdP4 = polyval_derivative_2d(T, P, 4, coeff_dens) # g/mL einter4, dEdT4, dEdP4 = polyval_derivative_2d(T, P, 4, coeff_eint) # kJ/mol expansion4 = -1 / density4 * dDdT4 # K^-1 compressibility4 = 1 / density4 * dDdP4 # bar^-1 import pybel py_mol = pybel.readstring('smi', smiles_list[0]) cp_inter4 = dEdT4 * 1000 # J/mol.K cp_pv4 = -py_mol.molwt * P / density4**2 * dDdT4 * 0.1 # J/mol/K ### T-poly3 _p_dens_list = [] _p_eint_list = [] _p_comp_list = [] _p_dDdT_list = [] _p_dEdT_list = [] for _p in post_result['density-t-poly3']: coef, score, tmin, tmax = post_result['density-t-poly3'][str(_p)] if score < 0.999 or T < tmin - 10 or T > tmax + 10: continue dens, dDdT = polyval_derivative(T, coef) _p_dens_list.append([float(_p), dens]) _p_dDdT_list.append([float(_p), dDdT]) for _p in post_result['einter-t-poly3']: coef, score, tmin, tmax = post_result['einter-t-poly3'][str(_p)] if score < 0.999 or T < tmin - 10 or T > tmax + 10: continue eint, dEdT = polyval_derivative(T, coef) _p_eint_list.append([float(_p), eint]) _p_dEdT_list.append([float(_p), dEdT]) for _p in post_result['compress-t-poly3']: coef, score, tmin, tmax = post_result['compress-t-poly3'][str(_p)] if score < 0.95 or T < tmin - 10 or T > tmax + 10: continue _p_comp_list.append([float(_p), polyval(T, coef)]) ### Default value density = None einter = None hvap = None cp_inter = None cp_pv = None expansion = None compressibility = None if len(_p_dens_list) >= 5: coef, score = polyfit(*zip(*_p_dens_list), 3) _p_list = list(zip(*_p_dens_list))[0] if P > min(_p_list) - 10 and P < max(_p_list) + 10: density = polyval(P, coef) coef, score = polyfit(*zip(*_p_dDdT_list), 3) dDdT = polyval(P, coef) expansion = -1 / density * dDdT # K^-1 cp_pv = -py_mol.molwt * P / density**2 * dDdT * 0.1 # J/mol/K if len(_p_eint_list) >= 5: coef, score = polyfit(*zip(*_p_eint_list), 3) _p_list = list(zip(*_p_eint_list))[0] if P > min(_p_list) - 10 and P < max(_p_list) + 10: einter = polyval(P, coef) hvap = 8.314 * T / 1000 - einter # kJ/mol coef, score = polyfit(*zip(*_p_dEdT_list), 3) dEdT = polyval(P, coef) cp_inter = dEdT * 1000 # J/mol.K if len(_p_comp_list) >= 5: coef, score = polyfit(*zip(*_p_comp_list), 3) _p_list = list(zip(*_p_comp_list))[0] if P > min(_p_list) - 10 and P < max(_p_list) + 10: compressibility = polyval(P, coef) return { 'density': density, 'einter': einter, 'hvap': hvap, 'cp_inter': cp_inter, 'cp_pv': cp_pv, 'expansion': expansion, 'compress': compressibility, 'density-poly4-score': score_dens, 'einter-poly4-score': score_eint, 'density-poly4': density4, 'einter-poly4': einter4, 'cp_inter-poly4': cp_inter4, 'cp_pv-poly4': cp_pv4, 'expansion-poly4': expansion4, 'compress-poly4': compressibility4, }
for mol in mols: try: os.chdir(os.path.join(Config.WORK_DIR, 'Cv', mol.name)) except: print(mol, 'Error: Dir not exist', file=fout) continue gauss.logs = ['conf-%i.log' % i for i in range(n_conformer)] try: result = gauss.analyze() except Exception as e: print(mol, str(e), file=fout) continue T_list = [] Cv_list = [] for T, val_stderr in result['Cv-corrected'].items(): T_list.append(T) Cv_list.append(val_stderr[0]) if T_list != [100, 200, 300, 400, 500, 600, 700]: print(mol, 'Some temperatures are failed', file=fout) else: coef, score = polyfit(T_list, Cv_list, 4) print(mol, *coef, score, file=fout) os.chdir(CWD) fout.close() if cmd == 'save-db': Cv.load_from_log('_cv.log')