import pylab as plt
import numpy as np
import numpy.linalg as alg
import matplotlib as mpl
from matplotlib.widgets import Slider, Button

mpl.rcParams['text.usetex'] = False #True pour mettre du beau LateX mais ça fait laguer ou False c'est moche mais ça lag pas
mpl.rcParams['axes.titlesize'] = 15
mpl.rcParams['axes.labelsize'] = 30
mpl.rcParams['lines.linewidth'] = 3
mpl.rcParams['lines.markersize'] = 8
mpl.rcParams['xtick.labelsize'] = 20
mpl.rcParams['ytick.labelsize'] = 20
mpl.rcParams['legend.fontsize'] = 25

#Calcul du diagramme binaire pour un mélange idéal, les valeurs initailes des paramètres (température d'ébullition et enthalpie de vaporisation) sont celles de l'eau et de l'éthanol (bien que ce mélange est non idéal)

##Le gros du calcul

def to_plot(Hvap1,Hvap2,Teb10,Teb20,P) :
    #Paramètres physiques
    P0 = 1e5
    R = 8.314
    
    #Variation de la température d'ébullition avec la pression 
    Teb1 = 1/(1/(Teb10+273.15)-R/Hvap1*np.log(P/P0))#Eau
    Teb2 = 1/(1/(Teb20+273.15)-R/Hvap2*np.log(P/P0))#Ethanol
    
    #Fractions molaires sur les courbes d'ébullition et rosée en fonction de la température
    def a1(T) :
        return P0/P * np.exp(Hvap1/R*(1/Teb1-1/T))
    def a2(T) :
        return P0/P * np.exp(Hvap2/R*(1/Teb2-1/T))
    def x2g(T) :
        c1 = a1(T)
        c2 = a2(T)
        return c2*(1-c1)/(c2-c1)
    def x2l(T) :
        c1 = a1(T)
        c2 = a2(T)
        return (1-c1)/(c2-c1)
    
    #On veut l'inverse (température sur les courbes en fonction de la fraction molaire)
    tabT = np.linspace(274,500,1000)
    tabxg = []
    tabxl = []
    tabTg = []
    tabTl = []
    for T in tabT :
        xg = x2g(T)
        xl = x2l(T)
        if xg >= 0 and xg <= 1 :
            tabxg.append(xg)
            tabTg.append(T-273.15)
        if xl >= 0 and xl <= 1 :
            tabxl.append(xl)
            tabTl.append(T-273.15)
    return tabxl,tabTl,tabxg,tabTg

# Define initial parameters
#Enthalpie standard de vaporisation
init_Hvap1 = 2264.76e3 * 18e-3 #eau
init_Hvap2 = 855e3 * 46.07e-3 #éthanol
#température d'ébullition à pression atmosphérique
init_Teb10 = 100 #eau
init_Teb20 = 78.3 #éthanol
init_P = 1e5

##Le plot avec sliders

# Create the figure and the line that we will manipulate
fig, ax = plt.subplots()
tabxl,tabTl,tabxg,tabTg = to_plot(init_Hvap1, init_Hvap2,init_Teb10,init_Teb20,init_P )
line, = plt.plot(tabxl,tabTl,label='Courbe de rosée' )
line2, = plt.plot(tabxg,tabTg,label="Courbe d'ébullition" )
ax.set_xlabel('Fraction molaire '+ r'$x$'+' en éthanol')
ax.set_ylabel('Température '+r'$T$'+' (en °C)')
ax.set_xlim(0,1)

# Adjust the main plot to make room for the sliders
#plt.subplots_adjust(left=0.25, bottom=0.25)
plt.subplots_adjust(left=0.1,bottom=0.32,top=0.95)

# Make horizontal sliders to control the parameters.
ax_Hvap1 = plt.axes([0.15, 0.07, 0.7, 0.03])
Hvap1_slider = Slider(
    ax=ax_Hvap1,
    label=r'$\Delta_\mathrm{vap} H^\circ(\mathrm{eau})$',
    valmin=0.1,
    valmax=3*init_Hvap1,
    valinit=init_Hvap1,
)
Hvap1_slider.label.set_size(20)
Hvap1_slider.valtext.set_fontsize(20)

ax_Hvap2 = plt.axes([0.15, 0.1, 0.7, 0.03])
Hvap2_slider = Slider(
    ax=ax_Hvap2,
    label=r'$\Delta_\mathrm{vap} H^\circ(\mathrm{éthanol})$',
    valmin=0.1,
    valmax=3*init_Hvap2,
    valinit=init_Hvap2,
)
Hvap2_slider.label.set_size(20)
Hvap2_slider.valtext.set_fontsize(20)

ax_Teb10 = plt.axes([0.15, 0.13, 0.7, 0.03])
Teb10_slider = Slider(
    ax=ax_Teb10,
    label=r'$T_\mathrm{éb}(\mathrm{eau})$',
    valmin=init_Teb10/2,
    valmax=2*init_Teb10,
    valinit=init_Teb10,
)
Teb10_slider.label.set_size(20)
Teb10_slider.valtext.set_fontsize(20)

ax_Teb20 = plt.axes([0.15, 0.16, 0.7, 0.03])
Teb20_slider = Slider(
    ax=ax_Teb20,
    label=r'$T_\mathrm{éb}(\mathrm{éthanol})$',
    valmin=init_Teb20/2,
    valmax=2*init_Teb20,
    valinit=init_Teb20,
)
Teb20_slider.label.set_size(20)
Teb20_slider.valtext.set_fontsize(20)

ax_P = plt.axes([0.15, 0.19, 0.7, 0.03])
P_slider = Slider(
    ax=ax_P,
    label=r'$P$',
    valmin=init_P/2,
    valmax=2*init_P,
    valinit=init_P,
)
P_slider.label.set_size(20)
P_slider.valtext.set_fontsize(20)

# The function to be called anytime a slider's value changes
def update(val):
    tabxl,tabTl,tabxg,tabTg = to_plot(Hvap1_slider.val,Hvap2_slider.val,Teb10_slider.val,Teb20_slider.val,P_slider.val )
    line.set_ydata(tabTl)
    line2.set_ydata(tabTg)
    ax.set_ylim(np.min([np.min(tabTl),np.min(tabTg)])-10,np.max([np.max(tabTl),np.max(tabTg)])+10)
    line.set_xdata(tabxl)
    line2.set_xdata(tabxg)
    fig.canvas.draw_idle()


# register the update function with each slider
Hvap1_slider.on_changed(update)
Hvap2_slider.on_changed(update)
Teb10_slider.on_changed(update)
Teb20_slider.on_changed(update)
P_slider.on_changed(update)

# Create a `matplotlib.widgets.Button` to reset the sliders to initial values.
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', hovercolor='0.975')

def reset(event):
    Hvap1_slider.reset()
    Hvap2_slider.reset()
    Teb10_slider.reset()
    Teb20_slider.reset()
    P_slider.reset()
button.on_clicked(reset)

ax.legend()
plt.show()