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