/[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 2740 - (show annotations) (download) (as text)
Tue Jan 28 13:58:59 2014 UTC (10 years, 5 months ago) by jpye
File MIME type: text/x-ascend
File size: 24117 byte(s)
linear dish array model, with pressure drops in pipe segments, first attempt
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 disable_cons_mass;
600 cons_mass.included := FALSE;
601 END disable_cons_mass;
602 METHOD enable_cons_mass;
603 cons_mass.included := TRUE;
604 END enable_cons_mass;
605 METHOD default_self;
606 RUN inlet.default_self;
607 RUN outlet.default_self;
608 RUN outlet_branch.default_self;
609 END default_self;
610 END tee;
611
612 (*------------------------------------------------------------------------------
613 MERGE PIECE
614 *)
615
616 (*
617 Joining two streams
618 *)
619 MODEL merge;
620 NOTES
621 'block' SELF {Model of a joining of two flow streams}
622 END NOTES;
623
624 inlet "in:" IS_A stream_node;
625 inlet_branch "in:" IS_A stream_node;
626 outlet "out:" IS_A stream_node;
627
628 inlet.cd, inlet_branch.cd, outlet.cd ARE_THE_SAME;
629 cd ALIASES inlet.cd;
630
631 inlet.p, inlet_branch.p, outlet.p ARE_THE_SAME;
632 (*inlet.h, inlet_branch.h, outlet.h ARE_THE_SAME;*)
633
634 (* cons. mass *)
635 cons_mass: inlet.mdot + inlet_branch.mdot= outlet.mdot;
636
637 (* cons. energy*)
638 cons_energy: inlet.mdot*inlet.h+inlet_branch.mdot*inlet_branch.h= outlet.mdot*outlet.h;
639
640 phi IS_A fraction;
641 phi_eq: phi * outlet.mdot = inlet_branch.mdot;
642 METHODS
643 METHOD default_self;
644 RUN inlet.default_self;
645 RUN outlet.default_self;
646 RUN inlet_branch.default_self;
647 END default_self;
648 END merge;
649
650 (*------------------------------------------------------------------------------
651 OVERALL CYCLE
652 *)
653
654 (*
655 simplest possible rankine cycle
656 *)
657 MODEL rankine_common;
658
659 BO IS_A boiler_simple;
660 TU IS_A turbine_simple;
661 CO IS_A condenser_simple;
662 PU IS_A pump_simple;
663 cd ALIASES BO.cd;
664
665 BO.outlet, TU.inlet ARE_THE_SAME;
666 TU.outlet, CO.inlet ARE_THE_SAME;
667 CO.outlet, PU.inlet ARE_THE_SAME;
668 PU.outlet, BO.inlet ARE_THE_SAME;
669
670 Qdot_loss ALIASES CO.Qdot;
671 Wdot IS_A energy_rate;
672 Wdot = TU.Wdot + PU.Wdot;
673
674 T_H ALIASES BO.outlet.T;
675 T_C ALIASES CO.outlet.T;
676
677 eta IS_A fraction;
678 eta * (BO.Qdot_fuel) = TU.Wdot + PU.Wdot;
679
680 eta_carnot IS_A fraction;
681 eta_carnot = 1 - T_C / T_H;
682
683 DE_cycle "cycle energy balance, should be zero" IS_A energy_rate;
684 DE_cycle = BO.Qdot + CO.Qdot - TU.Wdot - PU.Wdot;
685
686 mdot ALIASES TU.mdot;
687 x_turb_out ALIASES TU.outlet.x;
688 METHODS
689 METHOD default_self;
690 RUN BO.default_self;
691 RUN TU.default_self;
692 RUN CO.default_self;
693 RUN PU.default_self;
694 END default_self;
695 METHOD cycle_plot;
696 EXTERNAL cycle_plot_rankine(SELF);
697 END cycle_plot;
698 END rankine_common;
699
700
701 MODEL rankine_water REFINES rankine_common;
702 cd.component :== 'water';
703 cd.type :== 'helmholtz';
704 METHODS
705 (* first test case: just some plausible values *)
706 METHOD on_load;
707 RUN ClearAll;
708 RUN default_self;
709 FIX BO.eta; BO.eta := 1.0;
710 FIX TU.eta; TU.eta := 0.85;
711 FIX PU.eta; PU.eta := 0.8;
712 FIX Wdot; Wdot := 100 {MW};
713 (* FIX CO.outlet.p; CO.outlet.p := 10 {kPa};*)
714 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
715 FIX CO.outlet.x; CO.outlet.x := 1e-6;
716 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
717 PU.outlet.p.upper_bound := 150 {bar};
718 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
719
720 SOLVER QRSlv;
721 OPTION convopt 'RELNOM_SCALE';
722 OPTION iterationlimit 200;
723 END on_load;
724 METHOD set_x_limit;
725 FREE PU.outlet.p;
726 PU.outlet.p.upper_bound := 150 {bar};
727 FIX TU.outlet.x; TU.outlet.x := 0.9;
728 END set_x_limit;
729 (*
730 second test case: numbers from Example 2.1, K Weston, 'Energy Conversion',
731 1992, http://www.personal.utulsa.edu/~kenneth-weston/
732 *)
733 METHOD specify;
734 RUN ClearAll;
735 FIX PU.outlet.p;
736 FIX BO.outlet.T;
737 FIX PU.inlet.p;
738 FIX CO.outlet.x;
739 FIX TU.eta;
740 FIX PU.eta;
741 FIX BO.eta;
742 FIX mdot;
743 END specify;
744 METHOD values;
745 PU.outlet.p := 2000 {psi};
746 BO.outlet.T := 1460 {R}; BO.outlet.h := 3400 {kJ/kg};
747 PU.inlet.p := 1 {psi};
748 CO.outlet.x := 1e-6; (*PU.inlet.h := 69.73 {btu/lbm};*)
749 TU.eta := 1.0;
750 PU.eta := 1.0;
751 BO.eta := 1.0;
752 mdot := 900 {t/d};
753 END values;
754 (*
755 METHOD on_load;
756 RUN default_self;
757 RUN specify;
758 RUN values;
759
760 SOLVER QRSlv;
761 OPTION convopt 'RELNOM_SCALE';
762 OPTION iterationlimit 200;
763 END on_load;
764 *)
765 METHOD self_test;
766 (* check the results against those from K Weston's book *)
767 (* note that we have NOT neglected pump work in this case! *)
768 ASSERT abs(eta - 0.4294) < 0.0030;
769 ASSERT abs(eta_carnot - 0.6152) < 0.0005;
770 ASSERT abs(TU.outlet.x - 0.7736) < 0.0005;
771 ASSERT abs(TU.w - 603.1 {btu/lbm}) < 0.7 {btu/lbm};
772 END self_test;
773 METHOD default_self;
774 RUN rankine_common::default_self;
775 BO.outlet.h := 3000 {kJ/kg}; (* guess *)
776 TU.outlet.h := 3000 {kJ/kg}; (* guess *)
777 CO.outlet.h := 300 {kJ/kg};
778 CO.outlet.p := 10 {kPa};
779 END default_self;
780 END rankine_water;
781
782 MODEL rankine_co2 REFINES rankine_common;
783 cd.component :== 'carbondioxide';
784 cd.type :== 'helmholtz';
785 METHODS
786 METHOD on_load_1;
787 RUN ClearAll;
788 RUN default_self;
789 FIX BO.eta; BO.eta := 1.0;
790 FIX TU.eta; TU.eta := 0.85;
791 FIX PU.eta; PU.eta := 0.8;
792 FIX Wdot; Wdot := 100 {MW};
793 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
794 FIX CO.outlet.p; CO.outlet.p := 80 {bar};
795 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
796 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
797
798 SOLVER QRSlv;
799 OPTION convopt 'RELNOM_SCALE';
800 OPTION iterationlimit 200;
801 END on_load_1;
802 METHOD on_load;
803 RUN ClearAll;
804 RUN default_self;
805 FIX BO.eta; BO.eta := 1.0;
806 FIX TU.eta; TU.eta := 0.85;
807 FIX PU.eta; PU.eta := 0.8;
808 FIX Wdot; Wdot := 100 {MW};
809 FIX CO.outlet.T; CO.outlet.T := 10 {K} + 273.15 {K};
810 FIX CO.outlet.x; CO.outlet.x := 1e-6;
811 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
812 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
813
814 SOLVER QRSlv;
815 OPTION convopt 'RELNOM_SCALE';
816 OPTION iterationlimit 200;
817 END on_load;
818 METHOD default_self;
819 RUN rankine_common::default_self;
820 BO.outlet.h := 350 {kJ/kg}; (* guess *)
821 TU.outlet.h := 1000 {kJ/kg}; (* guess *)
822 CO.outlet.h := 350 {kJ/kg};
823 CO.outlet.p := 60 {bar};
824 CO.outlet.p.lower_bound := 5.2 {bar};
825 END default_self;
826 END rankine_co2;
827
828 MODEL rankine_toluene REFINES rankine_common;
829 cd.component :== 'toluene';
830 cd.type :== 'helmholtz';
831 METHODS
832 METHOD on_load;
833 RUN ClearAll;
834 RUN default_self;
835 FIX BO.eta; BO.eta := 1.0;
836 FIX TU.eta; TU.eta := 0.85;
837 FIX PU.eta; PU.eta := 0.8;
838 FIX Wdot; Wdot := 100 {MW};
839 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
840 FIX CO.outlet.x; CO.outlet.x := 1e-6;
841 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
842 FIX BO.outlet.T; BO.outlet.T := 375. {K} + 273.15 {K};
843
844 SOLVER QRSlv;
845 OPTION convopt 'RELNOM_SCALE';
846 OPTION iterationlimit 200;
847
848 FREE CO.outlet.h;
849 FIX CO.outlet.x; CO.outlet.x := 1e-6;
850
851 END on_load;
852 METHOD default_self;
853 RUN rankine_common::default_self;
854 PU.inlet.h := 400 {kJ/kg};
855 BO.outlet.h := 400 {kJ/kg};
856 CO.outlet.h := 400 {kJ/kg};
857 CO.outlet.p := 10 {kPa};
858 END default_self;
859 END rankine_toluene;
860
861
862
863 MODEL rankine_ammonia REFINES rankine_common;
864 cd.component :== 'ammonia';
865 cd.type :== 'helmholtz';
866 METHODS
867 METHOD on_load;
868 RUN ClearAll;
869 RUN default_self;
870 FIX BO.eta; BO.eta := 1.0;
871 FIX TU.eta; TU.eta := 0.85;
872 FIX PU.eta; PU.eta := 0.8;
873 FIX Wdot; Wdot := 100 {MW};
874 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
875 FIX CO.outlet.x; CO.outlet.x := 1e-6;
876 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
877 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
878
879 SOLVER QRSlv;
880 OPTION convopt 'RELNOM_SCALE';
881 OPTION iterationlimit 200;
882
883 FREE CO.outlet.h;
884 FIX CO.outlet.x; CO.outlet.x := 1e-6;
885
886 END on_load;
887 METHOD default_self;
888 RUN rankine_common::default_self;
889 PU.inlet.h := 400 {kJ/kg};
890 BO.outlet.h := 400 {kJ/kg};
891 CO.outlet.h := 400 {kJ/kg};
892 CO.outlet.p := 10 {kPa};
893 END default_self;
894 END rankine_ammonia;
895
896
897
898 (*------------------------------------------------------------------------------
899 REHEAT RANKINE CYCLE
900 *)
901 MODEL rankine_reheat_common;
902 BO1 IS_A boiler_simple;
903 BO2 IS_A boiler_simple;
904 TU1 IS_A turbine_simple;
905 TU2 IS_A turbine_simple;
906 CO IS_A condenser_simple;
907 PU IS_A pump_simple;
908 cd ALIASES BO1.cd;
909
910 BO1.outlet, TU1.inlet ARE_THE_SAME;
911 TU1.outlet, BO2.inlet ARE_THE_SAME;
912 BO2.outlet, TU2.inlet ARE_THE_SAME;
913 TU2.outlet, CO.inlet ARE_THE_SAME;
914 CO.outlet, PU.inlet ARE_THE_SAME;
915 PU.outlet, BO1.inlet ARE_THE_SAME;
916
917 BO1.eta, BO2.eta ARE_THE_SAME;
918
919 (* boiler peak temperature is reached for both main and reheat... *)
920 BO1.outlet.T, BO2.outlet.T ARE_THE_SAME;
921
922 mdot ALIASES PU.mdot;
923
924 T_H ALIASES BO1.outlet.T;
925 T_C ALIASES CO.outlet.T;
926
927 eta IS_A fraction;
928 eta * (BO1.Qdot_fuel + BO2.Qdot_fuel) = TU1.Wdot + TU2.Wdot + PU.Wdot;
929
930 DE_cycle IS_A energy_rate;
931 DE_cycle = BO1.Qdot + BO2.Qdot + CO.Qdot - TU1.Wdot - TU2.Wdot - PU.Wdot;
932
933 eta_carnot IS_A fraction;
934 eta_carnot = 1 - T_C / T_H;
935 METHODS
936 METHOD default_self;
937 RUN BO1.default_self;
938 RUN BO2.default_self;
939 RUN TU1.default_self;
940 RUN TU2.default_self;
941 RUN CO.default_self;
942 RUN PU.default_self;
943 END default_self;
944 METHOD cycle_plot;
945 EXTERNAL cycle_plot_rankine_reheat(SELF);
946 END cycle_plot;
947 END rankine_reheat_common;
948
949 (*
950 A model for a reheat Rankine cycle with water as the working fluid.
951 *)
952 MODEL rankine_reheat_water REFINES rankine_reheat_common;
953 cd.component :== 'water';
954 cd.type :== 'helmholtz';
955 METHODS
956 METHOD on_load;
957 RUN default_self;
958 RUN cengel_ex_10_4;
959 (* make the default case slightly more realistic than the Cengel example *)
960 FIX TU1.eta := 0.9;
961 FIX TU2.eta := 0.9;
962 FIX PU.eta := 0.8;
963 FIX TU1.inlet.T := 500 {K} + 273.15 {K};
964 FIX BO2.outlet.T := TU1.inlet.T;
965 END on_load;
966 METHOD cengel_ex_10_4;
967 (* This example 10.4 from Cengel & Boles, 2011, 'Thermodynamics: An
968 Engineering Approach', 7th Ed., McGraw-Hill. *)
969 RUN ClearAll;
970 RUN default_self;
971 FIX BO1.eta := 1.0;
972 FIX TU1.eta := 1.0;
973 FIX TU2.eta := 1.0;
974 FIX PU.eta := 1.0;
975
976 FIX TU1.inlet.p := 15 {MPa};
977 FIX TU1.inlet.T := (600 {K} + 273.15 {K});
978 FIX BO2.outlet.T := TU1.inlet.T;
979 FIX TU2.outlet.x := 0.896;
980 FIX CO.inlet.p := 10 {kPa};
981 FIX CO.outlet.x := 1e-6;
982 FIX mdot := 1 {kg/s};
983 END cengel_ex_10_4;
984 METHOD self_test_cengel;
985 ASSERT abs(TU2.outlet.s -7.3688 {kJ/kg/K}) < 0.0001 {kJ/kg/K};
986 ASSERT abs(TU2.outlet.h - 2335.1 {kJ/kg}) < 0.1 {kJ/kg};
987 ASSERT abs(BO2.outlet.p - 4.0 {MPa}) < 0.05 {MPa};
988 ASSERT abs(BO2.outlet.h - 3674.9 {kJ/kg}) < 0.2 {kJ/kg};
989 ASSERT abs(eta - 0.450) < 0.0005;
990 END self_test_cengel;
991 METHOD default_self;
992 RUN rankine_reheat_common::default_self;
993 BO1.outlet.h := 3000 {kJ/kg}; (* guess *)
994 TU1.outlet.h := 3000 {kJ/kg}; (* guess *)
995 TU2.inlet.h := 3000 {kJ/kg}; (* guess *)
996 END default_self;
997 END rankine_reheat_water;

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