Skip to content

Commit

Permalink
I tried, that fails
Browse files Browse the repository at this point in the history
  • Loading branch information
pierre-24 committed May 31, 2024
1 parent 14baea9 commit 4fda7dd
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 77 deletions.
19 changes: 19 additions & 0 deletions analyses/nitroxides/commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# -- Debye-Huckel theory

AU_TO_M = 5.291772e-11 # m
AU_TO_ANG = 5.291772e-1 # m
KB = 3.166811563e-6 # Eh / K
AVOGADRO = 6.02214076e23 # mol⁻¹

Expand Down Expand Up @@ -48,6 +49,24 @@ def dG_DH(z_reac: int, z_prod: int, a_reac: float, a_prod: float, epsilon_r: flo

return dG

# -- cplx
def dG_DH_cplx_Kx1(z_reac: int, z_prod: int, z_ct: int, a_reac: float, a_prod: float, a_ct: float, epsilon_r: float, c_act: float = C_NITROXIDE, c_elt: float = 1, z_elt: float = 1):
# complexation reaction correction!
kappa_reac = numpy.sqrt(kappa2(c_act, z_reac, epsilon_r) + kappa2(c_act, -z_reac, epsilon_r) + kappa2(c_elt, z_elt, epsilon_r) + kappa2(c_elt, -z_elt, epsilon_r)) # in bohr⁻¹
kappa_prod = numpy.sqrt(kappa2(c_act, z_prod, epsilon_r) + kappa2(c_act, -z_prod, epsilon_r) + kappa2(c_elt, z_elt, epsilon_r) + kappa2(c_elt, -z_elt, epsilon_r)) # in bohr⁻¹

dG = G_DH(z_prod, kappa_prod, epsilon_r, a_prod) - G_DH(z_reac, kappa_reac, epsilon_r, a_reac) - G_DH(z_ct, kappa_reac, epsilon_r, a_ct) # in au

return dG

def dG_DH_cplx_Kx2(z_reac: int, z_prod: int, z_ct: int, a_reac: float, a_prod: float, a_ct1: float, a_ct2: float, epsilon_r: float, c_act: float = C_NITROXIDE, c_elt: float = 1, z_elt: float = 1):
# complexation reaction correction!
kappa_reac = numpy.sqrt(kappa2(c_act, z_reac, epsilon_r) + kappa2(c_act, -z_reac, epsilon_r) + kappa2(c_elt, z_elt, epsilon_r) + kappa2(c_elt, -z_elt, epsilon_r)) # in bohr⁻¹
kappa_prod = numpy.sqrt(kappa2(c_act, z_prod, epsilon_r) + kappa2(c_act, -z_prod, epsilon_r) + kappa2(c_elt, z_elt, epsilon_r) + kappa2(c_elt, -z_elt, epsilon_r)) # in bohr⁻¹

dG = G_DH(z_prod, kappa_prod, epsilon_r, a_prod) - G_DH(z_reac, kappa_reac, epsilon_r, a_reac) - G_DH(z_ct, kappa_reac, epsilon_r, a_ct1) - G_DH(-z_ct, kappa_reac, epsilon_r, a_ct2) # in au

return dG

# -- Position labels on graph (using a monte-carlo metropolis approach)
class LabelPositioner:
Expand Down
45 changes: 45 additions & 0 deletions analyses/nitroxides/pairs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import numpy

class IonPair:
def __init__(self, q: float, a1: float, a2: float, s1: float = 1.0, s2: float = 1.0):
self.q = q
self.a1 = a1
self.a2 = a2

self.mu = q * (a1 + a2) * s1
self.a = (a1**3 + a2**3)**(1/3) * s2

@staticmethod
def _e_born_solvation(q: float, a: float, epsr: float, epsi: float = 1.0) -> float:
"""Solvatation energy from Born theory"""
return q ** 2 / (2*a) * (1/epsr - 1/epsi)

@staticmethod
def _e_coulomb(q1: float, q2: float, r: float, eps: float) -> float:
"""Coulombic interaction between two charges in a given medium"""
return q1 * q2 / (r*eps)

@staticmethod
def _e_coulomb2(q1: float, q2: float, mu: float, eps: float) -> float:
"""Coulombic interaction / formation of a dipole"""
return q1 * q2 * numpy.abs(q1) / (eps * mu)

@staticmethod
def _e_dipole_onsager(mu: float, a: float, epsr: float, epsi: float = 1.0) -> float:
"""Solvatation energy of a dipole in a cavity, according to Onsager"""
return -3*(epsr-epsi)/((2*epsr+1)*(2*epsi+1))*mu**2/a**3

def e_born_solvation(self, epsr: float, epsi: float = 1.0) -> float:
return IonPair._e_born_solvation(self.q, self.a1, epsr, epsi) + IonPair._e_born_solvation(-self.q, self.a2, epsr, epsi)

def e_coulomb(self, epsi: float = 1.0) -> float:
return IonPair._e_coulomb(self.q, -self.q, self.a1 + self.a2, epsi)

def e_coulomb2(self, eps: float) -> float:
return IonPair._e_coulomb2(self.q, -self.q, self.mu, eps)

def e_dipole_onsager(self, epsr, epsi: float = 1.0) -> float:
return IonPair._e_dipole_onsager(self.mu, self.a, epsr, epsi)

def e_pair(self, epsr: float, epsi: float = 1.0) -> float:
return self.e_coulomb2(epsi) + self.e_dipole_onsager(epsr, epsi) - self.e_born_solvation(epsr, epsi)
17 changes: 4 additions & 13 deletions analyses/plot_cplx_Kx1.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,17 @@
import argparse

from matplotlib.ticker import AutoMinorLocator, MultipleLocator
from nitroxides.commons import G_DH, AU_TO_M, AU_TO_KJMOL, kappa2, G_NME4, G_BF4, RADII_BF4, RADII_NME4, C_NITROXIDE
from nitroxides.commons import G_DH, AU_TO_ANG, AU_TO_KJMOL, kappa2, G_NME4, G_BF4, RADII_BF4, RADII_NME4, C_NITROXIDE, dG_DH_cplx_Kx1

T = 298.15
R = 8.3145e-3 # kJ mol⁻¹

def dG_DH_cplx(z_reac: int, z_prod: int, z_ct: int, a_reac: float, a_prod: float, a_ct: float, epsilon_r: float, c_act: float = C_NITROXIDE, c_elt: float = 1, z_elt: float = 1):
# complexation reaction correction!
kappa_reac = numpy.sqrt(kappa2(c_act, z_reac, epsilon_r) + kappa2(c_act, -z_reac, epsilon_r) + kappa2(c_elt, z_elt, epsilon_r) + kappa2(c_elt, -z_elt, epsilon_r)) # in bohr⁻¹
kappa_prod = numpy.sqrt(kappa2(c_act, z_prod, epsilon_r) + kappa2(c_act, -z_prod, epsilon_r) + kappa2(c_elt, z_elt, epsilon_r) + kappa2(c_elt, -z_elt, epsilon_r)) # in bohr⁻¹

dG = G_DH(z_prod, kappa_prod, epsilon_r, a_prod) - G_DH(z_reac, kappa_reac, epsilon_r, a_reac) - G_DH(z_ct, kappa_reac, epsilon_r, a_ct) # in au

return dG

def plot_Kx1(ax, data: pandas.DataFrame, family: str, solvent: str, epsilon_r: float, color: str):
subdata_k01 = data[(data['family'] == family) & (data['solvent'] == solvent) & (data['has_anion'] == True)] # K_01 → N+ + A-
subdata_k21 = data[(data['family'] == family) & (data['solvent'] == solvent) & (data['has_cation'] == True)] # K_21 → N- + C+

dG_DH_k01 = dG_DH_cplx(subdata_k01['z'] + 1, subdata_k01['z'], -1, subdata_k01['r_A'], subdata_k01['r_AX'], RADII_BF4[solvent], epsilon_r)
dG_DH_k21 = dG_DH_cplx(subdata_k21['z'] - 1, subdata_k21['z'], 1, subdata_k21['r_A'], subdata_k21['r_AX'], RADII_NME4[solvent], epsilon_r)
dG_DH_k01 = dG_DH_cplx_Kx1(subdata_k01['z'] + 1, subdata_k01['z'], -1, subdata_k01['r_A'] / AU_TO_ANG, subdata_k01['r_AX'] / AU_TO_ANG, RADII_BF4[solvent] / AU_TO_ANG, epsilon_r)
dG_DH_k21 = dG_DH_cplx_Kx1(subdata_k21['z'] - 1, subdata_k21['z'], 1, subdata_k21['r_A'] / AU_TO_ANG, subdata_k21['r_AX'] / AU_TO_ANG, RADII_NME4[solvent] / AU_TO_ANG, epsilon_r)

dG_k01 = (subdata_k01['G_cplx'] - G_BF4[solvent] + dG_DH_k01) * AU_TO_KJMOL
dG_k21 = (subdata_k21['G_cplx'] - G_NME4[solvent] + dG_DH_k21) * AU_TO_KJMOL
Expand All @@ -38,7 +29,7 @@ def plot_Kx1(ax, data: pandas.DataFrame, family: str, solvent: str, epsilon_r: f
def helpline_K01(ax, data: pandas.DataFrame, solvent: str, epsilon_r: float, color: str = 'black'):
subdata_k01 = data[(data['solvent'] == solvent) & (data['has_anion'] == True)] # K_01 → N+ + A-

dG_DH_k01 = dG_DH_cplx(subdata_k01['z'] + 1, subdata_k01['z'], -1, subdata_k01['r_A'], subdata_k01['r_AX'], RADII_BF4[solvent], epsilon_r)
dG_DH_k01 = dG_DH_cplx_Kx1(subdata_k01['z'] + 1, subdata_k01['z'], -1, subdata_k01['r_A'] / AU_TO_ANG, subdata_k01['r_AX'] / AU_TO_ANG, RADII_BF4[solvent] / AU_TO_ANG, epsilon_r)

dG_k01 = (subdata_k01['G_cplx'] - G_BF4[solvent]+ dG_DH_k01) * AU_TO_KJMOL

Expand Down
19 changes: 5 additions & 14 deletions analyses/plot_cplx_Kx2.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,17 @@
import argparse

from matplotlib.ticker import AutoMinorLocator, MultipleLocator
from nitroxides.commons import G_DH, AU_TO_M, AU_TO_KJMOL, kappa2, G_NME4, G_BF4, RADII_BF4, RADII_NME4, C_NITROXIDE
from nitroxides.commons import AU_TO_ANG, AU_TO_KJMOL, G_NME4, G_BF4, RADII_BF4, RADII_NME4, C_NITROXIDE, dG_DH_cplx_Kx2

T = 298.15
R = 8.3145e-3 # kJ mol⁻¹

def dG_DH_cplx(z_reac: int, z_prod: int, z_ct: int, a_reac: float, a_prod: float, a_ct1: float, a_ct2: float, epsilon_r: float, c_act: float = C_NITROXIDE, c_elt: float = 1, z_elt: float = 1):
# complexation reaction correction!
kappa_reac = numpy.sqrt(kappa2(c_act, z_reac, epsilon_r) + kappa2(c_act, -z_reac, epsilon_r) + kappa2(c_elt, z_elt, epsilon_r) + kappa2(c_elt, -z_elt, epsilon_r)) # in bohr⁻¹
kappa_prod = numpy.sqrt(kappa2(c_act, z_prod, epsilon_r) + kappa2(c_act, -z_prod, epsilon_r) + kappa2(c_elt, z_elt, epsilon_r) + kappa2(c_elt, -z_elt, epsilon_r)) # in bohr⁻¹

dG = G_DH(z_prod, kappa_prod, epsilon_r, a_prod) - G_DH(z_reac, kappa_reac, epsilon_r, a_reac) - G_DH(z_ct, kappa_reac, epsilon_r, a_ct1) - G_DH(-z_ct, kappa_reac, epsilon_r, a_ct2) # in au

return dG

def plot_Kx2(ax, data: pandas.DataFrame, family: str, solvent: str, epsilon_r: float, color: str):
subdata = data[(data['family'] == family) & (data['solvent'] == solvent)]

dG_DH_k02 = dG_DH_cplx(subdata['z'] + 1, subdata['z'] + 1, 1, subdata['r_A_ox'], subdata['r_AX_ox'], RADII_NME4[solvent], RADII_BF4[solvent], epsilon_r)
dG_DH_k12 = dG_DH_cplx(subdata['z'], subdata['z'], 1, subdata['r_A_rad'], subdata['r_AX_rad'], RADII_NME4[solvent], RADII_BF4[solvent], epsilon_r)
dG_DH_k22 = dG_DH_cplx(subdata['z'] - 1, subdata['z'] - 1, 1, subdata['r_A_red'], subdata['r_AX_red'], RADII_NME4[solvent], RADII_BF4[solvent], epsilon_r)
dG_DH_k02 = dG_DH_cplx_Kx2(subdata['z'] + 1, subdata['z'] + 1, 1, subdata['r_A_ox'] / AU_TO_ANG, subdata['r_AX_ox'] / AU_TO_ANG, RADII_NME4[solvent] / AU_TO_ANG, RADII_BF4[solvent] / AU_TO_ANG, epsilon_r)
dG_DH_k12 = dG_DH_cplx_Kx2(subdata['z'], subdata['z'], 1, subdata['r_A_rad'] / AU_TO_ANG, subdata['r_AX_rad'] / AU_TO_ANG, RADII_NME4[solvent] / AU_TO_ANG, RADII_BF4[solvent] / AU_TO_ANG, epsilon_r)
dG_DH_k22 = dG_DH_cplx_Kx2(subdata['z'] - 1, subdata['z'] - 1, 1, subdata['r_A_red'] / AU_TO_ANG, subdata['r_AX_red'] / AU_TO_ANG, RADII_NME4[solvent] / AU_TO_ANG, RADII_BF4[solvent] / AU_TO_ANG, epsilon_r)

dG_k02 = (subdata['G_cplx_ox'] - G_NME4[solvent] - G_BF4[solvent] + dG_DH_k02) * AU_TO_KJMOL
dG_k12 = (subdata['G_cplx_rad'] - G_NME4[solvent] - G_BF4[solvent] + dG_DH_k12) * AU_TO_KJMOL
Expand All @@ -41,7 +32,7 @@ def plot_Kx2(ax, data: pandas.DataFrame, family: str, solvent: str, epsilon_r: f
def helpline_K02(ax, data: pandas.DataFrame, solvent: str, epsilon_r: float, color: str = 'black'):
subdata = data[data['solvent'] == solvent]

dG_DH_k12 = dG_DH_cplx(subdata['z'], subdata['z'], 1, subdata['r_A_rad'], subdata['r_AX_rad'], RADII_NME4[solvent], RADII_BF4[solvent], epsilon_r)
dG_DH_k12 = dG_DH_cplx_Kx2(subdata['z'], subdata['z'], 1, subdata['r_A_rad'] / AU_TO_ANG, subdata['r_AX_rad'] / AU_TO_ANG, RADII_NME4[solvent] / AU_TO_ANG, RADII_BF4[solvent] / AU_TO_ANG, epsilon_r)
dG_k12 = (subdata['G_cplx_rad'] - G_NME4[solvent] - G_BF4[solvent] + dG_DH_k12) * AU_TO_KJMOL
k12 = numpy.exp(-dG_k12 / (R * T))

Expand Down
1 change: 1 addition & 0 deletions analyses/plot_cplx_r.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ def plot_r(ax, data: pandas.DataFrame, family: str, solvent: str, epsilon_r: flo

plt.tight_layout()
figure.savefig(args.output)

73 changes: 73 additions & 0 deletions analyses/plot_cplx_r_Kx1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import pandas
import matplotlib.pyplot as plt
import numpy
import sys
import argparse

from nitroxides.commons import AU_TO_ANG, AU_TO_EV, G_NME4, G_BF4, RADII_BF4, RADII_NME4, dG_DH_cplx_Kx1, AU_TO_KJMOL
from nitroxides.pairs import IonPair

S1=1
S2 = 1.5

def plot_r_Kx1(ax, data: pandas.DataFrame, family: str, solvent: str, epsilon_r: float, color: str, has_cation: bool = False, has_anion: bool = False):
subdata = data[(data['family'] == family) & (data['solvent'] == solvent) & (data['has_anion'] == has_anion) & (data['has_cation'] == has_cation)]

if has_anion:
dG_DH = dG_DH_cplx_Kx1(subdata['z'] + 1, subdata['z'], -1, subdata['r_A'] / AU_TO_ANG, subdata['r_AX'] / AU_TO_ANG, RADII_BF4[solvent] / AU_TO_ANG, epsilon_r) # K_01
dG = (subdata['G_cplx'] - G_BF4[solvent] + dG_DH) * AU_TO_EV
dGp = IonPair(
q=1,
a1=subdata['r_A'] / AU_TO_ANG,
a2=RADII_BF4[solvent] / AU_TO_ANG,
s1=subdata['d_OX'] / (subdata['r_A'] + RADII_BF4[solvent]),
s2=subdata['r_AX']/(subdata['r_A'] **3 + RADII_BF4[solvent]**3)**(1/3)
).e_pair(epsilon_r)
else:
dG_DH = dG_DH_cplx_Kx1(subdata['z'] - 1, subdata['z'], 1, subdata['r_A'] / AU_TO_ANG, subdata['r_AX'] / AU_TO_ANG, RADII_NME4[solvent] / AU_TO_ANG, epsilon_r) # K_21
dG = (subdata['G_cplx'] - G_NME4[solvent] + dG_DH) * AU_TO_EV
dGp = IonPair(
q=-1,
a1=subdata['r_A'] / AU_TO_ANG,
a2=RADII_NME4[solvent] / AU_TO_ANG,
s1=subdata['d_OX'] / (subdata['r_A'] + RADII_NME4[solvent]),
s2=subdata['r_AX']/(subdata['r_A'] **3 + RADII_NME4[solvent]**3)**(1/3)
).e_pair(epsilon_r)

ax.plot(dGp, dG, 'o', color=color, label=family.replace('Family.', ''))


parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', default='../data/Data_cplx_Kx1.csv')
parser.add_argument('-o', '--output', default='Data_cplx_r_Kx1.pdf')

args = parser.parse_args()

data = pandas.read_csv(args.input)

figure = plt.figure(figsize=(8, 6))
ax1, ax2 = figure.subplots(2, 1, sharey=True)

plot_r_Kx1(ax1, data, 'Family.AMO', 'acetonitrile', 35.,'tab:pink', has_anion=True)
plot_r_Kx1(ax1, data, 'Family.P6O', 'acetonitrile', 35.,'tab:blue', has_anion=True)
plot_r_Kx1(ax1, data, 'Family.P5O', 'acetonitrile', 35., 'black', has_anion=True)
plot_r_Kx1(ax1, data, 'Family.IIO', 'acetonitrile', 35., 'tab:green', has_anion=True)
plot_r_Kx1(ax1, data, 'Family.APO', 'acetonitrile', 35., 'tab:red', has_anion=True)

ax1.legend(ncols=5)
# ax1.text(38, 1, "Water", fontsize=18)

plot_r_Kx1(ax2, data, 'Family.AMO', 'acetonitrile', 35.,'tab:pink', has_cation=True)
plot_r_Kx1(ax2, data, 'Family.P6O', 'acetonitrile', 35.,'tab:blue', has_cation=True)
plot_r_Kx1(ax2, data, 'Family.P5O', 'acetonitrile', 35., 'black', has_cation=True)
plot_r_Kx1(ax2, data, 'Family.IIO', 'acetonitrile', 35., 'tab:green', has_cation=True)
plot_r_Kx1(ax2, data, 'Family.APO', 'acetonitrile', 35., 'tab:red', has_cation=True)

#ax2.text(38, -2, "Acetonitrile", fontsize=18)

[ax.set_ylabel('$\\Delta G^\\star_{pair}$ (eV)') for ax in [ax1, ax2]]

# ax2.set_xlabel('$d$ (Å)')

plt.tight_layout()
figure.savefig(args.output)
50 changes: 3 additions & 47 deletions analyses/plot_pairs.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,11 @@
import numpy
import argparse

from nitroxides.commons import AU_TO_EV, AU_TO_M, AU_TO_KJMOL
from nitroxides.commons import AU_TO_EV, AU_TO_ANG, AU_TO_KJMOL
from nitroxides.pairs import IonPair as System
import matplotlib.pyplot as plt

class System:
def __init__(self, q: float, a1: float, a2: float, s1: float = 1.0, s2: float = 1.0):
self.q = q
self.a1 = a1
self.a2 = a2
self.s = s

self.mu = q * (a1 + a2) * s1
self.a = (a1**3 + a2**3)**(1/3) * s2

@staticmethod
def _e_born_solvation(q: float, a: float, epsr: float, epsi: float = 1.0) -> float:
"""Solvatation energy from Born theory"""
return q ** 2 / (2*a) * (1/epsr - 1/epsi)

@staticmethod
def _e_coulomb(q1: float, q2: float, r: float, eps: float) -> float:
"""Coulombic interaction between two charges in a given medium"""
return q1 * q2 / (r*eps)

@staticmethod
def _e_coulomb2(q1: float, q2: float, mu: float, eps: float) -> float:
"""Coulombic interaction / formation of a dipole"""
return q1 * q2 * numpy.abs(q1) / (eps * mu)

@staticmethod
def _e_dipole_onsager(mu: float, a: float, epsr: float, epsi: float = 1.0) -> float:
"""Solvatation energy of a dipole in a cavity, according to Onsager"""
return -3*(epsr-epsi)/((2*epsr+1)*(2*epsi+1))*mu**2/a**3

def e_born_solvation(self, epsr: float, epsi: float = 1.0) -> float:
return System._e_born_solvation(self.q, self.a1, epsr, epsi) + System._e_born_solvation(-self.q, self.a2, epsr, epsi)

def e_coulomb(self, epsi: float = 1.0) -> float:
return System._e_coulomb(self.q, -self.q, self.a1 + self.a2, epsi)

def e_coulomb2(self, eps: float) -> float:
return System._e_coulomb2(self.q, -self.q, self.mu, eps)

def e_dipole_onsager(self, epsr, epsi: float = 1.0) -> float:
return System._e_dipole_onsager(self.mu, self.a, epsr, epsi)

def e_pair(self, epsr: float, epsi: float = 1.0) -> float:
return self.e_coulomb2(epsi) + self.e_dipole_onsager(epsr, epsi) - self.e_born_solvation(epsr, epsi)

a = 3.0 / AU_TO_M * 1e-10
a = 3.0 / AU_TO_ANG
MI = 0.75
MX = 3
N = 81
Expand Down
Loading

0 comments on commit 4fda7dd

Please sign in to comment.