B
    ^\_`,                 @   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 ).Kempersg      ?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   S/Users/vegardjervell/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	   i)r   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 z 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__   s&    
 
zKempers.__init__c             C   s   || _ | j| d S )N)Zmin_tempr   set_tmin)r#   r   r   r   r   set_min_temp6   s    zKempers.set_min_tempc             C   s
   || _ d S )N)r   )r#   r   r   r   r   set_temp:   s    zKempers.set_tempc             C   s
   || _ d S )N)r   )r#   r   r   r   r   set_pres=   s    zKempers.set_presc             C   s   t || _|   d S )N)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   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 )N)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 z and 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   r-   )r#   r   r   Z	old_compsr   r   r   	set_compsY   s
    zKempers.set_compsc             C   s   d S )Nr   )r#   r   r   r   r+   g   s    zKempers.reset_alpha_t0Fc             C   s   d S )Nr   )r#   kinr   r   r   get_soret_covk   s    zKempers.get_soret_covc             C   s   d S )Nr   )r#   r/   r   r   r   get_soret_comp   s    zKempers.get_soret_comc             C   s   d| j |d| j|d  S )Ng      ?)r/   )r0   r1   )r#   r/   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}x:t|D ].\}	}
|
| _|   ||d\||	< ||	< qbW t|| _| | fS t|j
t}x.t|D ]"\}	}
|
| _|   | ||	< qW t|| _| 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)
        r3   comavgz/mode must be either 'cov', 'com' or 'avg', not z 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 fractionsT)r/   N)r0   r1   r2   r   r   strr   r   r   lenshapeconcatenatevstacksum
IndexErroremptyfloat	enumerater+   	transpose)r#   r   moder/   	get_soretZold_mole_fracsZxNsoretkin_contribr   Zfracsr   r   r   get_soret_compy   sL    
 
zKempers.get_soret_compc       
      C   sd  |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}xpt|D ]$\}}	|	| _||d\||< ||< qW n>t	t|t| jf}xLt|D ]\}}	|	| _| ||< qW n&|| _|dkr2||d\}}n| }|| _|dkrX| | 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)
        r3   r4   r5   z/mode must be either 'cov', 'com' or 'avg', not z defaulting back to 'cov'T)r/   N)r0   r1   r2   r   r   r7   r   typelistr   ndarrayr>   r8   r   r@   rA   )
r#   tempsrB   r/   rC   Zold_temprD   rE   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}x2t|D ]\}}|| _| ||< qW n|| _| }|| _|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)
        r3   r4   r5   z/mode must be either 'cov', 'com' or 'avg', not z defaulting back to 'cov')r0   r1   r2   r   r   r7   r   rG   rH   r   rI   r>   r8   r   r@   )r#   Z	pressuresrB   rC   Zold_presrD   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#   vrN   muZdmudn_TVr   rP   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   )rQ   r   )	rX   r   rU   onesr8   r   identityr   dot)r#   rO   ZM1r   r   r   dmudx_TP  s     0zKempers.dmudx_TPN)F)F)F)r3   F)r3   F)r3   )__name__
__module____qualname__r&   r(   r)   r*   r,   r-   r.   r+   r0   r1   r2   rF   rL   rM   rX   r\   r   r   r   r   r      s    &



@
1
%r   )__doc__numpyr   pycThermopack.pyctpr   models.kineticgasr   scipy.constantsr   r   objectr   r   r   r   r   <module>   s   