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
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
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()))
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.")
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)
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)
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
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
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
def setUpstreamState(self, pressure, temperature): fluidState = FluidState('ParaHydrogen') fluidState.update_Tp(temperature, pressure) return fluidState
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)
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
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)
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 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 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