import numpy as np
import sys

sys.path.insert(0, dirName) # dirName = location where the files listed here are located
from psychClass import Psych

class HeatTrans():
    '''This class is a collection of codes for the calculation of heat transfer.'''
    props = Psych()
    def convertT(self,T,units = 'IP'):
        '''Convert temperature from either F to C (units = 'IP') or C to F (units = 'SI'); return the
           temperature in F, C, and K.'''
        if (units == 'IP'):
            tC = 5/9*(T - 32)
            tF = T
        else:
            tF = T*9/5+32
            tC = T
        tK = tC + 273.15
        return tF,tC,tK # F, C, K

    def fluidProps(self,T,units = 'IP',fluid = 'water',conc = 0.3):
        '''Calculate density, specific heat, and enthalpy of water or propylene glycol of concentration conc.'''
        tF,tC,tK = self.convertT(T,units)
      
        if (fluid == 'water'):
            rho = 995.044+0.278828*tF-0.0046581*tF**2+0.0000219711*tF**3-5.25842*10**(-8)*tF**4
            cp = 4.18
            h = 0.076174 + 4.18766*tC # [kJ/kg] enthalpy of water at atmospheric pressure; from a curve fit in EES
        else: # (fluid == 'pg'):
            rho = 508.41109-182.40820*conc+965.76507*273.15/tK+280.29104*conc*273.15/tK-472.22510*(273.15/tK)**2
            cp = 4.47642-0.60863*conc-0.71497*273.15/tK-1.93855*conc*273.15/tK+0.47873*(273.15/tK)**2	
            h = -20.89 + 3.9095*tC # [kJ/kg] enthalpy of PG at 30 % at atmospheric pressure; from a curve fit in EES
        return rho,cp,h # kg/m3, kJ/kg-K

    def heatTransLiq(self,Tc,Th,flow,units = 'IP',fluid = 'water',conc = 0.3):
        '''Calculate the heat transfer in a liquid given inlet temperature, outlet temperature, and flow rate.'''
        tcF,tcC,tcK = self.convertT(Tc,units)
        thF,thC,thK = self.convertT(Th,units)

        T = (Tc + Th)/2
        rho, cp, h = self.fluidProps(T,units,fluid,conc)

        DT = thC - tcC
        if (units == 'IP'):
            flowCF = 0.00006309 # gpm to m3/s
        else:
            flowCF = 1
        mDot = flow*flowCF*rho
        Q = (mDot*cp*DT)
        return Q,rho,cp,mDot # kW, kg/m3, kJ/kg-K

    def qAirTotal(self,t1,t2,flow,w1,w2,wFlow,tFlow,p,units = 'IP'):
        '''Calculate heat transfer in moist air.
           q,mDotDA,h1,h2,nu = f(t1,t2,flow,w1,w2,wFlow,tFlow,p,units = 'IP')'''
        h1 = HeatTrans.props.enthalpy(t1,w1,units)
        h2 = HeatTrans.props.enthalpy(t2,w2,units)
        mDotDA,nu = HeatTrans.props.mDA(flow,tFlow,wFlow,p,units)
        q = (mDotDA*(h2-h1))
        return q,mDotDA,h1,h2,nu # [kW],m3/kgDA,kJ/kgDA,kJ/kgDA

    def qAHUAirTotal(self,t1,t2,flow1,flow2,w1,w2,wFlow1,tFlow1,wFlow2,tFlow2,p,units = 'IP'):
        '''Calculate heat transfer in moist air in the AHUs. this is a little different because the flow rate in the 
           AHU is the sum of two measurements.'''
        h1 = HeatTrans.props.enthalpy(t1,w1,units)
        h2 = HeatTrans.props.enthalpy(t2,w2,units)
        mDotDA1,nu1 = HeatTrans.props.mDA(flow1,tFlow1,wFlow1,p,units)
        mDotDA2,nu2 = HeatTrans.props.mDA(flow2,tFlow2,wFlow2,p,units)
        mDotDA = mDotDA1+mDotDA2
        q = (mDotDA*(h2-h1))
        return q,mDotDA,h1,h2,(nu1+nu2)/2 # [kW],m3/kgDA,kJ/kgDA,kJ/kgDA

    def qLatent(self,flow,tFlow,wFlow,p,w1,w2,units = 'IP'):
        '''Calculate the latent heat transfer in moist air.'''
        mDotDA,nu = HeatTrans.props.mDA(flow,tFlow,wFlow,p,units)
        qLatent = (2470*mDotDA*(w2-w1)) # 2470 is from Harrison; 2501 kJ/kgDA from ASHRAE handbook
        return qLatent,mDotDA,nu # [kW],m3/kgDA

    def qSens(self,wFlow,tFlow,p,w1,t1,w2,t2,flow,units = 'IP'):
        '''Calculate the sensible heat transfer in moist air.'''
        cpTDA1 = HeatTrans.props.cpTDA(w1,t1,units) # kJ/kgDA
        cpTDA2 = HeatTrans.props.cpTDA(w2,t2,units) # kJ/kgDA
        mDotDA,nu = HeatTrans.props.mDA(flow,tFlow,wFlow,p,units)
        qSens = (cpTDA2-cpTDA1)*mDotDA # 2468 kJ/kg from ASHRAE handbook
        return qSens,cpTDA1,cpTDA2,nu,mDotDA # [kW],m3/kg,kJ/kg-K,kJ/kg-K