1 |
REQUIRE "johnpye/fprops/rankine_fprops.a4c"; |
2 |
|
3 |
(*------------------------------------------------------------------------------ |
4 |
REGENERATIVE RANKINE CYCLE |
5 |
*) |
6 |
(* |
7 |
Add a boiler feedwater heater and two-stage turbine. |
8 |
*) |
9 |
MODEL rankine_regen_water; |
10 |
|
11 |
BO IS_A boiler_simple; |
12 |
TU1 IS_A turbine_simple; |
13 |
BL IS_A tee; (* bleed *) |
14 |
TU2 IS_A turbine_simple; |
15 |
CO IS_A condenser_simple; |
16 |
HE IS_A heater_open; |
17 |
PU1 IS_A pump_simple; |
18 |
PU2 IS_A pump_simple; |
19 |
|
20 |
BO.cd.component :== 'water'; |
21 |
BO.cd.type :== 'pengrob'; |
22 |
|
23 |
(* main loop *) |
24 |
BO.outlet, TU1.inlet ARE_THE_SAME; |
25 |
TU1.outlet, BL.inlet ARE_THE_SAME; |
26 |
BL.outlet, TU2.inlet ARE_THE_SAME; |
27 |
TU2.outlet, CO.inlet ARE_THE_SAME; |
28 |
CO.outlet, PU1.inlet ARE_THE_SAME; |
29 |
PU1.outlet, HE.inlet ARE_THE_SAME; |
30 |
HE.outlet, PU2.inlet ARE_THE_SAME; |
31 |
PU2.outlet, BO.inlet ARE_THE_SAME; |
32 |
|
33 |
(* bleed stream *) |
34 |
BL.outlet_branch, HE.inlet_heat ARE_THE_SAME; |
35 |
phi ALIASES BL.phi; |
36 |
p_bleed ALIASES TU1.outlet.p; |
37 |
|
38 |
p_bleed_ratio IS_A fraction; |
39 |
p_bleed_ratio * (TU1.inlet.p - TU2.outlet.p) = (TU1.outlet.p - TU2.outlet.p); |
40 |
|
41 |
mdot ALIASES BO.mdot; |
42 |
cd ALIASES BO.inlet.cd; |
43 |
|
44 |
T_H ALIASES BO.outlet.T; |
45 |
T_C ALIASES CO.outlet.T; |
46 |
|
47 |
eta IS_A fraction; |
48 |
eta_eq:eta * (BO.Qdot_fuel) = TU1.Wdot + TU2.Wdot + PU1.Wdot + PU2.Wdot; |
49 |
|
50 |
Wdot_TU1 ALIASES TU1.Wdot; |
51 |
Wdot_TU2 ALIASES TU2.Wdot; |
52 |
Wdot_PU1 ALIASES PU1.Wdot; |
53 |
Wdot_PU2 ALIASES PU2.Wdot; |
54 |
Qdot_fuel ALIASES BO.Qdot_fuel; |
55 |
|
56 |
eta_carnot IS_A fraction; |
57 |
eta_carnot_eq: eta_carnot = 1 - T_C / T_H; |
58 |
|
59 |
eta_turb_tot IS_A fraction; |
60 |
TU_out_is IS_A stream_state; |
61 |
TU_out_is.cd, TU1.inlet.cd ARE_THE_SAME; |
62 |
TU_out_is.p, TU2.outlet.p ARE_THE_SAME; |
63 |
TU_out_is.s, TU1.inlet.s ARE_THE_SAME; |
64 |
eta_turb_eq:eta_turb_tot * (TU1.inlet.h - TU_out_is.h) = (TU1.inlet.h - TU2.outlet.h); |
65 |
|
66 |
(* some checking output... *) |
67 |
|
68 |
phi_weston IS_A fraction; |
69 |
phi_weston_eq:phi_weston * (TU1.outlet.h - PU1.outlet.h) = (PU2.inlet.h - PU1.outlet.h); |
70 |
phi_eq:phi_weston = phi; |
71 |
|
72 |
q_a IS_A specific_energy; |
73 |
q_a_eq: q_a = TU1.inlet.h - PU2.outlet.h; |
74 |
|
75 |
Wdot IS_A energy_rate; |
76 |
Wdot_eq: Wdot = TU1.Wdot + TU2.Wdot + PU1.Wdot + PU2.Wdot; |
77 |
|
78 |
cons_en: HE.inlet.mdot * HE.inlet.h + HE.inlet_heat.mdot * HE.inlet_heat.h = HE.outlet.mdot * HE.outlet.h; |
79 |
|
80 |
x_turb_out ALIASES TU2.outlet.x; |
81 |
METHODS |
82 |
METHOD default_self; |
83 |
RUN BO.default_self; |
84 |
RUN TU1.default_self; |
85 |
RUN TU2.default_self; |
86 |
RUN CO.default_self; |
87 |
RUN PU1.default_self; |
88 |
RUN PU2.default_self; |
89 |
BO.outlet.h := 4000 {kJ/kg}; |
90 |
p_bleed := 37 {bar}; |
91 |
TU1.outlet.h := 2300 {kJ/kg}; |
92 |
BL.cons_mass.included := FALSE; |
93 |
(*HE.cons_mass.included := FALSE;*) |
94 |
HE.cons_en.included := FALSE; |
95 |
cons_en.included := FALSE; |
96 |
HE.inlet.v := 100 {m^3/kg}; |
97 |
HE.inlet.p.nominal := 40 {bar}; |
98 |
HE.inlet.v.nominal := 1 {L/kg}; |
99 |
HE.inlet.h.nominal := 100 {kJ/kg}; |
100 |
END default_self; |
101 |
METHOD solarpaces2010; |
102 |
RUN ClearAll; |
103 |
RUN default_self; |
104 |
(* component efficiencies *) |
105 |
FIX BO.eta; BO.eta := 1.0; |
106 |
FIX TU1.eta; TU1.eta := 0.85; |
107 |
FIX TU2.eta; TU2.eta := 0.85; |
108 |
FIX PU1.eta; PU1.eta := 0.8; |
109 |
FIX PU2.eta; PU2.eta := 0.8; |
110 |
FIX Wdot; Wdot := 100 {MW}; |
111 |
(* |
112 |
(* FIX CO.outlet.p; CO.outlet.p := 10 {kPa};*) |
113 |
FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K}; |
114 |
FIX CO.outlet.x; CO.outlet.x := 1e-6; |
115 |
FIX PU1.outlet.p; PU1.outlet.p := 7 {bar}; |
116 |
FIX PU2.outlet.p; PU2.outlet.p := 150 {bar}; |
117 |
PU2.outlet.p.upper_bound := 150 {bar}; |
118 |
FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K}; |
119 |
*) |
120 |
(* turbine conditions *) |
121 |
FIX TU1.inlet.p; TU1.inlet.p := 150 {bar}; |
122 |
FIX TU1.inlet.T; TU1.inlet.T := 580 {K} + 273.15 {K}; |
123 |
FIX TU1.outlet.p; TU1.outlet.p := 10.3 {bar}; |
124 |
FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K}; |
125 |
(* heater conditions *) |
126 |
TU2.outlet.p := 10 {kPa}; |
127 |
(* FIX HE.outlet.p; HE.outlet.p := 0.7 {MPa}; *) |
128 |
FIX CO.outlet.x; CO.outlet.x := 1e-6; |
129 |
FIX HE.outlet.x; HE.outlet.x := 1e-6; |
130 |
END solarpaces2010; |
131 |
METHOD on_load; |
132 |
RUN solarpaces2010; |
133 |
(* |
134 |
This model needs to be solved using QRSlv with convopt set to 'RELNOMSCALE'. |
135 |
*) |
136 |
SOLVER QRSlv; |
137 |
OPTION convopt 'RELNOM_SCALE'; |
138 |
OPTION iterationlimit 400; |
139 |
END on_load; |
140 |
METHOD set_x_limit_correct_turb; |
141 |
FREE PU2.outlet.p; |
142 |
PU2.outlet.p.upper_bound := 150 {bar}; |
143 |
FIX TU2.outlet.x; TU2.outlet.x := 0.9; |
144 |
(* a little corrctn to ensure we're comparing the same *overall* turbine eff *) |
145 |
FREE TU1.eta; |
146 |
TU2.eta := 0.823; |
147 |
FIX eta_turb_tot; eta_turb_tot := 0.85; |
148 |
END set_x_limit_correct_turb; |
149 |
METHOD cycle_plot; |
150 |
EXTERNAL cycle_plot_rankine_regen2(SELF); |
151 |
END cycle_plot; |
152 |
METHOD moran_ex_8_5; |
153 |
RUN default_self; |
154 |
(* |
155 |
This is Example 8.5 from Moran and Shapiro, 'Fundamentals of |
156 |
Engineering Thermodynamics', 4th Ed. |
157 |
*) |
158 |
RUN ClearAll; |
159 |
(* component efficiencies *) |
160 |
FIX BO.eta; BO.eta := 1.0; |
161 |
FIX TU1.eta; TU1.eta := 0.85; |
162 |
FIX TU2.eta; TU2.eta := 0.85; |
163 |
FIX PU1.eta; PU1.eta := 1.0; |
164 |
FIX PU2.eta; PU2.eta := 1.0; |
165 |
(* turbine conditions *) |
166 |
FIX TU1.inlet.p; TU1.inlet.p := 8. {MPa}; |
167 |
FIX TU1.inlet.T; TU1.inlet.T := 480 {K} + 273.15 {K}; |
168 |
FIX TU1.outlet.p; TU1.outlet.p := 0.7 {MPa}; |
169 |
FIX TU2.outlet.p; TU2.outlet.p := 0.008 {MPa}; |
170 |
(* heater conditions *) |
171 |
(* FIX HE.outlet.p; HE.outlet.p := 0.7 {MPa}; *) |
172 |
FIX CO.outlet.x; CO.outlet.x := 0.0001; |
173 |
FIX HE.outlet.x; HE.outlet.x := 0.0001; |
174 |
FIX Wdot; Wdot := 100 {MW}; |
175 |
END moran_ex_8_5; |
176 |
METHOD self_test; |
177 |
(* solution values to the Moran & Shapiro example 8.5 problem *) |
178 |
ASSERT abs(eta - 0.369) < 0.001; |
179 |
ASSERT abs((TU1.Wdot+TU2.Wdot)/mdot - 984.4{kJ/kg}) < 1 {kJ/kg}; |
180 |
ASSERT abs(mdot - 3.69e5 {kg/h}) < 0.05e5 {kg/h}; |
181 |
ASSERT abs(CO.inlet.h - 2249.3 {kJ/kg}) < 1.0 {kJ/kg}; |
182 |
END self_test; |
183 |
METHOD weston_ex_2_6; |
184 |
(* |
185 |
The scenario here is example 2.6 from K Weston (op. cit.), p. 55. |
186 |
*) |
187 |
RUN ClearAll; |
188 |
|
189 |
(* all ideal components *) |
190 |
FIX BO.eta; BO.eta := 1.0; |
191 |
FIX TU1.eta; TU1.eta := 1.0; |
192 |
FIX TU2.eta; TU2.eta := 1.0; |
193 |
FIX PU1.eta; PU1.eta := 1.0; |
194 |
FIX PU2.eta; PU2.eta := 1.0; |
195 |
|
196 |
(* mass flow rate is arbitrary *) |
197 |
FIX mdot; |
198 |
mdot := 10 {kg/s}; |
199 |
|
200 |
(* max pressure constraint *) |
201 |
FIX PU2.outlet.p; |
202 |
PU2.outlet.p := 2000 {psi}; |
203 |
PU2.outlet.h := 1400 {btu/lbm}; (* guess *) |
204 |
|
205 |
(* boiler max temp *) |
206 |
FIX BO.outlet.T; |
207 |
BO.outlet.T := 1460 {R}; |
208 |
BO.outlet.h := 1400 {btu/lbm}; (* guess *) |
209 |
|
210 |
(* intermediate temperature setting *) |
211 |
FIX TU1.outlet.p; |
212 |
TU1.outlet.p := 200 {psi}; |
213 |
(* FIX TU1.outlet.T; |
214 |
TU1.outlet.T := 860 {R}; (* 400 °F *) |
215 |
TU1.outlet.h := 3000 {kJ/kg}; (* guess *) *) |
216 |
|
217 |
(* minimum pressure constraint *) |
218 |
FIX CO.outlet.p; |
219 |
CO.outlet.p := 1 {psi}; |
220 |
|
221 |
(* condenser outlet is saturated liquid *) |
222 |
FIX CO.outlet.h; |
223 |
CO.outlet.h := 69.73 {btu/lbm}; |
224 |
|
225 |
(* remove the redundant balance equations *) |
226 |
HE.cons_mass.included := TRUE; |
227 |
HE.cons_en.included := TRUE; |
228 |
BL.cons_mass.included := FALSE; |
229 |
phi_weston_eq.included := TRUE; |
230 |
phi_eq.included := FALSE; |
231 |
cons_en.included := FALSE; |
232 |
|
233 |
(* fix the bleed ratio *) |
234 |
FIX BL.phi; |
235 |
BL.phi := 0.251; |
236 |
|
237 |
(* FIX BL.outlet.h; |
238 |
BL.outlet.h := 355.5 {btu/lbm}; *) |
239 |
|
240 |
(** |
241 |
these values seem to be from another problem, need to check which ... |
242 |
ASSERT abs(TU1.inlet.s - 1.5603 {btu/lbm/R}) < 0.01 {btu/lbm/R}; |
243 |
ASSERT abs(TU1.outlet.s - 1.5603 {btu/lbm/R}) < 0.01 {btu/lbm/R}; |
244 |
ASSERT abs(TU2.outlet.s - 1.5603 {btu/lbm/R}) < 0.01 {btu/lbm/R}; |
245 |
ASSERT abs(PU1.inlet.s - 0.1326 {btu/lbm/R}) < 0.001 {btu/lbm/R}; |
246 |
ASSERT abs(PU1.outlet.s - 0.1326 {btu/lbm/R}) < 0.002 {btu/lbm/R}; |
247 |
ASSERT abs(PU2.inlet.s - 0.5438 {btu/lbm/R}) < 0.002 {btu/lbm/R}; |
248 |
ASSERT abs(PU2.outlet.s - 0.5438 {btu/lbm/R}) < 0.002 {btu/lbm/R}; |
249 |
|
250 |
ASSERT abs(TU1.inlet.h - 1474.1 {btu/lbm}) < 1.5 {btu/lbm}; |
251 |
ASSERT abs(TU1.outlet.h - 1210.0 {btu/lbm}) < 1.5 {btu/lbm}; |
252 |
ASSERT abs(TU2.outlet.h - 871.0 {btu/lbm}) < 1.5 {btu/lbm}; |
253 |
ASSERT abs(PU1.inlet.h - 69.73 {btu/lbm}) < 0.001 {btu/lbm}; |
254 |
ASSERT abs(PU1.outlet.h - 69.73 {btu/lbm}) < 1.0 {btu/lbm}; |
255 |
ASSERT abs(PU2.inlet.h - 355.5 {btu/lbm}) < 1.5 {btu/lbm}; |
256 |
ASSERT abs(PU2.outlet.h - 355.5 {btu/lbm}) < 8 {btu/lbm}; |
257 |
|
258 |
ASSERT abs(w_net - 518.1 {btu/lbm}) < 0.3 {btu/lbm}; |
259 |
|
260 |
ASSERT abs(w_net * mdot - (TU1.Wdot + TU2.Wdot)) < 1 {W}; |
261 |
|
262 |
ASSERT abs(q_a - 1118.6 {btu/lbm}) < 7 {btu/lbm}; |
263 |
|
264 |
ASSERT abs(eta - 0.463) < 0.003; |
265 |
|
266 |
ASSERT abs(phi - 0.251) < 0.001; |
267 |
*) |
268 |
END weston_ex_2_6; |
269 |
END rankine_regen_water; |
270 |
|
271 |
|
272 |
MODEL rankine_regen_common; |
273 |
BO IS_A boiler_simple; |
274 |
TU IS_A turbine_simple; |
275 |
CO IS_A condenser_simple; |
276 |
HE IS_A heater_closed; |
277 |
PU IS_A pump_simple; |
278 |
|
279 |
(* main loop *) |
280 |
BO.outlet, TU.inlet ARE_THE_SAME; |
281 |
TU.outlet, HE.inlet_heat ARE_THE_SAME; |
282 |
HE.outlet_heat, CO.inlet ARE_THE_SAME; |
283 |
CO.outlet, PU.inlet ARE_THE_SAME; |
284 |
PU.outlet, HE.inlet ARE_THE_SAME; |
285 |
HE.outlet, BO.inlet ARE_THE_SAME; |
286 |
|
287 |
mdot ALIASES BO.mdot; |
288 |
cd ALIASES BO.inlet.cd; |
289 |
|
290 |
T_H ALIASES BO.outlet.T; |
291 |
T_C ALIASES CO.outlet.T; |
292 |
|
293 |
eta IS_A fraction; |
294 |
eta_eq:eta * (BO.Qdot_fuel) = TU.Wdot + PU.Wdot; |
295 |
|
296 |
Wdot_TU ALIASES TU.Wdot; |
297 |
Wdot_PU ALIASES PU.Wdot; |
298 |
Qdot_fuel ALIASES BO.Qdot_fuel; |
299 |
|
300 |
eta_carnot IS_A fraction; |
301 |
eta_carnot_eq: eta_carnot = 1 - T_C / T_H; |
302 |
|
303 |
Wdot IS_A energy_rate; |
304 |
Wdot_eq: Wdot = TU.Wdot + PU.Wdot; |
305 |
|
306 |
T_ci ALIASES HE.inlet.T; |
307 |
T_co ALIASES HE.outlet.T; |
308 |
T_hi ALIASES HE.inlet_heat.T; |
309 |
T_ho ALIASES HE.outlet_heat.T; |
310 |
|
311 |
DE_cycle "cycle energy balance, should be zero" IS_A energy_rate; |
312 |
DE_cycle = BO.Qdot + CO.Qdot - TU.Wdot - PU.Wdot; |
313 |
|
314 |
x_turb_out ALIASES TU.outlet.x; |
315 |
METHODS |
316 |
METHOD default_self; |
317 |
RUN BO.default_self; |
318 |
RUN TU.default_self; |
319 |
RUN CO.default_self; |
320 |
RUN PU.default_self; |
321 |
RUN HE.default_self; |
322 |
HE.cons_mass_heat.included := FALSE; |
323 |
END default_self; |
324 |
METHOD cycle_plot; |
325 |
EXTERNAL cycle_plot_rankine_regen1(SELF); |
326 |
END cycle_plot; |
327 |
METHOD heater_plot; |
328 |
EXTERNAL heater_closed_plot(SELF); |
329 |
END heater_plot; |
330 |
END rankine_regen_common; |
331 |
|
332 |
|
333 |
MODEL rankine_regen_toluene REFINES rankine_regen_common; |
334 |
BO.cd.component :== 'toluene'; |
335 |
BO.cd.type :== 'helmholtz'; |
336 |
HE.inlet_heat.T = HE.outlet.T + 33 {K}; |
337 |
(* HE.outlet_heat.T = HE.inlet.T + 12 {K};*) |
338 |
METHODS |
339 |
METHOD on_load; |
340 |
RUN default_self; |
341 |
FIX BO.outlet.T; BO.outlet.T := 375. {K} + 273.15 {K}; (* lowered for toluene *) |
342 |
FIX PU.outlet.p; PU.outlet.p := 150 {bar}; |
343 |
FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K}; |
344 |
FIX CO.outlet.x; CO.outlet.x := 1e-6; |
345 |
FIX Wdot; Wdot := 100 {MW}; |
346 |
|
347 |
FIX BO.eta; BO.eta := 1.0; |
348 |
FIX TU.eta; TU.eta := 0.85; |
349 |
FIX PU.eta; PU.eta := 0.8; |
350 |
|
351 |
SOLVER QRSlv; |
352 |
OPTION convopt 'RELNOM_SCALE'; |
353 |
OPTION iterationlimit 200; |
354 |
END on_load; |
355 |
METHOD default_self; |
356 |
RUN rankine_regen_common::default_self; |
357 |
PU.inlet.h := 400 {kJ/kg}; |
358 |
BO.outlet.h := 400 {kJ/kg}; |
359 |
CO.outlet.h := 400 {kJ/kg}; |
360 |
CO.outlet.p := 10 {kPa}; |
361 |
END default_self; |
362 |
END rankine_regen_toluene; |
363 |
|
364 |
|
365 |
MODEL rankine_regen_ammonia REFINES rankine_regen_common; |
366 |
BO.cd.component :== 'ammonia'; |
367 |
BO.cd.type :== 'helmholtz'; |
368 |
METHODS |
369 |
METHOD on_load; |
370 |
RUN default_self; |
371 |
FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K}; |
372 |
FIX PU.outlet.p; PU.outlet.p := 150 {bar}; |
373 |
FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K}; |
374 |
FIX CO.outlet.x; CO.outlet.x := 1e-6; |
375 |
FIX HE.outlet.T; HE.outlet.T := 150.1 {K} + 273.15 {K}; |
376 |
FIX Wdot; Wdot := 100 {MW}; |
377 |
|
378 |
FIX BO.eta; BO.eta := 1.0; |
379 |
FIX TU.eta; TU.eta := 0.85; |
380 |
FIX PU.eta; PU.eta := 0.8; |
381 |
|
382 |
SOLVER QRSlv; |
383 |
OPTION convopt 'RELNOM_SCALE'; |
384 |
OPTION iterationlimit 200; |
385 |
END on_load; |
386 |
METHOD default_self; |
387 |
RUN rankine_regen_common::default_self; |
388 |
PU.inlet.h := 400 {kJ/kg}; |
389 |
BO.outlet.h := 400 {kJ/kg}; |
390 |
CO.outlet.h := 400 {kJ/kg}; |
391 |
CO.outlet.p := 10 {kPa}; |
392 |
END default_self; |
393 |
END rankine_regen_ammonia; |