/[ascend]/trunk/models/johnpye/fprops/rankine_fprops.a4c
ViewVC logotype

Contents of /trunk/models/johnpye/fprops/rankine_fprops.a4c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2692 - (show annotations) (download) (as text)
Tue Mar 5 04:45:27 2013 UTC (9 years, 8 months ago) by jpye
File MIME type: text/x-ascend
File size: 23068 byte(s)
Fix rankine_regen_water model (some initialisation had been omitted).
Update plotting routine for rankine_regen_water.
1 (* ASCEND modelling environment
2 Copyright (C) 2007, 2008, 2009, 2010 Carnegie Mellon University
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *)(*
17 A number of Rankine-cycle (steam turbine power cycle) models of increasing
18 complexity, following the general development of Moran & Shapiro, Çengel,
19 and others.
20
21 Author: John Pye
22 *)
23
24 REQUIRE "atoms.a4l";
25 REQUIRE "johnpye/thermo_types.a4c";
26
27 IMPORT "johnpye/fprops/fprops";
28 (*IMPORT "sensitivity/solve";*)
29 IMPORT "johnpye/extpy/extpy";
30 IMPORT "johnpye/fprops/cycle_plot";
31
32 (*------------------------------------------------------------------------------
33 BACKGROUND STUFF
34 *)
35
36 MODEL fluid;
37 component IS_A symbol_constant;
38 type IS_A symbol_constant;
39 END fluid;
40
41 (*
42 Thermo properties -- IAPWS-IF97
43 *)
44 MODEL stream_state;
45 cd IS_A fluid;
46 p IS_A pressure;
47 h IS_A specific_enthalpy;
48
49 T IS_A temperature;
50 v IS_A specific_volume;
51 s IS_A specific_entropy;
52 x IS_A fraction;
53
54 calc_vT: fprops_phsx_vT(
55 v, T : INPUT;
56 p, h, s, x : OUTPUT;
57 cd : DATA
58 );
59 calc_ph: fprops_Tvsx_ph(
60 p, h : INPUT;
61 T, v, s, x : OUTPUT;
62 cd : DATA
63 );
64 METHODS
65 METHOD default;
66 p := 10{bar};
67 p.nominal := 42 {bar};
68 IF cd.component == 'water' THEN
69 h := 2000 {kJ/kg};
70 ELSE
71 IF cd.component == 'carbondioxide' THEN
72 h := 350 {kJ/kg};
73 ELSE
74 h := 351 {kJ/kg};
75 END IF;
76 END IF;
77
78 T := 400 {K};
79 v.nominal := 10 {L/kg};
80 s := 4 {kJ/kg/K};
81 x := 0.8;
82
83 RUN enable_ph;
84 END default;
85 METHOD default_self;
86 RUN default;
87 END default_self;
88 METHOD enable_vT;
89 FOR i IN [1..4] DO
90 calc_ph[i].included := FALSE;
91 calc_vT[i].included := TRUE;
92 END FOR;
93 END enable_vT;
94 METHOD enable_ph;
95 FOR i IN [1..4] DO
96 calc_ph[i].included := TRUE;
97 calc_vT[i].included := FALSE;
98 END FOR;
99 END enable_ph;
100 METHOD solve;
101 EXTERNAL do_solve(SELF);
102 END solve;
103 END stream_state;
104
105 MODEL stream_state_test REFINES stream_state;
106 cd.component :== 'water';
107 cd.type :== 'helmholtz';
108 METHODS
109 METHOD on_load;
110 RUN default_all;
111 FIX p, h;
112 p := 10 {bar};
113 h := 2000 {kJ/kg};
114 SOLVER QRSlv;
115 OPTION convopt 'RELNOM_SCALE';
116 SOLVE;
117 ASSERT abs(T - 453.03 {K}) < 0.01 {K};
118 ASSERT abs(v - 0.119808 {m^3/kg}) < 0.0001 {m^3/kg};
119 ASSERT abs(x - 0.6142) < 0.0001;
120 ASSERT abs(s - 4.8696 {kJ/kg/K}) < 0.0001 {kJ/kg/K};
121 END on_load;
122 END stream_state_test;
123
124
125 MODEL stream_state_test_co2 REFINES stream_state;
126 cd.component :== 'carbondioxide';
127 cd.type :== 'helmholtz';
128 METHODS
129 METHOD on_load;
130 RUN default_all;
131 h := 350 {kJ/kg};
132 FIX p, x;
133 p := 6 {bar};
134 x := 1e-6;
135 SOLVER QRSlv;
136 OPTION convopt 'RELNOM_SCALE';
137 END on_load;
138 END stream_state_test_co2;
139
140
141 MODEL stream_state_test_toluene REFINES stream_state;
142 cd.component :== 'toluene';
143 cd.type :== 'helmholtz';
144 METHODS
145 METHOD on_load;
146 RUN default_all;
147 FIX p, x;
148 p := 8 {kPa};
149 x := 1e-6;
150 SOLVER QRSlv;
151 OPTION convopt 'RELNOM_SCALE';
152 END on_load;
153 END stream_state_test_toluene;
154
155
156 (* a simple connector that includes calculation of steam properties *)
157 MODEL stream_node;
158 state IS_A stream_state;
159 cd ALIASES state.cd;
160 p ALIASES state.p;
161 h ALIASES state.h;
162 v ALIASES state.v;
163 T ALIASES state.T;
164 s ALIASES state.s;
165 x ALIASES state.x;
166 mdot "param: mass flowrate" IS_A mass_rate;
167 METHODS
168 METHOD default_self;
169 RUN state.default_self;
170 RUN default;
171 END default_self;
172 METHOD default;
173 mdot.nominal := 2 {kg/s};
174 END default;
175 METHOD solve;
176 EXTERNAL do_solve(SELF);
177 END solve;
178 METHOD on_load;
179 RUN default_all; RUN reset; RUN values;
180 FIX p,h;
181 END on_load;
182 END stream_node;
183
184
185 MODEL stream_equipment;
186 outlet "out: outlet stream" IS_A stream_node;
187 inlet "in: inlet stream" IS_A stream_node;
188 inlet.cd, outlet.cd ARE_THE_SAME;
189 inlet.mdot, outlet.mdot ARE_THE_SAME;
190 cd ALIASES inlet.cd;
191 mdot ALIASES inlet.mdot;
192 METHODS
193 METHOD default_self;
194 RUN inlet.default_self;
195 RUN outlet.default_self;
196 END default_self;
197 END stream_equipment;
198
199 (*------------------------------------------------------------------------------
200 PUMP COMPONENT
201 *)
202
203 MODEL pump_simple REFINES stream_equipment;
204 NOTES
205 'block' SELF {Simple model of a compressor using isentropic efficiency}
206 'icon' SELF {Pump}
207 'graphic' SELF {0,0-0,10-10,6-10,4-0,0
208 1,0.4-1,9.6
209 9,3.6-9,6.4 }
210 'port_in' SELF {inlet:0,5}
211 'port_out' SELF {outlet:10,5}
212 END NOTES;
213
214 dp "param: it is in fixed state = 20{atm}" IS_A delta_pressure;
215
216 inlet.p + dp = outlet.p;
217
218 outlet_is IS_A stream_state;
219 outlet_is.p, outlet.p ARE_THE_SAME;
220 outlet_is.cd, outlet.cd ARE_THE_SAME;
221 outlet_is.s, inlet.s ARE_THE_SAME;
222 eta "param: efficiency of the pump/compressor" IS_A fraction;
223
224
225 eta_eq:eta * (inlet.h - outlet.h) = (inlet.h - outlet_is.h);
226
227 (* work done on the environment, will be negative *)
228 Wdot IS_A energy_rate;
229 Wdot_eq:Wdot = mdot * w;
230
231 w IS_A negative_specific_work;
232 w_eq:w = inlet.h - outlet.h;
233 METHODS
234 METHOD default_self;
235 RUN inlet.default_self;
236 RUN outlet.default_self;
237 RUN outlet_is.default_self;
238 END default_self;
239 END pump_simple;
240
241 MODEL pump_simple_test REFINES pump_simple;
242 cd.component :== 'water';
243 METHODS
244 METHOD on_load;
245 RUN default_self;
246 FIX inlet.p; inlet.p := 5 {bar};
247 FIX inlet.h; inlet.h := 400 {kJ/kg};
248 FIX outlet.p; outlet.p := 100 {bar};
249 FIX eta; eta := 0.65;
250 FIX mdot; mdot := 900 {t/d};
251
252 inlet.v := 0.97 {L/kg};
253 inlet.T := 300 {K};
254
255 SOLVER QRSlv;
256 OPTION convopt 'RELNOM_SCALE';
257 OPTION iterationlimit 200;
258 END on_load;
259 END pump_simple_test;
260
261 (*------------------------------------------------------------------------------
262 TURBINE COMPONENT
263 *)
264
265 MODEL turbine_simple REFINES stream_equipment;
266 NOTES
267 'block' SELF {Simple turbine model}
268 'graphic' SELF {10,0-10,10-0,8-0,2-10,0}
269 'port_in' SELF {inlet:3.34,1.332}
270 'port_out' SELF {outlet:6.67,0.667}
271 END NOTES;
272
273
274 dp "param: pressure drop, default value = [10{atm}]" IS_A delta_pressure;
275 inlet.p + dp = outlet.p;
276
277 outlet_is IS_A stream_state;
278 outlet_is.cd, outlet.cd ARE_THE_SAME;
279 outlet_is.p, outlet.p ARE_THE_SAME;
280 outlet_is.s, inlet.s ARE_THE_SAME;
281
282 eta "param: efficiency of turbine" IS_A fraction;
283 eta_eq:eta * (inlet.h - outlet_is.h) = (inlet.h - outlet.h);
284
285 (* work done on the environment, will be positive *)
286 Wdot IS_A energy_rate;
287 Wedot_eq:Wdot = mdot * w;
288
289 w IS_A positive_specific_work;
290 w_eq:w = inlet.h - outlet.h;
291 METHODS
292 METHOD default_self;
293 RUN inlet.default_self;
294 RUN outlet.default_self;
295 RUN outlet_is.default_self;
296 END default_self;
297 END turbine_simple;
298
299 MODEL turbine_simple_test REFINES turbine_simple;
300 cd.component :== 'water';
301 METHODS
302 METHOD on_load;
303 RUN default_self;
304 FIX inlet.p;
305 FIX inlet.h;
306 FIX outlet.p;
307 FIX eta;
308 FIX mdot;
309
310 inlet.p := 100 {bar};
311 inlet.h := 3000 {kJ/kg};
312 outlet.p := 5 {bar};
313 eta := 0.85;
314 mdot := 900 {t/d};
315 END on_load;
316 END turbine_simple_test;
317
318 (*------------------------------------------------------------------------------
319 BOILER COMPONENT
320 *)
321
322 (*
323 simple model assumes no pressure drop, but heating losses due to
324 flue gas temperature
325 *)
326 MODEL boiler_simple REFINES stream_equipment;
327 NOTES
328 'block' SELF {Simple boiler model}
329 'graphic' SELF {0,0-10,0-10,10-0,10-0,0}
330 END NOTES;
331
332 inlet.p, outlet.p ARE_THE_SAME;
333 Qdot_fuel IS_A energy_rate;
334
335 q IS_A specific_energy;
336 q = (outlet.h - inlet.h);
337
338 Qdot "param: energy rate" IS_A energy_rate;
339 heateqn: Qdot = mdot * q;
340
341 eta "param: efficiency of boiler" IS_A fraction;
342 Qdot = eta * Qdot_fuel;
343 METHODS
344 METHOD default_self;
345 RUN inlet.default_self;
346 RUN outlet.default_self;
347 END default_self;
348 END boiler_simple;
349
350 MODEL boiler_simple_test REFINES boiler_simple;
351 cd.component :== 'water';
352 METHODS
353 METHOD on_load;
354 RUN default_self;
355 FIX inlet.p;
356 FIX inlet.h;
357 FIX eta;
358 FIX mdot;
359
360 inlet.p := 100 {bar};
361 inlet.h := 500 {kJ/kg};
362
363 eta := 0.8;
364 outlet.h := 3000 {kJ/kg};
365 mdot := 900 {t/d};
366 END on_load;
367 END boiler_simple_test;
368
369 (*------------------------------------------------------------------------------
370 CONDENSER COMPONENT
371 *)
372
373 (*
374 this is really simple (fluid props permitting): just work out the heat
375 that must be expelled to get the water down to a certain state
376 *)
377 MODEL condenser_simple REFINES stream_equipment;
378 NOTES
379 'block' SELF {Condenser}
380 'icon' SELF {Condenser}
381 'graphic' SELF {0,0-10,0-10,10-0,10-0,0
382 0,5-1.5,5-2,6-3,4-4,6-5,4-6,6-7,4-8,6-8.5,5-10,5}
383 END NOTES;
384
385 inlet.p, outlet.p ARE_THE_SAME;
386 Qdot IS_A energy_rate;
387
388 cons_en: Qdot = mdot * (outlet.h - inlet.h);
389 METHODS
390 METHOD default_self;
391 RUN inlet.default_self;
392 RUN outlet.default_self;
393 END default_self;
394 END condenser_simple;
395
396 MODEL condenser_simple_test REFINES condenser_simple;
397 cd.component :== 'water';
398 METHODS
399 METHOD on_load;
400 RUN default_self;
401 FIX inlet.p, inlet.x;
402 FIX outlet.h;
403 FIX mdot;
404
405 inlet.p := 5 {bar};
406 inlet.x := 0.95;
407 outlet.h := 500 {kJ/kg};
408 mdot := 900 {t/d};
409 END on_load;
410 END condenser_simple_test;
411
412 (*------------------------------------------------------------------------------
413 FEEDWATER HEATER
414 *)
415
416 (*
417 open heater does not have inlet.mdot==outlet.mdot, so not a refinement
418 of 'stream_equipment'.
419 *)
420 MODEL heater_open;
421 NOTES
422 'block' SELF {Simple open feedwater heater}
423 'port_in' SELF {inlet:0,5-inlet_heat:5,0}
424 'port_out' SELF {outlet:10,5}
425 'graphic' SELF {0,0-10,0-10,10-0,10-0,0}
426 END NOTES;
427
428 inlet "in:" IS_A stream_node;
429 inlet_heat "in:" IS_A stream_node;
430 outlet "out:" IS_A stream_node;
431 inlet_heat.p, inlet.p, outlet.p ARE_THE_SAME;
432 inlet.cd, outlet.cd, inlet_heat.cd ARE_THE_SAME;
433 cd ALIASES inlet.cd;
434
435 (* cons. mass *)
436 cons_mass: inlet.mdot + inlet_heat.mdot = outlet.mdot;
437
438 m_ratio IS_A factor;
439 inlet_heat.mdot = m_ratio * inlet.mdot;
440 (* cons. energy *)
441 cons_en: inlet.h + m_ratio * inlet_heat.h = outlet.h;
442 METHODS
443 METHOD default_self;
444 RUN inlet.default_self;
445 RUN inlet_heat.default_self;
446 RUN outlet.default_self;
447 END default_self;
448 END heater_open;
449
450 MODEL heater_open_test REFINES heater_open;
451 cd.component :== 'water';
452 METHODS
453 METHOD on_load;
454 RUN default_self;
455 FIX inlet.p, inlet.h;
456 inlet.p := 40 {bar};
457 inlet.h := 634 {kJ/kg};
458 FIX inlet_heat.h;
459 inlet_heat.h := 2960 {kJ/kg};
460
461 FIX outlet.mdot;
462 outlet.mdot := 900 {t/d};
463
464 FIX inlet.mdot;
465 inlet.mdot := 700 {t/d};
466 END on_load;
467 END heater_open_test;
468
469 MODEL heater_open2;
470 NOTES
471 'block' SELF {Two-heat-inlet open feedwater heater}
472 'port_in' SELF {inlet:0,5-inlet_heat1:3.33,0-inlet_heat2:6.66,0}
473 'port_out' SELF {outlet:10,5}
474 'graphic' SELF {0,0-10,0-10,10-0,10-0,0}
475 END NOTES;
476
477 inlet "in:" IS_A stream_node;
478 inlet_heat1 "in:" IS_A stream_node;
479 inlet_heat2 "in:" IS_A stream_node;
480 outlet "out:" IS_A stream_node;
481 inlet.cd, inlet_heat1.cd, inlet_heat2.cd, outlet.cd ARE_THE_SAME;
482 inlet_heat1.p, inlet_heat2.p, inlet.p, outlet.p ARE_THE_SAME;
483 cd ALIASES inlet.cd;
484
485 (* cons. mass *)
486 cons_mass: inlet.mdot + inlet_heat1.mdot + inlet_heat2.mdot = outlet.mdot;
487
488 (* cons. energy *)
489 cons_en: inlet.mdot * inlet.h + inlet_heat1.mdot * inlet_heat1.h
490 + inlet_heat2.mdot * inlet_heat2.h = outlet.mdot * outlet.h;
491 METHODS
492 METHOD default_self;
493 RUN inlet.default_self;
494 RUN inlet_heat.default_self;
495 RUN inlet_heat2.default_self;
496 RUN outlet.default_self;
497 END default_self;
498 END heater_open2;
499
500 MODEL heater_closed;
501 NOTES
502 'block' SELF {Closed feedwater heater model (heat exchanger)}
503 'port_in' SELF {inlet:0,5-inlet_heat:5,0}
504 'port_out' SELF {outlet:10,3.33-outlet_heat:10,6.66}
505 'graphic' SELF {0,0-10,0-10,10-0,10-0,0}
506 END NOTES;
507
508 inlet "in:" IS_A stream_node;
509 inlet_heat "in:" IS_A stream_node;
510 outlet_heat "out:" IS_A stream_node;
511 outlet "out:" IS_A stream_node;
512
513 inlet.cd, outlet.cd ARE_THE_SAME;
514 inlet_heat.cd, outlet_heat.cd ARE_THE_SAME;
515 cd ALIASES inlet.cd;
516 cd_heat ALIASES inlet_heat.cd;
517
518 inlet_heat.p, outlet_heat.p ARE_THE_SAME;
519 inlet.p, outlet.p ARE_THE_SAME;
520
521 Qdot "heat transferred to main flow stream" IS_A energy_rate;
522
523 q IS_A specific_energy;
524 Qdot = q * inlet.mdot;
525
526 (* cons. mass *)
527 cons_mass: inlet.mdot = outlet.mdot;
528 cons_mass_heat: inlet_heat.mdot = outlet_heat.mdot;
529
530 m_ratio IS_A factor;
531 inlet_heat.mdot = inlet.mdot * m_ratio;
532
533 (* cons. energy *)
534 cons_en: q + inlet.h = outlet.h;
535 cons_en_heat: m_ratio * inlet_heat.h = m_ratio * outlet_heat.h + q;
536 METHODS
537 METHOD default_self;
538 RUN inlet.default_self;
539 RUN inlet_heat.default_self;
540 RUN outlet.default_self;
541 RUN outlet_heat.default_self;
542 END default_self;
543 END heater_closed;
544
545 MODEL heater_closed_test REFINES heater_closed;
546 cd.component :== 'water';
547 cd_heat.component :== 'water';
548 METHODS
549 METHOD on_load;
550 FIX inlet.p, inlet.h, inlet.mdot;
551 inlet.p := 40 {bar};
552 inlet.h := 634 {kJ/kg};
553 inlet.mdot := 700 {t/d};
554
555 FIX inlet_heat.p, inlet_heat.h, inlet_heat.mdot;
556 inlet_heat.p := 50 {bar};
557 inlet_heat.h := 2960 {kJ/kg};
558 inlet_heat.mdot := 500 {t/d};
559
560 FIX outlet.h;
561 outlet.h := 900 {kJ/kg};
562
563 SOLVER QRSlv;
564 OPTION convopt 'RELNOM_SCALE';
565 OPTION iterationlimit 200;
566 END on_load;
567 END heater_closed_test;
568
569 (*------------------------------------------------------------------------------
570 TEE PIECE
571 *)
572
573 (*
574 it's not a car :-)
575 *)
576 MODEL tee;
577 NOTES
578 'block' SELF {Tee piece: branching of flow}
579 'graphic' SELF {0,5-10,3.33-10,6.66-0,5}
580 'port_out' SELF {outlet:10,3.33-outlet_branch:10,6.66}
581 END NOTES;
582
583 inlet "in:" IS_A stream_node;
584 outlet "out:" IS_A stream_node;
585 outlet_branch "out:" IS_A stream_node;
586
587 inlet.cd, outlet.cd, outlet_branch.cd ARE_THE_SAME;
588 cd ALIASES inlet.cd;
589
590 inlet.p, outlet.p, outlet_branch.p ARE_THE_SAME;
591 inlet.h, outlet.h, outlet_branch.h ARE_THE_SAME;
592
593 (* cons. mass *)
594 cons_mass: inlet.mdot = outlet.mdot + outlet_branch.mdot;
595
596 phi IS_A fraction;
597 phi_eq: phi * inlet.mdot = outlet_branch.mdot;
598 METHODS
599 METHOD default_self;
600 RUN inlet.default_self;
601 RUN outlet.default_self;
602 RUN outlet_branch.default_self;
603 END default_self;
604 END tee;
605
606 (*------------------------------------------------------------------------------
607 OVERALL CYCLE
608 *)
609
610 (*
611 simplest possible rankine cycle
612 *)
613 MODEL rankine_common;
614
615 BO IS_A boiler_simple;
616 TU IS_A turbine_simple;
617 CO IS_A condenser_simple;
618 PU IS_A pump_simple;
619 cd ALIASES BO.cd;
620
621 BO.outlet, TU.inlet ARE_THE_SAME;
622 TU.outlet, CO.inlet ARE_THE_SAME;
623 CO.outlet, PU.inlet ARE_THE_SAME;
624 PU.outlet, BO.inlet ARE_THE_SAME;
625
626 Qdot_loss ALIASES CO.Qdot;
627 Wdot IS_A energy_rate;
628 Wdot = TU.Wdot + PU.Wdot;
629
630 T_H ALIASES BO.outlet.T;
631 T_C ALIASES CO.outlet.T;
632
633 eta IS_A fraction;
634 eta * (BO.Qdot_fuel) = TU.Wdot + PU.Wdot;
635
636 eta_carnot IS_A fraction;
637 eta_carnot = 1 - T_C / T_H;
638
639 DE_cycle "cycle energy balance, should be zero" IS_A energy_rate;
640 DE_cycle = BO.Qdot + CO.Qdot - TU.Wdot - PU.Wdot;
641
642 mdot ALIASES TU.mdot;
643 x_turb_out ALIASES TU.outlet.x;
644 METHODS
645 METHOD default_self;
646 RUN BO.default_self;
647 RUN TU.default_self;
648 RUN CO.default_self;
649 RUN PU.default_self;
650 END default_self;
651 METHOD cycle_plot;
652 EXTERNAL cycle_plot_rankine(SELF);
653 END cycle_plot;
654 END rankine_common;
655
656
657 MODEL rankine_water REFINES rankine_common;
658 cd.component :== 'water';
659 cd.type :== 'helmholtz';
660 METHODS
661 (* first test case: just some plausible values *)
662 METHOD on_load;
663 RUN ClearAll;
664 RUN default_self;
665 FIX BO.eta; BO.eta := 1.0;
666 FIX TU.eta; TU.eta := 0.85;
667 FIX PU.eta; PU.eta := 0.8;
668 FIX Wdot; Wdot := 100 {MW};
669 (* FIX CO.outlet.p; CO.outlet.p := 10 {kPa};*)
670 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
671 FIX CO.outlet.x; CO.outlet.x := 1e-6;
672 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
673 PU.outlet.p.upper_bound := 150 {bar};
674 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
675
676 SOLVER QRSlv;
677 OPTION convopt 'RELNOM_SCALE';
678 OPTION iterationlimit 200;
679 END on_load;
680 METHOD set_x_limit;
681 FREE PU.outlet.p;
682 PU.outlet.p.upper_bound := 150 {bar};
683 FIX TU.outlet.x; TU.outlet.x := 0.9;
684 END set_x_limit;
685 (*
686 second test case: numbers from Example 2.1, K Weston, 'Energy Conversion',
687 1992, http://www.personal.utulsa.edu/~kenneth-weston/
688 *)
689 METHOD specify;
690 RUN ClearAll;
691 FIX PU.outlet.p;
692 FIX BO.outlet.T;
693 FIX PU.inlet.p;
694 FIX CO.outlet.x;
695 FIX TU.eta;
696 FIX PU.eta;
697 FIX BO.eta;
698 FIX mdot;
699 END specify;
700 METHOD values;
701 PU.outlet.p := 2000 {psi};
702 BO.outlet.T := 1460 {R}; BO.outlet.h := 3400 {kJ/kg};
703 PU.inlet.p := 1 {psi};
704 CO.outlet.x := 1e-6; (*PU.inlet.h := 69.73 {btu/lbm};*)
705 TU.eta := 1.0;
706 PU.eta := 1.0;
707 BO.eta := 1.0;
708 mdot := 900 {t/d};
709 END values;
710 (*
711 METHOD on_load;
712 RUN default_self;
713 RUN specify;
714 RUN values;
715
716 SOLVER QRSlv;
717 OPTION convopt 'RELNOM_SCALE';
718 OPTION iterationlimit 200;
719 END on_load;
720 *)
721 METHOD self_test;
722 (* check the results against those from K Weston's book *)
723 (* note that we have NOT neglected pump work in this case! *)
724 ASSERT abs(eta - 0.4294) < 0.0030;
725 ASSERT abs(eta_carnot - 0.6152) < 0.0005;
726 ASSERT abs(TU.outlet.x - 0.7736) < 0.0005;
727 ASSERT abs(TU.w - 603.1 {btu/lbm}) < 0.7 {btu/lbm};
728 END self_test;
729 METHOD default_self;
730 RUN rankine_common::default_self;
731 BO.outlet.h := 3000 {kJ/kg}; (* guess *)
732 TU.outlet.h := 3000 {kJ/kg}; (* guess *)
733 CO.outlet.h := 300 {kJ/kg};
734 CO.outlet.p := 10 {kPa};
735 END default_self;
736 END rankine_water;
737
738 MODEL rankine_co2 REFINES rankine_common;
739 cd.component :== 'carbondioxide';
740 cd.type :== 'helmholtz';
741 METHODS
742 METHOD on_load_1;
743 RUN ClearAll;
744 RUN default_self;
745 FIX BO.eta; BO.eta := 1.0;
746 FIX TU.eta; TU.eta := 0.85;
747 FIX PU.eta; PU.eta := 0.8;
748 FIX Wdot; Wdot := 100 {MW};
749 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
750 FIX CO.outlet.p; CO.outlet.p := 80 {bar};
751 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
752 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
753
754 SOLVER QRSlv;
755 OPTION convopt 'RELNOM_SCALE';
756 OPTION iterationlimit 200;
757 END on_load_1;
758 METHOD on_load;
759 RUN ClearAll;
760 RUN default_self;
761 FIX BO.eta; BO.eta := 1.0;
762 FIX TU.eta; TU.eta := 0.85;
763 FIX PU.eta; PU.eta := 0.8;
764 FIX Wdot; Wdot := 100 {MW};
765 FIX CO.outlet.T; CO.outlet.T := 10 {K} + 273.15 {K};
766 FIX CO.outlet.x; CO.outlet.x := 1e-6;
767 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
768 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
769
770 SOLVER QRSlv;
771 OPTION convopt 'RELNOM_SCALE';
772 OPTION iterationlimit 200;
773 END on_load;
774 METHOD default_self;
775 RUN rankine_common::default_self;
776 BO.outlet.h := 350 {kJ/kg}; (* guess *)
777 TU.outlet.h := 1000 {kJ/kg}; (* guess *)
778 CO.outlet.h := 350 {kJ/kg};
779 CO.outlet.p := 60 {bar};
780 CO.outlet.p.lower_bound := 5.2 {bar};
781 END default_self;
782 END rankine_co2;
783
784 MODEL rankine_toluene REFINES rankine_common;
785 cd.component :== 'toluene';
786 cd.type :== 'helmholtz';
787 METHODS
788 METHOD on_load;
789 RUN ClearAll;
790 RUN default_self;
791 FIX BO.eta; BO.eta := 1.0;
792 FIX TU.eta; TU.eta := 0.85;
793 FIX PU.eta; PU.eta := 0.8;
794 FIX Wdot; Wdot := 100 {MW};
795 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
796 FIX CO.outlet.x; CO.outlet.x := 1e-6;
797 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
798 FIX BO.outlet.T; BO.outlet.T := 375. {K} + 273.15 {K};
799
800 SOLVER QRSlv;
801 OPTION convopt 'RELNOM_SCALE';
802 OPTION iterationlimit 200;
803
804 FREE CO.outlet.h;
805 FIX CO.outlet.x; CO.outlet.x := 1e-6;
806
807 END on_load;
808 METHOD default_self;
809 RUN rankine_common::default_self;
810 PU.inlet.h := 400 {kJ/kg};
811 BO.outlet.h := 400 {kJ/kg};
812 CO.outlet.h := 400 {kJ/kg};
813 CO.outlet.p := 10 {kPa};
814 END default_self;
815 END rankine_toluene;
816
817
818
819 MODEL rankine_ammonia REFINES rankine_common;
820 cd.component :== 'ammonia';
821 cd.type :== 'helmholtz';
822 METHODS
823 METHOD on_load;
824 RUN ClearAll;
825 RUN default_self;
826 FIX BO.eta; BO.eta := 1.0;
827 FIX TU.eta; TU.eta := 0.85;
828 FIX PU.eta; PU.eta := 0.8;
829 FIX Wdot; Wdot := 100 {MW};
830 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
831 FIX CO.outlet.x; CO.outlet.x := 1e-6;
832 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
833 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
834
835 SOLVER QRSlv;
836 OPTION convopt 'RELNOM_SCALE';
837 OPTION iterationlimit 200;
838
839 FREE CO.outlet.h;
840 FIX CO.outlet.x; CO.outlet.x := 1e-6;
841
842 END on_load;
843 METHOD default_self;
844 RUN rankine_common::default_self;
845 PU.inlet.h := 400 {kJ/kg};
846 BO.outlet.h := 400 {kJ/kg};
847 CO.outlet.h := 400 {kJ/kg};
848 CO.outlet.p := 10 {kPa};
849 END default_self;
850 END rankine_ammonia;
851
852
853
854 (*------------------------------------------------------------------------------
855 REHEAT RANKINE CYCLE
856 *)
857 MODEL rankine_reheat_common;
858 BO1 IS_A boiler_simple;
859 BO2 IS_A boiler_simple;
860 TU1 IS_A turbine_simple;
861 TU2 IS_A turbine_simple;
862 CO IS_A condenser_simple;
863 PU IS_A pump_simple;
864 cd ALIASES BO1.cd;
865
866 BO1.outlet, TU1.inlet ARE_THE_SAME;
867 TU1.outlet, BO2.inlet ARE_THE_SAME;
868 BO2.outlet, TU2.inlet ARE_THE_SAME;
869 TU2.outlet, CO.inlet ARE_THE_SAME;
870 CO.outlet, PU.inlet ARE_THE_SAME;
871 PU.outlet, BO1.inlet ARE_THE_SAME;
872
873 BO1.eta, BO2.eta ARE_THE_SAME;
874
875 (* boiler peak temperature is reached for both main and reheat... *)
876 BO1.outlet.T, BO2.outlet.T ARE_THE_SAME;
877
878 mdot ALIASES PU.mdot;
879
880 T_H ALIASES BO1.outlet.T;
881 T_C ALIASES CO.outlet.T;
882
883 eta IS_A fraction;
884 eta * (BO1.Qdot_fuel + BO2.Qdot_fuel) = TU1.Wdot + TU2.Wdot + PU.Wdot;
885
886 DE_cycle IS_A energy_rate;
887 DE_cycle = BO1.Qdot + BO2.Qdot + CO.Qdot - TU1.Wdot - TU2.Wdot - PU.Wdot;
888
889 eta_carnot IS_A fraction;
890 eta_carnot = 1 - T_C / T_H;
891 METHODS
892 METHOD default_self;
893 RUN BO1.default_self;
894 RUN BO2.default_self;
895 RUN TU1.default_self;
896 RUN TU2.default_self;
897 RUN CO.default_self;
898 RUN PU.default_self;
899 END default_self;
900 METHOD cycle_plot;
901 EXTERNAL cycle_plot_rankine_reheat(SELF);
902 END cycle_plot;
903 END rankine_reheat_common;
904
905 (*
906 A model for a reheat Rankine cycle with water as the working fluid.
907 *)
908 MODEL rankine_reheat_water REFINES rankine_reheat_common;
909 cd.component :== 'water';
910 cd.type :== 'helmholtz';
911 METHODS
912 METHOD on_load;
913 RUN default_self;
914 RUN cengel_ex_10_4;
915 (* make the default case slightly more realistic than the Cengel example *)
916 FIX TU1.eta := 0.9;
917 FIX TU2.eta := 0.9;
918 FIX PU.eta := 0.8;
919 FIX TU1.inlet.T := 500 {K} + 273.15 {K};
920 FIX BO2.outlet.T := TU1.inlet.T;
921 END on_load;
922 METHOD cengel_ex_10_4;
923 (* This example 10.4 from Cengel & Boles, 2011, 'Thermodynamics: An
924 Engineering Approach', 7th Ed., McGraw-Hill. *)
925 RUN ClearAll;
926 RUN default_self;
927 FIX BO1.eta := 1.0;
928 FIX TU1.eta := 1.0;
929 FIX TU2.eta := 1.0;
930 FIX PU.eta := 1.0;
931
932 FIX TU1.inlet.p := 15 {MPa};
933 FIX TU1.inlet.T := (600 {K} + 273.15 {K});
934 FIX BO2.outlet.T := TU1.inlet.T;
935 FIX TU2.outlet.x := 0.896;
936 FIX CO.inlet.p := 10 {kPa};
937 FIX CO.outlet.x := 1e-6;
938 FIX mdot := 1 {kg/s};
939 END cengel_ex_10_4;
940 METHOD self_test_cengel;
941 ASSERT abs(TU2.outlet.s -7.3688 {kJ/kg/K}) < 0.0001 {kJ/kg/K};
942 ASSERT abs(TU2.outlet.h - 2335.1 {kJ/kg}) < 0.1 {kJ/kg};
943 ASSERT abs(BO2.outlet.p - 4.0 {MPa}) < 0.05 {MPa};
944 ASSERT abs(BO2.outlet.h - 3674.9 {kJ/kg}) < 0.2 {kJ/kg};
945 ASSERT abs(eta - 0.450) < 0.0005;
946 END self_test_cengel;
947 METHOD default_self;
948 RUN rankine_reheat_common::default_self;
949 BO1.outlet.h := 3000 {kJ/kg}; (* guess *)
950 TU1.outlet.h := 3000 {kJ/kg}; (* guess *)
951 TU2.inlet.h := 3000 {kJ/kg}; (* guess *)
952 END default_self;
953 END rankine_reheat_water;

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22