B
    L_X                 @   s   d dl Zd dlmZ d dlmZ d dlmZ d dl	Z
d dlZd dlZd dlmZ G dd dZG dd dZdd	 ZG d
d dZdS )    N)Axes3D)CloughTocher2DInterpolatorc               @   sf   e Zd ZddgdfddZdddZddd	Zdd
dZdd Zdd Zdd Z	dd Z
dddZdS )Alpha_T0_empiricalg      ?wheightsc             C   s  | d\| _| _|| _ttjt	d }| j|j
|d | jk d krNnH| j|j
|d | jk d kr| j| j | _| _d| _ntd| d |j
|d | jk|d | jk@  | _t| jd  | _t| jd	  | _t| jd
  | _t| jt| jt| jt| jf| _t| j| _t| jt| j | _t| jt| j | _| jdkrld| _| jdkr~d| _|d | _|dkr| j| _n0|dkr| j| _n|dkr| j| _ntddS )a  
        Callable object, composition and components are set upon initialization
        __call__(temp): returns alpha_T0 for component 1 at given composition and temperature, approximated from experimental data

        :param comps: 'comp1,comp2'
        :param mole_fracs: mole fractions of components
        :param method: 'wheights' (default), 'ct': CloughTocher, 'plane': linear interpolation
        ,z/alpha_t0.xlsxComp1Comp2TzComponents z not found in database.c_avgT_avg	Alpha_T_0r      r   Zplanectz1method must be either 'wheights', 'plane' or 'ct'N) splitcomp1comp2compspd
read_excelospathdirname__file__locflip
ValueErrordatanparraytolistc_listT_list
alpha_listminmax	cT_rangeslen
num_pointsc_spanT_spancget_alpha_T0_wheightsget_alpha_T0get_alpha_T0_planeget_alpha_T0_CloughTocher)selfr   
mole_fracsmethoddf r2   ^/Users/vegardjervell/Documents/7_semester/irrev_prosjekt_renskriv/models/alpha_t0_empirical.py__init__   s:    
$&






zAlpha_T0_empirical.__init__Fc          
      s  || _ | jd }tt|| jd k || jd k|| jd k || jd kgrtdtt	|d d tt	|d d tt	| jd d d	 tt	| jd d d
 tt	| jd d d	 tt	| jd d d  | j
| | j d | j| | j d  }tdd tt|dd dD }tdd |D }d|d< t| j
|d  g}t| j|d  g}d}	x| ||||s~|	| jk r~| j
||	  }
| j||	  }| |
| j || j || j || j || j || j }x\|	| jd k rF|sF|	d7 }	| j
||	  }
| j||	  }| |
|||||rd}P qW |rVd||	< | j
||  }| j||  }|	d7 }	qxW | j||  }|||   t fddtt D  fddtt D }t|| }t|| d || d  || d  t| }|r.| |||||||| |dksD|	| jkrtdtt	|d d tt	|d d | j d tt	|d d  t|| gS )a  
        :param comps (str) : comp1,comp2 following Thermopack convention
        :param c (float) : Volumetric concentration at which to get kinetic_gas
        :param T (float) : Temperature (K) at which to get kinetic_gas
        :param plot (bool or '2d' or '3d') : display fitted data
        :return float : kinetic_gas at the specified conditions, approximated from experimental data
                        using the custom weighting scheme
        d   r   r         z
c = z T = z is outside range 
c : (z, z), T : )c             S   s   g | ]\}}|qS r2   r2   ).0i_r2   r2   r3   
<listcomp>W   s    z<Alpha_T0_empirical.get_alpha_T0_wheights.<locals>.<listcomp>c             S   s   | d S )Nr   r2   )pairr2   r2   r3   <lambda>W   s    z:Alpha_T0_empirical.get_alpha_T0_wheights.<locals>.<lambda>)keyc             S   s   g | ]}d qS )Fr2   )r9   r:   r2   r2   r3   r<   X   s    Tc                s4   g | ],}t  d | t  |d d   qS )Nr   )r   prod)r9   r:   )rr2   r3   r<   z   s    c                s8   g | ]0}t  d | t  |d d    qS )Nr   )r   r@   )r9   r:   )rA   totr2   r3   r<   {   s    i  z
Alpha_T0 at c = z for z# may be a bad approximation (R^2 = )plotr)   anyr   r   r$   warningswarnstrroundr   r'   r    r(   sorted	enumeratecheck_insider&   check_validr!   sumranger%   plot_fitr   )r.   TrC   r)   distdist_inddist_ind_maskclose_cclose_Tr:   new_cnew_Tvalid_pointclose_alphar   	fit_alphaR2r2   )rA   rB   r3   r*   @   sR    	
>($"$0Fz(Alpha_T0_empirical.get_alpha_T0_wheightsc          	   C   s  || _ | jd }tt|| jd k || jd k|| jd k || jd kgrtdtt	|d d tt	|d d tt	| jd d d	 tt	| jd d d
 tt	| jd d d	 tt	| jd d d  t
t| j| jg | j||g}t|| gS )a  
        :param comps (str) : comp1,comp2 following Thermopack convention
        :param c (float) : Volumetric concentration at which to get kinetic_gas
        :param T (float) : Temperature (K) at which to get kinetic_gas
        :param plot (bool or '2d' or '3d') : display fitted data
        :return float : kinetic_gas at the specified conditions, approximated from experimental data
                        by CloughTocher-interpolation
        r5   r   r   r6   r7   z
c = z T = z is outside range 
c : (z, z), T : r8   )rC   r)   rD   r   r   r$   rE   rF   rG   rH   interpolr   r    	transposer!   )r.   rP   rC   r)   rZ   r2   r2   r3   r-      s    	
>&z,Alpha_T0_empirical.get_alpha_T0_CloughTocherc          
      s  || _ | jd }tt|| jd k || jd k|| jd k || jd kgrtdtt	|d d tt	|d d tt	| jd d d	 tt	| jd d d
 tt	| jd d d	 tt	| jd d d  | j
| | j d | j| | j d  }tdd tt|dd dD }tdd |D }d}tg }xt|dk rF|| jk rFtdd |D }d||< t| j
||  g}t| j||  g}	td|d }
| j
||
  }| j||
  }| || j || j || j |	| j || j || j }x\|
| jd k rn|sn|
d7 }
| j
||
  }| j||
  }| ||||	||rd}P qW |r~d||
< | j
||  }| j||  }	x|
| jd k r|| jkr|
d7 }
| j
||
  }| j||
  }t||gf}t|	|gf}| ||||rd||
< P qW | j
||  }| j||  }	|d7 }qNW | j||  }t|dkrt||	|g }t|d |d  |d |d  }t||d |d |  |d |  |d  }nR|||   t fddtt D  fddtt D }t|| }t|| d |	| d  || d  t| }|rn| |||	||||| |dkrtdtt	|d d tt	|d d | j d tt	|d d  t|| gS )a  
        :param comps (str) : comp1,comp2 following Thermopack convention
        :param c (float) : Volumetric concentration at which to get kinetic_gas
        :param T (float) : Temperature (K) at which to get kinetic_gas
        :param plot (bool or '2d' or '3d') : display fitted data
        :return float : kinetic_gas at the specified conditions, approximated from experimental data
                        by fitting a plane to the closest three data points that enclose the desired point
        r5   r   r   r6   r7   z
c = z T = z is outside range 
c : (z, z), T : r8   c             S   s   g | ]\}}|qS r2   r2   )r9   r:   r;   r2   r2   r3   r<      s    z9Alpha_T0_empirical.get_alpha_T0_plane.<locals>.<listcomp>c             S   s   | d S )Nr   r2   )r=   r2   r2   r3   r>      s    z7Alpha_T0_empirical.get_alpha_T0_plane.<locals>.<lambda>)r?   c             S   s   g | ]}d qS )Fr2   )r9   r:   r2   r2   r3   r<      s    c             S   s   g | ]}d qS )Fr2   )r9   r:   r2   r2   r3   r<      s    Tc                s4   g | ],}t  d | t  |d d   qS )Nr   )r   r@   )r9   r:   )rA   r2   r3   r<      s    c                s8   g | ]0}t  d | t  |d d    qS )Nr   )r   r@   )r9   r:   )rA   rB   r2   r3   r<      s    z
Alpha_T0 at c = z for z may be a bad fit (R^2 = )rC   r)   rD   r   r   r$   rE   rF   rG   rH   r   r'   r    r(   rI   rJ   r%   r&   SkipCounterrL   concatenaterK   r!   r]   crossdotrM   rN   rO   r   )r.   rP   rC   r)   rQ   rR   rS   nrT   rU   r:   rV   rW   rX   Zbox_cZbox_TrY   Zclose_pointsZ
normal_vecrZ   r   r[   r2   )rA   rB   r3   r,      sv    	
>($
$$20
Fz%Alpha_T0_empirical.get_alpha_T0_planec       	      C   sd  t |dk rdS t|| || g }tj|tdd |D fdd}dd tt |D }x|dd D ]}t|d	 || d
 d	krx|d| ||d d  D ]@}t|d	 || d
 d	k rt|| || d
 d	krdS qW qpxf|d| ||d d  D ]F}t|d	 || d
 d	krt|| || d
 d	k rdS qW qpW dS )a  
        :param x (ndarray) : list of x-points
        :param y (ndarray) : list of y-points
        :param c (float) : x-point
        :param T (float) : y-point

        :return bool : Is the point (c,T) inside the polygon spanned by (x1,y1),(x2,y2),...
        r7   Fc             S   s   g | ]}d qS )r   r2   )r9   r:   r2   r2   r3   r<     s    z3Alpha_T0_empirical.check_inside.<locals>.<listcomp>r   )axisc             S   s   g | ]}|qS r2   r2   )r9   r:   r2   r2   r3   r<     s    Nr   T)r%   r   r   r]   r_   vstackrN   r`   )	r.   xyr)   rP   vecsindicesr:   jr2   r2   r3   rK     s    	""8
"<zAlpha_T0_empirical.check_insidec             C   sd   t || || g }t || || g }x*t||D ]\}	}
t |
|	dk r@dS q@W dS )a  
        :param new_x (float) : x-point
        :param new_y (float) : y-point
        :param x_list (ndarray) : list of x-points
        :param y_list (ndarray) : list of y-points
        :param c (float) : x-value at point that is being approximated
        :param T (float) : y-value at point that is being approximated

        :return bool : If the point (new_x,new_y) will improve the approximated value at (c, T)
        r   FT)r   r   r]   zipra   )r.   Znew_xZnew_yx_listZy_listr)   rP   rh   Znew_point_vecsvecZnew_point_vecr2   r2   r3   rL     s    zAlpha_T0_empirical.check_validc	                s  t d_tj jdks*jdkrtjjd jd  fddt	t
|D d tj||d	d
dd tj||ddd td td tdtt|d d tt|d  tdt|dd  d t|dd   t  jdksjdkrt }	|	jddd}
|
jjd jd jd dd
d |
j|||dd |
j|||dd |
d |
d |
d td tt|d  t  jd!krtd" dS )#a  
            Plots the fitted data, good for debugging and to view errors.
            Run __call__ with plot=True, plot='2d' or plot='3d' to activate
            NB: Does NOT display the plot. plt.show() must be called after function call to display
        Zplasma2dTr	   r
   c                s    g | ]} j|   qS r2   )cmapr!   )r9   r:   )	max_alphar.   r2   r3   r<   ;  s    z/Alpha_T0_empirical.plot_fit.<locals>.<listcomp>)colorZgreenrf   zInterpolation points)rq   markerlabelblackzPoint to approximate)rq   rs   zc [vol%]zT [K]zplots/selected/r6   r;   r   Nr7   3do   )
projectionr   Zblue)rq   rr   redz$\alpha_T^\circ$ [-]z$R^2 = $)rn   ru   TzArgument 'plot' can be:
'2d': plot 2d selection of data points
'3d': plot 3d fit and selection of data points
True: plot both the above)cmget_cmapro   r#   r!   rC   pltscatterr   rN   r%   xlabelylabelprintrG   rH   savefigclosefigureadd_subplot
set_xlabel
set_ylabel
set_zlabeltitleshow)r.   rQ   rT   rU   rY   r)   rP   rZ   r[   figaxr2   )rp   r.   r3   rO   0  s0    
4

(.&


zAlpha_T0_empirical.plot_fitc             C   s,   |j | jd | jd | jd dddd dS )	z~
        scatter experimental data points in 3d
        :param ax: A_matr matplotlib.Axes3D instance on which to plot
        r	   r
   r   rx   rf   (   )rq   rr   sN)r|   r   )r.   r   r2   r2   r3   plot_pointsZ  s    zAlpha_T0_empirical.plot_pointsc       
         s<  t d j\}}}}t||dd t||dt\ t }|jddd}	| |rt
fddttD }|jd	 |d
d nbt
 fddtt D }	jjkrt|	j |	 d  }	|jd	  |	d
dd tdj  |d |d |d dS )z
        Plot the data-set selected upon initialization and the interpolation with the method selected upon initialization.
        :param dim_1d: Set to True if data is 1d
        ignore   g{Gz?rv   ru   )rw   c                s$   g | ]} |  | d  qS )r   )r+   )r9   r:   )	T_list_1d	c_list_1dr.   r2   r3   r<   q  s    z0Alpha_T0_empirical.plot_mesh.<locals>.<listcomp>r5   rt   )rq   c                s,   g | ]$  fd dt tD qS )c                s,   g | ]$} |f  |f d  qS )r   )r+   )r9   r:   )r    r   rj   r.   r2   r3   r<   u  s    z;Alpha_T0_empirical.plot_mesh.<locals>.<listcomp>.<listcomp>)rN   r%   )r9   )r    r   r.   )rj   r3   r<   u  s   r   g      ?)rq   alphaz)Approximated $\alpha_T^\circ$ values for zc [%vol]zT [K]u   $\alpha_T^\circ$ [–]N)rE   filterwarningsr$   r   linspacemeshgridr{   r   r   r   r   rN   r%   rC   r+   r-   r   shaper]   Zplot_wireframer   r   r   r   r   )
r.   Zdim_1dmin_cmax_cmin_Tmax_Tr   r   Zalpha_vals_1dZ
alpha_valsr2   )r    r   r   r   r.   r3   	plot_mesha  s*    

$


zAlpha_T0_empirical.plot_meshN)F)F)F)F)__name__
__module____qualname__r4   r*   r-   r,   rK   rL   rO   r   r   r2   r2   r2   r3   r   
   s   5
K

`*r   c               @   s0   e Zd Zdd Zdd ZeZdd Zdd Zd	S )
r^   c             C   s$   ||kr|d | _ n|| _ || _d S )Nr   )valskip)r.   r   r   r2   r2   r3   r4     s    zSkipCounter.__init__c             C   s6   | j | | jkr$|  j |d 7  _ n|  j |7  _ | S )Nr   )r   r   )r.   otherr2   r2   r3   __lADD__  s    zSkipCounter.__lADD__c             C   s
   | j |k S )N)r   )r.   r   r2   r2   r3   __lt__  s    zSkipCounter.__lt__c             C   s   | j S )N)r   )r.   r2   r2   r3   	__index__  s    zSkipCounter.__index__N)r   r   r   r4   r   __add__r   r   r2   r2   r2   r3   r^     s
   r^   c                 sT  g } g }g }g }g }xVt dddD ]B}x:t dddD ]&}t ddddg}t ddddg}|| d || d   t t   }	|	t|	 }
t fddtt D  fddtt D }|d | }	| t t   |t	  |t|	|
 |d |   |t|	| |d |   |t|	t|	 |d |   q>W q&W t
j| tt |dd	 t
j| tt |d
d	 t
  t
j|tt |dd	 t
j|tt |d
d	 t
  t
 }|jddd}|j| |tt |dd	 |j| |tt |d
d	 |d |d t
  dS )z~
        Testing procedure for different wheighted averages based on distance from point to different experimental points
    g{Gz?g?   r6   c                s4   g | ],}t  d | t  |d d   qS )Nr   )r   r@   )r9   r:   )rA   r2   r3   r<     s    z!test_wheights.<locals>.<listcomp>c                s8   g | ]0}t  d | t  |d d    qS )Nr   )r   r@   )r9   r:   )rA   rB   r2   r3   r<     s    b)rq   rA   rv   ru   )rw   r[   Zr_minN)r   r   r   expsqrtrM   rN   r%   appendr"   r{   r|   absr   r   r   r   r   )ZR2_listmin_rZ
miss1_listZ
miss2_listZ
miss3_listZx_pZy_prf   rg   fw1w2r   r   r2   )rA   rB   r3   test_wheights  sB    *

r   c               @   s$   e Zd Zdd Zdd Zdd ZdS )
DB_Builderc             C   s
   || _ d S )N)filename)r.   r   r2   r2   r3   r4     s    zDB_Builder.__init__c       	      C   sf   t | j}|j|d |k|d |k@  }t|d }t|d }t|d }t|d }||||fS )Nr   r   r	   r
   )r   r   r   r   r"   r#   )	r.   r   r   r1   r   r   r   r   r   r2   r2   r3   get_cT_range  s    zDB_Builder.get_cT_rangec          
   C   sZ  t | j}|d }|d }tdd t||D }i }x>|D ]6\}}|| krf|| d | q>d|gi||< q>W x| D ]}tt	|| d || d< tt	|| d || d< tt	|| d || d< tt	|| d || d	< xrt
|| d D ]^\}	}| ||\}
}}}|
|| d |	< ||| d |	< ||| d |	< ||| d	 |	< qW qW t|d
}|d x| D ]}xt
|| d D ]\}	}||d | d tt|| d |	 d d tt|| d |	 d d t|| d |	  d t|| d	 |	  d  qW |d qW W d Q R X d S )Nr   r   c             s   s   | ]\}}||fV  qd S )Nr2   )r9   c1c2r2   r2   r3   	<genexpr>  s    z&DB_Builder.build_db.<locals>.<genexpr>ZMixr   r   r   r   wz)Comp1, Comp2, min_c, max_c, min_T, max_T
z, r   
)r   r   r   setrk   keysr   r   zerosr%   rJ   r   openwriterG   rH   )r.   Zoutfiler1   r   r   Zcomp_tuplesZ	comp_dictr   r   r:   r   r   r   r   filer2   r2   r3   build_db  s6    
zDB_Builder.build_dbN)r   r   r   r4   r   r   r2   r2   r2   r3   r     s   r   )pandasr   matplotlib.pyplotpyplotr{   matplotlib.cmry   Zmpl_toolkits.mplot3dr   numpyr   rE   r   scipy.interpolater   r\   r   r^   r   r   r2   r2   r2   r3   <module>   s     |1