Пример #1
0
 def __init__(self,
              T_evap=1.5, T_cond=39.9,
              x1=0.567, x2=0.624,
              Eff_SHX=0.64, m_pump=0.05):
     """Args
     ----
         T_evap : float
             Evaporator saturation temperature (deg C)
         T_cond : float
             Condenser saturation temperature (deg C)
         x1 : float
             Pump side mass fraction of LiBr in stream (low) [kg/kg]
         x2 : float
             Return side mass fraction of LiBr in stream (high/concentrate)
         Eff_SHX : float
             Effectiveness of the solution heat exchanger (K/K), 0 to 1
         m_pump : float
             Mass flow rate through the solution pump (kg/s)
     """
     self.T_evap = T_evap
     self.T_cond = T_cond
     self.x1 = x1
     self.x2 = x2
     self.m_pump = m_pump
     self.Eff_SHX = Eff_SHX
     self.dx = x1 - x2
     
     self.P_evap = CP.PropsSI('P','T',C2K(T_evap),'Q',1,water)
     self.P_cond = CP.PropsSI('P','T',C2K(T_cond),'Q',1,water)
             
     self.T_gen_inlet = 0
     self.T_gen_outlet = 0
     self.T_abs_inlet_max = 0
     self.T_abs_outlet_max = 0
     self.h_gen_inlet = 0
     self.h_gen_outlet = 0
     self.h_abs_inlet = 0
     self.h_abs_outlet = 0
     self.m_concentrate = 0
     self.m_refrig = 0
     self.T_SHX_concentrate_outlet = 0
     self.Q_SHX = 0
     self.T_abs_pre = np.nan
     self.h_abs_pre = np.nan
     self.Q_abs_pre_cool = 0
     self.P_abs_pre = np.nan
     self.Q_abs_main = 0
     self.Q_abs_total = 0
     self.T_gen_pre = np.nan
     self.Q_gen_pre_heat = 0
     self.Q_gen_main = 0
     self.Q_gen_total = 0
     self.Q_condenser_reject = 0
     self.Q_evap_heat = 0
     self.COP = 0
     self.W_pump = 0
     self.f = np.inf
Пример #2
0
 def _q_helper(self,T):
     x_local = libr_props.massFraction(C2K(T),self.P * 1e-5)
     # Could parametrize this by x, but libr_props.temperature also has an
     # implicit solve. Only P(T,x) is explicit.
     pwater.update(CP.PT_INPUTS, self.P, C2K(T))
     h_vapor_local = pwater.hmass() - h_w_ref
     h_solution_local = libr_props.massSpecificEnthalpy(C2K(T), x_local)
     # Mass balance on LiBr
     m_solution_local = self.m_in * self.x_in / x_local
     
     hlv1 = h_vapor_local - h_solution_local
     q1 = self.m_total * h_vapor_local - m_solution_local * hlv1
     return q1
Пример #3
0
 def _q(self,T):
     # First, determine the mass fraction here.
     if T > self.T_sat:
         raise ValueError("This function is for subcooled LiBr...")
     else:
         x_local = libr_props.massFraction(C2K(T),self.P*1e-5)
     return self._qx(x_local)
Пример #4
0
 def makeRejectStream(self, T_in, dT, Q):
     # Flow rate for reject streams is specified by inlet and outlet temperatures...
     cp = CP.PropsSI('C', 'T', C2K(T_in), 'Q', 0, 'water')
     #print "cp is ",cp
     dh = cp * dT
     m = Q / dh
     return HRHX_integral_model.streamExample1(T_in, m, cp)
Пример #5
0
 def makeColdStream(self, Q):
     # Flow rate for evaporator is specified by inlet and outlet temperature...
     T_in, T_out = 12, 7
     cp = CP.PropsSI('C', 'T', C2K(T_in), 'Q', 0, 'water')
     #print "cp is ",cp
     dh = cp * (T_out - T_in)
     m = -Q / dh
     return HRHX_integral_model.streamExample1(T_in, m, cp)
Пример #6
0
 def updateSHX_hot_side(self):
     DeltaT_max = self.T_gen_outlet - self.T_abs_outlet_max
     DeltaT_SHX_concentrate = self.Eff_SHX * DeltaT_max
     self.T_SHX_concentrate_outlet = self.T_gen_outlet \
         - DeltaT_SHX_concentrate
     self.h_SHX_concentrate_outlet = libr_props.massSpecificEnthalpy(
         C2K(self.T_SHX_concentrate_outlet), self.x2)
     self.Q_SHX = self.m_concentrate \
         * (self.h_gen_outlet - self.h_SHX_concentrate_outlet)
Пример #7
0
 def getHeatCurve(self):
     """Returns (Heat,T), arrays showing progress of the process.
     Note: absorber heat input is negative.
     Learn this from (my revision to) example 3.3.
     """
     Q, result = 0, []
     # Starting coordinates
     result.append((0,self.T_abs_pre))
     # Heat input to reach a saturated state.
     Q += self.m_concentrate * (self.h_abs_inlet - self.h_abs_pre)
     result.append((Q,self.T_abs_inlet_max))
     # Heat input to reach outlet.
     Q += self.m_pump * self.h_abs_outlet \
         - self.m_concentrate * self.h_abs_inlet \
         - self.m_refrig * self.h_abs_vapor_inlet
     result.append((Q,self.T_abs_outlet_max))
     # Pump -- no heat, just work
     
     # Pump outlet to generator through SHX
     Q += self.m_pump * self.h_gen_pre - self.m_pump * self.h_abs_outlet
     result.append((Q,self.T_gen_pre))
     # Generator preheat
     Q += self.m_concentrate * self.h_gen_inlet \
             - self.m_concentrate * self.h_gen_pre
     result.append((Q,self.T_gen_inlet))        
     # Generator proper
     Q += self.m_concentrate * self.h_gen_outlet \
             + self.m_refrig * self.h_gen_vapor_outlet \
             - self.m_pump * self.h_gen_inlet
     result.append((Q,self.T_gen_outlet))
     # SHX, concentrate side
     Q += self.m_concentrate * self.h_SHX_concentrate_outlet \
             - self.m_concentrate * self.h_gen_outlet
     result.append((Q,self.T_SHX_concentrate_outlet))
     # Solution expander
     result.append((Q,self.T_abs_pre))
     # Condenser cool to saturated
     result.append((Q,self.T_gen_inlet))
     pwater.update(CP.QT_INPUTS,0,C2K(self.T_cond))
     h_condenser_sat = pwater.hmass() - h_w_ref
     Q += self.m_refrig * h_condenser_sat \
             - self.m_refrig * self.h_gen_vapor_outlet
     result.append((Q,self.T_cond))
     # Real condense
     Q += self.m_refrig * (self.h_condenser_outlet - h_condenser_sat)
     result.append((Q,self.T_cond))
     # What if condenser subcools? Later.
     # Expander
     pwater.update(CP.HmassP_INPUTS,self.h_condenser_outlet + h_w_ref,
                   self.P_evap)
     T_into_evap = pwater.T()
     result.append((Q,T_into_evap))
     # Evaporator
     Q += self.m_refrig * (self.h_evap_outlet - self.h_evap_inlet)
     result.append((Q,self.T_evap))
     
     return zip(*result)
Пример #8
0
 def _q(self,T):
     """Provide process heat canonical curve for generator in various forms.
     Assumes that
     * inlet solution state is obtained from self,
     * generated vapor is flowing in reverse direction and
     * it is everywhere in local equilibrium with solution.
     
     Args
     ----
     T : Temperature (deg C)
         The local temperature
     
     Returns
     -------
     q : Local progress index
         Measured as cumulative heat flux (W).
     Q : Total heat flux (W)
         The total amount of heat transferred into the generator.
     """
     
     hlv0 = self.h_vapor_out - self.h_sat
     q0 = self.m_total * self.h_vapor_out - self.m_in * hlv0
     
     if T < self.T_in:
         raise "Generator outlet must be greater than pre-inlet temperature!"
     elif T < self.T_sat:
         # The state is either saturated or subcooled.
         # Use linear interpolation.
         q = self.m_in * self.cp_in * (T - self.T_in)
     else:
         x_local = libr_props.massFraction(C2K(T),self.P * 1e-5)
         pwater.update(CP.PT_INPUTS, self.P, C2K(T))
         h_vapor_local = pwater.hmass() - h_w_ref
         h_solution_local = libr_props.massSpecificEnthalpy(C2K(T), x_local)
         # Mass balance on LiBr
         m_solution_local = self.m_in * self.x_in / x_local
         
         hlv1 = h_vapor_local - h_solution_local
         q1 = self.m_total * h_vapor_local - m_solution_local * hlv1
         
         q = (q1 - q0) + self.Q_preheat
     # TODO
     # If q > Q (iff T > T_solution_outlet) then result is invalid.
     return q
Пример #9
0
 def update(self, P, m_in, T_in, x_in, x_out):
     self.P = P        
     self.m_in = m_in
     self.T_in = T_in
     self.x_in = x_in
     self.x_out = x_out
     
     # Find inlet enthalpy.
     # Find saturation point at inlet concentration.
     # Find ...
     self.T_sat = K2C(libr_props.temperature(self.P * 1e-5, self.x_in))
     self.T_out = K2C(libr_props.temperature(self.P * 1e-5, self.x_out))
     self.h_sat = libr_props.massSpecificEnthalpy(C2K(self.T_sat), self.x_in)
     self.h_out = libr_props.massSpecificEnthalpy(C2K(self.T_out),self.x_out)
     
     self.cp_in = libr_props.massSpecificHeat(C2K(self.T_in),self.x_in)
     # If h_in is an input:
     if False:
         preheat = (self.h_sat - self.h_in)/self.cp_in
         self.T_in = self.T_sat - preheat
     else:
         preheat = self.T_sat - self.T_in
         self.h_in = self.h_sat - preheat * self.cp_in
     
     pwater.update(CP.PT_INPUTS, self.P, C2K(self.T_sat))
     self.h_vapor_out = pwater.hmass() - h_w_ref
     
     # Mass balance on LiBr
     self.m_out = self.m_in * self.x_in / self.x_out
     # Mass balance on Water
     self.m_vapor_out = self.m_in - self.m_out
     self.m_total = self.m_out
     
     self.Q_preheat = self.m_in * (self.h_sat - self.h_in)
     self.Q_desorb = self.m_out * self.h_out \
             + self.m_vapor_out * self.h_vapor_out \
             - self.m_in * self.h_sat
     
     
     # Determine a reasonable limit for extending the domain.
     self.Tmax = K2C(libr_props.temperature(self.P*1e-5,libr_props.xmax))
Пример #10
0
 def _qx(self,x_local):
     T = K2C(libr_props.temperature(self.P*1e-5,x_local))
     dx = self.x_in - x_local
     # TODO
     h_local = libr_props.massSpecificEnthalpy(C2K(T),x_local)
     # And calculate
     m_vapor = self.m_in * dx / x_local
     m_out = self.m_in + m_vapor
     # Heat is inbound.
     result = -self.m_in * self.h_in - m_vapor * self.h_vapor_inlet \
         + m_out * h_local
     return T,result
Пример #11
0
def Hsat(x, T):
    """Applies correction based on concentration, then returns saturation
    enthalpy from CoolProp's LiBr-H2O solution. You should check if the
    state is crystalline; if so, the results are not accurate.
    
    Args
    ----
        x (float)
            Concentration of LiBr in liquid, from 0 to 0.75 [kg/kg].
        T (float)
            Equilibrium temperature, from 0 to 227 [C].
    """
    return CP.PropsSI('H', 'T', C2K(T), 'Q', 0, librname(x))
Пример #12
0
 def _q(self,T):
     from CoolProp.CoolProp import PropsSI
     if T < self.Tmin:
         return 0
     elif T > self.Tmax:
         return self._q(self.Tmax)
     else:
         try:
             # CoolProp raises an exception if this is the saturation temp.
             #h_out = CP.PropsSI('H','P',self.P,'T',C2K(T),self.fluid)
             h_out = PropsSI('H','P',self.P,'T',C2K(T),self.fluid)
         except:
             h_out = self.h_sat
     return self.mdot * (h_out - self.h_in)
Пример #13
0
def main():
    from hw2_1 import CelsiusToKelvin as C2K
    spec = AdsorptionChillerSpec()
    ctrl = AdsorptionChillerControl(t_evap=C2K(12), t_exhaust=C2K(100))
    chiller = AdsorptionChiller(spec, ctrl)
    t_ads = linspace(0, 240, endpoint=True)
    t_des = linspace(0, 240, endpoint=True)
    T_d0 = 300
    myt = 0
    fig1, (ax1, ax2) = plt.subplots(2, 1)
    ax1.cla()
    ax2.cla()
    print(spec)
    print(ctrl)
    headers = 'Delta_T Delta_t q_low q_high'.split()
    units = 'K s kg/kg kg/kg'.split()
    fmt1 = "{:>12} " * 4
    fmt2 = "{:>12.5} " * 4
    print(fmt1.format(*headers))
    print(fmt1.format(*units))
    print(fmt1.format(*['----------'] * 4))
    for k in range(5):
        cycle = chiller.loopOnce(T_d0, t_des, t_ads, ax1, ax2, [fig1], myt)
        dT, dt, q_low, q_high = cycle
        print(fmt2.format(*cycle))
        myt += dt
        T_d0 += dT
    print(fmt1.format(*['----------'] * 4))
    performance = chiller.afterSolve(q_low, q_high, dt)

    import tabulate
    headers = 'Q_ref Q_in COP m_dot_ref'.split()
    units = 'kW kW kW/kW kg/s'.split()
    print(tabulate.tabulate(zip(headers, units, performance)))
    plt.show()

    return chiller, cycle, performance
Пример #14
0
def main():
    T,Qu = C2K(50), 1.0
    g_water = PropsSI("G","T",T,"Q",Qu,"water") # mass-specific gibbs energy
    # TODO: identify bug to report to CoolProp and fix it.
    # Maybe just need to expose
    #     double CoolProp::AbstractState::gibbsmolar(void)
    # via
    #     src/wrappers/Python/CoolProp/AbstractState.pxd
    # eg
    #     cpdef double gibbsmolar(self) except *
    # Just to check, we could use this different method, but it has the same problem.
    #water = AbstractState("HEOS","Water")
    #water.update(QT_INPUTS, Qu, T)
    #g_water = water.gibbsmolar() / molarmass

    mu_1 = []
    g_liquid = []
    xvals = []
    for x in linspace(0.01,0.99):
        g = libr_props.massSpecificGibbs(T,x)
        #P = 0
        try:
            P = libr_props.pressure(T, x)
        except:
            print("Crystallized!")
            break
        xvals.append(x)
        g_liquid.append(g)
        mu = (1. / x) * (g - (1. - x) * g_water)
        mu_1.append( mu )
        print("T,x = {}, {} -> P = {} bar, g = {} J/kg, mu = {}".format(T,x,P,g,mu))
    
    plt.close('all')
    plt.xlabel("LiBr mass fraction in liquid phase")
    plt.ylabel("Potential function in liquid phase")
    plt.xlim(0,1)
    plt.plot(xvals, mu_1, label="mu_LiBr")
    plt.plot(xvals, g_liquid, label="g_liquid")
    plt.legend(loc='best')
    plt.title("g_water_vapor = {:g} J/kg".format(g_water))
    plt.savefig('../img/{}.figure{}.png'.format(me2,plt.gcf().number))
Пример #15
0
 def updateGenerator(self,Q_gen):
     genStream = self.getGeneratorStream()
     self.h_gen_inlet = genStream.h_sat
     self.T_gen_inlet = genStream.T_sat
     
     if Q_gen < genStream.Q_preheat:
         self.T_gen_outlet = genStream.T(Q_gen)
         self.x2 = self.x1
         # error?
     else:
         self.T_gen_outlet = genStream.T(Q_gen)
         self.x2 = libr_props.massFraction(C2K(self.T_gen_outlet),
                                           self.P_cond)
         genStream.update(self.P_cond, self.m_pump, self.T_gen_pre,
                          self.x1, self.x2)
         self.h_gen_outlet = genStream.h_out
         self.h_gen_vapor_outlet = genStream.h_vapor_out
     self.dx = self.x1 - self.x2
     # Mass balance on LiBr
     self.m_concentrate = self.m_pump * self.x1 / self.x2
     # Mass balance on Water
     self.m_refrig = self.m_pump - self.m_concentrate
     self.f = self.m_pump / self.m_refrig
Пример #16
0
 def hTx(T,x):
     return CP.PropsSI('H','T',C2K(T),'Q',0,libr_props2.librname(x))
Пример #17
0
amm = lambda(x): 'REFPROP::water[{}]&ammonia[{}]'.format(1-x,x)

# Units in this file:
# temperature [C]
# enthalpy [J/kg]
# pressure [Pa]
# mass fraction [kg/kg total]
# effectiveness [K/K]

# The LiBr enthalpy is zero at 293.15 K, 1 atm, per
# http://www.coolprop.org/fluid_properties/Incompressibles.html#general-introduction
# We need to evaluate water enthalpy relative to that, but it is not built-in.
# http://www.coolprop.org/coolprop/HighLevelAPI.html#reference-states
T_ref = 20
P_ref = 101325
h_w_ref = CP.PropsSI('H','T',C2K(T_ref),'P',P_ref,water)


# Specify evaporator outlet and condenser outlet temperatures
T_evap = 1.5
T_cond = 39.9
P_evap = CP.PropsSI('P','T',C2K(T_evap),'Q',1,water)
P_cond = CP.PropsSI('P','T',C2K(T_cond),'Q',1,water)

x2 = 0.624
dx = 0.057
x1 = x2 - dx

T_gen_inlet = libr_props2.Tsat(x1, P_cond, 80)
T_gen_outlet = libr_props2.Tsat(x2, P_cond, T_gen_inlet)
T_abs_inlet_max = libr_props2.Tsat(x2, P_evap, T_gen_outlet)
Пример #18
0
def Tsat(x, P, T_guess=25):
    # CP.PropsSI('T','P',P_evap,'Q',0,libr(x1)) # unsupported inputs
    P_err = lambda T: CP.PropsSI('P', 'T', T, 'Q', 0, librname(x)) - P
    f = fsolve(P_err, C2K(T_guess))
    return K2C(f[0])
Пример #19
0
 def generatorHeatCurveQ(self,T,x_out):
     """Provide process heat canonical curve for generator in various forms.
     Assumes that
     * inlet solution state is obtained from self,
     * generated vapor is flowing in reverse direction and
     * it is everywhere in local equilibrium with solution.
     
     Args
     ----
     T : Temperature (deg C)
         The local temperature
     x_out : Mass fraction (kg/kg)
         The outlet solution LiBr mass fraction
     
     Returns
     -------
     q : Local progress index
         Measured as cumulative heat flux (W).
     Q : Total heat flux (W)
         The total amount of heat transferred into the generator.
     """
     
     # We may need m_concentrate. It depends on Q -- solve from inlet.
     h_solution_inlet = self.h_gen_inlet
     h_vapor_outlet = self.h_gen_vapor_outlet
     T_solution_outlet = K2C(libr_props.temperature(self.P_cond * 1e-5,
                                            x_out))
     h_solution_outlet = libr_props.massSpecificEnthalpy(
         C2K(T_solution_outlet), x_out)
     # Mass balance on LiBr
     m_solution_outlet = self.m_pump * self.x1 / x_out
     # Mass balance on Water
     m_vapor_outlet = self.m_pump - m_solution_outlet
     m_total = m_solution_outlet
     
     hlv0 = h_vapor_outlet - h_solution_inlet
     q0 = m_total * h_vapor_outlet - self.m_pump * hlv0
     
     Q = m_solution_outlet * h_solution_outlet \
         + m_vapor_outlet * h_vapor_outlet \
         - self.m_pump * h_solution_inlet
     
     q = 0
     T0,T1,T2=self.genpoints[0][1],self.genpoints[1][1],self.genpoints[2][1]
     Q0,Q1,Q2=self.genpoints[0][0],self.genpoints[1][0],self.genpoints[2][0]
     if T < T0:
         raise "Generator outlet must be greater than pre-inlet temperature!"
     elif T < T1:
         # The state is either saturated or subcooled.
         # Use linear interpolation.
         q = (T - T0) / (T1 - T0) * (Q1 - Q0)
     else:
         x_local = libr_props.massFraction(C2K(T),self.P_cond * 1e-5)
         pwater.update(CP.PT_INPUTS, self.P_cond, C2K(T))
         h_vapor_local = pwater.hmass() - h_w_ref
         h_solution_local = libr_props.massSpecificEnthalpy(C2K(T), x_local)
         # Mass balance on LiBr
         m_solution_local = self.m_pump * self.x1 / x_local
         
         hlv1 = h_vapor_local - h_solution_local
         q1 = m_total * h_vapor_local - m_solution_local * hlv1
         
         q = (q1 - q0) + (Q1 - Q0)
     # TODO
     # If q > Q (iff T > T_solution_outlet) then result is invalid.
     return q, Q
Пример #20
0
def Tsat2(x, H, T_guess=25):
    # CP.PropsSI('T','P',P_evap,'Q',0,libr(x1)) # unsupported inputs
    H_err = lambda T: CP.PropsSI('H', 'T', T, 'Q', 0, librname(x)) - H
    f = fsolve(H_err, C2K(T_guess))
    return f[0]
Пример #21
0
 def P_err(x):
     return CP.PropsSI('P', 'T', C2K(T), 'Q', 0, librname(x)) - P
Пример #22
0
 def setT_cond(self,T_cond):
     self.T_cond = T_cond
     pwater.update(CP.QT_INPUTS, 1, C2K(T_cond))
     self.P_cond = pwater.p()
Пример #23
0
    def iterate1(self):
        """Update the internal parameters."""
        self.T_gen_inlet = K2C(libr_props.temperature(self.P_cond*1e-5,
                                                      self.x1))
        self.T_gen_outlet = K2C(libr_props.temperature(self.P_cond * 1e-5,
                                                   self.x2))
        self.T_abs_inlet_max = K2C(libr_props.temperature(self.P_evap * 1e-5,
                                                          self.x2))
        self.T_abs_outlet_max = K2C(libr_props.temperature(self.P_evap * 1e-5,
                                                           self.x1))
        
        self.h_gen_inlet = libr_props.massSpecificEnthalpy(
            C2K(self.T_gen_inlet), self.x1)
        self.h_gen_outlet = libr_props.massSpecificEnthalpy(
            C2K(self.T_gen_outlet), self.x2)
        self.h_abs_inlet = libr_props.massSpecificEnthalpy(
            C2K(self.T_abs_inlet_max), self.x2)
        self.h_abs_outlet = libr_props.massSpecificEnthalpy(
            C2K(self.T_abs_outlet_max), self.x1)
        
        # Mass balance on LiBr
        self.m_concentrate = self.m_pump * self.x1 / self.x2
        # Mass balance on Water
        self.m_refrig = self.m_pump - self.m_concentrate
        self.f = self.m_pump / self.m_refrig

        # Compute SHX outlets, assuming concentrate limits heat flow (C_min)
        # Neglect pump work for the present.
        DeltaT_max = self.T_gen_outlet - self.T_abs_outlet_max
        DeltaT_SHX_concentrate = self.Eff_SHX * DeltaT_max
        self.T_SHX_concentrate_outlet = self.T_gen_outlet \
            - DeltaT_SHX_concentrate
        self.h_SHX_concentrate_outlet = libr_props.massSpecificEnthalpy(
            C2K(self.T_SHX_concentrate_outlet), self.x2)
        self.Q_SHX = self.m_concentrate \
            * (self.h_gen_outlet - self.h_SHX_concentrate_outlet)
        
        # Expansion valve
        self.h_abs_pre = self.h_SHX_concentrate_outlet
        if self.h_abs_pre > self.h_abs_inlet:
            # Pre-cooling is required to reach saturation temperature
            self.Q_abs_pre_cool = self.m_concentrate \
                * (self.h_abs_pre - self.h_abs_inlet)
            q,t,xl = libr_props.twoPhaseProps(self.h_abs_pre,
                                              self.P_evap*1e-5,
                                              self.x2)
            self.T_abs_pre = K2C(t)
            self.x_abs_pre = xl
            # ignore vapor quality, q
            # Minimum vapor pressure for absorption to occur
            self.P_abs_pre = np.inf
        else:
            self.Q_abs_pre_cool = 0
            #self.T_abs_pre = K2C(CP.PropsSI('T',
            #    'H', self.h_abs_pre,
            #    'P', self.P_evap,
            #    librname(self.x2)))
            self.T_abs_pre = np.nan
            # Minimum vapor pressure for absorption to occur
#            self.P_abs_pre = CP.PropsSI('P',
#                'T', C2K(self.T_abs_pre),
#                'Q', 0,
#                librname(self.x2))
            self.P_abs_pre = np.nan
                
        # Heat rejection in absorber: energy balance
        pwater.update(CP.PQ_INPUTS, self.P_evap, 1)
        self.h_abs_vapor_inlet = pwater.hmass() - h_w_ref
        self.Q_abs_main = self.m_refrig * self.h_abs_vapor_inlet \
            + self.m_concentrate * self.h_abs_inlet \
            - self.m_pump * self.h_abs_outlet
        self.Q_abs_total = self.Q_abs_main + self.Q_abs_pre_cool
        
        # Energy balance in SHX, pump side
        D_in = CP.PropsSI('D',
            'T',C2K(self.T_abs_outlet_max),
            'Q',0,
            librname(self.x1))
        DeltaH_pump = (self.P_cond - self.P_evap) / D_in
        self.W_pump = self.m_pump * DeltaH_pump
        self.h_pump_outlet = self.h_abs_outlet + DeltaH_pump
        DeltaH_SHX_pumpside = self.Q_SHX / self.m_pump
        self.h_gen_pre = self.h_pump_outlet + DeltaH_SHX_pumpside
        if self.h_gen_pre > self.h_gen_inlet:
            # Flash steam
            self.T_gen_pre = np.nan
        else:
            # The state is either saturated or subcooled.
            # We need to calculate the temperature from specific heat.
            cp = libr_props.massSpecificHeat(C2K(self.T_gen_inlet),self.x1)
            deltaHsub = self.h_gen_inlet - self.h_gen_pre
            deltaT = deltaHsub / cp
            self.T_gen_pre = self.T_gen_inlet - deltaT
        
        self.Q_gen_pre_heat = self.m_pump * (self.h_gen_inlet - self.h_gen_pre)
        
        # Heat input to generator: energy balance
        pwater.update(CP.PT_INPUTS, self.P_cond, C2K(self.T_gen_inlet))
        self.h_gen_vapor_outlet = pwater.hmass() - h_w_ref
        self.vapor_superheat = self.T_gen_inlet - self.T_cond
        self.Q_gen_main = self.m_refrig * self.h_gen_vapor_outlet \
            + self.m_concentrate * self.h_gen_outlet \
            - self.m_pump * self.h_gen_inlet
        self.Q_gen_total = self.Q_gen_main + self.Q_gen_pre_heat
        
        # Condenser
        pwater.update(CP.PQ_INPUTS, self.P_cond, 0)
        self.h_condenser_outlet = pwater.hmass() - h_w_ref
        self.Q_condenser_reject = self.m_refrig * (self.h_gen_vapor_outlet
            - self.h_condenser_outlet)
        
        # Expansion valve
        self.h_evap_inlet = self.h_condenser_outlet
        
        # Evaporator
        self.h_evap_outlet = self.h_abs_vapor_inlet
        self.Q_evap_heat = self.m_refrig * (self.h_evap_outlet
            - self.h_evap_inlet)
        
        self.COP = self.Q_evap_heat / self.Q_gen_total
Пример #24
0
    def __init__(self,
                 T_evap=1.5, T_cond=39.9,
                 x1=0.567, x2=0.624,
                 Eff_SHX=0.64, m_pump=0.05):
        """Args
        ----
            T_evap : float
                Evaporator saturation temperature (deg C)
            T_cond : float
                Condenser saturation temperature (deg C)
            x1 : float
                Pump side mass fraction of LiBr in stream (low) [kg/kg]
            x2 : float
                Return side mass fraction of LiBr in stream (high/concentrate)
            Eff_SHX : float
                Effectiveness of the solution heat exchanger (K/K), 0 to 1
            m_pump : float
                Mass flow rate through the solution pump (kg/s)
        """
        self.T_evap = T_evap
        self.T_cond = T_cond
        self.x1 = x1
        self.x2 = x2
        self.m_pump = m_pump
        self.Eff_SHX = Eff_SHX
        self.dx = x1 - x2
        
        pwater.update(CP.QT_INPUTS, 1, C2K(T_evap))
        self.P_evap = pwater.p()
        
        pwater.update(CP.QT_INPUTS, 1, C2K(T_cond))
        self.P_cond = pwater.p()
        
        self.stateLabels = """abs_outlet
pump_outlet
gen_inlet
gen_sat_liquid
gen_outlet
SHX_conc_outlet
abs_inlet
abs_sat_liquid
gen_vapor_outlet
cond_sat_vapor
cond_outlet
evap_inlet
evap_sat_liquid
evap_sat_vapor
evap_outlet""".split('\n')
        #self.states=dict((k, nullPP('LiBrH2O')) for k in self.stateLabels)
        self.stateTable,self.states=makePointTable(self.stateLabels)
        
        
        self.T_gen_inlet = 0
        self.T_gen_outlet = 0
        self.T_abs_inlet_max = 0
        self.T_abs_outlet_max = 0
        self.h_gen_inlet = 0
        self.h_gen_outlet = 0
        self.h_abs_inlet = 0
        self.h_abs_outlet = 0
        self.m_concentrate = 0
        self.m_refrig = 0
        self.T_SHX_concentrate_outlet = 0
        self.Q_SHX = 0
        self.T_abs_pre = np.nan
        self.h_abs_pre = np.nan
        self.Q_abs_pre_cool = 0
        self.P_abs_pre = np.nan
        self.Q_abs_main = 0
        self.Q_abs_total = 0
        self.T_gen_pre = np.nan
        self.Q_gen_pre_heat = 0
        self.Q_gen_main = 0
        self.Q_gen_total = 0
        self.Q_condenser_reject = 0
        self.Q_evap_heat = 0
        self.COP = 0
        self.W_pump = 0
        self.f = np.inf
        self.x_abs_pre = self.x2
Пример #25
0
 def setT_evap(self,T_evap):
     self.T_evap = T_evap
     pwater.update(CP.QT_INPUTS, 1, C2K(T_evap))
     self.P_evap = pwater.p()
Пример #26
0
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 05 17:26:23 2015

@author: nfette
"""

from __future__ import print_function
import ammonia_props
from hw2_1 import CelsiusToKelvin as C2K

if __name__ == "__main__":
    myprops = ammonia_props.AmmoniaProps()
    f1 = myprops.props('TPx')
    T, P, x = C2K(20.), 10., 0.5  # K, bar, dim

    state = f1(T, P, x)
    print(state)
    dhdT = f1.massSpecificHeat(T=T, P=P, x=x)
    dhdT_expected = 4.604999985
    print("dh/dT = {}, expected {} kJ/kg-K".format(dhdT, dhdT_expected))
Пример #27
0
# -*- coding: utf-8 -*-
"""
Created on Wed Feb 18 14:42:55 2015

@author: nfette
"""
from __future__ import print_function
import ammonia_props
from hw2_1 import CelsiusToKelvin as C2K

if __name__ == "__main__":
    print("(a) Mixture properties from TPx:")
    myprops = ammonia_props.AmmoniaProps()
    f1 = myprops.props('TPx')
    T, P, x = C2K(50.), 10., 0.0  # K, bar, dim
    state = f1(T, P, x)
    print(state)
    print(f1.getOutputUnits())

    print("(b) ... in molar units:")
    Meff = state.molarMass()
    hbar = state.h * Meff
    print("Meff = {} kg/kmol".format(Meff))
    print("hbar = {} kJ/kmol".format(hbar))

    print("(c) Partial component enthalpies")
    dhdx = f1.dhdxetc(T=T, P=P, x=x)
    print("{} kJ/kg".format(dhdx))

    print("(d) Enthalpy of mixing")
    x = state.x
Пример #28
0
    def __init__(self,P,m_in,h_in,x_in,h_vapor_inlet,debug=False):
        self.P=P
        self.m_in=m_in
        self.h_in=h_in
        self.x_in=x_in
        self.h_vapor_inlet = h_vapor_inlet
        
        self.T_sat = K2C(libr_props.temperature(self.P * 1e-5,
                                                          self.x_in))
        self.h_sat = libr_props.massSpecificEnthalpy(C2K(self.T_sat),self.x_in)
        
        if self.h_in > self.h_sat:
            q,t,xl = libr_props.twoPhaseProps(self.h_in,self.P*1e-5,self.x_in)
            # Pre-cooling is required to reach saturation temperature
            self.Q_pre_cool = self.m_in * (self.h_sat - self.h_in)
            self.T_in = K2C(t)
            prepoints_x = np.linspace(xl,self.x_in,20,endpoint=False)
            prepoints_T = np.zeros_like(prepoints_x)
            prepoints_q = np.zeros_like(prepoints_x)
            
            for i,x in enumerate(prepoints_x):
                #q,t,xl = libr_props.twoPhaseProps(h,self.P*1e-5,self.x_in)
                t = libr_props.temperature(self.P * 1e-5, x)
                h = libr_props.massSpecificEnthalpy(t,x)
                prepoints_T[i] = K2C(t)
                prepoints_q[i] = self.m_in * (h - self.h_in)
                prepoints_x[i] = x
        else:
            self.Q_pre_cool = 0
            self.T_in = K2C(libr_props.temperature(self.P * 1e-5, self.x_in))
            prepoints_T = []
            prepoints_q = []
            prepoints_x = []
        
        # Set up bounds and points for interpolation.
        # Absorber limit is liquid water.
        pwater.update(CP.PQ_INPUTS,P,0)
        self.Tmin = pwater.T()
        x_points = np.linspace(x_in,0.1,100)
        T_points = np.zeros_like(x_points)
        q_points = np.zeros_like(x_points)
        #q_func = np.vectorize(self._q)
        #q_points = q_func(T_points)
        for i,x in enumerate(x_points):
            T_points[i],q_points[i] = self._qx(x)

        x_points = np.concatenate([prepoints_x,x_points])
        T_points = np.concatenate([prepoints_T,T_points])
        q_points = np.concatenate([prepoints_q,q_points])
        
        # Forward function
        T_points1 = np.resize(T_points,len(T_points)+1)
        q_points1 = np.resize(q_points,len(T_points)+1)
        T_points1[-1] = T_points[-1] - 5
        q_points1[-1] = q_points[-1]
        
        # Inverse function
        T_points2 = np.resize(T_points,len(T_points)+1)
        q_points2 = np.resize(q_points,len(T_points)+1)
        T_points2[-1] = T_points[-1]
        q_points2[-1] = q_points[-1] * 1.05
        
        if debug:        
            import matplotlib.pyplot as plt
            import tabulate
            xmod = np.resize(x_points,len(x_points)+1)
            print(tabulate.tabulate(zip(xmod,T_points1,q_points1,
                                    T_points2,q_points2),
                                    headers=['x','T1','q1','T2','q2']))
            plt.figure(); plt.plot(T_points1,q_points1); plt.title("q(T)")
            plt.figure(); plt.plot(q_points2,T_points2); plt.title("T(q)")
        # Interpolate data must be in increasing order, so we reverse it
        # compared to reaction direction.
        self.q = PchipInterpolator(T_points1[::-1], q_points1[::-1])
        self.T = PchipInterpolator(q_points2[::-1], T_points2[::-1])
Пример #29
0
        Qu = 1. - x / x_liquid
        Q_vapor = 1
        h_vap = CP.PropsSI('H','T',T,'Q',Q_vapor,'Water')
        v_vap = CP.PropsSI('D','T',T,'Q',Q_vapor,'Water')
        cp_vap = CP.PropsSI('C','T',T,'Q',Q_vapor,'Water')
        h = (1.0 - Qu) * h_liquid + Qu * h_vap
        v = (1.0 - Qu) * v_liquid + Qu * v_vap
        hh[i] = h
        vv[i] = v
    dhdp_T = (hh[1] - hh[0]) / deltaP
    dvdT_p = (vv[2] - vv[0]) / deltaT
    a = dhdp_T - (vv[0] - T * dvdT_p)    
    dhdT_p = (state3.h - state1.h) / deltaT
    b = dhdT_p - cp
    print(state1)
    print(state2)
    print(state3)
    print("a = {}. b = {}".format(a,b))
    return a,b


if __name__ == "__main__":
    TC, P, x = 100, 10, 0.5 # C, bar, dim
    # go to 120 C and 11 bar
    residualsAmmonia(C2K(TC), P, x)
    # units are kJ/kg-K
    
    TC, P, x = 100, 1e3 / 1e5, 0.5 # C, bar, dim
    residualsLiBr(C2K(TC), P, x)
    # units are J/kg-K
    
Пример #30
0
    
# Units in this file:
# temperature [C]
# enthalpy [J/kg]
# pressure [Pa]
# mass fraction [kg/kg total]
# effectiveness [K/K]

# The LiBr enthalpy is zero at 293.15 K, 1 atm, per
# http://www.coolprop.org/fluid_properties/Incompressibles.html#general-introduction
# We need to evaluate water enthalpy relative to that, but it is not built-in.
# http://www.coolprop.org/coolprop/HighLevelAPI.html#reference-states
T_ref = 20
P_ref = 101325

pwater.update(CP.PT_INPUTS,P_ref,C2K(T_ref))
h_w_ref = pwater.hmass()

class GeneratorLiBr(object):
    """Provide process heat canonical curve for generator in various forms.
        For purpose of external heat exchange,  generator process goes ...
        P_cond, T_gen_pre, x1  (subcooled)
        P_cond, T_gen_inlet, x1 (saturated liquid) + backwards flowing vapor
        P_cond, T_gen_outlet, x2 (saturated liquid)
        
        Args:
            P : Pressure (Pa)            
                The process is assumed to occur at constant pressure level.
            m_in : Solution inlet mass flow rate (kg/s)
                The mass flow rate of the stream pumped up from low pressure.
            T_in : Solution inlet temperature (C)