Esempio n. 1
0
 def plotDome(self):
     fState = FluidState(self.fluid)
     p = np.logspace(np.log10(self.pMin),
                     np.log10(self.critical.p),
                     num=200)
     qLabels = ['0.2', '0.4', '0.6', '0.8']
     for q in np.arange(0, 1.1, 0.1):
         try:
             h = np.zeros(len(p))
             for i in range(len(p) - 1):
                 fState.update_pq(p[i], q)
                 h[i] = fState.h
             # Putting labels
             if '{:1.1f}'.format(q) in qLabels:
                 angle, offset_x, offset_y = self.getLabelPlacement(
                     x1=h[9], x2=h[10], y1=p[9], y2=p[10])
                 self.ax.annotate("{:1.1f}".format(q),
                                  xy=(h[10] / 1e3, p[10] / 1e5),
                                  xytext=(-offset_x, -offset_y),
                                  textcoords='offset points',
                                  color='b',
                                  size="small",
                                  rotation=angle)
             h[-1] = self.critical.h
             if (q == 0):
                 self.ax.semilogy(h / 1e3,
                                  p / 1e5,
                                  'b',
                                  label='vapor quality')
             else:
                 self.ax.semilogy(h / 1e3, p / 1e5, 'b')
         except RuntimeError, e:
             print '------------------'
             print 'Runtime Warning for q=%e' % q
             print(e)
Esempio n. 2
0
	def plotDome(self):
		fState = FluidState(self.fluid)
		p = np.logspace(np.log10(self.pMin), np.log10(self.critical.p), num = 200)
		qLabels = ['0.2', '0.4', '0.6', '0.8']
		for q in np.arange(0, 1.1, 0.1):
			try:
				h = np.zeros(len(p))
				for i in range(len(p) - 1):
					fState.update_pq(p[i], q)
					h[i] = fState.h
				# Putting labels
				if '{:1.1f}'.format(q) in qLabels:
					angle, offset_x, offset_y = self.getLabelPlacement(x1 = h[9], x2 = h[10],
											y1 = p[9], y2 = p[10])
					self.ax.annotate("{:1.1f}".format(q), 
									xy = (h[10]/ 1e3, p[10] / 1e5),
									xytext=(-offset_x, -offset_y),
									textcoords='offset points',
									color='b', size="small", rotation = angle)
				h[-1] = self.critical.h
				if (q == 0):			
					self.ax.semilogy(h/1e3, p/1e5, 'b', label = 'vapor quality')
				else:
					self.ax.semilogy(h/1e3, p/1e5, 'b')
			except RuntimeError, e:
				print '------------------'
				print 'Runtime Warning for q=%e'%q 
				print(e)
Esempio n. 3
0
class DerivativeTest:
    def __init__ (self, fluid):
        self.fluid = fluid
        self.fState = FluidState(self.fluid)

    def numerical_derivative(self, stateVarNum,
                                    stateVarDenom, stateVarDenom_val, 
                                    stateVarConst, stateVarConst_val, delta = 1.000001):
        """
        stateVarNum - name of state variable in numerator of the derivative (name is in style of FluidState properties)
        stateVarDenom - name of state variable in denominator of the derivative (name is in style of FluidState.update arguments)
        stateVarConst - name of constant state variable (name is in style of FluidState.update arguments)
        """
        self.fState.update(stateVarDenom, stateVarDenom_val, stateVarConst, stateVarConst_val)
        stateVarNum_val = getattr(self.fState, stateVarNum)
        stateVarDenom_val_new = stateVarDenom_val * delta
        self.fState.update(stateVarDenom, stateVarDenom_val_new, stateVarConst, stateVarConst_val)
        stateVarNum_val_new = getattr(self.fState, stateVarNum)
        num_derivative = (stateVarNum_val_new - stateVarNum_val) / (stateVarDenom_val_new - stateVarDenom_val)
        return num_derivative
    
    @staticmethod
    def test():
        test_instance = DerivativeTest("Water")
        _drhodT_s = test_instance.numerical_derivative('rho', 
                                                     'T', 633.15,
                                                     'S', 4000)
        print ('Numerical: ' + str(_drhodT_s))
        fState = FluidState("Water")
        fState.update_Ts(633.15, 4000)
        print ('Analytical: ' + str(fState.rho**2 * fState.dsdT_v / fState.dpdT_v))
        print ('q = {}'.format(fState.q))
Esempio n. 4
0
    def compute(self):
        f = Fluid(self.fluidName)
        fState = FluidState(self.fluidName)
        numPoints = 100
        pressures = np.logspace(np.log10(f.tripple["p"]), np.log10(f.critical["p"]), numPoints, endpoint=False)
        data = np.zeros((numPoints, 10))
        data[:, 0] = pressures

        for i in range(len(pressures)):
            fState.update_pq(pressures[i], 0)
            satL = fState.SatL
            satV = fState.SatV

            data[i, 1] = fState.T
            data[i, 2] = satL.rho
            data[i, 3] = satV.rho
            data[i, 4] = satL.h
            data[i, 5] = satV.h
            data[i, 7] = satL.s
            data[i, 8] = satV.s
            # Compute evaporation enthalpy
        data[:, 6] = data[:, 5] - data[:, 4]
        # Compute evaporation entropy
        data[:, 9] = data[:, 8] - data[:, 7]

        self.T_p_satPlot = data[:, (0, 1)]
        self.rho_p_satPlot = data[:, (0, 2, 3)]
        self.delta_h_p_satPlot = data[:, (0, 6)]
        self.delta_s_p_satPlot = data[:, (0, 9)]
        self.satTableView = data
Esempio n. 5
0
 def test():
     test_instance = DerivativeTest("Water")
     _drhodT_s = test_instance.numerical_derivative('rho', 
                                                  'T', 633.15,
                                                  'S', 4000)
     print ('Numerical: ' + str(_drhodT_s))
     fState = FluidState("Water")
     fState.update_Ts(633.15, 4000)
     print ('Analytical: ' + str(fState.rho**2 * fState.dsdT_v / fState.dpdT_v))
     print ('q = {}'.format(fState.q))
Esempio n. 6
0
 def test():
     test_instance = DerivativeTest("Water")
     _drhodT_s = test_instance.numerical_derivative('rho', 'T', 633.15, 'S',
                                                    4000)
     print('Numerical: ' + str(_drhodT_s))
     fState = FluidState("Water")
     fState.update_Ts(633.15, 4000)
     print('Analytical: ' +
           str(fState.rho**2 * fState.dsdT_v / fState.dpdT_v))
     print('q = {}'.format(fState.q))
Esempio n. 7
0
	def postProcess(self, TAmbient):
		## State diagram
		if (self.cycleDiagram.enable):
			self.createStateDiagram()
		## Table of states
		self.cycleStatesTable.resize(len(self.fp))
		for i in range(len(self.fp)):
			fp = self.fp[i]
			self.cycleStatesTable[i] = (fp.T, fp.p, fp.rho, fp.h, fp.s, fp.q, fp.dT, self.flows[i].mDot, fp.b(TAmbient))
		# Select the zero for the exergy scale
		fp = FluidState(self.fluid)
		fp.update_Tp(TAmbient, 1e5)
		b0 = fp.b(TAmbient)
		self.cycleStatesTable['b'] -= b0
Esempio n. 8
0
 def postProcess(self, TAmbient):
     ## State diagram
     if (self.cycleDiagram.enable):
         self.createStateDiagram()
     ## Table of states
     self.cycleStatesTable.resize(len(self.fp))
     for i in range(len(self.fp)):
         fp = self.fp[i]
         self.cycleStatesTable[i] = (fp.T, fp.p, fp.rho, fp.h, fp.s, fp.q,
                                     fp.dT, self.flows[i].mDot,
                                     fp.b(TAmbient))
     # Select the zero for the exergy scale
     fp = FluidState(self.fluid)
     fp.update_Tp(TAmbient, 1e5)
     b0 = fp.b(TAmbient)
     self.cycleStatesTable['b'] -= b0
Esempio n. 9
0
 def computePressureDrop(self, fStateFilm = None):
     
     if (fStateFilm is None):
         fStateFilm = FluidState(self.fluidName)
         fStateFilm.update_Tp(self.inletTemperature, self.inletPressure)
     
     self.inletDensity = fStateFilm.rho
     self.massFlowRate = self.inletMassFlowRate
     self.fluidMass = self.fluidVolume * self.inletDensity
     self.volumetricFlowRate = self.massFlowRate / self.inletDensity    
     self.flowVelocity = self.massFlowRate / (self.inletDensity * self.crossSectionalArea)
     self.Re = self.inletDensity * self.flowVelocity * self.internalDiameter / fStateFilm.mu
     self.zeta = FrictionFlowSingularComponents.ChurchilCorrelation(self.Re, self.internalDiameter, self.surfaceRoughness)
     self.dragCoefficient = self.zeta * self.length / self.internalDiameter
     self.pressureDrop = self.dragCoefficient * self.inletDensity * self.flowVelocity * self.flowVelocity / 2.
     self.outletPressure = self.inletPressure - self.pressureDrop
     if (self.outletPressure <= 0):
         raise ValueError("This mass flow rate cannot be achieved.")    
Esempio n. 10
0
 def computeHeatExchange(self, fStateFilm = None):      
     if (fStateFilm is None):
         fStateFilm = FluidState(self.fluidName)
         fStateFilm.update_Tp(self.inletTemperature, self.inletPressure)
         self.inletEnthalpy = fStateFilm.h
     
     self.Pr = fStateFilm.Pr
     self.cond = fStateFilm.cond
     
     # Determining Nusselt number
     if (self.Re <= 2.3e3):
         # laminar flow
         self.Nu = 3.66
     elif (self.Re > 2.3e3 and self.Re < 1e4):
         # transition    
         interpCoeff = (self.Re - 2.3e3) / (1e4 - 2.3e3) 
         Nu_low = 3.66
         xi = (1.8 * 4 - 1.5)**(-2)
         Nu_high = ((xi / 8.) * 1e4 * self.Pr) / (1 + 12.7 * math.sqrt(xi / 8.) * (self.Pr**(2 / 3.) - 1)) * \
         (1 + (self.internalDiameter / self.length)**(2 / 3.))
         self.Nu = interpCoeff * Nu_high + (1 - interpCoeff) * Nu_low
     elif (self.Re >= 1e4): # and self.Re <= 1e6):
         # turbulent flow
         xi = (1.8 * math.log(self.Re, 10) - 1.5)**(-2)
         self.Nu = ((xi / 8.) * self.Re * self.Pr) / (1 + 12.7 * math.sqrt(xi / 8.) * (self.Pr**(2 / 3.) - 1))
     #elif (self.Re > 1e6):
     #    raise ValueError("Reynolds Number outside range of validity")
     
     self.alpha = self.cond * self.Nu / self.internalDiameter
     
     if (self.computationWithIteration == True):            
         LMTD = - (self.outletTemperature - self.inletTemperature) / \
                 math.log((self.TWall - self.inletTemperature) / \
                     (self.TWall - self.outletTemperature))
         self.QDot = self.alpha * self.internalSurfaceArea * LMTD
     else:
         self.QDot = self.alpha * self.internalSurfaceArea * (self.inletTemperature - self.TWall)
     
     self.outletEnthalpy = self.inletEnthalpy - (self.QDot / self.massFlowRate)
     
     fStateOut = FluidState(self.fluidName)
     fStateOut.update_ph(self.outletPressure, self.outletEnthalpy)
     prevOutletTemperature = self.outletTemperature 
     self.outletTemperature = fStateOut.T
     
     if ((self.outletTemperature - self.TWall)*(self.inletTemperature - self.TWall) < 0):
         if (self.computationWithIteration == True):
             self.outletTemperature = 0.5 * prevOutletTemperature + 0.5 * self.TWall
         else:
             self.outletTemperature = self.TWall
     else:
         if (self.computationWithIteration == True):
             self.outletTemperature = 0.9 * prevOutletTemperature + 0.1 * self.outletTemperature    
Esempio n. 11
0
 def connectPorts(self, port1, port2, fluid=None):
     if fluid == None:
         fluid = self.fluid
     fp = FluidState(fluid)
     flow = P.FluidFlow()
     self.fp.append(fp)
     self.flows.append(flow)
     port1.state = fp
     port2.state = fp
     port1.flow = flow
     port2.flow = flow
Esempio n. 12
0
	def compute(self):
		R = 8.314462
		mMol = Fluid(self.fluidName).molarMass / 1e3
		self.T = (self.T1 + self.T2) / 2
		state = FluidState(self.fluidName)
		state.update_Tp(self.T, self.p)

		self.rho = state.rho
		self.mu = state.mu
		self.c = np.sqrt(8 * R * state.T / (np.pi * mMol))
		self.l = (2 * self.mu) / (state.rho * self.c)
		
		self.Kn = self.l / self.d
		self.f = 16./15 * (1 / state.Pr) * (state.gamma / (state.gamma + 1))
		self.fct = 1. / (1 + 15./4 * self.Kn) #* self.f
				
		self.qDot = self.fct * state.cond / self.d * np.abs(self.T1 - self.T2)
		
		Rg = R / mMol
		self.qDotFM = (state.cp - Rg / 2 ) * state.p / np.sqrt(2 * np.pi * Rg * self.T) * np.abs(self.T1 - self.T2) 
Esempio n. 13
0
    def compute(self):
        R = 8.314462
        mMol = Fluid(self.fluidName).molarMass / 1e3
        self.T = (self.T1 + self.T2) / 2
        state = FluidState(self.fluidName)
        state.update_Tp(self.T, self.p)

        self.rho = state.rho
        self.mu = state.mu
        self.c = np.sqrt(8 * R * state.T / (np.pi * mMol))
        self.l = (2 * self.mu) / (state.rho * self.c)

        self.Kn = self.l / self.d
        self.f = 16. / 15 * (1 / state.Pr) * (state.gamma / (state.gamma + 1))
        self.fct = 1. / (1 + 15. / 4 * self.Kn)  #* self.f

        self.qDot = self.fct * state.cond / self.d * np.abs(self.T1 - self.T2)

        Rg = R / mMol
        self.qDotFM = (state.cp - Rg / 2) * state.p / np.sqrt(
            2 * np.pi * Rg * self.T) * np.abs(self.T1 - self.T2)
Esempio n. 14
0
class DerivativeTest:
    def __init__(self, fluid):
        self.fluid = fluid
        self.fState = FluidState(self.fluid)

    def numerical_derivative(self,
                             stateVarNum,
                             stateVarDenom,
                             stateVarDenom_val,
                             stateVarConst,
                             stateVarConst_val,
                             delta=1.000001):
        """
        stateVarNum - name of state variable in numerator of the derivative (name is in style of FluidState properties)
        stateVarDenom - name of state variable in denominator of the derivative (name is in style of FluidState.update arguments)
        stateVarConst - name of constant state variable (name is in style of FluidState.update arguments)
        """
        self.fState.update(stateVarDenom, stateVarDenom_val, stateVarConst,
                           stateVarConst_val)
        stateVarNum_val = getattr(self.fState, stateVarNum)
        stateVarDenom_val_new = stateVarDenom_val * delta
        self.fState.update(stateVarDenom, stateVarDenom_val_new, stateVarConst,
                           stateVarConst_val)
        stateVarNum_val_new = getattr(self.fState, stateVarNum)
        num_derivative = (stateVarNum_val_new - stateVarNum_val) / (
            stateVarDenom_val_new - stateVarDenom_val)
        return num_derivative

    @staticmethod
    def test():
        test_instance = DerivativeTest("Water")
        _drhodT_s = test_instance.numerical_derivative('rho', 'T', 633.15, 'S',
                                                       4000)
        print('Numerical: ' + str(_drhodT_s))
        fState = FluidState("Water")
        fState.update_Ts(633.15, 4000)
        print('Analytical: ' +
              str(fState.rho**2 * fState.dsdT_v / fState.dpdT_v))
        print('q = {}'.format(fState.q))
Esempio n. 15
0
    def compute(self):
        fState = FluidState(self.fluidName)
        fState.update(
            self.stateVariable1,
            self.getStateValue(self.stateVariable1, 1),
            self.stateVariable2,
            self.getStateValue(self.stateVariable2, 2),
        )
        self.T = fState.T
        self.p = fState.p
        self.rho = fState.rho
        self.h = fState.h
        self.s = fState.s
        self.q = fState.q
        self.u = fState.u

        self.cp = fState.cp
        self.cv = fState.cv
        self.gamma = fState.gamma
        self.Pr = fState.Pr
        self.cond = fState.cond
        self.mu = fState.mu
        self.dpdT_v = fState.dpdT_v
        self.dpdv_T = fState.dpdv_T

        self.isTwoPhase = fState.isTwoPhase()
        if self.isTwoPhase:
            satL = fState.SatL
            satV = fState.SatV

            self.rho_L = satL.rho
            self.h_L = satL.h
            self.s_L = satL.s

            self.rho_V = satV.rho
            self.h_V = satV.h
            self.s_V = satV.s
Esempio n. 16
0
    def test():
        fp = [FluidState('Water') for _ in range(4)]
        he = HeatExchangerTwoStreams()
        he.inlet1.state = fp[0]
        he.outlet1.state = fp[1]
        he.inlet2.state = fp[2]
        he.outlet2.state = fp[3]

        he.inlet1.state.update_Tp(80 + 273.15, 1e5)
        he.inlet2.state.update_Tp(20 + 273.15, 1e5)
        m1Dot = 1.
        m2Dot = 1.

        he.compute(m1Dot, m2Dot)
        print he
Esempio n. 17
0
 def computeWithIteration(self):
     self.computeGeometry()
     
     #In state
     fStateIn = FluidState(self.fluidName)
     fStateIn.update_Tp(self.inletTemperature, self.inletPressure)
     self.inletEnthalpy = fStateIn.h
     
     # Mean state
     fStateMean = FluidState(self.fluidName)
     outletTemperature_guess = (self.inletTemperature + self.TWall) / 2.
     self.outletTemperature = outletTemperature_guess
     prevOutletTemperature = self.outletTemperature
     
     for i in range(int(self.maxIterations)):
         meanTemperature = (self.inletTemperature + outletTemperature_guess) / 2.
         fStateMean.update_Tp(meanTemperature, self.inletPressure)
         self.computePressureDrop(fStateFilm = fStateMean)
         self.computeHeatExchange(fStateFilm = fStateMean)
         if (abs(prevOutletTemperature - self.outletTemperature) / prevOutletTemperature < self.relativeTolerance):
             break
         if (abs(self.outletTemperature - self.TWall) < 0.01):
             break
         outletTemperature_guess = self.outletTemperature
Esempio n. 18
0
	def setLimits(self, pMin = None, pMax = None,  hMin = None, hMax = None, TMax = None):
		# Reference points
		self.minLiquid = FluidState(self.fluid)
		self.minVapor = FluidState(self.fluid)
		self.critical = FluidState(self.fluid)
		self.critical.update_Trho(self.fluid.critical['T'], self.fluid.critical['rho'])

		# For general use
		fState = FluidState(self.fluid)

		# Pressure range
		if (pMin is None):
			pMin = self.fluid.tripple['p'] * 1.05
			if (pMin < 1e3):
				pMin = 1e3
		self.pMin = pMin
		
		self.minLiquid.update_pq(self.pMin, 0)		
		self.minVapor.update_pq(self.pMin, 1)
		
		if (pMax is None):
			pMax = 3 * self.critical.p
		self.pMax = pMax
		
		
		# Enthalpy range
		domeWidth = self.minVapor.h - self.minLiquid.h		
		if (hMin is None):
			hMin = self.minLiquid.h
		self.hMin = hMin
		
		# Determining max enthalpy
		if (TMax is None):
			if (hMax is None):
				# default max enthalpy	
				if (self.critical.h > self.minVapor.h):
					hMax = self.critical.h + domeWidth
				else:
					hMax = self.minVapor.h + domeWidth
		else:
			fState.update_Tp(TMax, self.pMin)
			hMax = fState.h
			
		self.hMax = hMax
		
		# Axes ranges
		self.xMin = self.hMin
		self.xMax = self.hMax
		self.yMin = self.pMin
		self.yMax = self.pMax
		
		# Density range
		fState.update_ph(self.pMin, self.hMax)
		self.rhoMin = fState.rho
		self.rhoMax = self.minLiquid.rho
		
		# Temperature range
		self.TMin = self.fluid.saturation_p(self.pMin)["TsatL"]
		
		if (TMax is None):
			fState.update_ph(self.pMin, self.hMax)
			TMax = fState.T
		self.TMax = TMax
		
		# Entropy range
		self.sMin = 1.01 * self.minLiquid.s
		
		fState.update_ph(self.pMin, self.hMax)
		self.sMax = fState.s
		
		# Minor diagonal coeff
		self.minDiagonalSlope = np.log10(self.pMax/self.pMin) / (self.hMax - self.hMin) * 1e3
		
		# Major diagonal coeff
		self.majDiagonalSlope = - self.minDiagonalSlope
Esempio n. 19
0
'''
Created on Feb 23, 2015

@author: Atanas Pavlov
'''

import numpy as np
from smo.media.CoolProp.CoolProp import FluidState, Fluid

fluid = Fluid('Water')

dT = 1e-4
dq = 1e-3

f1 = FluidState(fluid)
f2 = FluidState(fluid)

f1.update_Tq(273.15 + 150, 0.5)

# dqdT_v
f2.update_Trho(f1.T + dT, f1.rho)
dqdT_v = (f2.q - f1.q) / (f2.T - f1.T)
print ("dqdT_v() numerical: {:e}, analytical: {:e}".format(dqdT_v, f1.dqdT_v)) 

# dvdT_q
f2.update_Tq(f1.T + dT, f1.q)
dvdT_q = (f2.v - f1.v) / (f2.T - f1.T)
dvdT_q_1 = f1.q * f1.SatV.dvdT + (1 - f1.q) * f1.SatL.dvdT
print ("dvdT_q() numerical: {:e}, analytical: {:e}, analytical2: {:e}".format(dvdT_q, f1.dvdT_q, dvdT_q_1))

# dvdq_T
Esempio n. 20
0
	def plotIsochores(self):
		fState = FluidState(self.fluid)
		rhoArr1 = np.logspace(np.log10(self.rhoMin), np.log10(self.critical.rho), num = 20, endpoint = False)
		rhoArr2 = np.logspace(np.log10(self.critical.rho), np.log10(self.rhoMax), num = 5)
		rhoArr = np.zeros(len(rhoArr1) + len(rhoArr2))
		rhoArr[:len(rhoArr1)] = rhoArr1[:]
		rhoArr[len(rhoArr1):] = rhoArr2[:]
		TArr = np.logspace(np.log10(self.TMin), np.log10(self.TMax), num = 100)
		# For label location purposes
		h_level_low = self.hMin + (self.critical.h - self.hMin) * 3 / 4.
		h_level_high = self.critical.h + (self.hMax - self.critical.h) * 1 / 2. 
		for rho in rhoArr:
			try:
				hArr = np.zeros(len(TArr))
				pArr = np.zeros(len(TArr))
				for i in range(len(TArr)):
					fState.update_Trho(TArr[i], rho)
					hArr[i] = fState.h
					pArr[i] = fState.p
					# Putting labels
					# Determining annotated point and label text offest
					
					if (pArr[i-1] < self.pMax and pArr[i] > self.pMax):
						if (hArr[i] < h_level_low):
							angle, offset_x, offset_y = self.getLabelPlacement(x1 = hArr[i-1], x2 = hArr[i],
																				y1 = pArr[i-1], y2 = pArr[i])
							self.ax.annotate(formatNumber(rho, sig = 2), 
											xy = (hArr[i-1] / 1e3, pArr[i-1] / 1e5),
											xytext=(0, -10),
											textcoords='offset points',
											color='g', size="small", rotation = angle)
						elif (hArr[i] > h_level_low and hArr[i] < h_level_high):
							angle, offset_x, offset_y = self.getLabelPlacement(x1 = hArr[i-2], x2 = hArr[i-1],
																				y1 = pArr[i-2], y2 = pArr[i-1])
							self.ax.annotate(formatNumber(rho, sig = 2), 
											xy = (hArr[i-2] / 1e3, pArr[i-2] / 1e5),
											xytext=(5, -5),
											textcoords='offset points',
											color='g', size="small", rotation = angle)
						elif (hArr[i] > h_level_high):
							angle, offset_x, offset_y = self.getLabelPlacement(x1 = hArr[i-10], x2 = hArr[i-9],
																				y1 = pArr[i-10], y2 = pArr[i-9])
							self.ax.annotate(formatNumber(rho, sig = 2), 
											xy = (hArr[i-10] / 1e3, pArr[i-10] / 1e5),
											xytext=(0, -5),
											textcoords='offset points',
											color='g', size="small", rotation = angle)
					elif (i == len(TArr) - 1 and pArr[i] < self.pMax and pArr[i-1] > self.pMin):
						angle, offset_x, offset_y = self.getLabelPlacement(x1 = hArr[i-1], x2 = hArr[i],
																			y1 = pArr[i-1], y2 = pArr[i])
						self.ax.annotate(formatNumber(rho, sig = 2), 
										xy = (hArr[i] / 1e3, pArr[i] / 1e5),
										xytext=(-30, -12),
										textcoords='offset points',
										color='g', size="small", rotation = angle)
				if (rho == rhoArr[0]):
					self.ax.semilogy(hArr/1e3, pArr/1e5, 'g', label = 'density [kg/m3]')
				else:
					self.ax.semilogy(hArr/1e3, pArr/1e5, 'g')
			except RuntimeError, e:
				print '------------------'
				print 'Runtime Warning for rho=%e'%rho 
				print(e)
Esempio n. 21
0
	def compute(self):
		if (self.geomConf == 'HP' or self.geomConf == 'IP'):
			self.Tfilm = (self.TWallTop + self.TWallBottom) / 2.0
			self.deltaT = self.TWallTop - self.TWallBottom
		elif (self.geomConf == 'VP'):
			self.Tfilm = (self.TWallLeft + self.TWallRight) / 2.0
			self.deltaT = self.TWallLeft - self.TWallRight
		elif (self.geomConf == 'HA'):
			self.Tfilm = (self.TInner + self.TOuter) / 2.0
			self.deltaT = self.TInner - self.TOuter
		
		# Compute fluid properties
		fState = FluidState(self.fluidName)
		fState.update_Tp(self.Tfilm, self.pressure)		
		self.rho = fState.rho
		self.mu = fState.mu
		nu = self.mu / self.rho
		self.beta = fState.beta
		self.Pr = fState.Pr
		self.cond = fState.cond
			
		# Compute geometry factors
		if (self.geomConf == 'HP' or self.geomConf == 'IP'):
			s = self.dist
			self.area = self.width * self.length
		elif (self.geomConf == 'VP'):
			s = self.dist
			self.area = self.width * self.height
		elif (self.geomConf == 'HA'):
			s = self.rOuter - self.rInner
			self.area = 2 * np.pi * self.rInner * self.length
		else:
			raise ValueError("Geometry configuration {0} not implemented".format(GeometryConfigurationsInternal[self.geomConf]))
		
		# Compute free convection dimensionless numbers
		self.Gr = 9.81 * (s**3) * self.beta * np.abs(self.deltaT) / (nu**2)
		self.Ra = self.Gr * self.Pr
		
		# Use the appropriate empirical Nusselt correlation
		if (self.geomConf == 'HP'):
			if (self.Ra >= 0 and self.Ra <= 1708):
				self.Nu = 1.
			elif (self.Ra > 1708 and self.Ra <= 2.2 * 1e4):
				self.Nu = 0.208 * self.Ra**0.25
			elif (self.Ra > 2.2 * 1e4):
				self.Nu = 0.092 * self.Ra**0.33
		elif (self.geomConf == 'VP'):
			if (self.height / s <= 80):
				if (self.Ra > 1e9):
					raise ValueError("Outside range of validity")
				else:
					if (self.Ra > 1e7):
						self.Nu = 0.049 * self.Ra**0.33
					else:
						self.Nu = 0.42 * self.Pr**0.012 * self.Ra**0.25 * (self.height / s)**(-0.25)
						if (self.Nu < 1.):
							self.Nu = 1.				
			else:
				raise ValueError("Outside range of validity")
		elif (self.geomConf == 'IP'):
			if (self.deltaT < 0):
				from scipy.interpolate import interp1d
				angles = np.array([0, 30, 45, 60, 90])
				values = np.array([4.9, 5.7, 5.9, 6.5, 6.9]) * 1e-2
				interpFunc = interp1d(angles, values, kind='linear')
				C =  interpFunc(self.angle)
				self.Nu = C * self.Ra**0.33 * self.Pr**0.074
			else:
				if (self.Ra >= 5e3 and self.Ra <= 1e8):
					if (self.angle == 45):
						self.Nu = 1 + (0.025 * self.Ra**1.36) / (self.Ra + 1.3 + 1e4)
					else:
						raise ValueError("Outside range of validity")
				else:
					raise ValueError("Outside range of validity")
		elif (self.geomConf == 'HA'):
			if (self.deltaT > 0):
				if (self.Ra > 7.1e3):
					if (self.rOuter / self.rInner) <= 8:
						self.Nu = 0.2 * self.Ra**0.25 * (self.rOuter / self.rInner)**0.5
					else:
						raise ValueError("Outside range of validity")
				else:
					raise ValueError("Outside range of validity")
			else:
				raise ValueError("Outside range of validity")
		else: 
			pass
		self.Nu = self.Nu * self.heatExchangeGain
		
		# Compute the convection coefficient and the total heat flow rate
		self.alpha = self.Nu * self.cond / s
		self.QDot = self.area * self.alpha * self.deltaT
Esempio n. 22
0
	def compute(self):
		self.deltaT = self.TWall - self.TFluid
		if (self.propT == 'MT'):
			self.Tfilm = (self.TWall + self.TFluid) / 2.0
		else:
			self.Tfilm = self.TFluid
		
		# Compute fluid properties
		fState = FluidState(self.fluidName)
		fState.update_Tp(self.Tfilm, self.pressure)		
		self.rho = fState.rho
		self.mu = fState.mu
		nu = self.mu / self.rho
		self.beta = fState.beta
		self.Pr = fState.Pr
		self.cond = fState.cond
		
		# Compute geometry factors
		if (self.geomConf == 'VP'):
			s = self.height
			self.area = self.width * self.height
		elif (self.geomConf == 'VC'):
			s = self.height
			self.area = np.pi * self.diameter * self.height
		elif (self.geomConf == 'HC'):
			s = self.diameter
			self.area = np.pi * self.diameter * self.length
		elif (self.geomConf == 'HPT' or self.geomConf == 'HPB'):
			if (self.surfaceShape == 'RCT'):
				s = self.width * self.length / (2.0 * (self.width + self.length))
				self.area = self.width * self.length
			elif (self.surfaceShape == 'CIR'):
				s = self.diameter / 4.0
				self.area = (np.pi / 4) * self.diameter**2
		elif (self.geomConf == 'SPH'):
			s = self.diameter
			self.area = np.pi * self.diameter**2
		elif (self.geomConf == 'IPT' or self.geomConf == 'IPB'):
			s = self.length
			self.area = self.width * self.height
		elif (self.geomConf == 'FIN'):
			#halfway between full rib and bare pipe
			s = self.diameter + self.finHeight;
			finsPerLength = 1.0/(self.finThickness + self.finSpacing)
			self.area = np.pi * self.diameter * (1 - self.finThickness * finsPerLength)
			self.area += finsPerLength * np.pi * self.finHeight * 2 * (self.diameter + self.finHeight)
			self.area += finsPerLength * np.pi * self.finThickness * (self.diameter + 2 * self.finHeight)
			self.area *= self.length
		else:
			raise ValueError("Geometry configuration {0} not implemented".format(GeometryConfigurationsExternal[self.geomConf]))
		
		# Compute free convection dimensionless numbers
		self.Gr = 9.81 * (s**3) * self.beta * np.abs(self.deltaT) / (nu**2)
		self.Ra = self.Gr * self.Pr
		
		# Use the appropriate empirical Nusselt correlation
		if (self.geomConf == 'VP'):
			fPr = (1 + (0.492 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
			self.Nu = (0.825 + 0.387 * (self.Ra * fPr)**(1.0 / 6))**2
		elif (self.geomConf == 'VC'):
			fPr = (1 + (0.492 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
			Nu_plate = (0.825 + 0.387 * (self.Ra * fPr)**(1.0 / 6))**2
			self.Nu = Nu_plate + 0.97 * self.height / self.diameter		
		elif (self.geomConf == 'HC'):
			fPr = (1 + (0.559 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
			self.Nu = (0.6 + 0.387 * (self.Ra * fPr)**(1.0 / 6))**2			
		elif ((self.geomConf == 'HPT' and self.deltaT <= 0) or (self.geomConf == 'HPB' and self.deltaT >= 0)):
			fPr = (1 + (0.492 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
			if (self.Ra * fPr < 1e10):
				self.Nu = 0.6 * (self.Ra * fPr)**(1.0 / 5)
				if (self.Nu < 1):
					self.Nu = 1
			else: 
				raise ValueError("Outside range of validity")
		elif ((self.geomConf == 'HPT' and self.deltaT > 0) or (self.geomConf == 'HPB' and self.deltaT < 0)):
			fPr = (1 + (0.322 / self.Pr)**(11.0 / 20))**(-20.0 / 11) 
			if (self.Ra * fPr <= 7 * 1e4):
				self.Nu = 0.766 * (self.Ra * fPr)**(1.0 / 5)
			else:
				self.Nu = 0.15 * (self.Ra * fPr)**(1.0 / 3)
		elif (self.geomConf == 'SPH'):
			self.Nu = 0.56 * (self.Pr * self.Ra /(0.846 + self.Pr))**(1.0 / 4) + 2
		elif ((self.geomConf == 'IPT' and self.deltaT <= 0) or (self.geomConf == 'IPB' and self.deltaT >= 0)):
			fPr = (1 + (0.492 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
			self.Nu = (0.825 + 0.387 * (self.Ra * np.cos(self.angle) * fPr)**(1.0 / 6))**2	
		elif ((self.geomConf == 'IPT' and self.deltaT > 0) or (self.geomConf == 'IPB' and self.deltaT < 0)):
			Ra_crit = 10**(8.9 - 0.00178 * (self.angle * 180 / np.pi)**1.82)
			self.Nu = 0.56 * (Ra_crit * np.cos(self.angle))**(1.0 / 4) + 0.13 * (self.Ra**(1.0 / 3) - Ra_crit**(1.0 / 3))
		elif (self.geomConf == 'FIN'):
			#Correlation from VDI Heat Atlas F2.4.4
			self.Nu = 0.24 * (self.Ra * self.finSpacing / self.diameter)**(1.0 / 3)
		else: 
			pass
		self.Nu = self.Nu * self.heatExchangeGain
		
		# Compute the convection coefficient and the total heat flow rate
		self.alpha = self.Nu * self.cond / s
		self.QDot = self.area * self.alpha * self.deltaT
Esempio n. 23
0
	def plotIsentrops(self):
		fState = FluidState(self.fluid)
		sArr = np.linspace(self.sMin, self.sMax, num = 20)
		for s in sArr:
			try:
				hArr = []
				pArr = []
				fState.update_ps(self.pMax, s)
				if (fState.T > self.TMax):
					fState.update_Ts(self.TMax, s)
				T = fState.T
				hArr.append(fState.h)
				pArr.append(fState.p)
				# Calculated v
				v_res = fState.v
				while (T > self.TMin):
					_dvdT_s = - fState.dsdT_v / fState.dpdT_v
					if math.isnan(_dvdT_s ):
						break
					TStep = - (self.critical.T / 200.) / (np.abs(_dvdT_s) + 1) 
					T = T + TStep
					if T < self.TMin:
						break
					v_res += _dvdT_s * TStep
					fState.update_Trho(T, 1. / v_res)
					p = fState.p
					# If it goes out of the screen through the bottom
					if (p < self.pMin):
						break
					# Calculated s
					s_res = fState.s
					# Correcting v
					ds = s - s_res
					sigma = ds * fState.dvds_T
					v = v_res + sigma
					fState.update_Trho(T, 1. / v)
					hArr.append(fState.h)
					pArr.append(fState.p)
					##################
					# Putting labels
					i = len(hArr) - 1
					b = np.log10(self.pMax / 1e5) - self.majDiagonalSlope * self.hMin / 1e3
					if (np.log10(pArr[i-1] / 1e5) - self.majDiagonalSlope * hArr[i-1] / 1e3 - b) * \
						(np.log10(pArr[i] / 1e5) - self.majDiagonalSlope * hArr[i] / 1e3 - b) <= 0:
						angle, offset_x, offset_y = self.getLabelPlacement(x1 = hArr[i-1], x2 = hArr[i],
																			y1 = pArr[i-1], y2 = pArr[i])
						self.ax.annotate(formatNumber(s/1e3, sig = 3), 
											xy = (hArr[i-1]/1e3, pArr[i-1]/1e5),
											xytext=(-offset_x, -offset_y),
											textcoords='offset points',
											color='m', size="small", rotation = angle)
					#######################
				hArr = np.array(hArr)
				pArr = np.array(pArr)
				if (s == sArr[0]):
					self.ax.semilogy(hArr/1e3, pArr/1e5, 'm', label = "entropy [kJ/kg-K]")
				else:
					self.ax.semilogy(hArr/1e3, pArr/1e5, 'm')
			except RuntimeError, e:
				print '------------------'
				print 'Runtime Warning for s=%e'%s 
				print e
Esempio n. 24
0
'''
Created on Feb 23, 2015

@author: Atanas Pavlov
'''

import numpy as np
from smo.media.CoolProp.CoolProp import FluidState, Fluid

fluid = Fluid('Water')

dT = 1e-4
dq = 1e-3

f1 = FluidState(fluid)
f2 = FluidState(fluid)

f1.update_Tq(273.15 + 150, 0.5)

# dqdT_v
f2.update_Trho(f1.T + dT, f1.rho)
dqdT_v = (f2.q - f1.q) / (f2.T - f1.T)
print("dqdT_v() numerical: {:e}, analytical: {:e}".format(dqdT_v, f1.dqdT_v))

# dvdT_q
f2.update_Tq(f1.T + dT, f1.q)
dvdT_q = (f2.v - f1.v) / (f2.T - f1.T)
dvdT_q_1 = f1.q * f1.SatV.dvdT + (1 - f1.q) * f1.SatL.dvdT
print("dvdT_q() numerical: {:e}, analytical: {:e}, analytical2: {:e}".format(
    dvdT_q, f1.dvdT_q, dvdT_q_1))
Esempio n. 25
0
    def plotIsotherms(self):
        fState = FluidState(self.fluid)
        TArr = np.logspace(np.log10(self.TMin), np.log10(self.TMax), num=20)
        TOrders = np.floor(np.log10(TArr))
        TArr = np.ceil(TArr / 10**(TOrders - 2)) * 10**(TOrders - 2)
        fSatL = FluidState(self.fluidName)
        fSatV = FluidState(self.fluidName)
        f1 = FluidState(self.fluidName)
        for T in TArr:
            if self.temperatureUnit == 'degC':
                T_label = T - 273.15
            else:
                T_label = T
            try:
                f1.update_Tp(T, self.pMax)
                if (T > self.critical.T):
                    rhoArr1 = np.logspace(np.log10(self.rhoMin),
                                          np.log10(self.critical.rho),
                                          num=100)
                    rhoArr2 = np.logspace(np.log10(self.critical.rho),
                                          np.log10(f1.rho),
                                          num=100)
                else:
                    fSatL.update_Tq(T, 0)
                    fSatV.update_Tq(T, 1)
                    rhoArr1 = np.logspace(np.log10(self.rhoMin),
                                          np.log10(fSatV.rho),
                                          num=100)
                    rhoArr2 = np.logspace(np.log10(fSatL.rho),
                                          np.log10(f1.rho),
                                          num=100)
                rhoArr = np.hstack((rhoArr1, rhoArr2))
                hArr = np.zeros(len(rhoArr))
                pArr = np.zeros(len(rhoArr))
                for i in range(len(rhoArr)):
                    fState.update_Trho(T, rhoArr[i])
                    hArr[i] = fState.h
                    pArr[i] = fState.p
                    # Determining label location
                    if (T < self.critical.T):
                        if (i == len(rhoArr1)):
                            self.ax.annotate(formatNumber(T_label, sig=3),
                                             xy=((fSatL.h + fSatV.h) / 2. /
                                                 1e3, pArr[i] / 1e5),
                                             xytext=(0, 3),
                                             textcoords='offset points',
                                             color='r',
                                             size="small")
                    else:
                        if (i > 0):
                            b = np.log10(
                                self.pMin /
                                1e5) - self.minDiagonalSlope * self.hMin / 1e3
                            if (np.log10(pArr[i-1] / 1e5) - self.minDiagonalSlope * hArr[i-1] / 1e3 - b) * \
                             (np.log10(pArr[i] / 1e5) - self.minDiagonalSlope * hArr[i] / 1e3 - b) <= 0:
                                # Getting label rotation angle
                                angle, offset_x, offset_y = self.getLabelPlacement(
                                    x1=hArr[i - 1],
                                    x2=hArr[i],
                                    y1=pArr[i - 1],
                                    y2=pArr[i])
                                self.ax.annotate(formatNumber(T_label, sig=3),
                                                 xy=(hArr[i] / 1e3,
                                                     pArr[i] / 1e5),
                                                 xytext=(offset_x, offset_y),
                                                 textcoords='offset points',
                                                 color='r',
                                                 size="small",
                                                 rotation=angle)

                if (T == TArr[0]):
                    if self.temperatureUnit == 'degC':
                        label = "temperature [C]"
                    else:
                        label = "temperature [K]"
                    self.ax.semilogy(hArr / 1e3, pArr / 1e5, 'r', label=label)
                else:
                    self.ax.semilogy(hArr / 1e3, pArr / 1e5, 'r')
            except RuntimeError, e:
                print '------------------'
                print 'Runtime Warning for T=%e' % T
                print(e)
Esempio n. 26
0
    def plotIsochores(self):
        fState = FluidState(self.fluid)
        rhoArr1 = np.logspace(np.log10(self.rhoMin),
                              np.log10(self.critical.rho),
                              num=20,
                              endpoint=False)
        rhoArr2 = np.logspace(np.log10(self.critical.rho),
                              np.log10(self.rhoMax),
                              num=5)
        rhoArr = np.zeros(len(rhoArr1) + len(rhoArr2))
        rhoArr[:len(rhoArr1)] = rhoArr1[:]
        rhoArr[len(rhoArr1):] = rhoArr2[:]
        TArr = np.logspace(np.log10(self.TMin), np.log10(self.TMax), num=100)
        # For label location purposes
        h_level_low = self.hMin + (self.critical.h - self.hMin) * 3 / 4.
        h_level_high = self.critical.h + (self.hMax - self.critical.h) * 1 / 2.
        for rho in rhoArr:
            try:
                hArr = np.zeros(len(TArr))
                pArr = np.zeros(len(TArr))
                for i in range(len(TArr)):
                    fState.update_Trho(TArr[i], rho)
                    hArr[i] = fState.h
                    pArr[i] = fState.p
                    # Putting labels
                    # Determining annotated point and label text offest

                    if (pArr[i - 1] < self.pMax and pArr[i] > self.pMax):
                        if (hArr[i] < h_level_low):
                            angle, offset_x, offset_y = self.getLabelPlacement(
                                x1=hArr[i - 1],
                                x2=hArr[i],
                                y1=pArr[i - 1],
                                y2=pArr[i])
                            self.ax.annotate(formatNumber(rho, sig=2),
                                             xy=(hArr[i - 1] / 1e3,
                                                 pArr[i - 1] / 1e5),
                                             xytext=(0, -10),
                                             textcoords='offset points',
                                             color='g',
                                             size="small",
                                             rotation=angle)
                        elif (hArr[i] > h_level_low
                              and hArr[i] < h_level_high):
                            angle, offset_x, offset_y = self.getLabelPlacement(
                                x1=hArr[i - 2],
                                x2=hArr[i - 1],
                                y1=pArr[i - 2],
                                y2=pArr[i - 1])
                            self.ax.annotate(formatNumber(rho, sig=2),
                                             xy=(hArr[i - 2] / 1e3,
                                                 pArr[i - 2] / 1e5),
                                             xytext=(5, -5),
                                             textcoords='offset points',
                                             color='g',
                                             size="small",
                                             rotation=angle)
                        elif (hArr[i] > h_level_high):
                            angle, offset_x, offset_y = self.getLabelPlacement(
                                x1=hArr[i - 10],
                                x2=hArr[i - 9],
                                y1=pArr[i - 10],
                                y2=pArr[i - 9])
                            self.ax.annotate(formatNumber(rho, sig=2),
                                             xy=(hArr[i - 10] / 1e3,
                                                 pArr[i - 10] / 1e5),
                                             xytext=(0, -5),
                                             textcoords='offset points',
                                             color='g',
                                             size="small",
                                             rotation=angle)
                    elif (i == len(TArr) - 1 and pArr[i] < self.pMax
                          and pArr[i - 1] > self.pMin):
                        angle, offset_x, offset_y = self.getLabelPlacement(
                            x1=hArr[i - 1],
                            x2=hArr[i],
                            y1=pArr[i - 1],
                            y2=pArr[i])
                        self.ax.annotate(formatNumber(rho, sig=2),
                                         xy=(hArr[i] / 1e3, pArr[i] / 1e5),
                                         xytext=(-30, -12),
                                         textcoords='offset points',
                                         color='g',
                                         size="small",
                                         rotation=angle)
                if (rho == rhoArr[0]):
                    self.ax.semilogy(hArr / 1e3,
                                     pArr / 1e5,
                                     'g',
                                     label='density [kg/m3]')
                else:
                    self.ax.semilogy(hArr / 1e3, pArr / 1e5, 'g')
            except RuntimeError, e:
                print '------------------'
                print 'Runtime Warning for rho=%e' % rho
                print(e)
Esempio n. 27
0
 def __init__(self, fluid):
     self.fluid = fluid
     self.fState = FluidState(self.fluid)
Esempio n. 28
0
    def setLimits(self, pMin=None, pMax=None, hMin=None, hMax=None, TMax=None):
        # Reference points
        self.minLiquid = FluidState(self.fluid)
        self.minVapor = FluidState(self.fluid)
        self.critical = FluidState(self.fluid)
        self.critical.update_Trho(self.fluid.critical['T'],
                                  self.fluid.critical['rho'])

        # For general use
        fState = FluidState(self.fluid)

        # Pressure range
        if (pMin is None):
            pMin = self.fluid.tripple['p'] * 1.05
            if (pMin < 1e3):
                pMin = 1e3
        self.pMin = pMin

        self.minLiquid.update_pq(self.pMin, 0)
        self.minVapor.update_pq(self.pMin, 1)

        if (pMax is None):
            pMax = 3 * self.critical.p
        self.pMax = pMax

        # Enthalpy range
        domeWidth = self.minVapor.h - self.minLiquid.h
        if (hMin is None):
            hMin = self.minLiquid.h
        self.hMin = hMin

        # Determining max enthalpy
        if (TMax is None):
            if (hMax is None):
                # default max enthalpy
                if (self.critical.h > self.minVapor.h):
                    hMax = self.critical.h + domeWidth
                else:
                    hMax = self.minVapor.h + domeWidth
        else:
            fState.update_Tp(TMax, self.pMin)
            hMax = fState.h

        self.hMax = hMax

        # Axes ranges
        self.xMin = self.hMin
        self.xMax = self.hMax
        self.yMin = self.pMin
        self.yMax = self.pMax

        # Density range
        fState.update_ph(self.pMin, self.hMax)
        self.rhoMin = fState.rho
        self.rhoMax = self.minLiquid.rho

        # Temperature range
        self.TMin = self.fluid.saturation_p(self.pMin)["TsatL"]

        if (TMax is None):
            fState.update_ph(self.pMin, self.hMax)
            TMax = fState.T
        self.TMax = TMax

        # Entropy range
        self.sMin = 1.01 * self.minLiquid.s

        fState.update_ph(self.pMin, self.hMax)
        self.sMax = fState.s

        # Minor diagonal coeff
        self.minDiagonalSlope = np.log10(
            self.pMax / self.pMin) / (self.hMax - self.hMin) * 1e3

        # Major diagonal coeff
        self.majDiagonalSlope = -self.minDiagonalSlope
Esempio n. 29
0
class PHDiagram(StateDiagram):
    def __init__(self, fluidName, temperatureUnit='K'):
        super(PHDiagram, self).__init__(fluidName)
        self.temperatureUnit = temperatureUnit

    def setLimits(self, pMin=None, pMax=None, hMin=None, hMax=None, TMax=None):
        # Reference points
        self.minLiquid = FluidState(self.fluid)
        self.minVapor = FluidState(self.fluid)
        self.critical = FluidState(self.fluid)
        self.critical.update_Trho(self.fluid.critical['T'],
                                  self.fluid.critical['rho'])

        # For general use
        fState = FluidState(self.fluid)

        # Pressure range
        if (pMin is None):
            pMin = self.fluid.tripple['p'] * 1.05
            if (pMin < 1e3):
                pMin = 1e3
        self.pMin = pMin

        self.minLiquid.update_pq(self.pMin, 0)
        self.minVapor.update_pq(self.pMin, 1)

        if (pMax is None):
            pMax = 3 * self.critical.p
        self.pMax = pMax

        # Enthalpy range
        domeWidth = self.minVapor.h - self.minLiquid.h
        if (hMin is None):
            hMin = self.minLiquid.h
        self.hMin = hMin

        # Determining max enthalpy
        if (TMax is None):
            if (hMax is None):
                # default max enthalpy
                if (self.critical.h > self.minVapor.h):
                    hMax = self.critical.h + domeWidth
                else:
                    hMax = self.minVapor.h + domeWidth
        else:
            fState.update_Tp(TMax, self.pMin)
            hMax = fState.h

        self.hMax = hMax

        # Axes ranges
        self.xMin = self.hMin
        self.xMax = self.hMax
        self.yMin = self.pMin
        self.yMax = self.pMax

        # Density range
        fState.update_ph(self.pMin, self.hMax)
        self.rhoMin = fState.rho
        self.rhoMax = self.minLiquid.rho

        # Temperature range
        self.TMin = self.fluid.saturation_p(self.pMin)["TsatL"]

        if (TMax is None):
            fState.update_ph(self.pMin, self.hMax)
            TMax = fState.T
        self.TMax = TMax

        # Entropy range
        self.sMin = 1.01 * self.minLiquid.s

        fState.update_ph(self.pMin, self.hMax)
        self.sMax = fState.s

        # Minor diagonal coeff
        self.minDiagonalSlope = np.log10(
            self.pMax / self.pMin) / (self.hMax - self.hMin) * 1e3

        # Major diagonal coeff
        self.majDiagonalSlope = -self.minDiagonalSlope

    def plotDome(self):
        fState = FluidState(self.fluid)
        p = np.logspace(np.log10(self.pMin),
                        np.log10(self.critical.p),
                        num=200)
        qLabels = ['0.2', '0.4', '0.6', '0.8']
        for q in np.arange(0, 1.1, 0.1):
            try:
                h = np.zeros(len(p))
                for i in range(len(p) - 1):
                    fState.update_pq(p[i], q)
                    h[i] = fState.h
                # Putting labels
                if '{:1.1f}'.format(q) in qLabels:
                    angle, offset_x, offset_y = self.getLabelPlacement(
                        x1=h[9], x2=h[10], y1=p[9], y2=p[10])
                    self.ax.annotate("{:1.1f}".format(q),
                                     xy=(h[10] / 1e3, p[10] / 1e5),
                                     xytext=(-offset_x, -offset_y),
                                     textcoords='offset points',
                                     color='b',
                                     size="small",
                                     rotation=angle)
                h[-1] = self.critical.h
                if (q == 0):
                    self.ax.semilogy(h / 1e3,
                                     p / 1e5,
                                     'b',
                                     label='vapor quality')
                else:
                    self.ax.semilogy(h / 1e3, p / 1e5, 'b')
            except RuntimeError, e:
                print '------------------'
                print 'Runtime Warning for q=%e' % q
                print(e)
Esempio n. 30
0
    def compute(self):
        if (self.geomConf == 'HP' or self.geomConf == 'IP'):
            self.Tfilm = (self.TWallTop + self.TWallBottom) / 2.0
            self.deltaT = self.TWallTop - self.TWallBottom
        elif (self.geomConf == 'VP'):
            self.Tfilm = (self.TWallLeft + self.TWallRight) / 2.0
            self.deltaT = self.TWallLeft - self.TWallRight
        elif (self.geomConf == 'HA'):
            self.Tfilm = (self.TInner + self.TOuter) / 2.0
            self.deltaT = self.TInner - self.TOuter

        # Compute fluid properties
        fState = FluidState(self.fluidName)
        fState.update_Tp(self.Tfilm, self.pressure)
        self.rho = fState.rho
        self.mu = fState.mu
        nu = self.mu / self.rho
        self.beta = fState.beta
        self.Pr = fState.Pr
        self.cond = fState.cond

        # Compute geometry factors
        if (self.geomConf == 'HP' or self.geomConf == 'IP'):
            s = self.dist
            self.area = self.width * self.length
        elif (self.geomConf == 'VP'):
            s = self.dist
            self.area = self.width * self.height
        elif (self.geomConf == 'HA'):
            s = self.rOuter - self.rInner
            self.area = 2 * np.pi * self.rInner * self.length
        else:
            raise ValueError(
                "Geometry configuration {0} not implemented".format(
                    GeometryConfigurationsInternal[self.geomConf]))

        # Compute free convection dimensionless numbers
        self.Gr = 9.81 * (s**3) * self.beta * np.abs(self.deltaT) / (nu**2)
        self.Ra = self.Gr * self.Pr

        # Use the appropriate empirical Nusselt correlation
        if (self.geomConf == 'HP'):
            if (self.Ra >= 0 and self.Ra <= 1708):
                self.Nu = 1.
            elif (self.Ra > 1708 and self.Ra <= 2.2 * 1e4):
                self.Nu = 0.208 * self.Ra**0.25
            elif (self.Ra > 2.2 * 1e4):
                self.Nu = 0.092 * self.Ra**0.33
        elif (self.geomConf == 'VP'):
            if (self.height / s <= 80):
                if (self.Ra > 1e9):
                    raise ValueError("Outside range of validity")
                else:
                    if (self.Ra > 1e7):
                        self.Nu = 0.049 * self.Ra**0.33
                    else:
                        self.Nu = 0.42 * self.Pr**0.012 * self.Ra**0.25 * (
                            self.height / s)**(-0.25)
                        if (self.Nu < 1.):
                            self.Nu = 1.
            else:
                raise ValueError("Outside range of validity")
        elif (self.geomConf == 'IP'):
            if (self.deltaT < 0):
                from scipy.interpolate import interp1d
                angles = np.array([0, 30, 45, 60, 90])
                values = np.array([4.9, 5.7, 5.9, 6.5, 6.9]) * 1e-2
                interpFunc = interp1d(angles, values, kind='linear')
                C = interpFunc(self.angle)
                self.Nu = C * self.Ra**0.33 * self.Pr**0.074
            else:
                if (self.Ra >= 5e3 and self.Ra <= 1e8):
                    if (self.angle == 45):
                        self.Nu = 1 + (0.025 * self.Ra**1.36) / (self.Ra +
                                                                 1.3 + 1e4)
                    else:
                        raise ValueError("Outside range of validity")
                else:
                    raise ValueError("Outside range of validity")
        elif (self.geomConf == 'HA'):
            if (self.deltaT > 0):
                if (self.Ra > 7.1e3):
                    if (self.rOuter / self.rInner) <= 8:
                        self.Nu = 0.2 * self.Ra**0.25 * (self.rOuter /
                                                         self.rInner)**0.5
                    else:
                        raise ValueError("Outside range of validity")
                else:
                    raise ValueError("Outside range of validity")
            else:
                raise ValueError("Outside range of validity")
        else:
            pass
        self.Nu = self.Nu * self.heatExchangeGain

        # Compute the convection coefficient and the total heat flow rate
        self.alpha = self.Nu * self.cond / s
        self.QDot = self.area * self.alpha * self.deltaT
Esempio n. 31
0
 def __init__ (self, fluid):
     self.fluid = fluid
     self.fState = FluidState(self.fluid)
Esempio n. 32
0
class PHDiagram(StateDiagram):
	def __init__(self, fluidName, temperatureUnit = 'K'):
		super(PHDiagram, self).__init__(fluidName)
		self.temperatureUnit = temperatureUnit
	
	def setLimits(self, pMin = None, pMax = None,  hMin = None, hMax = None, TMax = None):
		# Reference points
		self.minLiquid = FluidState(self.fluid)
		self.minVapor = FluidState(self.fluid)
		self.critical = FluidState(self.fluid)
		self.critical.update_Trho(self.fluid.critical['T'], self.fluid.critical['rho'])

		# For general use
		fState = FluidState(self.fluid)

		# Pressure range
		if (pMin is None):
			pMin = self.fluid.tripple['p'] * 1.05
			if (pMin < 1e3):
				pMin = 1e3
		self.pMin = pMin
		
		self.minLiquid.update_pq(self.pMin, 0)		
		self.minVapor.update_pq(self.pMin, 1)
		
		if (pMax is None):
			pMax = 3 * self.critical.p
		self.pMax = pMax
		
		
		# Enthalpy range
		domeWidth = self.minVapor.h - self.minLiquid.h		
		if (hMin is None):
			hMin = self.minLiquid.h
		self.hMin = hMin
		
		# Determining max enthalpy
		if (TMax is None):
			if (hMax is None):
				# default max enthalpy	
				if (self.critical.h > self.minVapor.h):
					hMax = self.critical.h + domeWidth
				else:
					hMax = self.minVapor.h + domeWidth
		else:
			fState.update_Tp(TMax, self.pMin)
			hMax = fState.h
			
		self.hMax = hMax
		
		# Axes ranges
		self.xMin = self.hMin
		self.xMax = self.hMax
		self.yMin = self.pMin
		self.yMax = self.pMax
		
		# Density range
		fState.update_ph(self.pMin, self.hMax)
		self.rhoMin = fState.rho
		self.rhoMax = self.minLiquid.rho
		
		# Temperature range
		self.TMin = self.fluid.saturation_p(self.pMin)["TsatL"]
		
		if (TMax is None):
			fState.update_ph(self.pMin, self.hMax)
			TMax = fState.T
		self.TMax = TMax
		
		# Entropy range
		self.sMin = 1.01 * self.minLiquid.s
		
		fState.update_ph(self.pMin, self.hMax)
		self.sMax = fState.s
		
		# Minor diagonal coeff
		self.minDiagonalSlope = np.log10(self.pMax/self.pMin) / (self.hMax - self.hMin) * 1e3
		
		# Major diagonal coeff
		self.majDiagonalSlope = - self.minDiagonalSlope
	
	def plotDome(self):
		fState = FluidState(self.fluid)
		p = np.logspace(np.log10(self.pMin), np.log10(self.critical.p), num = 200)
		qLabels = ['0.2', '0.4', '0.6', '0.8']
		for q in np.arange(0, 1.1, 0.1):
			try:
				h = np.zeros(len(p))
				for i in range(len(p) - 1):
					fState.update_pq(p[i], q)
					h[i] = fState.h
				# Putting labels
				if '{:1.1f}'.format(q) in qLabels:
					angle, offset_x, offset_y = self.getLabelPlacement(x1 = h[9], x2 = h[10],
											y1 = p[9], y2 = p[10])
					self.ax.annotate("{:1.1f}".format(q), 
									xy = (h[10]/ 1e3, p[10] / 1e5),
									xytext=(-offset_x, -offset_y),
									textcoords='offset points',
									color='b', size="small", rotation = angle)
				h[-1] = self.critical.h
				if (q == 0):			
					self.ax.semilogy(h/1e3, p/1e5, 'b', label = 'vapor quality')
				else:
					self.ax.semilogy(h/1e3, p/1e5, 'b')
			except RuntimeError, e:
				print '------------------'
				print 'Runtime Warning for q=%e'%q 
				print(e)
Esempio n. 33
0
 def plotIsentrops(self):
     fState = FluidState(self.fluid)
     sArr = np.linspace(self.sMin, self.sMax, num=20)
     for s in sArr:
         try:
             hArr = []
             pArr = []
             fState.update_ps(self.pMax, s)
             if (fState.T > self.TMax):
                 fState.update_Ts(self.TMax, s)
             T = fState.T
             hArr.append(fState.h)
             pArr.append(fState.p)
             # Calculated v
             v_res = fState.v
             while (T > self.TMin):
                 _dvdT_s = -fState.dsdT_v / fState.dpdT_v
                 if math.isnan(_dvdT_s):
                     break
                 TStep = -(self.critical.T / 200.) / (np.abs(_dvdT_s) + 1)
                 T = T + TStep
                 if T < self.TMin:
                     break
                 v_res += _dvdT_s * TStep
                 fState.update_Trho(T, 1. / v_res)
                 p = fState.p
                 # If it goes out of the screen through the bottom
                 if (p < self.pMin):
                     break
                 # Calculated s
                 s_res = fState.s
                 # Correcting v
                 ds = s - s_res
                 sigma = ds * fState.dvds_T
                 v = v_res + sigma
                 fState.update_Trho(T, 1. / v)
                 hArr.append(fState.h)
                 pArr.append(fState.p)
                 ##################
                 # Putting labels
                 i = len(hArr) - 1
                 b = np.log10(self.pMax /
                              1e5) - self.majDiagonalSlope * self.hMin / 1e3
                 if (np.log10(pArr[i-1] / 1e5) - self.majDiagonalSlope * hArr[i-1] / 1e3 - b) * \
                  (np.log10(pArr[i] / 1e5) - self.majDiagonalSlope * hArr[i] / 1e3 - b) <= 0:
                     angle, offset_x, offset_y = self.getLabelPlacement(
                         x1=hArr[i - 1],
                         x2=hArr[i],
                         y1=pArr[i - 1],
                         y2=pArr[i])
                     self.ax.annotate(formatNumber(s / 1e3, sig=3),
                                      xy=(hArr[i - 1] / 1e3,
                                          pArr[i - 1] / 1e5),
                                      xytext=(-offset_x, -offset_y),
                                      textcoords='offset points',
                                      color='m',
                                      size="small",
                                      rotation=angle)
                 #######################
             hArr = np.array(hArr)
             pArr = np.array(pArr)
             if (s == sArr[0]):
                 self.ax.semilogy(hArr / 1e3,
                                  pArr / 1e5,
                                  'm',
                                  label="entropy [kJ/kg-K]")
             else:
                 self.ax.semilogy(hArr / 1e3, pArr / 1e5, 'm')
         except RuntimeError, e:
             print '------------------'
             print 'Runtime Warning for s=%e' % s
             print e
 def setUpstreamState(self, pressure, temperature):
     fluidState = FluidState('ParaHydrogen')
     fluidState.update_Tp(temperature, pressure)
     return fluidState
Esempio n. 35
0
	def plotIsotherms(self):
		fState = FluidState(self.fluid)
		TArr = np.logspace(np.log10(self.TMin), np.log10(self.TMax), num = 20)
		TOrders = np.floor(np.log10(TArr))
		TArr = np.ceil(TArr / 10**(TOrders - 2)) * 10**(TOrders - 2)
		fSatL = FluidState(self.fluidName)
		fSatV = FluidState(self.fluidName)
		f1 = FluidState(self.fluidName)
		for T in TArr:
			if self.temperatureUnit == 'degC':
				T_label = T  - 273.15
			else:
				T_label = T
			try:
				f1.update_Tp(T, self.pMax)
				if (T > self.critical.T):
					rhoArr1 = np.logspace(np.log10(self.rhoMin), np.log10(self.critical.rho), num = 100)
					rhoArr2 = np.logspace(np.log10(self.critical.rho), np.log10(f1.rho), num = 100)
				else:
					fSatL.update_Tq(T, 0)
					fSatV.update_Tq(T, 1)
					rhoArr1 = np.logspace(np.log10(self.rhoMin), np.log10(fSatV.rho), num = 100)
					rhoArr2 = np.logspace(np.log10(fSatL.rho), np.log10(f1.rho), num = 100)
				rhoArr = np.hstack((rhoArr1, rhoArr2))
				hArr = np.zeros(len(rhoArr))
				pArr = np.zeros(len(rhoArr))
				for i in range(len(rhoArr)):
					fState.update_Trho(T, rhoArr[i])
					hArr[i] = fState.h
					pArr[i] = fState.p
					# Determining label location
					if (T < self.critical.T):
						if (i == len(rhoArr1)):
							self.ax.annotate(formatNumber(T_label, sig = 3), 
											xy = ((fSatL.h + fSatV.h) / 2. / 1e3, pArr[i] / 1e5),
											xytext=(0, 3),
											textcoords='offset points',
											color='r', size="small")
					else:
						if (i>0):
							b = np.log10(self.pMin / 1e5) - self.minDiagonalSlope * self.hMin / 1e3
							if (np.log10(pArr[i-1] / 1e5) - self.minDiagonalSlope * hArr[i-1] / 1e3 - b) * \
								(np.log10(pArr[i] / 1e5) - self.minDiagonalSlope * hArr[i] / 1e3 - b) <= 0:
								# Getting label rotation angle
								angle, offset_x, offset_y = self.getLabelPlacement(x1 = hArr[i-1], x2 = hArr[i],
																					y1 = pArr[i-1], y2 = pArr[i])
								self.ax.annotate(formatNumber(T_label, sig = 3), 
												xy = (hArr[i]/1e3, pArr[i]/1e5),
												xytext=(offset_x, offset_y),
												textcoords='offset points',
												color='r', size="small", rotation = angle)
				
				if (T == TArr[0]):
					if self.temperatureUnit == 'degC':
						label = "temperature [C]"
					else:
						label = "temperature [K]"
					self.ax.semilogy(hArr/1e3, pArr/1e5, 'r', label = label)
				else:
					self.ax.semilogy(hArr/1e3, pArr/1e5, 'r')
			except RuntimeError, e:
				print '------------------'
				print 'Runtime Warning for T=%e'%T 
				print(e)
Esempio n. 36
0
def testState():
    s1 = FluidState('ParaHydrogen')
    s1.update('P', 700e5, 'T', 288)
    print("p={0}".format(s1.p()))
    print("T={0}".format(s1.T()))
    print("rho={0}".format(s1.rho()))
    print("h={0}".format(s1.h()))
    print("s={0}".format(s1.s()))
    print("cp={0}".format(s1.cp()))
    print("cv={0}".format(s1.cv()))
    print("gamma={0}".format(s1.gamma()))
    print("dpdt_v={0}".format(s1.dpdt_v()))
    print("dpdv_t={0}".format(s1.dpdv_t()))
    print("beta={0}".format(s1.beta()))
    print("mu={0}".format(s1.mu()))
    print("lambfa={0}".format(s1.cond()))
    print("Pr={0}".format(s1.Pr()))

    s2 = FluidState('ParaHydrogen')
    s2.update_Tp(s1.T(), s1.p())
    print("update_Tp rho={0}".format(s2.rho()))
    s3 = FluidState('ParaHydrogen')
    s3.update_Trho(s1.T(), s1.rho())
    print("update_Trho p={0}".format(s3.p()))
    s4 = FluidState('ParaHydrogen')
    s4.update_prho(s1.p(), s1.rho())
    print("update_prho T={0}".format(s4.T()))
    s5 = FluidState('ParaHydrogen')
    s5.update_ph(s1.p(), s1.h())
    print("update_ph ={0}".format(s5.T()))
    s6 = FluidState('ParaHydrogen')
    s6.update_ps(s1.p(), s1.s())
    print("update_ps T={0}".format(s6.T()))
    s7 = FluidState('ParaHydrogen')
    s7.update_pq(1e5, 0)
    print("update_pq T={0}".format(s7.T()))
    s8 = FluidState('ParaHydrogen')
    s8.update_Tq(25, 0)
    print("update_Tq p={0}".format(s8.p()))
    print('--------------------')
    print('Initialize state from fluid')
    h2 = Fluid('ParaHydrogen')
    s9 = FluidState(h2)
    s9.update_Tp(s1.T(), s1.p())
    print("rho={0}".format(s9.rho()))
Esempio n. 37
0
    def compute(self):
        self.deltaT = self.TWall - self.TFluid
        if (self.propT == 'MT'):
            self.Tfilm = (self.TWall + self.TFluid) / 2.0
        else:
            self.Tfilm = self.TFluid

        # Compute fluid properties
        fState = FluidState(self.fluidName)
        fState.update_Tp(self.Tfilm, self.pressure)
        self.rho = fState.rho
        self.mu = fState.mu
        nu = self.mu / self.rho
        self.beta = fState.beta
        self.Pr = fState.Pr
        self.cond = fState.cond

        # Compute geometry factors
        if (self.geomConf == 'VP'):
            s = self.height
            self.area = self.width * self.height
        elif (self.geomConf == 'VC'):
            s = self.height
            self.area = np.pi * self.diameter * self.height
        elif (self.geomConf == 'HC'):
            s = self.diameter
            self.area = np.pi * self.diameter * self.length
        elif (self.geomConf == 'HPT' or self.geomConf == 'HPB'):
            if (self.surfaceShape == 'RCT'):
                s = self.width * self.length / (2.0 *
                                                (self.width + self.length))
                self.area = self.width * self.length
            elif (self.surfaceShape == 'CIR'):
                s = self.diameter / 4.0
                self.area = (np.pi / 4) * self.diameter**2
        elif (self.geomConf == 'SPH'):
            s = self.diameter
            self.area = np.pi * self.diameter**2
        elif (self.geomConf == 'IPT' or self.geomConf == 'IPB'):
            s = self.length
            self.area = self.width * self.height
        elif (self.geomConf == 'FIN'):
            #halfway between full rib and bare pipe
            s = self.diameter + self.finHeight
            finsPerLength = 1.0 / (self.finThickness + self.finSpacing)
            self.area = np.pi * self.diameter * (
                1 - self.finThickness * finsPerLength)
            self.area += finsPerLength * np.pi * self.finHeight * 2 * (
                self.diameter + self.finHeight)
            self.area += finsPerLength * np.pi * self.finThickness * (
                self.diameter + 2 * self.finHeight)
            self.area *= self.length
        else:
            raise ValueError(
                "Geometry configuration {0} not implemented".format(
                    GeometryConfigurationsExternal[self.geomConf]))

        # Compute free convection dimensionless numbers
        self.Gr = 9.81 * (s**3) * self.beta * np.abs(self.deltaT) / (nu**2)
        self.Ra = self.Gr * self.Pr

        # Use the appropriate empirical Nusselt correlation
        if (self.geomConf == 'VP'):
            fPr = (1 + (0.492 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
            self.Nu = (0.825 + 0.387 * (self.Ra * fPr)**(1.0 / 6))**2
        elif (self.geomConf == 'VC'):
            fPr = (1 + (0.492 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
            Nu_plate = (0.825 + 0.387 * (self.Ra * fPr)**(1.0 / 6))**2
            self.Nu = Nu_plate + 0.97 * self.height / self.diameter
        elif (self.geomConf == 'HC'):
            fPr = (1 + (0.559 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
            self.Nu = (0.6 + 0.387 * (self.Ra * fPr)**(1.0 / 6))**2
        elif ((self.geomConf == 'HPT' and self.deltaT <= 0)
              or (self.geomConf == 'HPB' and self.deltaT >= 0)):
            fPr = (1 + (0.492 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
            if (self.Ra * fPr < 1e10):
                self.Nu = 0.6 * (self.Ra * fPr)**(1.0 / 5)
                if (self.Nu < 1):
                    self.Nu = 1
            else:
                raise ValueError("Outside range of validity")
        elif ((self.geomConf == 'HPT' and self.deltaT > 0)
              or (self.geomConf == 'HPB' and self.deltaT < 0)):
            fPr = (1 + (0.322 / self.Pr)**(11.0 / 20))**(-20.0 / 11)
            if (self.Ra * fPr <= 7 * 1e4):
                self.Nu = 0.766 * (self.Ra * fPr)**(1.0 / 5)
            else:
                self.Nu = 0.15 * (self.Ra * fPr)**(1.0 / 3)
        elif (self.geomConf == 'SPH'):
            self.Nu = 0.56 * (self.Pr * self.Ra /
                              (0.846 + self.Pr))**(1.0 / 4) + 2
        elif ((self.geomConf == 'IPT' and self.deltaT <= 0)
              or (self.geomConf == 'IPB' and self.deltaT >= 0)):
            fPr = (1 + (0.492 / self.Pr)**(9.0 / 16))**(-16.0 / 9)
            self.Nu = (0.825 + 0.387 *
                       (self.Ra * np.cos(self.angle) * fPr)**(1.0 / 6))**2
        elif ((self.geomConf == 'IPT' and self.deltaT > 0)
              or (self.geomConf == 'IPB' and self.deltaT < 0)):
            Ra_crit = 10**(8.9 - 0.00178 * (self.angle * 180 / np.pi)**1.82)
            self.Nu = 0.56 * (Ra_crit * np.cos(self.angle))**(
                1.0 / 4) + 0.13 * (self.Ra**(1.0 / 3) - Ra_crit**(1.0 / 3))
        elif (self.geomConf == 'FIN'):
            #Correlation from VDI Heat Atlas F2.4.4
            self.Nu = 0.24 * (self.Ra * self.finSpacing /
                              self.diameter)**(1.0 / 3)
        else:
            pass
        self.Nu = self.Nu * self.heatExchangeGain

        # Compute the convection coefficient and the total heat flow rate
        self.alpha = self.Nu * self.cond / s
        self.QDot = self.area * self.alpha * self.deltaT