Robert Elder commited on
Commit ·
ddaa121
1
Parent(s): f17905e
syncing 50% EtOH changes from master branch
Browse files
quantity_module/data/solvent-viscosity.xlsx
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:54dcc8e1abe242707b2039ff8735a7a986b28023cc23ef9a9e96f3aa5223b451
|
| 3 |
+
size 13816
|
quantity_module/functions.py
CHANGED
|
@@ -21,6 +21,7 @@ N_sample = int(1e6)
|
|
| 21 |
|
| 22 |
## list of solvents to include, all semi-polar and non-polar solvents in ISO 10993-18:2020 Table D.1 (except DMSO, which is not used in practice)
|
| 23 |
solvents = ['acetonitrile','methanol','acetone','ethanol','tetrahydrofuran','propanol','isopropanol','dichloromethane','toluene','cyclohexane','heptane','hexane']
|
|
|
|
| 24 |
|
| 25 |
## c distribution parameters
|
| 26 |
T_cut = 20
|
|
@@ -68,23 +69,42 @@ else:
|
|
| 68 |
df_final = pd.merge(df_final, df_desc[['Solute_InChIKey', 'Vabc', 'VMcGowan']], how='left', on='Solute_InChIKey', suffixes=('', '_dupe'))
|
| 69 |
|
| 70 |
#### solvent-specific viscosity
|
| 71 |
-
# add MW
|
| 72 |
-
mws = []
|
| 73 |
-
for solv in df_visc['Solvent_Name']:
|
| 74 |
-
mw = chemicals.search_chemical(solv).MW
|
| 75 |
-
mws.append(mw)
|
| 76 |
-
df_visc['MW'] = mws
|
| 77 |
## selected solvent MWs
|
| 78 |
-
Solvent_MWs = {solv:df_visc.loc[df_visc['Solvent_Name']==solv,'MW'].iloc[0] for solv in solvents}
|
|
|
|
| 79 |
#Solvent_Densities = {solv:string2density(solv)[0] for solv in solvents} # can fail sometimes, so these are hardcoded for now
|
| 80 |
#Solvent_Densities = {'ethanol': 0.79, 'isopropanol': 0.787515, 'acetonitrile': 0.78467, 'toluene': 0.86925, 'dichloromethane': 1.326875, 'hexane': 0.6602}
|
| 81 |
-
Solvent_Densities = {'acetonitrile': 0.7847, 'methanol': 0.7955, 'acetone': 0.7893, 'ethanol': 0.7898, 'tetrahydrofuran': 0.8878, 'propanol': 0.8057, 'isopropanol': 0.787, 'dichloromethane': 1.3269, 'toluene': 0.8673, 'cyclohexane': 0.7793, 'heptane': 0.6808, 'hexane': 0.6599}
|
| 82 |
# linear relation to estimate Vabc when it fails for a molecule
|
| 83 |
Vabc = df_desc['Vabc']
|
| 84 |
Vmcg = df_desc['VMcGowan']
|
| 85 |
m = ~pd.isna(Vabc)
|
| 86 |
popt_V = np.polyfit(Vmcg[m], Vabc[m], 1)
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
def get_WC(T,solv,V):
|
| 89 |
params = df_visc[df_visc['Solvent_Name']==solv].iloc[0]
|
| 90 |
if params['Equation'] == '10^A(1/T-1/B)':
|
|
@@ -103,9 +123,12 @@ def get_WC(T,solv,V):
|
|
| 103 |
eta = params['A'] * 298.15/T
|
| 104 |
elif params['Equation'] == 'A*T+B':
|
| 105 |
eta = params['A'] * T + params['A']
|
|
|
|
|
|
|
|
|
|
| 106 |
else:
|
| 107 |
eta = np.nan
|
| 108 |
-
D_WC = 7.4e-8*(params['MW']*params['WC_assoc_param'])**0.5*
|
| 109 |
return D_WC, eta, params['MW']
|
| 110 |
|
| 111 |
#### add Wilke-Chang
|
|
|
|
| 21 |
|
| 22 |
## list of solvents to include, all semi-polar and non-polar solvents in ISO 10993-18:2020 Table D.1 (except DMSO, which is not used in practice)
|
| 23 |
solvents = ['acetonitrile','methanol','acetone','ethanol','tetrahydrofuran','propanol','isopropanol','dichloromethane','toluene','cyclohexane','heptane','hexane']
|
| 24 |
+
#solvents = ['acetonitrile','methanol','acetone','ethanol','50% ethanol','tetrahydrofuran','propanol','isopropanol','dichloromethane','toluene','cyclohexane','heptane','hexane']
|
| 25 |
|
| 26 |
## c distribution parameters
|
| 27 |
T_cut = 20
|
|
|
|
| 69 |
df_final = pd.merge(df_final, df_desc[['Solute_InChIKey', 'Vabc', 'VMcGowan']], how='left', on='Solute_InChIKey', suffixes=('', '_dupe'))
|
| 70 |
|
| 71 |
#### solvent-specific viscosity
|
| 72 |
+
# add MW -- already in the spreadsheet
|
| 73 |
+
#mws = []
|
| 74 |
+
#for solv in df_visc['Solvent_Name']:
|
| 75 |
+
# mw = chemicals.search_chemical(solv).MW
|
| 76 |
+
# mws.append(mw)
|
| 77 |
+
#df_visc['MW'] = mws
|
| 78 |
## selected solvent MWs
|
| 79 |
+
#Solvent_MWs = {solv:df_visc.loc[df_visc['Solvent_Name']==solv,'MW'].iloc[0] for solv in solvents}
|
| 80 |
+
Solvent_MWs = dict(df_visc[['Solvent_Name','MW']].itertuples(index=False))
|
| 81 |
#Solvent_Densities = {solv:string2density(solv)[0] for solv in solvents} # can fail sometimes, so these are hardcoded for now
|
| 82 |
#Solvent_Densities = {'ethanol': 0.79, 'isopropanol': 0.787515, 'acetonitrile': 0.78467, 'toluene': 0.86925, 'dichloromethane': 1.326875, 'hexane': 0.6602}
|
| 83 |
+
Solvent_Densities = {'acetonitrile': 0.7847, 'methanol': 0.7955, 'acetone': 0.7893, 'ethanol': 0.7898, '50% ethanol': (0.7898+1)/2, 'tetrahydrofuran': 0.8878, 'propanol': 0.8057, 'isopropanol': 0.787, 'dichloromethane': 1.3269, 'toluene': 0.8673, 'cyclohexane': 0.7793, 'heptane': 0.6808, 'hexane': 0.6599}
|
| 84 |
# linear relation to estimate Vabc when it fails for a molecule
|
| 85 |
Vabc = df_desc['Vabc']
|
| 86 |
Vmcg = df_desc['VMcGowan']
|
| 87 |
m = ~pd.isna(Vabc)
|
| 88 |
popt_V = np.polyfit(Vmcg[m], Vabc[m], 1)
|
| 89 |
|
| 90 |
+
# ---- model: Grunberg–Nissan style with polynomial interaction that vanishes at x=0,1 ----
|
| 91 |
+
# fitted to data from R. Belda, J. V. Herráez, O. Diez, Rheological study and thermodynamic analysis of the binary system (water/ethanol): Influence of concentration. Physics and Chemistry of Liquids 42, 467-479 (2004).
|
| 92 |
+
popt_etoh = np.array([-6.35036532e+00, 1.86507282e+03, -5.30902320e+00, 1.60463200e+03, -1.03040657e+01, 3.05646061e+00, -4.93824317e+00, 4.16274239e+03, -1.18411097e+03, 1.69557649e+03])
|
| 93 |
+
def predict_lneta(p, T, x, n_poly=3, interaction_has_T=True):
|
| 94 |
+
Aw, Bw, Ae, Be = p[:4] # ln(eta_w)=Aw+Bw/T, ln(eta_e)=Ae+Be/T
|
| 95 |
+
ln_eta_w = Aw + Bw / T
|
| 96 |
+
ln_eta_e = Ae + Be / T
|
| 97 |
+
xc = 2.0*x - 1.0 # map wt frac [0,1] -> [-1,1]
|
| 98 |
+
Phi = np.vstack([xc**k for k in range(n_poly)]) # (n_poly, N)
|
| 99 |
+
if interaction_has_T:
|
| 100 |
+
a = p[4:4+n_poly]
|
| 101 |
+
b = p[4+n_poly:4+2*n_poly]
|
| 102 |
+
G = (a @ Phi) + (b @ Phi) / T
|
| 103 |
+
else:
|
| 104 |
+
a = p[4:4+n_poly]
|
| 105 |
+
G = (a @ Phi)
|
| 106 |
+
return x*ln_eta_e + (1-x)*ln_eta_w + x*(1-x)*G
|
| 107 |
+
|
| 108 |
def get_WC(T,solv,V):
|
| 109 |
params = df_visc[df_visc['Solvent_Name']==solv].iloc[0]
|
| 110 |
if params['Equation'] == '10^A(1/T-1/B)':
|
|
|
|
| 123 |
eta = params['A'] * 298.15/T
|
| 124 |
elif params['Equation'] == 'A*T+B':
|
| 125 |
eta = params['A'] * T + params['A']
|
| 126 |
+
elif params['Equation'] == 'fitted_EtOH':
|
| 127 |
+
# assuming 50% is by volume --> by mass for consistency with fitted model
|
| 128 |
+
eta = np.exp(predict_lneta(popt_etoh, T, 0.5*0.7898/(0.5*0.7898+0.5*1.000), n_poly=3, interaction_has_T=True))
|
| 129 |
else:
|
| 130 |
eta = np.nan
|
| 131 |
+
D_WC = 7.4e-8*(params['MW']*params['WC_assoc_param'])**0.5*T/eta/V**0.6
|
| 132 |
return D_WC, eta, params['MW']
|
| 133 |
|
| 134 |
#### add Wilke-Chang
|