U
    ^\_`,                     @   sL   d Z ddlZddlmZ ddlmZ ddlmZ ddl	Z	G dd de
ZdS )a  
Author: Vegard G. Jervell
Date: December 2020
Purpose: Parent class containing some general procedures to be used in both Kempers89 and Kempers01
Requires: numpy, ThermoPack
Note: This is a virtual class, and will not do anything exciting if initialized on its own.
    N)cubic)
KineticGas)gas_constantc                   @   s   e Zd ZddgdddfddZdd Zd	d
 Zdd Zdd Zdd Zdd Z	dd Z
d(ddZd)ddZd*ddZd+ddZd,dd Zd-d!d"Zd#d$ Zd%d& Zd'S ).Kempers      ?i,  g     j@   c           	         s   || _ t|| _|| _|| _|| _d| _ fdd| j dD }d|krzt	
d| d  t | _| j| j d n~tt|tt|krd fd	d
t|D }t	
d| d | j  d | d  t | _| j| j d n | _dS )a  
        KempersXX parent class, contains interface for retrieving soret-coefficient for spans of temperatures, pressures or compositions
        and some general initialization procedures that are common for the two KempersXX' models
        :param comps (str): comma separated list of components
        :param x (1darray): list of mole fractions
        :param eos (ThermoPack): Initialized Equation of State object, initialized with components 'comp'
        :param temp (float > 0): Temperature [K]
        :param pres (float > 0): Pressure [Pa]
        :param phase: Phase of mixture, used for calculating dmudn_TP, see thermo.thermopack for phase identifiers
        r   c                    s   g | ]}  |qS  getcompindex.0compeosr   P/home/ubuntu/Home/Documents/7_semester/irrev_prosjekt_renskriv/models/kempers.py
<listcomp>#   s     z$Kempers.__init__.<locals>.<listcomp>,zjEquation of state and KempersXX must be initialized with same components.
I'm initializing using SRK with z now to avoid crashingSRKc                 3   s   | ]}  |V  qd S Nget_comp_namer   ir   r   r   	<genexpr>+   s     z#Kempers.__init__.<locals>.<genexpr>ztEquation of state and KempersXX must be initialized with same components in the same order
but are initialized with  and z".
I'm initializing using SRK with N)compsnparrayxtemppresphasetotal_molessplitwarningswarnr   r   initanysortedjoin)	selfr   r   r   r    r!   r"   eoscomp_indseoscompsr   r   r   __init__   sB    

zKempers.__init__c                 C   s   || _ | j| d S r   )Zmin_tempr   set_tminr+   r    r   r   r   set_min_temp6   s    zKempers.set_min_tempc                 C   s
   || _ d S r   )r    r0   r   r   r   set_temp:   s    zKempers.set_tempc                 C   s
   || _ d S r   )r!   )r+   r!   r   r   r   set_pres=   s    zKempers.set_presc                 C   s   t || _|   d S r   )r   r   r   reset_alpha_t0)r+   r   r   r   r   set_mole_fracs@   s    zKempers.set_mole_fracsc                    s    fdd| j dD }d|kr0td dS tt|tt|krd fddt|D }td	| d
 | j  d  dS  | _	dS dS )zb
        Change equation of state
        :param eos_key (str): new equation of state key
        c                    s   g | ]}  |qS r   r	   r   r   r   r   r   I   s     z#Kempers.set_eos.<locals>.<listcomp>r   r   zdEquation of state and KempersXX must have the same components.I'm just not going to change anything!r   c                 3   s   | ]}  |V  qd S r   r   r   r   r   r   r   P   s     z"Kempers.set_eos.<locals>.<genexpr>z]Equation of state and KempersXX must have the same components in the same orderbut are given r   z.I'm not changing anything!r   N)
r   r$   r%   r&   r(   r   r   r)   r*   r   )r+   r   r,   r-   r   r   r   set_eosD   s$    
zKempers.set_eosc                 C   s&   | j }|| _ | |dkrn|| _ dS )z
        Change components
        :param comps: Comma separated list of components
        :param eos: Initialized equation of state, with same components as 'comp'
        r   N)r   r6   )r+   r   r   Z	old_compsr   r   r   	set_compsY   s
    zKempers.set_compsc                 C   s   d S r   r   )r+   r   r   r   r4   g   s    zKempers.reset_alpha_t0Fc                 C   s   d S r   r   r+   kinr   r   r   get_soret_covk   s    zKempers.get_soret_covc                 C   s   d S r   r   r8   r   r   r   get_soret_comp   s    zKempers.get_soret_comc                 C   s   d| j |d| j|d  S )Nr   r9   )r:   r;   r8   r   r   r   get_soret_avgu   s    zKempers.get_soret_avgcovc                 C   s  |dkr| j }n<|dkr | j}n,|dkr0| j}ntdt| d  | j }dd | jD }t|}t	|j
dkr|j
d	 t	| jkrd| }tjt|t|fdd
}n|j
d	 t	| jkr|g}nf|j
d t	| jd krdtj|dd
 }tj|t|fdd
}n |j
d t	| jkr*ntd|dkrt|j
t}t|j
t}t|D ].\}	}
|
| _|   ||d\||	< ||	< q`t|| _| | fS t|j
t}t|D ]"\}	}
|
| _|   | ||	< qt|| _| S dS )a  
        Get soret-coefficients for a range of compositions
        Args:
            x : array-like
                mole fractions of components, if N - 1 components are given, N is calculated implicitly
                row i is composition i, column j is mole fraction of component j
                [[x1, x2, ..., xN], #composition 1
                 [x1, x2, ..., xN]] #composition 2

        return:
            tuple of floats or ndarrays, matching shape of input : soret coefficients at given composition(s)
        r>   comavg/mode must be either 'cov', 'com' or 'avg', not  defaulting back to 'cov'c                 S   s   g | ]}|qS r   r   )r   Zfracr   r   r   r      s     z*Kempers.get_soret_comp.<locals>.<listcomp>r   r   )axisz&x must contain N-1 or N mole fractionsTr<   N)r:   r;   r=   r%   r&   strr   r   r   lenshapeconcatenatevstacksum
IndexErroremptyfloat	enumerater4   	transpose)r+   r   moder9   	get_soretZold_mole_fracsZxNsoretkin_contribr   Zfracsr   r   r   get_soret_compy   sL    
 
zKempers.get_soret_compc           
      C   s\  |dkr| j }n<|dkr | j}n,|dkr0| j}ntdt| d  | j }| j}t|tt	j
fkr
|dkrt	t|t| jf}t	t|t| jf}t|D ]$\}}	|	| _||d\||< ||< qn:t	t|t| jf}t|D ]\}}	|	| _| ||< qn&|| _|dkr*||d\}}n| }|| _|dkrP| | fS | S dS )	a/  
        Get soret coefficients for a range of temperatures
        Args:
            temps (int, float or array-like) : temperature(s) [K] to get soret-coefficients for

        return:
            tuple of floats or arrays, matching shape of input : Soret-coefficients at given temperature(s)
        r>   r?   r@   rA   rB   Tr<   N)r:   r;   r=   r%   r&   rD   r    typelistr   ndarrayrK   rE   r   rM   rN   )
r+   tempsrO   r9   rP   Zold_temprQ   rR   r   Tr   r   r   get_soret_temp   s8    	

zKempers.get_soret_tempc                 C   s   |dkr| j }n<|dkr | j}n,|dkr0| j}ntdt| d  | j }| j}t|tt	j
fkrt	t|t| jf}t|D ]\}}|| _| ||< qn|| _| }|| _|S )a6  
        Get soret coefficients for a range of pressures
            Args:
                pressures (float or array-like) : pressure(s) [Pa] to get soret-coefficients for

            return:
                tuple of floats or arrays, matching shape of input : Soret-coefficients at given pressure(s)
        r>   r?   r@   rA   rB   )r:   r;   r=   r%   r&   rD   r!   rT   rU   r   rV   rK   rE   r   rM   )r+   Z	pressuresrO   rP   Zold_presrQ   r   r!   r   r   r   get_soret_pres   s$    
zKempers.get_soret_presc                 C   s   | j j| j| j| j| jdd\}}| j j| j|| j | j| j dd\}}| j j| j|| j | j| j dd\}}|t	j
||dd S )z
        Calculate chemical potential derivative with respect to number of moles at constant temperature and pressure
        :return: ndarray, dmudn[i,j] = dmu_idn_j
        T)dvdn)dmudn)dpdnr   axes)r   specific_volumer    r!   r   r"   chemical_potential_tvr#   pressure_tvr   	tensordot)r+   vr[   muZdmudn_TVr!   r]   r   r   r   dmudn_TP  s    "
 
(zKempers.dmudn_TPc                 C   sd   |   }tjtt| jd| j ddtt| jd| j dd| j     | j }t||S )z
        Calculate chemical potential derivative with respect to mole fraction of components
        at constant temperature and pressure
        :return: ndarray, dmudx[i,j] = dmu_idn_j
        r   r   r^   r   )	rf   r   rc   onesrE   r   identityr#   dot)r+   r\   ZM1r   r   r   dmudx_TP  s     &zKempers.dmudx_TPN)F)F)F)r>   F)r>   F)r>   )__name__
__module____qualname__r.   r1   r2   r3   r5   r6   r7   r4   r:   r;   r=   rS   rY   rZ   rf   rj   r   r   r   r   r      s    &



@
1
%r   )__doc__numpyr   pycThermopack.pyctpr   models.kineticgasr   scipy.constantsr   r%   objectr   r   r   r   r   <module>   s   