/[ascend]/trunk/models/test/bug567/rankine_fprops.a4c
ViewVC logotype

Contents of /trunk/models/test/bug567/rankine_fprops.a4c

Parent Directory Parent Directory | Revision Log Revision Log


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

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