Rankine Cycle + HRSG #554
-
Issue with NaN Results in TESPy ModelHi, community. Hope you're all great. Together with a student (I'm his tutor), we are developing a model of a HRSG and a small Rankine Cycle. The process data is from real pieces of equipment. The (ackward) truth is that we are stuck. We cannot find why the system shows The process fluid diagram is attached. It contains the connections' numbers (almost every connection is represented, with the small exception of a valve inside the steam turbine and the gas path). I’m fully aware that debugging is really a pain in the foot, and that this code is still a work-in-progress in terms of style. I am posting to ask for help, and I’ll continue improving readiness and clarity. Thanks in advance! 🙏 PS: Apologies for the bad English and the Spanish-English messy mixture Python Codedef export(__file__, results):
import os
path = os.path.dirname(os.path.abspath(__file__))
text_file = os.path.join(path, 'results.txt')
formatted_text = results.to_string(index=False, justify='left')
with open(text_file, 'w') as file:
file.write(formatted_text)
from tespy.networks import Network
from tespy.components import (
CycleCloser,
Turbine,
Pump,
Valve,
Source,
Sink,
Splitter,
Merge,
SimpleHeatExchanger,
HeatExchanger,
Drum,
)
from tespy.connections import Bus
from tespy.tools import ExergyAnalysis
my_plant = Network()
my_plant.set_attr(
T_unit='C',
p_unit='bar',
h_unit='kJ / kg',
m_unit='t / h',
s_unit='kJ / kgK',
iterinfo=False
)
powergen = Bus("electrical power output")
my_plant.add_busses(powergen)
pamb = 1.013 # bar(a)
Tamb = 17 # C
cc = CycleCloser('cycle closer HPDRUM to ST')
st_ext = Turbine('extraction st', eta_s=0.9)
st_cond = Turbine('cond st', eta_s=0.9)
att_pump = Pump('att_pump', eta_s=0.7)
cond_pump = Pump('cond_pump', eta_s=0.7)
sg_pump = Pump('steam generator pump', eta_s=0.7)
lp_pump=Pump('low pressure pump', eta_s=0.7)
cond_st_cv = Valve('cond st cv', pr=0.85)
water_inlet_1 = Source('Process condensate return')
water_inlet_2 = Source('Water makeup')
turbine_exhaust = Source('Hot gases source')
wst = Sink('LPDRUM saturated steam waste')
wst_2 = Sink('HPDRUM saturated liquid waste')
process_steam = Sink('process IP steam')
gases_outlet = Sink('hot gases outlet')
sp_1 = Splitter('st inner splitter')
sp_2 = Splitter('condensate header')
sp_3 = Splitter('HPEC1 splitter')
sp_4 = Splitter('HPDRUM outlet')
bd_1 = Splitter('LPDRUM splitter to waste')
bd_2= Splitter('HPDRUM splitter to waste')
me_1 = Merge('Attemper')
me_3 = Merge('Water from reposition & condensate mixture', num_in=3)
me_4 = Merge('merge at the inlet of sweet water condenser in SG')
me_5 = Merge('attemp HPS2')
HE = HeatExchanger('heat exchanger', pr1=0.9, pr2=0.9)
LPEV1 = HeatExchanger('LPEV1', pr2=1)
LPDRUM = Drum('LP Drum')
HPEC1 = HeatExchanger('HPEC1', pr1=1, pr2=1)
HPEC2 = HeatExchanger('HPEC2',pr1=1, pr2=1)
HPEC3 = HeatExchanger('HPEC3',pr1=1, pr2=1)
HPEV1 = HeatExchanger('HPEV1', pr2=1)
HPS1 = HeatExchanger('HPS1', pr1=1, pr2=1)
HPS2 = HeatExchanger('HPS2', pr1=1, pr2=1)
HPDRUM = Drum('HP Drum')
condenser = SimpleHeatExchanger('condenser', pr=1)
HE_cond = HeatExchanger('sweet water condenser', pr1=1, pr2=1)
powergen.add_comps(
{"comp": st_ext, "char": 0.97, "base": "component"},
{"comp": st_cond, "char": 0.97, "base": "component"},
{"comp": att_pump, "char": 0.97, "base": "bus"},
{"comp": cond_pump, "char": 0.97, "base": "bus"},
{"comp": sg_pump, "char": 0.97, "base": "bus"},
)
from tespy.connections import (Connection, Ref)
N = 50
c = [None] * N
names = [None] * N
# caudal_vapor_sobrecalentado = 2*102.3 # t/h
c[0] = Connection(cc, 'out1', st_ext, 'in1', label='1')
c[0].set_attr(
#m=caudal_vapor_sobrecalentado,
fluid={'water': 1}
)
names[0] = 'hp steam'
c[1] = Connection(st_ext, 'out1', sp_1, 'in1', label='2')
names[1] = 'extraction st outlet'
caudal_extraccion_turbina = 160 # t/h
c[2] = Connection(sp_1, 'out2', me_1, 'in2', label='3')
c[2].set_attr(m=caudal_extraccion_turbina)
names[2] = 'Steam from TV to attemp'
c[3] = Connection(sp_1, 'out1', cond_st_cv, 'in1', label='4')
names[3] = 'cond st cv inlet'
c[4] = Connection(cond_st_cv, 'out1', st_cond, 'in1', label='5')
names[4] = 'cond st inlet'
c[5] = Connection(st_cond, 'out1', condenser, 'in1', label='6')
names[5] = 'condenser inlet'
c[6] = Connection(condenser, 'out1', sp_2, 'in1', label='7')
c[6].set_attr(x=0, T=Tamb + 18)
names[6] = 'condenser outlet'
c[7] = Connection(sp_2, 'out1', cond_pump, 'in1', label='8')
names[7] = 'cond pump inlet'
c[8] = Connection(sp_2, 'out2', att_pump, 'in1', label='9')
names[8] = 'att pump inlet'
c[9] = Connection(att_pump,'out1', me_1,'in1',label='10')
names[9] = 'att pump outlet'
presion_vapor_proceso = 13 # bar(a)
grado_sobrecalentamiento = 10 # C
c[10] = Connection(me_1, 'out1',process_steam,'in1',label='11')
c[10].set_attr(
Td_bp=grado_sobrecalentamiento,
p=presion_vapor_proceso
)
names[10] = 'process steam'
c[11] = Connection(cond_pump,'out1', me_3, 'in1', label='12')
c[11].set_attr(p=pamb)
names[11] = 'cond pump outlet'
retorno_condensado = 0.75 # dim
c[12] = Connection(water_inlet_1, 'out1', me_3, 'in2', label='13')
c[12].set_attr( m=Ref(c[10], retorno_condensado, 0), fluid={'water': 1})
names[12] = 'Condensate return from process'
c[13] = Connection(water_inlet_2,'out1',me_3,'in3',label='14')
c[13].set_attr(T=Tamb)
names[13] = 'Water makeup'
c[14] = Connection(me_3,'out1', lp_pump,'in1', label='15')
names[14] = 'Water mixture feed to low pressure pump'
c[15] = Connection(lp_pump,'out1', HE,'in2', label='16')
c[15].set_attr(p=2.3, T=55)
names[15] = 'Water mixture feed to heat exchanger'
c[16] = Connection(HE,'out2', LPDRUM,'in1',label='17')
c[16].set_attr(T=100)
names[16] = 'heated water feed to LPDRUM'
c[17] = Connection(HE,'out1', sg_pump,'in1', label='18')
names[17] = 'Cooled water feed to HP pump'
c[18] = Connection(sg_pump, 'out1', sp_3,'in1', label='19')
c[18].set_attr(p=88.52)
names[18] = 'pressurized water to HPEC1'
c[19] = Connection(sp_3, 'out1', me_4, 'in2', label='20')
c[19].set_attr(m=0)
names[19] = 'pressurized water to sg condenser'
c[20] = Connection(sp_3, 'out2', HPEC1, 'in1', label='21')
names[20] = 'pressurized water to HPEC1'
c[21] = Connection(HPEC1, 'out1', HPEC2, 'in1', label='22')
c[21].set_attr(T=116.1)
names[21] = 'pressurized water to HPEC2'
c[22] = Connection(HPEC2, 'out1', me_4, 'in1', label='23')
c[22].set_attr(T=230.9)
names[22] = 'outlet of HPEC2 to merge with cold flow'
c[23] = Connection(me_4, 'out1', HE_cond, 'in1', label='24')
names[23] = 'outlet of merge to sweet water condenser'
c[24] = Connection(HE_cond, 'out1', HPEC3, 'in1', label='25')
names[24] = 'outlet of sweet water condenser to HPEC3'
c[25] = Connection(HPEC3, 'out1', HPDRUM, 'in1', label='26')
c[25].set_attr(T=289.9)
names[25] = 'outlet of HPEC3 to HP drum'
c[26] = Connection(HPDRUM, 'out1', bd_2, 'in1', label='27')
names[26] = 'saturated liquid outlet of HPDRUM to Splitter'
c[27] = Connection(bd_2, 'out1', HPEV1, 'in1', label='28')
names[27] = 'saturated liquid outlet of HPDRUM to HPEV1'
c[28] = Connection(bd_2, 'out2', wst_2, 'in1', label='29')
names[28] = 'saturated liquid outlet of HPDRUM to waste'
c[28].set_attr(m=2)
c[29] = Connection(HPEV1, 'out1', HPDRUM, 'in2', label='30')
c[29].set_attr(x=0.05)
names[29] = 'saturated steam outlet of HPEV1 to HPDRUM'
c[30] = Connection(HPDRUM, 'out2', sp_4 , 'in1', label='31')
names[30] = 'saturated steam outlet of HPDRUM'
c[31] = Connection(sp_4, 'out1', HPS1, 'in1', label='32')
names[31] = 'saturated steam inlet to HPS1'
c[32] = Connection(HPS1, 'out1', me_5, 'in1', label='33')
c[32].set_attr(T=528.6)
names[32] = 'Steam outlet of HPS1 to attemp'
c[33] = Connection(sp_4, 'out2', HE_cond, 'in2', label='34')
names[33] = 'Steam derivation of HPDRUM to sweet water condenser'
c[34] = Connection(HE_cond, 'out2', me_5, 'in2', label='35')
c[34].set_attr(x=0)
names[34] = 'Sweet water condenser outlet to attemp'
c[35] = Connection(me_5, 'out1', HPS2, 'in1', label='36')
c[35].set_attr(T=428.8)
names[35] = 'Attemp outlet to HPS2'
c[36] = Connection(HPS2, 'out1', cc, 'in1', label='37')
temperatura_vapor_sobrecalentado = 480 # C
c[36].set_attr(T=temperatura_vapor_sobrecalentado)
names[36] = 'Superheated steam to steam turbine'
c[37] = Connection(LPDRUM,'out1', bd_1,'in1', label='38')
names[37] = 'Saturated liquid outlet of LPDRUM to LPEV1'
c[38] = Connection(bd_1, 'out1', HE, 'in1', label='39')
names[38] = 'LPDRUM saturated liquid outlet to HE'
c[39] = Connection(bd_1, 'out2', LPEV1, 'in1', label='40')
names[39] = 'Saturated liquid inlet to LPEV1'
c[40] = Connection(LPEV1, 'out1', LPDRUM, 'in2', label='41')
c[40].set_attr(x=0.05)
names[40] = 'Saturated steam inlet to LPDRUM'
c[41] = Connection(LPDRUM, 'out2', wst, 'in1', label='42')
names[41] = 'Saturated steam outlet to vent'
c[41].set_attr(m=2*0.05)
c[42] = Connection(turbine_exhaust, 'out1', HPS2, 'in2', label='43')
x_gh_CO2 = 0.061 # dim
x_gh_H2O = 0.07768 # dim
x_gh_N2 = 0.7364 # dim
x_gh_O2 = 0.1126 # dim
x_gh_Ar = 1 - x_gh_CO2 - x_gh_H2O - x_gh_N2 - x_gh_O2
T_gh = 712.9 # C
G_gh = 2*481.98 # t/h
p_gh = pamb # bar(a)
c[42].set_attr(
m=G_gh,
T=T_gh,
p=p_gh,
fluid={'O2': x_gh_O2, 'N2': x_gh_N2, 'CO2': x_gh_CO2, 'water': x_gh_H2O, 'Ar': x_gh_Ar}
)
names[42] = 'Hot gases input to HPS2'
c[43] = Connection(HPS2, 'out2', HPS1, 'in2', label='44')
names[43] = 'Hot gases input to HPS1'
c[44] = Connection(HPS1, 'out2', HPEV1, 'in2', label='45')
names[44] = 'Hot gases input to HPEV1'
c[45] = Connection(HPEV1, 'out2', HPEC3, 'in2', label='46')
names[45] = 'Hot gases input to HPEC3'
c[46] = Connection(HPEC3, 'out2', HPEC2, 'in2', label='47')
names[46] = 'Hot gases input to HPEC2'
c[47] = Connection(HPEC2, 'out2', LPEV1 , 'in2', label='48')
names[47] = 'Hot gases input to LPEV1'
c[48] = Connection(LPEV1, 'out2', HPEC1 , 'in2', label='49')
names[48] = 'Hot gases input to HPEC1'
c[49] = Connection(HPEC1, 'out2', gases_outlet , 'in1', label='50')
names[49] = 'Hot gases outlet'
for j in range(0,N):
my_plant.add_conns(c[j])
my_plant.solve(mode='design')
my_plant.print_results()
bus_results = my_plant.results['electrical power output']
df_results_for_conns = my_plant.results['Connection']
df_results_for_conns['denomination'] = names
results = df_results_for_conns[['denomination',
'p','p_unit',
'T','T_unit',
'h','h_unit',
's','s_unit',
'x',
'm','m_unit']]
start_index_for_gases = 42
results_gases = results[start_index_for_gases:]
results_gases = results_gases[['denomination',
'p','p_unit',
'T','T_unit',
'h','h_unit',
's','s_unit',
'm','m_unit']]
results = results[0:start_index_for_gases]
results = results.drop(results.index[0])
results = results.round(3)
export(__file__, results) |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 9 replies
-
There's some problem with two branches that split and then merge, and the equalization of pressures. One of these branches is the economizer bypass, and the other is the sweet-water condenser (for superheated steam attemperation). Apart from that, the code assumes that the drum component internally, implicitly equalizes all pressures, as a merge does (or a split). That's why the pr1=1 equation is not indicated in the LPEV1 (or HPEV1). EDIT: By deleting pr1=1 in the HPEC1 one of these problems should disappear. But when I tried to do so in HE_COND, obviously an equation is missing, and I can't figure which. Python Codedef export(__file__, results):
import os
path = os.path.dirname(os.path.abspath(__file__))
text_file = os.path.join(path, 'results.txt')
formatted_text = results.to_string(index=False, justify='left')
with open(text_file, 'w') as file:
file.write(formatted_text)
from tespy.networks import Network
from tespy.components import (
CycleCloser,
Turbine,
Pump,
Valve,
Source,
Sink,
Splitter,
Merge,
SimpleHeatExchanger,
HeatExchanger,
Drum,
)
from tespy.connections import Bus
from tespy.tools import ExergyAnalysis
my_plant = Network()
my_plant.set_attr(
T_unit='C',
p_unit='bar',
h_unit='kJ / kg',
m_unit='t / h',
s_unit='kJ / kgK',
iterinfo=False
)
powergen = Bus("electrical power output")
my_plant.add_busses(powergen)
pamb = 1.013 # bar(a)
Tamb = 17 # C
cc = CycleCloser('cycle closer HPDRUM to ST')
st_ext = Turbine('extraction st', eta_s=0.9)
st_cond = Turbine('cond st', eta_s=0.9)
att_pump = Pump('att_pump', eta_s=0.7)
cond_pump = Pump('cond_pump', eta_s=0.7)
sg_pump = Pump('steam generator pump', eta_s=0.7)
lp_pump=Pump('low pressure pump', eta_s=0.7)
cond_st_cv = Valve('cond st cv', pr=0.85)
water_inlet_1 = Source('Process condensate return')
water_inlet_2 = Source('Water makeup')
turbine_exhaust = Source('Hot gases source')
wst = Sink('LPDRUM saturated steam waste')
wst_2 = Sink('HPDRUM saturated liquid waste')
process_steam = Sink('process IP steam')
gases_outlet = Sink('hot gases outlet')
sp_1 = Splitter('st inner splitter')
sp_2 = Splitter('condensate header')
sp_3 = Splitter('HPEC1 splitter')
sp_4 = Splitter('HPDRUM outlet')
bd_1 = Splitter('LPDRUM splitter to waste')
bd_2= Splitter('HPDRUM splitter to waste')
me_1 = Merge('Attemper')
me_3 = Merge('Water from reposition & condensate mixture', num_in=3)
me_4 = Merge('merge at the inlet of sweet water condenser in SG')
me_5 = Merge('attemp HPS2')
HE = HeatExchanger('heat exchanger', pr1=0.9, pr2=0.9)
LPEV1 = HeatExchanger('LPEV1', pr2=1)
LPDRUM = Drum('LP Drum')
#HPEC1 = HeatExchanger('HPEC1', pr1=1, pr2=1)
HPEC1 = HeatExchanger('HPEC1', pr2=1)
HPEC2 = HeatExchanger('HPEC2',pr1=1, pr2=1)
HPEC3 = HeatExchanger('HPEC3',pr1=1, pr2=1)
HPEV1 = HeatExchanger('HPEV1', pr2=1)
HPS1 = HeatExchanger('HPS1', pr1=1, pr2=1)
HPS2 = HeatExchanger('HPS2', pr1=1, pr2=1)
HPDRUM = Drum('HP Drum')
condenser = SimpleHeatExchanger('condenser', pr=1)
#HE_cond = HeatExchanger('sweet water condenser', pr1=1, pr2=1)
HE_cond = HeatExchanger('sweet water condenser', pr1=1)
powergen.add_comps(
{"comp": st_ext, "char": 0.97, "base": "component"},
{"comp": st_cond, "char": 0.97, "base": "component"},
{"comp": att_pump, "char": 0.97, "base": "bus"},
{"comp": cond_pump, "char": 0.97, "base": "bus"},
{"comp": sg_pump, "char": 0.97, "base": "bus"},
)
from tespy.connections import (Connection, Ref)
N = 50
c = [None] * N
names = [None] * N
# caudal_vapor_sobrecalentado = 2*102.3 # t/h
c[0] = Connection(cc, 'out1', st_ext, 'in1', label='1')
c[0].set_attr(
#m=caudal_vapor_sobrecalentado,
fluid={'water': 1}
)
names[0] = 'hp steam'
c[1] = Connection(st_ext, 'out1', sp_1, 'in1', label='2')
names[1] = 'extraction st outlet'
caudal_extraccion_turbina = 160 # t/h
c[2] = Connection(sp_1, 'out2', me_1, 'in2', label='3')
c[2].set_attr(m=caudal_extraccion_turbina)
names[2] = 'Steam from TV to attemp'
c[3] = Connection(sp_1, 'out1', cond_st_cv, 'in1', label='4')
names[3] = 'cond st cv inlet'
c[4] = Connection(cond_st_cv, 'out1', st_cond, 'in1', label='5')
names[4] = 'cond st inlet'
c[5] = Connection(st_cond, 'out1', condenser, 'in1', label='6')
names[5] = 'condenser inlet'
c[6] = Connection(condenser, 'out1', sp_2, 'in1', label='7')
c[6].set_attr(x=0, T=Tamb + 18)
names[6] = 'condenser outlet'
c[7] = Connection(sp_2, 'out1', cond_pump, 'in1', label='8')
names[7] = 'cond pump inlet'
c[8] = Connection(sp_2, 'out2', att_pump, 'in1', label='9')
names[8] = 'att pump inlet'
c[9] = Connection(att_pump,'out1', me_1,'in1',label='10')
names[9] = 'att pump outlet'
presion_vapor_proceso = 13 # bar(a)
grado_sobrecalentamiento = 10 # C
c[10] = Connection(me_1, 'out1',process_steam,'in1',label='11')
c[10].set_attr(
Td_bp=grado_sobrecalentamiento,
p=presion_vapor_proceso
)
names[10] = 'process steam'
c[11] = Connection(cond_pump,'out1', me_3, 'in1', label='12')
c[11].set_attr(p=pamb)
names[11] = 'cond pump outlet'
retorno_condensado = 0.75 # dim
c[12] = Connection(water_inlet_1, 'out1', me_3, 'in2', label='13')
c[12].set_attr( m=Ref(c[10], retorno_condensado, 0), fluid={'water': 1})
names[12] = 'Condensate return from process'
c[13] = Connection(water_inlet_2,'out1',me_3,'in3',label='14')
c[13].set_attr(T=Tamb)
names[13] = 'Water makeup'
c[14] = Connection(me_3,'out1', lp_pump,'in1', label='15')
names[14] = 'Water mixture feed to low pressure pump'
c[15] = Connection(lp_pump,'out1', HE,'in2', label='16')
c[15].set_attr(p=2.3, T=55)
names[15] = 'Water mixture feed to heat exchanger'
c[16] = Connection(HE,'out2', LPDRUM,'in1',label='17')
c[16].set_attr(T=100)
names[16] = 'heated water feed to LPDRUM'
c[17] = Connection(HE,'out1', sg_pump,'in1', label='18')
names[17] = 'Cooled water feed to HP pump'
c[18] = Connection(sg_pump, 'out1', sp_3,'in1', label='19')
c[18].set_attr(p=88.52)
names[18] = 'pressurized water to HPEC1'
c[19] = Connection(sp_3, 'out1', me_4, 'in2', label='20')
c[19].set_attr(m=0)
names[19] = 'pressurized water to sg condenser'
c[20] = Connection(sp_3, 'out2', HPEC1, 'in1', label='21')
names[20] = 'pressurized water to HPEC1'
c[21] = Connection(HPEC1, 'out1', HPEC2, 'in1', label='22')
c[21].set_attr(T=116.1)
names[21] = 'pressurized water to HPEC2'
c[22] = Connection(HPEC2, 'out1', me_4, 'in1', label='23')
c[22].set_attr(T=230.9)
names[22] = 'outlet of HPEC2 to merge with cold flow'
c[23] = Connection(me_4, 'out1', HE_cond, 'in1', label='24')
c[23].set_attr(p=88.52)
names[23] = 'outlet of merge to sweet water condenser'
c[24] = Connection(HE_cond, 'out1', HPEC3, 'in1', label='25')
names[24] = 'outlet of sweet water condenser to HPEC3'
c[25] = Connection(HPEC3, 'out1', HPDRUM, 'in1', label='26')
c[25].set_attr(T=289.9)
names[25] = 'outlet of HPEC3 to HP drum'
c[26] = Connection(HPDRUM, 'out1', bd_2, 'in1', label='27')
names[26] = 'saturated liquid outlet of HPDRUM to Splitter'
c[27] = Connection(bd_2, 'out1', HPEV1, 'in1', label='28')
names[27] = 'saturated liquid outlet of HPDRUM to HPEV1'
c[28] = Connection(bd_2, 'out2', wst_2, 'in1', label='29')
names[28] = 'saturated liquid outlet of HPDRUM to waste'
c[28].set_attr(m=2)
c[29] = Connection(HPEV1, 'out1', HPDRUM, 'in2', label='30')
c[29].set_attr(x=0.05)
names[29] = 'saturated steam outlet of HPEV1 to HPDRUM'
c[30] = Connection(HPDRUM, 'out2', sp_4 , 'in1', label='31')
names[30] = 'saturated steam outlet of HPDRUM'
c[31] = Connection(sp_4, 'out1', HPS1, 'in1', label='32')
names[31] = 'saturated steam inlet to HPS1'
c[32] = Connection(HPS1, 'out1', me_5, 'in1', label='33')
c[32].set_attr(T=528.6)
names[32] = 'Steam outlet of HPS1 to attemp'
c[33] = Connection(sp_4, 'out2', HE_cond, 'in2', label='34')
names[33] = 'Steam derivation of HPDRUM to sweet water condenser'
c[34] = Connection(HE_cond, 'out2', me_5, 'in2', label='35')
c[34].set_attr(x=0)
names[34] = 'Sweet water condenser outlet to attemp'
c[35] = Connection(me_5, 'out1', HPS2, 'in1', label='36')
c[35].set_attr(T=428.8)
names[35] = 'Attemp outlet to HPS2'
c[36] = Connection(HPS2, 'out1', cc, 'in1', label='37')
temperatura_vapor_sobrecalentado = 480 # C
c[36].set_attr(T=temperatura_vapor_sobrecalentado)
names[36] = 'Superheated steam to steam turbine'
c[37] = Connection(LPDRUM,'out1', bd_1,'in1', label='38')
names[37] = 'Saturated liquid outlet of LPDRUM to LPEV1'
c[38] = Connection(bd_1, 'out1', HE, 'in1', label='39')
names[38] = 'LPDRUM saturated liquid outlet to HE'
c[39] = Connection(bd_1, 'out2', LPEV1, 'in1', label='40')
names[39] = 'Saturated liquid inlet to LPEV1'
c[40] = Connection(LPEV1, 'out1', LPDRUM, 'in2', label='41')
c[40].set_attr(x=0.05)
names[40] = 'Saturated steam inlet to LPDRUM'
c[41] = Connection(LPDRUM, 'out2', wst, 'in1', label='42')
names[41] = 'Saturated steam outlet to vent'
c[41].set_attr(m=2*0.05)
c[42] = Connection(turbine_exhaust, 'out1', HPS2, 'in2', label='43')
x_gh_CO2 = 0.061 # dim
x_gh_H2O = 0.07768 # dim
x_gh_N2 = 0.7364 # dim
x_gh_O2 = 0.1126 # dim
x_gh_Ar = 1 - x_gh_CO2 - x_gh_H2O - x_gh_N2 - x_gh_O2
T_gh = 712.9 # C
G_gh = 2*481.98 # t/h
p_gh = pamb # bar(a)
c[42].set_attr(
m=G_gh,
T=T_gh,
p=p_gh,
fluid={'O2': x_gh_O2, 'N2': x_gh_N2, 'CO2': x_gh_CO2, 'water': x_gh_H2O, 'Ar': x_gh_Ar}
)
names[42] = 'Hot gases input to HPS2'
c[43] = Connection(HPS2, 'out2', HPS1, 'in2', label='44')
names[43] = 'Hot gases input to HPS1'
c[44] = Connection(HPS1, 'out2', HPEV1, 'in2', label='45')
names[44] = 'Hot gases input to HPEV1'
c[45] = Connection(HPEV1, 'out2', HPEC3, 'in2', label='46')
names[45] = 'Hot gases input to HPEC3'
c[46] = Connection(HPEC3, 'out2', HPEC2, 'in2', label='47')
names[46] = 'Hot gases input to HPEC2'
c[47] = Connection(HPEC2, 'out2', LPEV1 , 'in2', label='48')
names[47] = 'Hot gases input to LPEV1'
c[48] = Connection(LPEV1, 'out2', HPEC1 , 'in2', label='49')
names[48] = 'Hot gases input to HPEC1'
c[49] = Connection(HPEC1, 'out2', gases_outlet , 'in1', label='50')
names[49] = 'Hot gases outlet'
for j in range(0,N):
my_plant.add_conns(c[j])
my_plant.solve(mode='design')
my_plant.print_results()
bus_results = my_plant.results['electrical power output']
df_results_for_conns = my_plant.results['Connection']
df_results_for_conns['denomination'] = names
results = df_results_for_conns[['denomination',
'p','p_unit',
'T','T_unit',
'h','h_unit',
's','s_unit',
'x',
'm','m_unit']]
start_index_for_gases = 42
results_gases = results[start_index_for_gases:]
results_gases = results_gases[['denomination',
'p','p_unit',
'T','T_unit',
'h','h_unit',
's','s_unit',
'm','m_unit']]
results = results[0:start_index_for_gases]
results = results.drop(results.index[0])
results = results.round(3)
export(__file__, results) |
Beta Was this translation helpful? Give feedback.
-
Hi Francesco, hope you are doing well. We resolved the model in EES. We obtained razonable results and we were also able to plot the HRSG T-Q diagram. However, when tryng to resolve the model in Tespy using the same input values used in EES, we are getting Nan results both for steam and gases flow. I tryed defining some initial seed values for temperature and pressure both in steam and gases side (using as reference the results obtained in EES) but it seems like the programm is strugling to converge. I attach the PDF with the results obtenied in EES. Highlated values are inputs. These inputs are: kA and pr for HPEC1, HPEC2, HPEC3, LPEV1, HPEV1, HPS1, HPS2 Also you will find attached the PFD of the instalation we are modeling. Finally, the tespy code: def export(file, results): from tespy.networks import Network from tespy.connections import Bus powergen = Bus("electrical power output") pamb = 1.013 # bar(a) cc = CycleCloser('cycle closer HPDRUM to ST') att_pump = Pump('att_pump', eta_s=0.7) cond_st_cv = Valve('cond st cv', pr=0.85) water_inlet_1 = Source('Process condensate return') wst = Sink('LPDRUM saturated steam waste') sp_1 = Splitter('st inner splitter') me_1 = Merge('Attemper') A_HE=5000 #m2 A_LPEV1=5000 #m2 LPDRUM = Drum('LP Drum') A_HPEC1=4700 #[m^2] A_HPEC2=4700 #[m^2] A_HPEC3=9500 #[m^2] A_HPEV1=12300 #[m^2] A_HPS1=2500 #[m^2] A_HPS2=175 #[m^2] HPDRUM = Drum('HP Drum') condenser = SimpleHeatExchanger('condenser', pr=1) powergen.add_comps( from tespy.connections import (Connection, Ref) N = 49 caudal_vapor_sobrecalentado = 2*100 # t/h c[1] = Connection(st_ext, 'out1', sp_1, 'in1', label='2') c[2] = Connection(sp_1, 'out2', me_1, 'in2', label='3') c[3] = Connection(sp_1, 'out1', cond_st_cv, 'in1', label='4') c[4] = Connection(cond_st_cv, 'out1', st_cond, 'in1', label='5') c[5] = Connection(st_cond, 'out1', condenser, 'in1', label='6') c[6] = Connection(condenser, 'out1', sp_2, 'in1', label='7') c[7] = Connection(sp_2, 'out1', cond_pump, 'in1', label='8') c[8] = Connection(sp_2, 'out2', att_pump, 'in1', label='9') c[9] = Connection(att_pump,'out1', me_1,'in1',label='10') presion_vapor_proceso = 13 # bar(a) c[11] = Connection(cond_pump,'out1', me_3, 'in1', label='12') retorno_condensado = 0.5 c[13] = Connection(water_inlet_2,'out1',me_3,'in3',label='14') c[14] = Connection(me_3,'out1', lp_pump,'in1', label='15') c[15] = Connection(lp_pump,'out1', HE,'in2', label='16') c[16] = Connection(HE,'out2', LPDRUM,'in1',label='17') c[17] = Connection(HE,'out1', sg_pump,'in1', label='18') c[18] = Connection(sg_pump, 'out1', sp_3,'in1', label='19') c[19] = Connection(sp_3, 'out1', me_4, 'in2', label='20') c[20] = Connection(sp_3, 'out2', HPEC1, 'in2', label='21') # in2 c[21] = Connection(HPEC1, 'out2', HPEC2, 'in2', label='22') # in2 c[22] = Connection(HPEC2, 'out2', me_4, 'in1', label='23') c[23] = Connection(me_4, 'out1', HE_cond, 'in2', label='24') c[24] = Connection(HE_cond, 'out2', HPEC3, 'in2', label='25') c[25] = Connection(HPEC3, 'out2', HPDRUM, 'in1', label='26') c[26] = Connection(HPDRUM, 'out1', bd_2, 'in1', label='27') c[27] = Connection(bd_2, 'out1', HPEV1, 'in2', label='28') c[28] = Connection(bd_2, 'out2', wst_2, 'in1', label='29') c[29] = Connection(HPEV1, 'out2', HPDRUM, 'in2', label='30') c[30] = Connection(HPDRUM, 'out2', sp_4 , 'in1', label='31') c[31] = Connection(sp_4, 'out1', HPS1, 'in2', label='32') # in2 c[32] = Connection(HPS1, 'out2', me_5, 'in1', label='33') c[33] = Connection(sp_4, 'out2', HE_cond, 'in1', label='34') c[34] = Connection(HE_cond, 'out1', me_5, 'in2', label='35') c[35] = Connection(me_5, 'out1', HPS2, 'in2', label='36') # in 2! c[36] = Connection(LPDRUM,'out1', bd_1,'in1', label='37') c[37] = Connection(bd_1, 'out1', HE, 'in1', label='38') c[38] = Connection(bd_1, 'out2', LPEV1, 'in2', label='39') c[39] = Connection(LPEV1, 'out2', LPDRUM, 'in2', label='40') c[40] = Connection(LPDRUM, 'out2', wst, 'in1', label='41') c[41] = Connection(turbine_exhaust, 'out1', HPS2, 'in1', label='42') c[42] = Connection(HPS2, 'out1', HPS1, 'in1', label='43') c[43] = Connection(HPS1, 'out1', HPEV1, 'in1', label='44') c[44] = Connection(HPEV1, 'out1', HPEC3, 'in1', label='45') c[45] = Connection(HPEC3, 'out1', HPEC2, 'in1', label='46') c[46] = Connection(HPEC2, 'out1', LPEV1 , 'in1', label='47') c[47] = Connection(LPEV1, 'out1', HPEC1 , 'in1', label='48') c[48] = Connection(HPEC1, 'out1', gases_outlet , 'in1', label='49') for j in range(0,N): bus_results = my_plant.results['electrical power output'] df_results_for_conns['denomination'] = names results = df_results_for_conns[['denomination', start_index_for_gases = 41 results_gases = results[start_index_for_gases:] results = results[0:start_index_for_gases] results = results.round(3) export(file, results) |
Beta Was this translation helpful? Give feedback.
-
Hi, everybody. Finally, we got a working code. I'll comment about the details in the next post. ### GENERAL INFO ###
# ibuzzo@fi.uba.ar
# pbarral@fi.uba.ar
# 2025-02-02
# tespy v0.78.post2
### NETWORK ###
from tespy.networks import Network
my_plant = Network()
my_plant.set_attr(
T_unit = 'C',
p_unit = 'bar',
h_unit = 'kJ / kg',
m_unit = 't / h',
s_unit = 'kJ / kgK',
iterinfo = False
)
### COMPONENTS ###
### DEFINITIONS ###
from tespy.components import (
Turbine, Valve, SimpleHeatExchanger, Pump, Drum, HeatExchanger, Splitter, Merge, Sink, Source
)
st_ext = Turbine('extraction st', eta_s = 0.9)
st_cond = Turbine('cond st', eta_s = 0.9)
att_pump = Pump('att_pump', eta_s = 0.7)
cond_pump = Pump('cond_pump', eta_s = 0.7)
sg_pump = Pump('steam generator pump', eta_s = 0.7)
lp_pump = Pump('low pressure pump', eta_s = 0.7)
cond_st_cv = Valve('cond st cv', pr = 0.85)
water_inlet_1 = Source('Process condensate return')
water_inlet_2 = Source('Water makeup')
turbine_exhaust = Source('Hot gases source')
wst = Sink('LPDRUM saturated steam waste')
wst_2 = Sink('HPDRUM saturated liquid waste')
process_steam = Sink('process IP steam')
gases_outlet = Sink('hot gases outlet')
sp_1 = Splitter('st inner splitter')
sp_2 = Splitter('condensate header')
sp_3 = Splitter('HPEC1 splitter')
sp_4 = Splitter('HPDRUM outlet')
bd_1 = Splitter('LPDRUM splitter to waste')
bd_2 = Splitter('HPDRUM splitter to waste')
me_1 = Merge('Attemper')
me_2 = Merge('St condensate & process condensate return')
me_3 = Merge('Water from reposition & condensate mixture', num_in = 3)
me_4 = Merge('merge at the inlet of sweet water condenser in SG')
me_5 = Merge('attemp HPS2')
A_HE = 5000 #[m^2]
HE = HeatExchanger('heat exchanger', pr1 = 1, pr2 = 1)
A_LPEV1 = 5000 #[m^2]
K_LPEV1 = 35 #[W/m^2-C]
#LPEV1 = HeatExchanger('LPEV1', pr1 = 1, kA = K_LPEV1 * A_LPEV1)
LPEV1 = HeatExchanger('LPEV1', pr1 = 1)
LPDRUM = Drum('LP Drum')
A_HPEC1 = 4700 #[m^2]
K_HPEC1 = 30 #[W/m^2-C]
#HPEC1 = HeatExchanger('HPEC1', pr1 = 1, kA = K_HPEC1 * A_HPEC1)
HPEC1 = HeatExchanger('HPEC1', pr1 = 1)
A_HPEC2 = 4700 #[m^2]
K_HPEC2 = 40 #[W/m^2-C]
#HPEC2 = HeatExchanger('HPEC2', pr1 = 1, pr2 = 1, kA = K_HPEC2 * A_HPEC2)
HPEC2 = HeatExchanger('HPEC2', pr1 = 1, pr2 = 1)
A_HPEC3 = 9500 #[m^2]
K_HPEC3 = 45 #[W/m^2-C]
#HPEC3 = HeatExchanger('HPEC3', pr1 = 1, pr2 = 1, kA = K_HPEC3 * A_HPEC3)
HPEC3 = HeatExchanger('HPEC3', pr1 = 1, pr2 = 1)
A_HPEV1 = 12300 #[m^2]
K_HPEV1 = 85 #[W/m^2-C]
#HPEV1 = HeatExchanger('HPEV1', pr1 = 1, kA = K_HPEV1 * A_HPEV1)
HPEV1 = HeatExchanger('HPEV1', pr1 = 1)
A_HPS1 = 2500 #[m^2]
K_HPS1 = 110 #[W/m^2-C]
#HPS1 = HeatExchanger('HPS1', pr1 = 1, kA = K_HPS1 * A_HPS1)
HPS1 = HeatExchanger('HPS1', pr1 = 1)
A_HPS2 = 175 #[m^2]
K_HPS2 = 200 #[W/m^2-C]
#HPS2 = HeatExchanger('HPS2', pr1 = 1, pr2 = 1, kA = K_HPS2 * A_HPS2)
HPS2 = HeatExchanger('HPS2', pr1 = 1, pr2 = 1)
HPDRUM = Drum('HP Drum')
condenser = SimpleHeatExchanger('condenser', pr = 1)
HE_cond = HeatExchanger('sweet water condenser', pr1 = 1, pr2 = 1)
### BUSES ###
from tespy.connections import Bus
powergen = Bus("electrical power output")
my_plant.add_busses(powergen)
powergen.add_comps(
{"comp": st_ext, "char": 1, "base": "component"},
{"comp": st_cond, "char": 1, "base": "component"},
{"comp": att_pump, "char": 1, "base": "bus"},
{"comp": cond_pump, "char": 1, "base": "bus"},
{"comp": sg_pump, "char": 1, "base": "bus"},
)
### CONNECTIONS ###
### DEFINITIONS ###
from tespy.connections import (Connection, Ref)
c01 = Connection(HPS2, 'out2', st_ext, 'in1', label = '1 - hp steam')
c02 = Connection(st_ext, 'out1', sp_1, 'in1', label = '2 - extraction st outlet')
c03 = Connection(sp_1, 'out2', me_1, 'in2', label = '3 - Steam from TV to attemp')
c04 = Connection(sp_1, 'out1', cond_st_cv, 'in1', label = '4 - cond st cv inlet')
c05 = Connection(cond_st_cv, 'out1', st_cond, 'in1', label = '5 - cond st inlet')
c06 = Connection(st_cond, 'out1', condenser, 'in1', label = '6 - condenser inlet')
c07 = Connection(condenser, 'out1', sp_2, 'in1', label = '7 - condenser outlet')
c08 = Connection(sp_2, 'out1', cond_pump, 'in1', label = '8 - cond pump inlet')
c09 = Connection(sp_2, 'out2', att_pump, 'in1', label = '9 - att pump inlet')
c10 = Connection(att_pump,'out1', me_1,'in1', label = '10 - att pump outlet')
c11 = Connection(me_1, 'out1',process_steam,'in1', label = '11 - process steam')
c12 = Connection(cond_pump,'out1', me_3, 'in1', label = '12 - cond pump outlet')
c13 = Connection(water_inlet_1, 'out1', me_3, 'in2', label = '13 - Condensate return from process')
c14 = Connection(water_inlet_2,'out1',me_3,'in3', label = '14 - Water makeup')
c15 = Connection(me_3,'out1', lp_pump,'in1', label = '15 - Water mixture feed to low pressure pump')
c16 = Connection(lp_pump,'out1', HE,'in2', label = '16 - Water mixture feed to heat exchanger')
c17 = Connection(HE,'out2', LPDRUM,'in1', label = '17 - heated water feed to LPDRUM')
c18 = Connection(HE,'out1', sg_pump,'in1', label = '18 - Cooled water feed to HP pump')
c19 = Connection(sg_pump, 'out1', sp_3,'in1', label = '19 - pressurized water to HPEC1')
c20 = Connection(sp_3, 'out1', me_4, 'in2', label = '20 - pressurized water to sg condenser')
c21 = Connection(sp_3, 'out2', HPEC1, 'in2', label = '21 - pressurized water to HPEC1')
c22 = Connection(HPEC1, 'out2', HPEC2, 'in2', label = '22 - pressurized water to HPEC2')
c23 = Connection(HPEC2, 'out2', me_4, 'in1', label = '23 - outlet of HPEC2 to merge with cold flow')
c24 = Connection(me_4, 'out1', HE_cond, 'in2', label = '24 - outlet of merge to sweet water condenser')
c25 = Connection(HE_cond, 'out2', HPEC3, 'in2', label = '25 - outlet of sweet water condenser to HPEC3')
c26 = Connection(HPEC3, 'out2', HPDRUM, 'in1', label = '26 - outlet of HPEC3 to HP drum')
c27 = Connection(HPDRUM, 'out1', bd_2, 'in1', label = '27 - saturated liquid outlet of HPDRUM to Splitter')
c28 = Connection(bd_2, 'out1', HPEV1, 'in2', label = '28 - saturated liquid outlet of HPDRUM to HPEV1')
c29 = Connection(bd_2, 'out2', wst_2, 'in1', label = '29 - saturated liquid outlet of HPDRUM to waste')
c30 = Connection(HPEV1, 'out2', HPDRUM, 'in2', label = '30 - saturated steam outlet of HPEV1 to HPDRUM')
c31 = Connection(HPDRUM, 'out2', sp_4 , 'in1', label = '31 - saturated steam outlet of HPDRUM')
c32 = Connection(sp_4, 'out1', HPS1, 'in2', label = '32 - saturated steam inlet to HPS1')
c33 = Connection(HPS1, 'out2', me_5, 'in1', label = '33 - Steam outlet of HPS1 to attemp')
c34 = Connection(sp_4, 'out2', HE_cond, 'in1', label = '34 - Steam derivation of HPDRUM to sweet water condenser')
c35 = Connection(HE_cond, 'out1', me_5, 'in2', label = '35 - Sweet water condenser outlet to attemp')
c36 = Connection(me_5, 'out1', HPS2, 'in2', label = '36 - Attemp outlet to HPS2')
c37 = Connection(LPDRUM,'out1', bd_1,'in1', label = '37 - Saturated liquid outlet of LPDRUM to HE')
c38 = Connection(bd_1, 'out1', HE, 'in1', label = '38 - LPDRUM saturated liquid outlet to HE')
c39 = Connection(bd_1, 'out2', LPEV1, 'in2', label = '39 - Saturated liquid inlet to LPEV1')
c40 = Connection(LPEV1, 'out2', LPDRUM, 'in2', label = '40 - Saturated steam inlet to LPDRUM')
c41 = Connection(LPDRUM, 'out2', wst, 'in1', label = '41 - Saturated steam outlet to vent')
c42 = Connection(turbine_exhaust, 'out1', HPS2, 'in1', label = '42 - Hot gases input to HPS2')
c43 = Connection(HPS2, 'out1', HPS1, 'in1', label = '43 - Hot gases input to HPS1')
c44 = Connection(HPS1, 'out1', HPEV1, 'in1', label = '44 - Hot gases input to HPEV1')
c45 = Connection(HPEV1, 'out1', HPEC3, 'in1', label = '45 - Hot gases input to HPEC3')
c46 = Connection(HPEC3, 'out1', HPEC2, 'in1', label = '46 - Hot gases input to HPEC2')
c47 = Connection(HPEC2, 'out1', LPEV1 , 'in1', label = '47 - Hot gases input to LPEV1')
c48 = Connection(LPEV1, 'out1', HPEC1 , 'in1', label = '48 - Hot gases input to HPEC1')
c49 = Connection(HPEC1, 'out1', gases_outlet , 'in1', label = '49 - Hot gases outlet')
my_plant.add_conns(c01, c02, c03, c04, c05, c06, c07, c08, c09, c10,
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
c31, c32, c33, c34, c35, c36, c37, c38, c39, c40,
c41, c42, c43, c44, c45, c46, c47, c48, c49)
### ATTRIBUTRES ###
t_0 = 17 #[C]
p_0 = 1.01325 #[bar(a)]
x_gh_CO2 = 0.061 #[dim]
x_gh_H2O = 0.07768 #[dim]
x_gh_N2 = 0.7364 #[dim]
x_gh_O2 = 0.1126 #[dim]
x_gh_Ar = 1 - x_gh_CO2 - x_gh_H2O - x_gh_N2 - x_gh_O2
p_gh = p_0
G_dot_gh = 481.98 * 2 #[tonne/h]
p_steam = 90 + p_0 #[bar(a)]
t_steam = 485 #[C]
G_dot_steam = 200 #[tonne/h]
purga = 0.01
p_mix_tank = 0 + p_0 #[bar(a)]
grado_sobrecalentamiento = 10 #[C]
t_cond = t_0 + 18 #[C]
G_dot_process_steam = 100 #[tonne/h]
p_process_steam = 12 + p_0 #[bar(a)]
retorno = 0.5
G_dot_process_cond = G_dot_process_steam * retorno
t_process_cond = 70 #[C]
c01.set_attr(m = G_dot_steam, fluid={'water': 1}, T = t_steam, p = p_steam)
import CoolProp.CoolProp as CP
p_sat = CP.PropsSI('P', 'T', t_cond + 273.15, 'Q', 0, 'Water') / 1e5 #[bar(a)]
c06.set_attr(p = p_sat)
c07.set_attr(x=0)
c11.set_attr(m = G_dot_process_steam, Td_bp = grado_sobrecalentamiento, p = p_process_steam)
c12.set_attr(p = p_mix_tank)
c13.set_attr(T = t_process_cond, m = G_dot_process_cond)
c14.set_attr(T = t_0)
c17.set_attr(T = 50)
c20.set_attr(m = 0)
c29.set_attr(m = Ref(c16, purga, 0))
c30.set_attr(x = 0.98)
c35.set_attr(x = 0)
c40.set_attr(x = 0.98)
c41.set_attr(m = 50 / 1000 * 2)
c42.set_attr(m = G_dot_gh, p = p_gh, fluid={'O2': x_gh_O2, 'N2': x_gh_N2, 'CO2': x_gh_CO2, 'water': x_gh_H2O, 'Ar': x_gh_Ar})
### GUESSES ###
c42.set_attr(T = 721.7, T0 = 721.7)
c43.set_attr(T = 694.9, T0 = 694.9)
c44.set_attr(T = 568.5, T0 = 568.5)
c45.set_attr(T = 313.4, T0 = 313.4)
c46.set_attr(T = 284.7, T0 = 284.7)
c47.set_attr(T = 228.6, T0 = 228.6)
c48.set_attr(T = 177.4, T0 = 177.4)
c49.set_attr(T0 = 154.6)
c01.set_attr(p0=91.01, T0=485.0, h0=3348.0, m0=200.01600000000002)
c02.set_attr(p0=13.01, T0=232.1, h0=2890.0, m0=200.01600000000002)
c03.set_attr(p0=13.01, T0=232.1, h0=2890.0, m0=97.236)
c04.set_attr(p0=13.01, T0=232.1, h0=2890.0, m0=102.78)
c05.set_attr(p0=11.06, T0=228.4, h0=2890.0, m0=102.78)
c06.set_attr(p0=0.05629, T0=35.0, h0=2161.0, m0=102.78)
c07.set_attr(p0=0.05629, T0=35.0, h0=146.6, m0=102.78)
c08.set_attr(p0=0.05629, T0=35.0, h0=146.6, m0=100.00800000000001)
c09.set_attr(p0=0.05629, T0=35.0, h0=146.6, m0=2.7702)
c10.set_attr(p0=13.01, T0=35.17, h0=148.5, m0=2.7702)
c11.set_attr(p0=13.01, T0=201.7, h0=2814.0, m0=100.00800000000001)
c12.set_attr(p0=1.013, T0=35.01, h0=146.8, m0=100.00800000000001)
c13.set_attr(p0=1.013, T0=70.0, h0=293.1, m0=50.004000000000005)
c14.set_attr(p0=1.013, T0=17.0, h0=71.45, m0=52.128)
c15.set_attr(p0=1.013, T0=39.03, h0=163.6, m0=202.104)
c16.set_attr(p0=1.634, T0=39.04, h0=163.6, m0=202.104)
c17.set_attr(p0=1.634, T0=50.0, h0=209.5, m0=202.104)
c18.set_attr(p0=1.634, T0=103.1, h0=432.2, m0=202.03199999999998)
c19.set_attr(p0=91.01, T0=104.7, h0=445.6, m0=202.03199999999998)
c20.set_attr(p0=91.01, T0=104.7, h0=445.6, m0=0.0)
c21.set_attr(p0=91.01, T0=104.7, h0=445.6, m0=202.03199999999998)
c22.set_attr(p0=91.01, T0=132.8, h0=564.2, m0=202.03199999999998)
c23.set_attr(p0=91.01, T0=201.7, h0=863.2, m0=202.03199999999998)
c24.set_attr(p0=91.01, T0=201.7, h0=863.2, m0=202.03199999999998)
c25.set_attr(p0=91.01, T0=263.9, h0=1154.0, m0=202.03199999999998)
c26.set_attr(p0=91.01, T0=293.6, h0=1308.0, m0=202.03199999999998)
c27.set_attr(p0=91.01, T0=304.1, h0=1368.0, m0=2090.1600000000003)
c28.set_attr(p0=91.01, T0=304.1, h0=1368.0, m0=2088.0)
c29.set_attr(p0=91.01, T0=304.1, h0=1368.0, m0=2.02104)
c30.set_attr(p0=91.01, T0=304.1, h0=1506.0, m0=2088.0)
c31.set_attr(p0=91.01, T0=304.1, h0=2741.0, m0=200.01600000000002)
c32.set_attr(p0=91.01, T0=304.1, h0=2741.0, m0=157.248)
c33.set_attr(p0=91.01, T0=620.7, h0=3684.0, m0=157.248)
c34.set_attr(p0=91.01, T0=304.1, h0=2741.0, m0=42.768)
c35.set_attr(p0=91.01, T0=304.1, h0=1368.0, m0=42.768)
c36.set_attr(p0=91.01, T0=425.1, h0=3189.0, m0=200.01600000000002)
c37.set_attr(p0=1.634, T0=113.9, h0=478.1, m0=447.84000000000003)
c38.set_attr(p0=1.634, T0=113.9, h0=478.1, m0=202.03199999999998)
c39.set_attr(p0=1.634, T0=113.9, h0=478.1, m0=245.70000000000002)
c40.set_attr(p0=1.634, T0=113.9, h0=700.0, m0=245.70000000000002)
c41.set_attr(p0=1.634, T0=113.9, h0=2697.0, m0=0.100008)
### SOLVING AND PRINTING ###
my_plant.solve(mode='design')
results = my_plant.results['Connection']
results = results[[
'p',
'T',
'h',
's',
'x',
'm'
]].copy()
results.columns = ['p [bar(a)]', 't [°C]', 'h [kJ/kg]',
's [kJ/kg-K]', 'x [dim]', 'm [t/h]']
from tabulate import tabulate
columns_to_format = ['p [bar(a)]', 't [°C]', 'h [kJ/kg]', 's [kJ/kg-K]', 'x [dim]', 'm [t/h]']
results[columns_to_format] = results[columns_to_format].apply(
lambda col: col.apply(lambda x: f"{x:.2f}" if isinstance(x, (int, float)) else x)
)
print(tabulate(results, headers='keys', tablefmt='fancy_grid', numalign='right', stralign='center'))
my_plant.print_results()
|
Beta Was this translation helpful? Give feedback.
-
Firstly, there are a lot of guesses in the code. They were read from an Excel file generated with EES, where we had solved the model (with a simple script, we could read the file and generate a .txt with the equations). This was because we originally worked with EES, and we needed to understand which inputs were required. This wasn't simple at all. As stated, the original idea was to provide all the kA values. Moreover, we intended to provide both the heat exchanger areas (obtained from the manufacturer's data) and some general k values (which were estimated, though I could find the actual values in a past work of mine). Although we still need to compare the results with the manufacturer's data, the agreement between EES and TESPy is an excellent sign. The set of inputs is quite reasonable. If kA values are provided, they represent the size of each heat exchanger. The temperature at state 17 corresponds to the plate heat exchanger. These values (kA ones) were not set as inputs due to some convergence issues. We will continue analyzing this. But to summarize, we provided the flue gas temperature at every stage. Considering pinch and approach points, both are ways of defining the flue gas temperature, so this approach is not unusual. It is unclear whether the design process should start with boiler areas. I'd say it starts with steam and gas temperatures. The steam pressure is controlled by the supplementary firing loop, which is not represented in the model. This steam pressure acts as a setpoint in a control loop and serves as a proxy for steam production. The flue gas inlet temperature is a consequence of this firing. The steam temperature is a setpoint in the attemperation loop, which is controlled by a valve in that branch (not represented in the model). Obviously, our model would have issues if the pressure ratio in the superheater were not 1. However, we stopped at this level of complexity for simplicity, as our original goal was to understand TESPy to facilitate migration from EES. In this regard, TESPy is extremely useful, as it eliminates the need to repeatedly state the same equations. Moreover, while writing the model in EES, I had to check the TESPy documentation for the drum component to confirm whether a first-law balance was required, which reinforces that solving such models in EES is unnecessary—TESPy makes the process significantly faster. The main steam flow is a fixed input because we are not providing details about the steam turbine inlet control valve or the turbine size. Therefore, this flow is not actually a setpoint. The process steam flow is provided as an input since it is controlled by the steam turbine’s extraction control valve (which is not modeled). The real steam turbine governor can control two parameters, such as power and extraction pressure, frequency and extraction pressure, inlet pressure and extraction pressure, etc. The process steam and process condensate are inputs that are not directly related to our plant. Rather, they are boundary conditions, just like the flue gas flow. The process steam temperature is controlled by the attemperation loop. The boiler has an economizer bypass to reduce performance. However, we are not using it, as off-design data would be required first. Since we already had a lot of work to develop this model, we will stop here for now. The plate heat exchanger is intended to improve performance, though I am not entirely sure if it actually does. I have conducted some parametric studies, and the results are inconclusive. To develop this model, we started with a simpler boiler, excluding all its control loops. Then, we used results from this simpler model as initial guesses to aid convergence. Attached is the EES file with its results. The T-Q diagram for the boiler is: The PFD is Here There are some equations from Ganapathy to account for HRSG partial load. We are not sure whether we will implement them in TESPy, perhaps only in EES. In conclusion, we are quite satisfied with our progress in learning TESPy, even though we are only using a small portion of its capabilities. We will continue studying it. Personally, I find that it saves a lot of time and, more importantly, helps prevent errors and missing equations. I would be happy to collaborate in turning this example into a tutorial or similar resource. Please feel free to contact me (Pablo) if anyone is interested in this work to discuss details. I'll also work in a tespy file of a simple HRSG, solving 1st law and mass balances starting with pinch and approach values. The simpler model for a one-pressure boiler. When it's done, it will be posted in this forum. Thanks! PS: Apologies for mixing Spanish and (bad) English in the code. We'll correct these for the final version of this work, which will be presented at our university. PS 2: Another important benefit of using tespy is that Copilot (which is provided by our university) really helped when coding. Interesting suggestions, and quickly learnt some repetitive patterns in the code, and autocompleted a lot and always pretty accurately. |
Beta Was this translation helpful? Give feedback.
Firstly, there are a lot of guesses in the code. They were read from an Excel file generated with EES, where we had solved the model (with a simple script, we could read the file and generate a .txt with the equations). This was because we originally worked with EES, and we needed to understand which inputs were required. This wasn't simple at all.
As stated, the original idea was to provide all the kA values. Moreover, we intended to provide both the heat exchanger areas (obtained from the manufacturer's data) and some general k values (which were estimated, though I could find the actual values in a past work of mine). Although we still need to compare the results with the manufacturer'…