def calc_parameters(self): r"""Postprocessing parameter calculation.""" # component parameters self.Q.val = self.inl[0].m.val_SI * ( self.outl[0].h.val_SI - self.inl[0].h.val_SI) self.ttd_u.val = T_bp_p(self.inl[0].get_flow()) - self.outl[1].T.val_SI self.ttd_l.val = self.outl[0].T.val_SI - self.inl[1].T.val_SI # pr and zeta for i in range(2): self.get_attr('pr' + str(i + 1)).val = ( self.outl[i].p.val_SI / self.inl[i].p.val_SI) self.get_attr('zeta' + str(i + 1)).val = ( (self.inl[i].p.val_SI - self.outl[i].p.val_SI) * np.pi ** 2 / ( 4 * self.inl[i].m.val_SI ** 2 * (self.inl[i].vol.val_SI + self.outl[i].vol.val_SI) )) # kA and logarithmic temperature difference if self.ttd_u.val < 0 or self.ttd_l.val < 0: self.td_log.val = np.nan self.kA.val = np.nan else: self.td_log.val = ((self.ttd_l.val - self.ttd_u.val) / np.log(self.ttd_l.val / self.ttd_u.val)) self.kA.val = -self.Q.val / self.td_log.val
def kA_char_func(self): r""" Calculate heat transfer from heat transfer coefficient characteristic. Returns ------- residual : float Residual value of equation. .. math:: 0 = \dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1}\right) + kA_{design} \cdot f_{kA} \cdot \frac{T_{out,1} - T_{in,2} - T_{sat} \left(p_{in,1}\right) + T_{out,2}} {\ln{\frac{T_{out,1} - T_{in,2}} {T_{sat} \left(p_{in,1}\right) - T_{out,2}}}} f_{kA} = \frac{2}{\frac{1}{f_1 \left( expr_1\right)} + \frac{1}{f_2 \left( expr_2\right)}} Note ---- For standard functions f\ :subscript:`1` \ and f\ :subscript:`2` \ see module :py:mod:`tespy.data`. """ p1 = self.kA_char1.param p2 = self.kA_char2.param f1 = self.get_char_expr(p1, **self.kA_char1.char_params) f2 = self.get_char_expr(p2, **self.kA_char2.char_params) i1 = self.inl[0] i2 = self.inl[1] o1 = self.outl[0] o2 = self.outl[1] # temperature value manipulation for convergence stability T_i1 = T_bp_p(i1.get_flow()) T_i2 = T_mix_ph(i2.get_flow(), T0=i2.T.val_SI) T_o1 = T_mix_ph(o1.get_flow(), T0=o1.T.val_SI) T_o2 = T_mix_ph(o2.get_flow(), T0=o2.T.val_SI) if T_i1 <= T_o2 and not i1.T.val_set: T_i1 = T_o2 + 0.5 if T_i1 <= T_o2 and not o2.T.val_set: T_o2 = T_i1 - 0.5 if T_o1 <= T_i2 and not o1.T.val_set: T_o1 = T_i2 + 1 if T_o1 <= T_i2 and not i2.T.val_set: T_i2 = T_o1 - 1 td_log = ((T_o1 - T_i2 - T_i1 + T_o2) / np.log((T_o1 - T_i2) / (T_i1 - T_o2))) fkA1 = self.kA_char1.char_func.evaluate(f1) fkA2 = self.kA_char2.char_func.evaluate(f2) fkA = 2 / (1 / fkA1 + 1 / fkA2) return ( i1.m.val_SI * (o1.h.val_SI - i1.h.val_SI) + self.kA.design * fkA * td_log)
def test_condenser(self): """ Test component properties of condenser. """ instance = condenser('condenser') self.setup_heat_exchanger_network(instance) # design specification instance.set_attr(pr1=0.98, pr2=0.98, ttd_u=5, offdesign=['zeta2', 'kA']) self.c1.set_attr(T=100, p0=0.5, fluid={'Ar': 0, 'H2O': 1}) self.c3.set_attr(T=30, p=5, fluid={'Ar': 0, 'H2O': 1}) self.c4.set_attr(T=40) instance.set_attr(Q=-80e3) self.nw.solve('design') convergence_check(self.nw.lin_dep) self.nw.save('tmp') # test heat transfer Q = self.c1.m.val_SI * (self.c2.h.val_SI - self.c1.h.val_SI) msg = ('Value ofheat flow be ' + str(round(instance.Q.val, 0)) + ', is ' + str(round(Q, 0)) + '.') eq_(round(Q, 1), round(instance.Q.val, 1), msg) # test upper terminal temperature difference. For the component # condenser the temperature of the condensing fluid is relevant. ttd_u = round(T_bp_p(self.c1.to_flow()) - self.c4.T.val_SI, 1) p = round(self.c1.p.val_SI, 5) kA = instance.kA.val msg = ('Value of terminal temperature difference must be ' + str(round(instance.ttd_u.val, 1)) + ', is ' + str(ttd_u) + '.') eq_(ttd_u, round(instance.ttd_u.val, 1), msg) # test lower terminal temperature difference instance.set_attr(ttd_l=20, ttd_u=np.nan, design=['pr2', 'ttd_l']) self.nw.solve('design') convergence_check(self.nw.lin_dep) msg = ('Value of terminal temperature difference must be ' + str(instance.ttd_l.val) + ', is ' + str(self.c2.T.val - self.c3.T.val) + '.') eq_(round(self.c2.T.val - self.c3.T.val, 1), round(instance.ttd_l.val, 1), msg) # check kA value with condensing pressure in offdesign mode: # no changes to design point means: identical pressure self.nw.solve('offdesign', design_path='tmp') convergence_check(self.nw.lin_dep) msg = ('Value of condensing pressure be ' + str(p) + ', is ' + str(round(self.c1.p.val_SI, 5)) + '.') eq_(p, round(self.c1.p.val_SI, 5), msg) shutil.rmtree('./tmp', ignore_errors=True)
def ttd_u_func(self): r""" Equation for upper terminal temperature difference. Returns ------- residual : float Residual value of equation. .. math:: 0 = ttd_{u} - T_{sat} \left(p_{in,1}\right) + T_{out,2} Note ---- The upper terminal temperature difference ttd_u refers to boiling temperature at hot side inlet. """ T_i1 = T_bp_p(self.inl[0].get_flow()) T_o2 = T_mix_ph(self.outl[1].get_flow(), T0=self.outl[1].T.val_SI) return self.ttd_u.val - T_i1 + T_o2
def kA_func(self): r""" Calculate heat transfer from heat transfer coefficient. Returns ------- residual : float Residual value of equation. .. math:: 0 = \dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1}\right) + kA \cdot \frac{T_{out,1} - T_{in,2} - T_{sat} \left(p_{in,1}\right) + T_{out,2}} {\ln{\frac{T_{out,1} - T_{in,2}} {T_{sat} \left(p_{in,1}\right) - T_{out,2}}}} """ i1 = self.inl[0] i2 = self.inl[1] o1 = self.outl[0] o2 = self.outl[1] T_i1 = T_bp_p(i1.get_flow()) T_i2 = T_mix_ph(i2.get_flow(), T0=i2.T.val_SI) T_o1 = T_mix_ph(o1.get_flow(), T0=o1.T.val_SI) T_o2 = T_mix_ph(o2.get_flow(), T0=o2.T.val_SI) if T_i1 <= T_o2 and not i1.T.val_set: T_i1 = T_o2 + 0.5 if T_i1 <= T_o2 and not o2.T.val_set: T_o2 = T_i1 - 0.5 if T_o1 <= T_i2 and not o1.T.val_set: T_o1 = T_i2 + 1 if T_o1 <= T_i2 and not i2.T.val_set: T_i2 = T_o1 - 1 td_log = ((T_o1 - T_i2 - T_i1 + T_o2) / np.log((T_o1 - T_i2) / (T_i1 - T_o2))) return i1.m.val_SI * (o1.h.val_SI - i1.h.val_SI) + self.kA.val * td_log
def test_Condenser(self): """Test component properties of Condenser.""" instance = Condenser('condenser') self.setup_HeatExchanger_network(instance) # design specification instance.set_attr(pr1=0.98, pr2=0.98, ttd_u=5, offdesign=['zeta2', 'kA_char']) self.c1.set_attr(T=100, p0=0.5, fluid={'Ar': 0, 'H2O': 1, 'S800': 0}) self.c3.set_attr(T=30, p=5, fluid={'Ar': 0, 'H2O': 1, 'S800': 0}) self.c4.set_attr(T=40) instance.set_attr(Q=-80e3) self.nw.solve('design') convergence_check(self.nw.lin_dep) self.nw.save('tmp') Q_design = instance.Q.val # test specified kA value instance.set_attr(kA=instance.kA.val * 2 / 3, Q=None) self.nw.solve('design') convergence_check(self.nw.lin_dep) # test heat transfer Q = self.c1.m.val_SI * (self.c2.h.val_SI - self.c1.h.val_SI) msg = ( 'Value of heat flow must be ' + str(round(Q_design * 2 / 3, 0)) + ', is ' + str(round(Q, 0)) + '.') assert round(Q, 1) == round(Q_design * 2 / 3, 1), msg # back to design case instance.set_attr(kA=None, Q=Q_design) self.nw.solve('design') convergence_check(self.nw.lin_dep) # test heat transfer Q = self.c1.m.val_SI * (self.c2.h.val_SI - self.c1.h.val_SI) msg = ('Value of heat flow must be ' + str(round(instance.Q.val, 0)) + ', is ' + str(round(Q, 0)) + '.') assert round(Q, 1) == round(instance.Q.val, 1), msg # test upper terminal temperature difference. For the component # condenser the temperature of the condensing fluid is relevant. ttd_u = round(T_bp_p(self.c1.get_flow()) - self.c4.T.val_SI, 1) p = round(self.c1.p.val_SI, 5) msg = ('Value of terminal temperature difference must be ' + str(round(instance.ttd_u.val, 1)) + ', is ' + str(ttd_u) + '.') assert ttd_u == round(instance.ttd_u.val, 1), msg # test lower terminal temperature difference instance.set_attr(ttd_l=20, ttd_u=np.nan, design=['pr2', 'ttd_l']) self.nw.solve('design') convergence_check(self.nw.lin_dep) msg = ('Value of terminal temperature difference must be ' + str(instance.ttd_l.val) + ', is ' + str(self.c2.T.val - self.c3.T.val) + '.') ttd_l_calc = round(self.c2.T.val - self.c3.T.val, 1) ttd_l = round(instance.ttd_l.val, 1) assert ttd_l_calc == ttd_l, msg # check kA value with condensing pressure in offdesign mode: # no changes to design point means: identical pressure self.nw.solve('offdesign', design_path='tmp') convergence_check(self.nw.lin_dep) msg = ('Value of condensing pressure be ' + str(p) + ', is ' + str(round(self.c1.p.val_SI, 5)) + '.') assert p == round(self.c1.p.val_SI, 5), msg shutil.rmtree('./tmp', ignore_errors=True)
def test_ORCEvaporator(self): """Test component properties of orc evaporator.""" # design specification self.instance.set_attr(pr1=0.95, pr2=0.975, pr3=0.975, design=['pr1', 'pr2', 'pr3'], offdesign=['zeta1', 'zeta2', 'zeta3']) self.c1.set_attr(T=146.6, p=4.34, m=20.4, state='g', fluid={ 'water': 1, 'Isopentane': 0 }) self.c3.set_attr(T=146.6, p=10.2, fluid={'water': 1, 'Isopentane': 0}) self.c4.set_attr(T=118.6) self.c5.set_attr(T=111.6, p=10.8, fluid={'water': 0, 'Isopentane': 1}) # test heat transfer Q = -6.64e+07 self.instance.set_attr(Q=Q) self.nw.solve('design') convergence_check(self.nw.lin_dep) Q_is = -self.c5.m.val_SI * (self.c6.h.val_SI - self.c5.h.val_SI) msg = ('Value of heat flow must be ' + str(round(Q, 0)) + ', is ' + str(round(Q_is, 0)) + '.') assert round(Q, 0) == round(Q_is, 0), msg # test bus self.instance.set_attr(Q=np.nan) P = -6.64e+07 b = Bus('heat transfer', P=P) b.add_comps({'comp': self.instance}) self.nw.add_busses(b) self.nw.solve('design') convergence_check(self.nw.lin_dep) self.nw.save('tmp') Q_is = -self.c5.m.val_SI * (self.c6.h.val_SI - self.c5.h.val_SI) msg = ('Value of heat flow must be ' + str(round(P, 0)) + ', is ' + str(round(Q_is, 0)) + '.') assert round(P, 0) == round(Q_is, 0), msg # Check the state of the steam and working fluid outlet: x_outl1_calc = self.c2.x.val x_outl3_calc = self.c6.x.val zeta1 = self.instance.zeta1.val zeta2 = self.instance.zeta2.val zeta3 = self.instance.zeta3.val msg = ('Vapor mass fraction of steam outlet must be 0.0, is ' + str(round(x_outl1_calc, 1)) + '.') assert round(x_outl1_calc, 1) == 0.0, msg msg = ('Vapor mass fraction of working fluid outlet must be 1.0, is ' + str(round(x_outl3_calc, 1)) + '.') assert round(x_outl3_calc, 1) == 1.0, msg # Check offdesign by zeta values # geometry independent friction coefficient self.nw.solve('offdesign', design_path='tmp') convergence_check(self.nw.lin_dep) msg = ('Geometry independent friction coefficient ' 'at hot side 1 (steam) ' 'must be ' + str(round(zeta1, 1)) + ', is ' + str(round(self.instance.zeta1.val, 1)) + '.') assert round(self.instance.zeta1.val, 1) == round(zeta1, 1), msg msg = ('Geometry independent friction coefficient at ' 'hot side 2 (brine) ' 'must be ' + str(round(zeta2, 1)) + ', is ' + str(round(self.instance.zeta2.val, 1)) + '.') assert round(self.instance.zeta2.val, 1) == round(zeta2, 1), msg msg = ('Geometry independent friction coefficient at cold side ' '(Isopentane) must be ' + str(round(zeta3, 1)) + ', is ' + str(round(self.instance.zeta3.val, 1)) + '.') assert round(self.instance.zeta3.val, 1) == round(zeta3, 1), msg # test parameters of 'subcooling' and 'overheating' self.instance.set_attr(subcooling=True, overheating=True) dT = 0.5 self.c2.set_attr(Td_bp=-dT) self.c6.set_attr(Td_bp=dT) self.nw.solve('offdesign', design_path='tmp') convergence_check(self.nw.lin_dep) T_steam = T_bp_p(self.c2.get_flow()) - dT T_isop = T_bp_p(self.c6.get_flow()) + dT msg = ('Temperature of working fluid outlet must be ' + str(round(T_isop, 1)) + ', is ' + str(round(self.c6.T.val_SI, 1)) + '.') assert round(T_isop, 1) == round(self.c6.T.val_SI, 1), msg msg = ('Temperature of steam outlet must be ' + str(round(T_steam, 1)) + ', is ' + str(round(self.c2.T.val_SI, 1)) + '.') assert round(T_steam, 1) == round(self.c2.T.val_SI, 1), msg shutil.rmtree('./tmp', ignore_errors=True)