1 |
# -*- coding: utf8 -*- |
2 |
import extpy, sys |
3 |
from solverreporter import * |
4 |
|
5 |
import sys, os, os.path |
6 |
sys.path.append(os.path.expanduser("~/ascend/models/johnpye/fprops/python")) |
7 |
import fprops |
8 |
|
9 |
try: |
10 |
from pylab import * |
11 |
except: |
12 |
pass |
13 |
|
14 |
#--- for (T,s) plots --- |
15 |
|
16 |
def sat_curve(d): |
17 |
Tt = d.T_t |
18 |
Tc = d.T_c |
19 |
TT = [] |
20 |
pp = [] |
21 |
ssf = [] |
22 |
ssg = [] |
23 |
for T in linspace(Tt,Tc,100): |
24 |
res,p,rf,rg = fprops.fprops_sat_T(T,d) |
25 |
if not res: |
26 |
TT.append(T - 273.15) |
27 |
pp.append(p) |
28 |
ssf.append(fprops.helmholtz_s_raw(T,rf,d)/1.e3) |
29 |
ssg.append(fprops.helmholtz_s_raw(T,rg,d)/1.e3) |
30 |
plot(ssf,TT,"b--") |
31 |
plot(ssg,TT,"r--") |
32 |
|
33 |
class TSPoint: |
34 |
def __init__(self,T,s): |
35 |
self.T = T |
36 |
self.s = s |
37 |
|
38 |
def write(msg): |
39 |
extpy.getbrowser().reporter.reportNote(msg) |
40 |
|
41 |
def pconst(S1,S2,n): |
42 |
"""Return a set of (T,s) points between two states, with pressure held constant.""" |
43 |
D = fprops.fprops_fluid(str(S1.cd.component.getSymbolValue())) |
44 |
out = [] |
45 |
hh = linspace(float(S1.h), float(S2.h), n) |
46 |
for h in hh: |
47 |
res, T, rho = fprops.fprops_solve_ph(float(S1.p), h, 0, D) |
48 |
if not res: |
49 |
out += [TSPoint(T,fprops.helmholtz_s(T,rho,D))] |
50 |
return out |
51 |
|
52 |
|
53 |
def plot_Ts(SS,style='b-'): |
54 |
xx = [] |
55 |
yy = [] |
56 |
for S in SS: |
57 |
yy.append(float(S.T) - 273.15) |
58 |
xx.append(float(S.s)/1.e3) |
59 |
plot(xx,yy,style) |
60 |
|
61 |
#--- for (T,H) plots --- |
62 |
|
63 |
class THPoint: |
64 |
def __init__(self,T,h,mdot = 1.): |
65 |
self.T = T |
66 |
self.h = h |
67 |
self.mdot = mdot |
68 |
|
69 |
def pconsth(S1,S2,n): |
70 |
"""Return a set of (T,H) points between two states, with pressure constant""" |
71 |
D = fprops.fprops_fluid(str(S1.cd.component.getSymbolValue())) |
72 |
out = [] |
73 |
hh = linspace(float(S1.h), float(S2.h), n) |
74 |
mdot = float(S1.mdot) |
75 |
for h in hh: |
76 |
res, T, rho = fprops.fprops_solve_ph(float(S1.p), h, 0, D) |
77 |
if not res: |
78 |
out += [THPoint(T,h * mdot)] |
79 |
return out |
80 |
|
81 |
def plot_TH(SS,style='b-',Href = 0): |
82 |
xx = [] |
83 |
yy = [] |
84 |
for S in SS: |
85 |
yy.append(float(S.T) - 273.15) |
86 |
xx.append(((float(S.h)*float(S.mdot)) - Href)/1.e6) |
87 |
plot(xx,yy,style) |
88 |
|
89 |
#--- various Rankine cycle configurations --- |
90 |
|
91 |
def cycle_plot_rankine(self): |
92 |
"""Plot T-s diagram for a simple Rankine cycle""" |
93 |
import loading |
94 |
loading.load_matplotlib(throw=True) |
95 |
ioff() |
96 |
figure() |
97 |
hold(1) |
98 |
D = fprops.fprops_fluid(str(self.cd.component.getSymbolValue())) |
99 |
sat_curve(D) |
100 |
|
101 |
boiler_curve = pconst(self.BO.inlet, self.BO.outlet,100) |
102 |
condenser_curve = pconst(self.CO.inlet,self.CO.outlet,100) |
103 |
SS = [self.PU.outlet, self.BO.inlet] + boiler_curve + [self.TU.inlet, self.TU.outlet] + condenser_curve + [self.CO.outlet, self.PU.outlet] |
104 |
plot_Ts(SS) |
105 |
|
106 |
title(unicode(r"Rankine cycle with %s" % D.name)) |
107 |
ylabel(unicode(r"T / [��C]")) |
108 |
xlabel("s / [kJ/kg/K]") |
109 |
|
110 |
extpy.getbrowser().reporter.reportNote("Plotting completed") |
111 |
ion() |
112 |
show() |
113 |
|
114 |
|
115 |
def cycle_plot_rankine_regen2(self): |
116 |
"""Plot T-s diagram for a regenerative Rankine cycle (bleed steam regen)""" |
117 |
import loading |
118 |
loading.load_matplotlib(throw=True) |
119 |
ioff() |
120 |
figure() |
121 |
hold(1) |
122 |
D = fprops.fprops_fluid(str(self.cd.component.getSymbolValue())) |
123 |
sat_curve(D) |
124 |
|
125 |
boiler_curve = pconst(self.BO.inlet, self.BO.outlet,100) |
126 |
condenser_curve = pconst(self.CO.inlet,self.CO.outlet,100) |
127 |
|
128 |
SS = [self.PU1.inlet, self.PU1.outlet] + \ |
129 |
pconst(self.HE.inlet, self.HE.outlet, 100) + \ |
130 |
[self.PU2.inlet, self.PU2.outlet] + \ |
131 |
boiler_curve + \ |
132 |
[self.TU1.inlet, self.TU1.outlet, self.TU2.outlet] + \ |
133 |
condenser_curve + [self.PU1.inlet] |
134 |
|
135 |
plot_Ts(SS) |
136 |
plot_Ts( |
137 |
[self.PU1.inlet, self.PU1.outlet, self.HE.inlet, self.HE.outlet, |
138 |
self.PU2.inlet, self.PU2.outlet, self.TU1.inlet, self.TU1.outlet, |
139 |
self.TU2.outlet, self.PU1.inlet] |
140 |
,'bo' |
141 |
) |
142 |
|
143 |
# line for the heat exchanger |
144 |
plot_Ts(pconst(self.HE.inlet_heat, self.HE.outlet,100),'b-') |
145 |
|
146 |
title(unicode(r"Regenerative Rankine cycle with %s" % D.name)) |
147 |
ylabel(unicode(r"T / [��C]")) |
148 |
xlabel("s / [kJ/kg/K]") |
149 |
|
150 |
extpy.getbrowser().reporter.reportNote("Plotting completed") |
151 |
ion() |
152 |
show() |
153 |
savefig(os.path.expanduser("~/Desktop/regen2.eps")) |
154 |
|
155 |
|
156 |
|
157 |
def cycle_plot_rankine_regen1(self): |
158 |
"""Plot T-s diagram for a regenerative Rankine cycle""" |
159 |
import loading |
160 |
loading.load_matplotlib(throw=True) |
161 |
ioff() |
162 |
figure() |
163 |
hold(1) |
164 |
D = fprops.fprops_fluid(str(self.cd.component.getSymbolValue())) |
165 |
sat_curve(D) |
166 |
|
167 |
boiler_curve = pconst(self.BO.inlet, self.BO.outlet,100) |
168 |
condenser_curve = pconst(self.CO.inlet,self.CO.outlet,100) |
169 |
he_hot = pconst(self.HE.inlet_heat, self.HE.outlet_heat,100) |
170 |
he_cold = pconst(self.HE.inlet, self.HE.outlet,100) |
171 |
|
172 |
SS = [self.PU.outlet] + he_cold + [self.BO.inlet] + boiler_curve + [self.TU.inlet, self.TU.outlet] + he_hot + condenser_curve + [self.PU.inlet, self.PU.outlet] |
173 |
|
174 |
plot_Ts(SS) |
175 |
plot_Ts( |
176 |
[self.PU.outlet,self.BO.inlet,self.TU.inlet, self.TU.outlet |
177 |
,self.HE.outlet_heat, self.PU.inlet, self.PU.outlet] |
178 |
,'bo' |
179 |
) |
180 |
|
181 |
# dotted lines for the heat exchanger |
182 |
plot_Ts([self.HE.inlet_heat, self.HE.outlet],'b:') |
183 |
plot_Ts([self.HE.outlet_heat, self.HE.inlet],'b:') |
184 |
|
185 |
title(unicode(r"Regenerative Rankine cycle with %s" % D.name)) |
186 |
ylabel(unicode(r"T / [��C]")) |
187 |
xlabel("s / [kJ/kg/K]") |
188 |
|
189 |
extpy.getbrowser().reporter.reportNote("Plotting completed") |
190 |
ion() |
191 |
show() |
192 |
savefig(os.path.expanduser("~/Desktop/regen1.eps")) |
193 |
|
194 |
|
195 |
#--- heat exchange (T,H) plot --- |
196 |
|
197 |
def heater_closed_plot(self): |
198 |
"""Plot T-H diagram of heat transfer in a heater_closed model""" |
199 |
import loading |
200 |
loading.load_matplotlib(throw=True) |
201 |
ioff() |
202 |
figure() |
203 |
hold(1) |
204 |
D = fprops.fprops_fluid(str(self.cd.component.getSymbolValue())) |
205 |
HE = self.HE |
206 |
|
207 |
extpy.getbrowser().reporter.reportNote("Fluid is %s" % D.name) |
208 |
|
209 |
plot_TH(pconsth(HE.inlet_heat, HE.outlet_heat, 50),'r-', |
210 |
Href = (float(HE.outlet_heat.h)*float(HE.outlet_heat.mdot))\ |
211 |
) |
212 |
|
213 |
plot_TH(pconsth(HE.inlet, HE.outlet, 50),'b-', |
214 |
Href = (float(HE.inlet.h)*float(HE.inlet.mdot))\ |
215 |
) |
216 |
|
217 |
title(unicode(r"Closed feedwater heater with %s" % D.name)) |
218 |
ylabel(unicode(r"T / [��C]")) |
219 |
xlabel("H / [MW]") |
220 |
|
221 |
extpy.getbrowser().reporter.reportNote("Plotting completed") |
222 |
ion() |
223 |
show() |
224 |
savefig(os.path.expanduser("~/Desktop/heater_closed.eps")) |
225 |
|
226 |
#--- the big one: a combined-cycle GT --- |
227 |
|
228 |
def cycle_plot_ccgt(self): |
229 |
"""Plot T-s diagram for combined-cycle gas turbine""" |
230 |
import loading |
231 |
loading.load_matplotlib(throw=True) |
232 |
ioff() |
233 |
figure() |
234 |
|
235 |
D = fprops.fprops_fluid(str(self.cd_rankine.component.getSymbolValue())) |
236 |
|
237 |
# plot gas turbine cycle |
238 |
SS = [self.GC.inlet, self.GC.outlet, self.GT.inlet, self.GT.outlet, self.HE.inlet, self.HE.outlet, self.GC.inlet] |
239 |
plot_Ts(SS,'g-') |
240 |
plot_Ts(SS,'go') |
241 |
hold(1) |
242 |
|
243 |
sat_curve(D) |
244 |
|
245 |
boiler_curve = pconst(self.HE.inlet_cold,self.HE.outlet_cold,100) |
246 |
condenser_curve = pconst(self.CO.inlet,self.CO.outlet,100) |
247 |
SS2 = [self.PU.outlet, self.HE.inlet_cold] + boiler_curve + [self.HE.outlet_cold, self.TU.inlet, self.TU.outlet, self.CO.inlet] + condenser_curve + [self.CO.outlet, self.PU.inlet, self.PU.outlet] |
248 |
plot_Ts(SS2) |
249 |
plot_Ts([self.PU.outlet, self.HE.inlet_cold,self.HE.outlet_cold, self.TU.inlet, self.TU.outlet, self.CO.inlet,self.CO.outlet, self.PU.inlet, self.PU.outlet],'bo') |
250 |
|
251 |
title(unicode(r"Combined cycle with air and %s" % D.name)) |
252 |
ylabel(unicode(r"T / [��C]")) |
253 |
xlabel("s / [kJ/kg/K]") |
254 |
|
255 |
extpy.getbrowser().reporter.reportNote("Plotting completed") |
256 |
ion() |
257 |
show() |
258 |
savefig(os.path.expanduser("~/Desktop/ccgt.eps")) |
259 |
savefig(os.path.expanduser("~/Desktop/ccgt.png")) |
260 |
|
261 |
|
262 |
#--- simple gas turbine models --- |
263 |
|
264 |
def cycle_plot_brayton_regen(self): |
265 |
"""Plot T-s diagran for regenerative gas turbine""" |
266 |
import loading |
267 |
loading.load_matplotlib(throw=True) |
268 |
ioff() |
269 |
figure() |
270 |
|
271 |
# plot gas turbine cycle |
272 |
SS = [self.CO.inlet, self.CO.outlet, self.RE.inlet, self.RE.outlet, self.BU.inlet,self.BU.outlet, self.TU.inlet, self.TU.outlet,self.RE.inlet_hot, self.RE.outlet_hot, self.DI.inlet, self.DI.outlet,self.CO.inlet] |
273 |
plot_Ts(SS,'g-') |
274 |
plot_Ts(SS,'go') |
275 |
hold(1) |
276 |
|
277 |
title(unicode(r"Regenerative Brayton cycle")) |
278 |
ylabel(unicode(r"T / [��C]")) |
279 |
xlabel("s / [kJ/kg/K]") |
280 |
|
281 |
extpy.getbrowser().reporter.reportNote("Plotting completed") |
282 |
ion() |
283 |
show() |
284 |
savefig(os.path.expanduser("~/Desktop/brayton_regen.eps")) |
285 |
|
286 |
#--- air-to-stream heat exchanger plot --- |
287 |
|
288 |
def air_stream_heat_exchanger_plot(self): |
289 |
"""Plot T-H diagram of heat transfer in a heater_closed model""" |
290 |
import loading |
291 |
loading.load_matplotlib(throw=True) |
292 |
ioff() |
293 |
figure() |
294 |
hold(1) |
295 |
D = fprops.fprops_fluid(str(self.cd_cold.component.getSymbolValue())) |
296 |
|
297 |
n = self.n.getIntValue() |
298 |
extpy.getbrowser().reporter.reportNote("Fluid is %s" % D.name) |
299 |
|
300 |
# hot side is the air, calculated in the model |
301 |
plot_TH( [self.H[i] for i in range(1+int(n))],'r-',\ |
302 |
Href = (float(self.outlet.h)*float(self.outlet.mdot))\ |
303 |
) |
304 |
|
305 |
plot_TH(pconsth(self.inlet_cold, self.outlet_cold, 50),'b-', |
306 |
Href = (float(self.inlet_cold.h)*float(self.inlet_cold.mdot))\ |
307 |
) |
308 |
|
309 |
title(unicode(r"Combined-cycle air-%s heat exchanger" % D.name)) |
310 |
ylabel(unicode(r"T / [��C]")) |
311 |
xlabel("H / [MW]") |
312 |
|
313 |
extpy.getbrowser().reporter.reportNote("Plotting completed") |
314 |
ion() |
315 |
show() |
316 |
savefig(os.path.expanduser("~/Desktop/air_strea_heatex.eps")) |
317 |
|
318 |
|
319 |
extpy.registermethod(cycle_plot_rankine) |
320 |
extpy.registermethod(cycle_plot_rankine_regen1) |
321 |
extpy.registermethod(cycle_plot_rankine_regen2) |
322 |
extpy.registermethod(cycle_plot_brayton_regen) |
323 |
extpy.registermethod(cycle_plot_ccgt) |
324 |
|
325 |
extpy.registermethod(heater_closed_plot) |
326 |
extpy.registermethod(air_stream_heat_exchanger_plot) |
327 |
|
328 |
#the above method can be called using "EXTERNAL fourbarplot(SELF)" in ASCEND. |