/[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 2660 - (show annotations) (download) (as text)
Wed Jan 16 05:57:03 2013 UTC (9 years, 5 months ago) by jpye
File MIME type: text/x-ascend
File size: 21450 byte(s)
Working on updating rankine_fprops and associated models to work with new fprops2 code.
Some issue discovered with (p,h) for water (added python/solve_ph1.py to check it).
Next cunit tests to drive some ASCEND models embedding FPROPS (note use of slvreq for this).
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 IS_A mass_rate;
167 METHODS
168
169 METHOD default_self;
170 RUN state.default_self;
171 RUN default;
172 END default_self;
173
174 METHOD default;
175 mdot.nominal := 2 {kg/s};
176 END default;
177 METHOD solve;
178 EXTERNAL do_solve(SELF);
179 END solve;
180 METHOD on_load;
181 RUN default_all; RUN reset; RUN values;
182 FIX p,h;
183 END on_load;
184 END stream_node;
185
186 MODEL stream_equipment;
187 inlet "in: inlet steam stream" IS_A stream_node;
188 outlet "out: outlet steam stream" IS_A stream_node;
189 inlet.cd, outlet.cd ARE_THE_SAME;
190 inlet.mdot, outlet.mdot ARE_THE_SAME;
191 cd ALIASES inlet.cd;
192 mdot ALIASES inlet.mdot;
193 END stream_equipment;
194
195 (*------------------------------------------------------------------------------
196 PUMP COMPONENT
197 *)
198
199 MODEL pump_simple REFINES stream_equipment;
200 NOTES
201 'block' SELF {Simple model of a pump using isentropic efficiency}
202 END NOTES;
203
204 dp IS_A delta_pressure;
205 inlet.p + dp = outlet.p;
206
207 outlet_is IS_A stream_state;
208 outlet_is.p, outlet.p ARE_THE_SAME;
209 outlet_is.cd, outlet.cd ARE_THE_SAME;
210 outlet_is.s, inlet.s ARE_THE_SAME;
211 eta IS_A fraction;
212
213 eta_eq:eta * (inlet.h - outlet.h) = (inlet.h - outlet_is.h);
214
215 (* work done on the environment, will be negative *)
216 Wdot IS_A energy_rate;
217 Wdot_eq:Wdot = mdot * w;
218
219 w IS_A negative_specific_work;
220 w_eq:w = inlet.h - outlet.h;
221 METHODS
222 METHOD default_self;
223 RUN inlet.default_self;
224 RUN outlet.default_self;
225 RUN outlet_is.default_self;
226 END default_self;
227 END pump_simple;
228
229 MODEL pump_simple_test REFINES pump_simple;
230 cd.component :== 'water';
231 METHODS
232 METHOD on_load;
233 RUN default_self;
234 FIX inlet.p; inlet.p := 5 {bar};
235 FIX inlet.h; inlet.h := 400 {kJ/kg};
236 FIX outlet.p; outlet.p := 100 {bar};
237 FIX eta; eta := 0.65;
238 FIX mdot; mdot := 900 {t/d};
239
240 inlet.v := 0.97 {L/kg};
241 inlet.T := 300 {K};
242
243 SOLVER QRSlv;
244 OPTION convopt 'RELNOM_SCALE';
245 OPTION iterationlimit 200;
246 END on_load;
247 END pump_simple_test;
248
249 (*------------------------------------------------------------------------------
250 TURBINE COMPONENT
251 *)
252
253 MODEL turbine_simple REFINES stream_equipment;
254 NOTES
255 'block' SELF {Simple turbine model}
256 END NOTES;
257
258 dp IS_A delta_pressure;
259 inlet.p + dp = outlet.p;
260
261 outlet_is IS_A stream_state;
262 outlet_is.cd, outlet.cd ARE_THE_SAME;
263 outlet_is.p, outlet.p ARE_THE_SAME;
264 outlet_is.s, inlet.s ARE_THE_SAME;
265
266 eta IS_A fraction;
267 eta_eq:eta * (inlet.h - outlet_is.h) = (inlet.h - outlet.h);
268
269 (* work done on the environment, will be positive *)
270 Wdot IS_A energy_rate;
271 Wedot_eq:Wdot = mdot * w;
272
273 w IS_A positive_specific_work;
274 w_eq:w = inlet.h - outlet.h;
275 METHODS
276 METHOD default_self;
277 RUN inlet.default_self;
278 RUN outlet.default_self;
279 RUN outlet_is.default_self;
280 END default_self;
281 END turbine_simple;
282
283 MODEL turbine_simple_test REFINES turbine_simple;
284 cd.component :== 'water';
285 METHODS
286 METHOD on_load;
287 RUN default_self;
288 FIX inlet.p;
289 FIX inlet.h;
290 FIX outlet.p;
291 FIX eta;
292 FIX mdot;
293
294 inlet.p := 100 {bar};
295 inlet.h := 3000 {kJ/kg};
296 outlet.p := 5 {bar};
297 eta := 0.85;
298 mdot := 900 {t/d};
299 END on_load;
300 END turbine_simple_test;
301
302 (*------------------------------------------------------------------------------
303 BOILER COMPONENT
304 *)
305
306 (*
307 simple model assumes no pressure drop, but heating losses due to
308 flue gas temperature
309 *)
310 MODEL boiler_simple REFINES stream_equipment;
311 NOTES
312 'block' SELF {Simple boiler model}
313 END NOTES;
314
315 inlet.p, outlet.p ARE_THE_SAME;
316 Qdot_fuel IS_A energy_rate;
317
318 q IS_A specific_energy;
319 q = (outlet.h - inlet.h);
320
321 Qdot IS_A energy_rate;
322 heateqn: Qdot = mdot * q;
323
324 eta IS_A fraction;
325 Qdot = eta * Qdot_fuel;
326 METHODS
327 METHOD default_self;
328 RUN inlet.default_self;
329 RUN outlet.default_self;
330 END default_self;
331 END boiler_simple;
332
333 MODEL boiler_simple_test REFINES boiler_simple;
334 cd.component :== 'water';
335 METHODS
336 METHOD on_load;
337 RUN default_self;
338 FIX inlet.p;
339 FIX inlet.h;
340 FIX eta;
341 FIX mdot;
342
343 inlet.p := 100 {bar};
344 inlet.h := 500 {kJ/kg};
345
346 eta := 0.8;
347 outlet.h := 3000 {kJ/kg};
348 mdot := 900 {t/d};
349 END on_load;
350 END boiler_simple_test;
351
352 (*------------------------------------------------------------------------------
353 CONDENSER COMPONENT
354 *)
355
356 (*
357 this is really simple (fluid props permitting): just work out the heat
358 that must be expelled to get the water down to a certain state
359 *)
360 MODEL condenser_simple REFINES stream_equipment;
361 NOTES
362 'block' SELF {Simple condenser model}
363 'inline' inlet {in: yahoooo}
364 END NOTES;
365
366 inlet.p, outlet.p ARE_THE_SAME;
367 Qdot IS_A energy_rate;
368
369 cons_en: Qdot = mdot * (outlet.h - inlet.h);
370 METHODS
371 METHOD default_self;
372 RUN inlet.default_self;
373 RUN outlet.default_self;
374 END default_self;
375 END condenser_simple;
376
377 MODEL condenser_simple_test REFINES condenser_simple;
378 cd.component :== 'water';
379 METHODS
380 METHOD on_load;
381 RUN default_self;
382 FIX inlet.p, inlet.x;
383 FIX outlet.h;
384 FIX mdot;
385
386 inlet.p := 5 {bar};
387 inlet.x := 0.95;
388 outlet.h := 500 {kJ/kg};
389 mdot := 900 {t/d};
390 END on_load;
391 END condenser_simple_test;
392
393 (*------------------------------------------------------------------------------
394 FEEDWATER HEATER
395 *)
396
397 (*
398 open heater does not have inlet.mdot==outlet.mdot, so not a refinement
399 of 'stream_equipment'.
400 *)
401 MODEL heater_open;
402 NOTES
403 'block' SELF {Simple open feedwater heater model}
404 END NOTES;
405
406 inlet "in:" IS_A stream_node;
407 inlet_heat "in:" IS_A stream_node;
408 outlet "out:" IS_A stream_node;
409 inlet_heat.p, inlet.p, outlet.p ARE_THE_SAME;
410 inlet.cd, outlet.cd, inlet_heat.cd ARE_THE_SAME;
411 cd ALIASES inlet.cd;
412
413 (* cons. mass *)
414 cons_mass: inlet.mdot + inlet_heat.mdot = outlet.mdot;
415
416 m_ratio IS_A factor;
417 inlet_heat.mdot = m_ratio * inlet.mdot;
418 (* cons. energy *)
419 cons_en: inlet.h + m_ratio * inlet_heat.h = outlet.h;
420 METHODS
421 METHOD default_self;
422 RUN inlet.default_self;
423 RUN inlet_heat.default_self;
424 RUN outlet.default_self;
425 END default_self;
426 END heater_open;
427
428 MODEL heater_open_test REFINES heater_open;
429 cd.component :== 'water';
430 METHODS
431 METHOD on_load;
432 RUN default_self;
433 FIX inlet.p, inlet.h;
434 inlet.p := 40 {bar};
435 inlet.h := 634 {kJ/kg};
436 FIX inlet_heat.h;
437 inlet_heat.h := 2960 {kJ/kg};
438
439 FIX outlet.mdot;
440 outlet.mdot := 900 {t/d};
441
442 FIX inlet.mdot;
443 inlet.mdot := 700 {t/d};
444 END on_load;
445 END heater_open_test;
446
447 MODEL heater_open2;
448 NOTES
449 'block' SELF {Simple open feedwater heater model}
450 END NOTES;
451
452 inlet "in:" IS_A stream_node;
453 inlet_heat1 "in:" IS_A stream_node;
454 inlet_heat2 "in:" IS_A stream_node;
455 outlet "out:" IS_A stream_node;
456 inlet.cd, inlet_heat1.cd, inlet_heat2.cd, outlet.cd ARE_THE_SAME;
457 inlet_heat1.p, inlet_heat2.p, inlet.p, outlet.p ARE_THE_SAME;
458 cd ALIASES inlet.cd;
459
460 (* cons. mass *)
461 cons_mass: inlet.mdot + inlet_heat1.mdot + inlet_heat2.mdot = outlet.mdot;
462
463 (* cons. energy *)
464 cons_en: inlet.mdot * inlet.h + inlet_heat1.mdot * inlet_heat1.h
465 + inlet_heat2.mdot * inlet_heat2.h = outlet.mdot * outlet.h;
466 METHODS
467 METHOD default_self;
468 RUN inlet.default_self;
469 RUN inlet_heat.default_self;
470 RUN inlet_heat2.default_self;
471 RUN outlet.default_self;
472 END default_self;
473 END heater_open2;
474
475 MODEL heater_closed;
476 NOTES
477 'block' SELF {Simple open feedwater heater model}
478 END NOTES;
479
480 inlet "in:" IS_A stream_node;
481 inlet_heat "in:" IS_A stream_node;
482 outlet "out:" IS_A stream_node;
483 outlet_heat "out:" IS_A stream_node;
484
485 inlet.cd, outlet.cd ARE_THE_SAME;
486 inlet_heat.cd, outlet_heat.cd ARE_THE_SAME;
487 cd ALIASES inlet.cd;
488 cd_heat ALIASES inlet_heat.cd;
489
490 inlet_heat.p, outlet_heat.p ARE_THE_SAME;
491 inlet.p, outlet.p ARE_THE_SAME;
492
493 Qdot "heat transferred to main flow stream" IS_A energy_rate;
494
495 q IS_A specific_energy;
496 Qdot = q * inlet.mdot;
497
498 (* cons. mass *)
499 cons_mass: inlet.mdot = outlet.mdot;
500 cons_mass_heat: inlet_heat.mdot = outlet_heat.mdot;
501
502 m_ratio IS_A factor;
503 inlet_heat.mdot = inlet.mdot * m_ratio;
504
505 (* cons. energy *)
506 cons_en: q + inlet.h = outlet.h;
507 cons_en_heat: m_ratio * inlet_heat.h = m_ratio * outlet_heat.h + q;
508 METHODS
509 METHOD default_self;
510 RUN inlet.default_self;
511 RUN inlet_heat.default_self;
512 RUN outlet.default_self;
513 RUN outlet_heat.default_self;
514 END default_self;
515 END heater_closed;
516
517 MODEL heater_closed_test REFINES heater_closed;
518 cd.component :== 'water';
519 cd_heat.component :== 'water';
520 METHODS
521 METHOD on_load;
522 FIX inlet.p, inlet.h, inlet.mdot;
523 inlet.p := 40 {bar};
524 inlet.h := 634 {kJ/kg};
525 inlet.mdot := 700 {t/d};
526
527 FIX inlet_heat.p, inlet_heat.h, inlet_heat.mdot;
528 inlet_heat.p := 50 {bar};
529 inlet_heat.h := 2960 {kJ/kg};
530 inlet_heat.mdot := 500 {t/d};
531
532 FIX outlet.h;
533 outlet.h := 900 {kJ/kg};
534
535 SOLVER QRSlv;
536 OPTION convopt 'RELNOM_SCALE';
537 OPTION iterationlimit 200;
538 END on_load;
539 END heater_closed_test;
540
541 (*------------------------------------------------------------------------------
542 TEE PIECE
543 *)
544
545 (*
546 it's not a car :-)
547 *)
548 MODEL tee;
549 NOTES
550 'block' SELF {Model of a branching of two flow streams}
551 END NOTES;
552
553 inlet "in:" IS_A stream_node;
554 outlet "out:" IS_A stream_node;
555 outlet_branch "out:" IS_A stream_node;
556
557 inlet.cd, outlet.cd, outlet_branch.cd ARE_THE_SAME;
558 cd ALIASES inlet.cd;
559
560 inlet.p, outlet.p, outlet_branch.p ARE_THE_SAME;
561 inlet.h, outlet.h, outlet_branch.h ARE_THE_SAME;
562
563 (* cons. mass *)
564 cons_mass: inlet.mdot = outlet.mdot + outlet_branch.mdot;
565
566 phi IS_A fraction;
567 phi_eq: phi * inlet.mdot = outlet_branch.mdot;
568
569 END tee;
570
571 (*------------------------------------------------------------------------------
572 OVERALL CYCLE
573 *)
574
575 (*
576 simplest possible rankine cycle
577 *)
578 MODEL rankine_common;
579
580 BO IS_A boiler_simple;
581 TU IS_A turbine_simple;
582 CO IS_A condenser_simple;
583 PU IS_A pump_simple;
584 cd ALIASES BO.cd;
585
586 BO.outlet, TU.inlet ARE_THE_SAME;
587 TU.outlet, CO.inlet ARE_THE_SAME;
588 CO.outlet, PU.inlet ARE_THE_SAME;
589 PU.outlet, BO.inlet ARE_THE_SAME;
590
591 Qdot_loss ALIASES CO.Qdot;
592 Wdot IS_A energy_rate;
593 Wdot = TU.Wdot + PU.Wdot;
594
595 T_H ALIASES BO.outlet.T;
596 T_C ALIASES CO.outlet.T;
597
598 eta IS_A fraction;
599 eta * (BO.Qdot_fuel) = TU.Wdot + PU.Wdot;
600
601 eta_carnot IS_A fraction;
602 eta_carnot = 1 - T_C / T_H;
603
604 DE_cycle "cycle energy balance, should be zero" IS_A energy_rate;
605 DE_cycle = BO.Qdot + CO.Qdot - TU.Wdot - PU.Wdot;
606
607 mdot ALIASES TU.mdot;
608 x_turb_out ALIASES TU.outlet.x;
609 METHODS
610 METHOD default_self;
611 RUN BO.default_self;
612 RUN TU.default_self;
613 RUN CO.default_self;
614 RUN PU.default_self;
615 END default_self;
616 METHOD cycle_plot;
617 EXTERNAL cycle_plot_rankine(SELF);
618 END cycle_plot;
619 END rankine_common;
620
621
622 MODEL rankine_water REFINES rankine_common;
623 cd.component :== 'water';
624 cd.type :== 'helmholtz';
625 METHODS
626 (* first test case: just some plausible values *)
627 METHOD on_load;
628 RUN ClearAll;
629 RUN default_self;
630 FIX BO.eta; BO.eta := 1.0;
631 FIX TU.eta; TU.eta := 0.85;
632 FIX PU.eta; PU.eta := 0.8;
633 FIX Wdot; Wdot := 100 {MW};
634 (* FIX CO.outlet.p; CO.outlet.p := 10 {kPa};*)
635 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
636 FIX CO.outlet.x; CO.outlet.x := 1e-6;
637 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
638 PU.outlet.p.upper_bound := 150 {bar};
639 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
640
641 SOLVER QRSlv;
642 OPTION convopt 'RELNOM_SCALE';
643 OPTION iterationlimit 200;
644 END on_load;
645 METHOD set_x_limit;
646 FREE PU.outlet.p;
647 PU.outlet.p.upper_bound := 150 {bar};
648 FIX TU.outlet.x; TU.outlet.x := 0.9;
649 END set_x_limit;
650 (*
651 second test case: numbers from Example 2.1, K Weston, 'Energy Conversion',
652 1992, http://www.personal.utulsa.edu/~kenneth-weston/
653 *)
654 METHOD specify;
655 RUN ClearAll;
656 FIX PU.outlet.p;
657 FIX BO.outlet.T;
658 FIX PU.inlet.p;
659 FIX CO.outlet.x;
660 FIX TU.eta;
661 FIX PU.eta;
662 FIX BO.eta;
663 FIX mdot;
664 END specify;
665 METHOD values;
666 PU.outlet.p := 2000 {psi};
667 BO.outlet.T := 1460 {R}; BO.outlet.h := 3400 {kJ/kg};
668 PU.inlet.p := 1 {psi};
669 CO.outlet.x := 1e-6; (*PU.inlet.h := 69.73 {btu/lbm};*)
670 TU.eta := 1.0;
671 PU.eta := 1.0;
672 BO.eta := 1.0;
673 mdot := 900 {t/d};
674 END values;
675 (*
676 METHOD on_load;
677 RUN default_self;
678 RUN specify;
679 RUN values;
680
681 SOLVER QRSlv;
682 OPTION convopt 'RELNOM_SCALE';
683 OPTION iterationlimit 200;
684 END on_load;
685 *)
686 METHOD self_test;
687 (* check the results against those from K Weston's book *)
688 (* note that we have NOT neglected pump work in this case! *)
689 ASSERT abs(eta - 0.4294) < 0.0030;
690 ASSERT abs(eta_carnot - 0.6152) < 0.0005;
691 ASSERT abs(TU.outlet.x - 0.7736) < 0.0005;
692 ASSERT abs(TU.w - 603.1 {btu/lbm}) < 0.7 {btu/lbm};
693 END self_test;
694 METHOD default_self;
695 RUN rankine_common::default_self;
696 BO.outlet.h := 3000 {kJ/kg}; (* guess *)
697 TU.outlet.h := 3000 {kJ/kg}; (* guess *)
698 CO.outlet.h := 200 {kJ/kg};
699 CO.outlet.p := 10 {kPa};
700 END default_self;
701 END rankine_water;
702
703 MODEL rankine_co2 REFINES rankine_common;
704 cd.component :== 'carbondioxide';
705 cd.type :== 'helmholtz';
706 METHODS
707 METHOD on_load_1;
708 RUN ClearAll;
709 RUN default_self;
710 FIX BO.eta; BO.eta := 1.0;
711 FIX TU.eta; TU.eta := 0.85;
712 FIX PU.eta; PU.eta := 0.8;
713 FIX Wdot; Wdot := 100 {MW};
714 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
715 FIX CO.outlet.p; CO.outlet.p := 80 {bar};
716 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
717 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
718
719 SOLVER QRSlv;
720 OPTION convopt 'RELNOM_SCALE';
721 OPTION iterationlimit 200;
722 END on_load_1;
723 METHOD on_load;
724 RUN ClearAll;
725 RUN default_self;
726 FIX BO.eta; BO.eta := 1.0;
727 FIX TU.eta; TU.eta := 0.85;
728 FIX PU.eta; PU.eta := 0.8;
729 FIX Wdot; Wdot := 100 {MW};
730 FIX CO.outlet.T; CO.outlet.T := 10 {K} + 273.15 {K};
731 FIX CO.outlet.x; CO.outlet.x := 1e-6;
732 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
733 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
734
735 SOLVER QRSlv;
736 OPTION convopt 'RELNOM_SCALE';
737 OPTION iterationlimit 200;
738 END on_load;
739 METHOD default_self;
740 RUN rankine_common::default_self;
741 BO.outlet.h := 350 {kJ/kg}; (* guess *)
742 TU.outlet.h := 1000 {kJ/kg}; (* guess *)
743 CO.outlet.h := 350 {kJ/kg};
744 CO.outlet.p := 60 {bar};
745 CO.outlet.p.lower_bound := 5.2 {bar};
746 END default_self;
747 END rankine_co2;
748
749 MODEL rankine_toluene REFINES rankine_common;
750 cd.component :== 'toluene';
751 cd.type :== 'helmholtz';
752 METHODS
753 METHOD on_load;
754 RUN ClearAll;
755 RUN default_self;
756 FIX BO.eta; BO.eta := 1.0;
757 FIX TU.eta; TU.eta := 0.85;
758 FIX PU.eta; PU.eta := 0.8;
759 FIX Wdot; Wdot := 100 {MW};
760 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
761 FIX CO.outlet.x; CO.outlet.x := 1e-6;
762 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
763 FIX BO.outlet.T; BO.outlet.T := 375. {K} + 273.15 {K};
764
765 SOLVER QRSlv;
766 OPTION convopt 'RELNOM_SCALE';
767 OPTION iterationlimit 200;
768
769 FREE CO.outlet.h;
770 FIX CO.outlet.x; CO.outlet.x := 1e-6;
771
772 END on_load;
773 METHOD default_self;
774 RUN rankine_common::default_self;
775 PU.inlet.h := 400 {kJ/kg};
776 BO.outlet.h := 400 {kJ/kg};
777 CO.outlet.h := 400 {kJ/kg};
778 CO.outlet.p := 10 {kPa};
779 END default_self;
780 END rankine_toluene;
781
782
783
784 MODEL rankine_ammonia REFINES rankine_common;
785 cd.component :== 'ammonia';
786 METHODS
787 METHOD on_load;
788 RUN ClearAll;
789 RUN default_self;
790 FIX BO.eta; BO.eta := 1.0;
791 FIX TU.eta; TU.eta := 0.85;
792 FIX PU.eta; PU.eta := 0.8;
793 FIX Wdot; Wdot := 100 {MW};
794 FIX CO.outlet.T; CO.outlet.T := 40 {K} + 273.15 {K};
795 FIX CO.outlet.x; CO.outlet.x := 1e-6;
796 FIX PU.outlet.p; PU.outlet.p := 150 {bar};
797 FIX BO.outlet.T; BO.outlet.T := 580 {K} + 273.15 {K};
798
799 SOLVER QRSlv;
800 OPTION convopt 'RELNOM_SCALE';
801 OPTION iterationlimit 200;
802
803 FREE CO.outlet.h;
804 FIX CO.outlet.x; CO.outlet.x := 1e-6;
805
806 END on_load;
807 METHOD default_self;
808 RUN rankine_common::default_self;
809 PU.inlet.h := 400 {kJ/kg};
810 BO.outlet.h := 400 {kJ/kg};
811 CO.outlet.h := 400 {kJ/kg};
812 CO.outlet.p := 10 {kPa};
813 END default_self;
814 END rankine_ammonia;
815
816
817
818 (*------------------------------------------------------------------------------
819 REHEAT RANKINE CYCLE
820 *)
821 MODEL rankine_reheat_common;
822 BO1 IS_A boiler_simple;
823 BO2 IS_A boiler_simple;
824 TU1 IS_A turbine_simple;
825 TU2 IS_A turbine_simple;
826 CO IS_A condenser_simple;
827 PU IS_A pump_simple;
828
829 BO1.outlet, TU1.inlet ARE_THE_SAME;
830 TU1.outlet, BO2.inlet ARE_THE_SAME;
831 BO2.outlet, TU2.inlet ARE_THE_SAME;
832 TU2.outlet, CO.inlet ARE_THE_SAME;
833 CO.outlet, PU.inlet ARE_THE_SAME;
834 PU.outlet, BO1.inlet ARE_THE_SAME;
835
836 BO1.eta, BO2.eta ARE_THE_SAME;
837
838 (* boiler peak temperature is reached for both main and reheat... *)
839 BO1.outlet.T, BO2.outlet.T ARE_THE_SAME;
840
841 mdot ALIASES PU.mdot;
842
843 T_H ALIASES BO1.outlet.T;
844 T_C ALIASES CO.outlet.T;
845
846 eta IS_A fraction;
847 eta * (BO1.Qdot_fuel + BO2.Qdot_fuel) = TU1.Wdot + TU2.Wdot + PU.Wdot;
848
849 DE_cycle IS_A energy_rate;
850 DE_cycle = BO1.Qdot + BO2.Qdot + CO.Qdot - TU1.Wdot - TU2.Wdot - PU.Wdot;
851
852 eta_carnot IS_A fraction;
853 eta_carnot = 1 - T_C / T_H;
854 METHODS
855 METHOD default_self;
856 RUN BO1.default_self;
857 RUN BO2.default_self;
858 RUN TU1.default_self;
859 RUN TU2.default_self;
860 RUN CO.default_self;
861 RUN PU.default_self;
862 END default_self;
863 END rankine_reheat_common;
864
865 (*
866 A model for Rankine cycle with water as the working fluid
867 *)
868 MODEL rankine_reheat_water REFINES rankine_reheat_common;
869 BO1.cd.component :== 'water';
870 METHODS
871 METHOD on_load;
872 RUN default_self;
873 RUN cengel_ex_10_4;
874 END on_load;
875 METHOD cengel_ex_10_4;
876 (* This example 10.4 from Cengel & Boles, 2011, 'Thermodynamics: An
877 Engineering Approach', 7th Ed., McGraw-Hill. *)
878 RUN ClearAll;
879 RUN default_self;
880 FIX BO1.eta; BO1.eta := 1.0;
881 FIX TU1.eta; TU1.eta := 1.0;
882 FIX TU2.eta; TU2.eta := 1.0;
883 FIX PU.eta; PU.eta := 1.0;
884
885 FIX TU1.inlet.p; TU1.inlet.p := 15 {MPa};
886 FIX TU1.inlet.T; TU1.inlet.T := (600 {K} + 273.15 {K});
887 FIX BO2.outlet.T; BO2.outlet.T := TU1.inlet.T;
888 FIX TU2.outlet.x; TU2.outlet.x := 0.896;
889 FIX CO.inlet.p; CO.inlet.p := 10 {kPa};
890 FIX CO.outlet.x; CO.outlet.x := 1e-6;
891 FIX mdot; mdot := 1 {kg/s};
892 END cengel_ex_10_4;
893 METHOD self_test_cengel;
894 ASSERT abs(TU2.outlet.s -7.3688 {kJ/kg/K}) < 0.0001 {kJ/kg/K};
895 ASSERT abs(TU2.outlet.h - 2335.1 {kJ/kg}) < 0.1 {kJ/kg};
896 ASSERT abs(BO2.outlet.p - 4.0 {MPa}) < 0.05 {MPa};
897 ASSERT abs(BO2.outlet.h - 3674.9 {kJ/kg}) < 0.2 {kJ/kg};
898 ASSERT abs(eta - 0.450) < 0.0005;
899 END self_test_cengel;
900 METHOD default_self;
901 RUN rankine_reheat_common::default_self;
902 BO1.outlet.h := 3000 {kJ/kg}; (* guess *)
903 TU1.outlet.h := 3000 {kJ/kg}; (* guess *)
904 TU2.inlet.h := 3000 {kJ/kg}; (* guess *)
905 END default_self;
906 END rankine_reheat_water;

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