1 |
REQUIRE "collocation.a4l"; |
2 |
REQUIRE "ben/bencolumn.a4l"; |
3 |
(* => ben/bencolumn.a4l, ben/benflash.a4l, ben/benstream.a4l, |
4 |
* ben/benHGthermo.a4l, ben/benpropertyoptions.a4l, |
5 |
* ben/bencomponents.a4l, atoms.a4l, measures.a4l, system.a4l, |
6 |
* basemodel.a4l *) |
7 |
REQUIRE "KenPendings.a4l"; |
8 |
(* => KenPendings.a4l, ben/benstream.a4l, ben/benHGthermo.a4l, |
9 |
* ben/benpropertyoptions.a4l, ben/bencomponents.a4l, atoms.a4l, |
10 |
* measures.a4l, system.a4l, basemodel.a4l *) |
11 |
PROVIDE "abc_flowsheet.a4l"; |
12 |
|
13 |
(* |
14 |
* abc_flowsheet.a4l |
15 |
* by Kenneth H. Tyner |
16 |
* Part of the ASCEND Library |
17 |
* $Date: 1998/06/17 19:49:24 $ |
18 |
* $Revision: 1.4 $ |
19 |
* $Author: mthomas $ |
20 |
* $Source: /afs/cs.cmu.edu/project/ascend/Repository/models/abc_flowsheet.a4l,v $ |
21 |
* |
22 |
* This file is part of the ASCEND Modeling Library. |
23 |
* |
24 |
* Copyright (C) 1997, 1998 Carnegie Mellon University |
25 |
* |
26 |
* The ASCEND Modeling Library is free software; you can redistribute |
27 |
* it and/or modify it under the terms of the GNU General Public |
28 |
* License as published by the Free Software Foundation; either |
29 |
* version 2 of the License, or (at your option) any later version. |
30 |
* |
31 |
* The ASCEND Modeling Library is distributed in hope that it |
32 |
* will be useful, but WITHOUT ANY WARRANTY; without even the implied |
33 |
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
34 |
* See the GNU General Public License for more details. |
35 |
* |
36 |
* You should have received a copy of the GNU General Public License |
37 |
* along with the program; if not, write to the Free Software |
38 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check |
39 |
* the file named COPYING. |
40 |
*) |
41 |
|
42 |
(* |
43 |
* Distillation flowsheet demos (using aceton-benzene-chloroform. |
44 |
*) |
45 |
MODEL demo_flowsheet( |
46 |
n_columns IS_A integer_constant; |
47 |
components IS_A set OF symbol_constant; |
48 |
reference IS_A symbol_constant; |
49 |
n_trays[1..n_columns] IS_A integer_constant; |
50 |
vapor_options WILL_BE vapor_phase_options; |
51 |
liquid_options WILL_BE liquid_phase_options; |
52 |
) WHERE ( |
53 |
reference IN components == TRUE; |
54 |
); |
55 |
|
56 |
feed_P[1..n_columns] IS_A pressure; |
57 |
feed_T[1..n_columns] IS_A temperature; |
58 |
FOR i IN [1..n_columns] CREATE |
59 |
feed_vapor_state[i] IS_A vapor_mixture( |
60 |
feed_P[i], |
61 |
feed_T[i], |
62 |
vapor_options |
63 |
); |
64 |
feed_liquid_state[i] IS_A liquid_mixture( |
65 |
feed_P[i], |
66 |
feed_T[i], |
67 |
liquid_options |
68 |
); |
69 |
END FOR; |
70 |
|
71 |
Equilibrated[1..n_columns] IS_A boolean; |
72 |
FOR i IN [1..n_columns] CREATE |
73 |
feed_state[i] IS_A td_VLE_mixture( |
74 |
feed_P[i], |
75 |
feed_T[i], |
76 |
feed_vapor_state[i], |
77 |
feed_liquid_state[i], |
78 |
Equilibrated[i] |
79 |
); |
80 |
END FOR; |
81 |
FOR i IN [1..n_columns] CREATE |
82 |
Feed[i] IS_A vapor_liquid_stream(feed_state[i]); |
83 |
END FOR; |
84 |
|
85 |
|
86 |
distillate_P[1..n_columns] IS_A pressure; |
87 |
distillate_T[1..n_columns] IS_A temperature; |
88 |
FOR i IN [1..n_columns] CREATE |
89 |
distillate_state[i] IS_A liquid_mixture( |
90 |
distillate_P[i], |
91 |
distillate_T[i], |
92 |
liquid_options |
93 |
); |
94 |
END FOR; |
95 |
FOR i IN [1..n_columns] CREATE |
96 |
Distillate[i] IS_A liquid_stream(distillate_state[i]); |
97 |
END FOR; |
98 |
|
99 |
bottoms_P[1..n_columns] IS_A pressure; |
100 |
bottoms_T[1..n_columns] IS_A temperature; |
101 |
FOR i IN [1..n_columns] CREATE |
102 |
bottoms_state[i] IS_A liquid_mixture( |
103 |
bottoms_P[i], |
104 |
bottoms_T[i], |
105 |
liquid_options |
106 |
); |
107 |
END FOR; |
108 |
FOR i IN [1..n_columns] CREATE |
109 |
Bottoms[i] IS_A liquid_stream(bottoms_state[i]); |
110 |
END FOR; |
111 |
|
112 |
reduce[1..n_columns] IS_A fraction; |
113 |
z_on[1..n_columns] IS_A boolean; |
114 |
hat_on[1..n_columns] IS_A boolean; |
115 |
hb_on[1..n_columns] IS_A boolean; |
116 |
|
117 |
z_on[1..n_columns] := FALSE; |
118 |
hat_on[1..n_columns] := FALSE; |
119 |
hb_on[1..n_columns] := FALSE; |
120 |
Equilibrated[1..n_columns] := FALSE; |
121 |
|
122 |
FOR i IN [1..n_columns] CREATE |
123 |
Column[i] IS_A simple_coll_column( |
124 |
n_trays[i], |
125 |
Distillate[i], |
126 |
Feed[i], |
127 |
Bottoms[i], |
128 |
Equilibrated[i], |
129 |
reduce[i], |
130 |
z_on[i], |
131 |
hat_on[i], |
132 |
hb_on[i] |
133 |
); |
134 |
END FOR; |
135 |
|
136 |
(* hooking it all up *) |
137 |
n_sheet_feeds IS_A integer_constant; |
138 |
n_sheet_feeds :== 1; |
139 |
|
140 |
outputs IS_A set OF symbol_constant; |
141 |
outputs :== [components,'waste']; |
142 |
|
143 |
product_P[outputs] IS_A pressure; |
144 |
product_T[outputs] IS_A temperature; |
145 |
sheet_feed_P[n_sheet_feeds] IS_A pressure; |
146 |
sheet_feed_T[n_sheet_feeds] IS_A temperature; |
147 |
FOR i IN [outputs] CREATE |
148 |
product_state[i] IS_A liquid_mixture( |
149 |
product_P[i], |
150 |
product_T[i], |
151 |
liquid_options |
152 |
); |
153 |
END FOR; |
154 |
FOR i IN [n_sheet_feeds] CREATE |
155 |
sheet_feed_state[i] IS_A liquid_mixture( |
156 |
sheet_feed_P[i], |
157 |
sheet_feed_T[i], |
158 |
liquid_options |
159 |
); |
160 |
END FOR; |
161 |
|
162 |
FOR i IN [outputs] CREATE |
163 |
product[i] IS_A liquid_stream(product_state[i]); |
164 |
END FOR; |
165 |
Product[n] ALIASES |
166 |
(product[outputs]) |
167 |
WHERE n IS_A set OF integer_constant |
168 |
WITH_VALUE (1..CARD[components]+1); |
169 |
|
170 |
FOR i IN [1..n_sheet_feeds] CREATE |
171 |
Sheet_Feed[i] IS_A liquid_stream(sheet_feed_state[i]); |
172 |
END FOR; |
173 |
|
174 |
sources IS_A set OF integer_constant; |
175 |
sinks IS_A set OF integer_constant; |
176 |
|
177 |
sources :== [1..(n_columns*2 + n_sheet_feeds)]; |
178 |
sinks :== [1..(n_columns+CARD[components]+1)]; |
179 |
(* |
180 |
link_T[sources][sinks] IS_A temperature; |
181 |
link_P[sources][sinks] IS_A pressure; |
182 |
FOR i IN sources CREATE |
183 |
FOR j IN sinks CREATE |
184 |
link_state[i][j] IS_A liquid_mixture( |
185 |
link_P[i][j], |
186 |
link_T[i][j], |
187 |
liquid_options |
188 |
); |
189 |
END FOR; |
190 |
END FOR;*) |
191 |
FOR i IN sources CREATE |
192 |
FOR j IN sinks CREATE |
193 |
(* Source_Link[i][j] IS_A liquid_stream(link_state[i][j]);*) |
194 |
Source_Link[i][j] IS_A mass_stream(components); |
195 |
END FOR; |
196 |
END FOR; |
197 |
FOR i IN sinks CREATE |
198 |
FOR j IN sources CREATE |
199 |
Sink_Link[i][j] ALIASES Source_Link[j][i]; |
200 |
END FOR; |
201 |
END FOR; |
202 |
|
203 |
mb_reduce[1..n_columns] IS_A factor; |
204 |
prod_reduce[1..CARD[components]+1] IS_A factor; |
205 |
|
206 |
FOR i IN [1..n_columns] CREATE |
207 |
mixer[i] IS_A mass_balance_homotopy_mixer_single_output_int( |
208 |
sources, |
209 |
Sink_Link[i], |
210 |
Feed[i], |
211 |
mb_reduce[i] |
212 |
); |
213 |
dist_split[i] IS_A liquid_stream_splitter_int( |
214 |
Distillate[i], |
215 |
sinks, |
216 |
Source_Link[i] |
217 |
); |
218 |
bot_split[i] IS_A liquid_stream_splitter_int( |
219 |
Bottoms[i], |
220 |
sinks, |
221 |
Source_Link[n_columns + i] |
222 |
); |
223 |
END FOR; |
224 |
FOR i IN [1..n_sheet_feeds] CREATE |
225 |
feed_split[i] IS_A liquid_stream_splitter_int( |
226 |
Sheet_Feed[i], |
227 |
sinks, |
228 |
Source_Link[n_columns*2 + i] |
229 |
); |
230 |
END FOR; |
231 |
FOR i IN [1..CARD[components]+1] CREATE |
232 |
prod_mix[i] IS_A mass_balance_homotopy_mixer_single_output_int2( |
233 |
sources, |
234 |
Sink_Link[n_columns + i], |
235 |
Product[i], |
236 |
prod_reduce[i] |
237 |
); |
238 |
END FOR; |
239 |
|
240 |
(* conditionals *) |
241 |
(* could just use mass streams *) |
242 |
stream_exists[sources][sinks] IS_A boolean; |
243 |
stream_exists[sources][sinks] := FALSE; |
244 |
(* FOR i IN sources CREATE |
245 |
FOR j IN sinks CREATE |
246 |
WHEN (stream_exists[i][j]) |
247 |
CASE TRUE: |
248 |
USE Source_Link[i][j].state; |
249 |
USE Source_Link[i][j].Htot_def; |
250 |
USE Source_Link[i][j].bubble_point; |
251 |
END FOR; |
252 |
END FOR; |
253 |
END FOR; |
254 |
*) |
255 |
METHODS |
256 |
METHOD scale; |
257 |
RUN Column[1..n_columns].scale; |
258 |
END scale; |
259 |
METHOD set_connections; |
260 |
dist_split[1..n_columns].split[sinks].fixed := TRUE; |
261 |
bot_split[1..n_columns].split[sinks].fixed := TRUE; |
262 |
feed_split[1..n_sheet_feeds].split[sinks].fixed := TRUE; |
263 |
|
264 |
FOR i IN [1..n_columns] DO |
265 |
FOR j IN sinks DO |
266 |
IF (stream_exists[i][j] == FALSE) THEN |
267 |
dist_split[i].split[j] := 0; |
268 |
END IF; |
269 |
END FOR; |
270 |
END FOR; |
271 |
FOR i IN [n_columns+1..n_columns*2] DO |
272 |
FOR j IN sinks DO |
273 |
IF (stream_exists[i][j] == FALSE) THEN |
274 |
bot_split[i-n_columns].split[j] := 0; |
275 |
END IF; |
276 |
END FOR; |
277 |
END FOR; |
278 |
FOR i IN [n_columns*2+1..n_columns*2+n_sheet_feeds] DO |
279 |
FOR j IN sinks DO |
280 |
IF (stream_exists[i][j] == FALSE) THEN |
281 |
feed_split[i-n_columns*2].split[j] := 0; |
282 |
END IF; |
283 |
END FOR; |
284 |
END FOR; |
285 |
(* |
286 |
FOR i IN sources DO |
287 |
FOR j IN sinks DO |
288 |
IF (stream_exists[i][j] == FALSE) THEN |
289 |
Source_Link[i][j].f_def[components].included |
290 |
:= FALSE; |
291 |
ELSE |
292 |
Source_Link[i][j].f_def[components].included |
293 |
:= TRUE; |
294 |
END FOR; |
295 |
END IF; |
296 |
END FOR; |
297 |
*) |
298 |
END set_connections; |
299 |
METHOD remove_connections; |
300 |
FOR i IN sources DO |
301 |
FOR j IN sinks DO |
302 |
stream_exists[i][j] := FALSE; |
303 |
END FOR; |
304 |
END FOR; |
305 |
END remove_connections; |
306 |
METHOD fix_splits; |
307 |
FOR i IN [1..n_columns] DO |
308 |
dist_split[i].split[sinks].fixed := TRUE; |
309 |
bot_split[i].split[sinks].fixed := TRUE; |
310 |
END FOR; |
311 |
FOR i IN [1..n_sheet_feeds] DO |
312 |
feed_split[i].split[sinks].fixed := TRUE; |
313 |
END FOR; |
314 |
END fix_splits; |
315 |
|
316 |
METHOD calc_multipliers; |
317 |
RUN mixer[1..n_columns].calc_multipliers; |
318 |
END calc_multipliers; |
319 |
|
320 |
METHOD calc_outputs; |
321 |
RUN mixer[1..n_columns].calc_outputs; |
322 |
END calc_outputs; |
323 |
|
324 |
METHOD reduce_mix_diff; |
325 |
RUN mixer[1..n_columns].reduce_mix_diff; |
326 |
END reduce_mix_diff; |
327 |
|
328 |
METHOD clear; |
329 |
RUN Sheet_Feed[1..n_sheet_feeds].clear; |
330 |
RUN Column[1..n_columns].clear; |
331 |
RUN Source_Link[sources][sinks].clear; |
332 |
RUN mixer[1..n_columns].clear; |
333 |
RUN dist_split[1..n_columns].clear; |
334 |
RUN bot_split[1..n_columns].clear; |
335 |
RUN feed_split[1..n_sheet_feeds].clear; |
336 |
RUN prod_mix[1..CARD[components]+1].clear; |
337 |
END clear; |
338 |
|
339 |
METHOD reset; |
340 |
RUN clear; |
341 |
|
342 |
RUN dist_split[1..n_columns].seqmod; |
343 |
RUN bot_split[1..n_columns].seqmod; |
344 |
RUN feed_split[1..n_sheet_feeds].seqmod; |
345 |
|
346 |
RUN Column[1..n_columns].reset; |
347 |
RUN mixer[1..n_columns].seqmod; |
348 |
RUN prod_mix[1..CARD[components]+1].seqmod; |
349 |
|
350 |
RUN Sheet_Feed[1..n_sheet_feeds].specify; |
351 |
END reset; |
352 |
|
353 |
END demo_flowsheet; |
354 |
|
355 |
MODEL abc_demo_sheet; |
356 |
components IS_A set OF symbol_constant; |
357 |
reference IS_A symbol_constant; |
358 |
n_columns IS_A integer_constant; |
359 |
n_trays[1..n_columns] IS_A integer_constant; |
360 |
|
361 |
n_columns :== 3; |
362 |
components :== ['acetone','benzene','chloroform']; |
363 |
reference :== 'chloroform'; |
364 |
n_trays[1] :== 4; |
365 |
n_trays[2] :== 2; |
366 |
n_trays[3] :== 2; |
367 |
|
368 |
|
369 |
|
370 |
ds IS_A |
371 |
td_component_data_set(components,reference); |
372 |
vapor_options IS_A vapor_phase_options(ds,'Pitzer','Pitzer'); |
373 |
(* liquid_options IS_A liquid_phase_options(ds,'Rackett','UNIFAC');*) |
374 |
liquid_options IS_A liquid_phase_options(ds,'Rackett','Wilson'); |
375 |
|
376 |
abc_sheet IS_A demo_flowsheet(n_columns, |
377 |
components,reference,n_trays, |
378 |
vapor_options,liquid_options); |
379 |
|
380 |
(* PLOTING SECTION *) |
381 |
|
382 |
FOR i IN [1..n_columns] CREATE |
383 |
liq_eq_plot[i] IS_A ternary_plot_equilateral( |
384 |
'abc liquid comp', |
385 |
components, |
386 |
'acetone', |
387 |
'chloroform', |
388 |
abc_sheet.Column[i].n_plt_points_x, |
389 |
abc_sheet.Column[i].x_plot |
390 |
); |
391 |
END FOR; |
392 |
|
393 |
curves IS_A set OF symbol_constant; |
394 |
curves :== ['Column_1','Column_2','Column_3']; |
395 |
curve[c] ALIASES |
396 |
(liq_eq_plot[1..n_columns].curve) |
397 |
WHERE c IS_A set OF symbol_constant |
398 |
WITH_VALUE ([curves]); |
399 |
|
400 |
eq_plot IS_A ternary_plot_equilateral2( |
401 |
'Acetone-Benzene-Chloroform Liquid Comps', |
402 |
components, |
403 |
'acetone', |
404 |
'chloroform', |
405 |
curves, |
406 |
curve |
407 |
); |
408 |
|
409 |
|
410 |
|
411 |
|
412 |
(* |
413 |
r_plot IS_A ternary_plot_right( |
414 |
'abc liquid comp', |
415 |
abc_column.components, |
416 |
'acetone', |
417 |
'chloroform', |
418 |
abc_column.Column.n_plt_points_x, |
419 |
abc_column.Column.x_plot |
420 |
); |
421 |
*) |
422 |
|
423 |
METHODS |
424 |
METHOD values; |
425 |
abc_sheet.Column[1].feed_tray_state.alpha['acetone'] := 1.73; |
426 |
abc_sheet.Column[1].feed_tray_state.alpha['benzene'] := 0.97; |
427 |
abc_sheet.Column[1].feed_tray_state.alpha['chloroform'] := 1.19; |
428 |
abc_sheet.Feed[1].f['acetone'] := 3.5{mole/s}; |
429 |
abc_sheet.Feed[1].f['chloroform'] := 2.5{mole/s}; |
430 |
abc_sheet.Feed[1].f['benzene'] := 4.0{mole/s}; |
431 |
abc_sheet.Distillate[1].Ftot := 3.5{mole/s}; |
432 |
abc_sheet.Column[1].rectifying_section.stot := 10; |
433 |
abc_sheet.Column[1].stripping_section.stot := 10; |
434 |
abc_sheet.feed_state[1].phi['vapor'] := 0; |
435 |
abc_sheet.Column[1].condenser.reflux_ratio := 4.0; |
436 |
abc_sheet.Column[1].s_stack[1] := 20.0; |
437 |
abc_sheet.Column[1].s_stack[2] := 15.0; |
438 |
abc_sheet.feed_T[1] := 298 {K}; |
439 |
abc_sheet.feed_P[1] := 1{atm}; |
440 |
RUN abc_sheet.Column[1].propagate_feed; |
441 |
|
442 |
abc_sheet.Column[2].feed_tray_state.alpha['acetone'] := 1.76; |
443 |
abc_sheet.Column[2].feed_tray_state.alpha['benzene'] := 0.79; |
444 |
abc_sheet.Column[2].feed_tray_state.alpha['chloroform'] := 1.22; |
445 |
abc_sheet.Feed[2].f['acetone'] := 0.2{mole/s}; |
446 |
abc_sheet.Feed[2].f['chloroform'] := 2.5{mole/s}; |
447 |
abc_sheet.Feed[2].f['benzene'] := 4.0{mole/s}; |
448 |
abc_sheet.Distillate[2].Ftot := 2.675{mole/s}; |
449 |
abc_sheet.Column[2].rectifying_section.stot := 10; |
450 |
abc_sheet.Column[2].stripping_section.stot := 7; |
451 |
abc_sheet.feed_state[2].phi['vapor'] := 0; |
452 |
abc_sheet.Column[2].condenser.reflux_ratio := 4.25; |
453 |
abc_sheet.feed_T[2] := 298 {K}; |
454 |
abc_sheet.feed_P[2] := 1{atm}; |
455 |
RUN abc_sheet.Column[2].propagate_feed; |
456 |
|
457 |
abc_sheet.Column[3].feed_tray_state.alpha['acetone'] := 1.0; |
458 |
abc_sheet.Column[3].feed_tray_state.alpha['benzene'] := 0.6; |
459 |
abc_sheet.Column[3].feed_tray_state.alpha['chloroform'] := 1.11; |
460 |
abc_sheet.Feed[3].f['acetone'] := 0.3{mole/s}; |
461 |
abc_sheet.Feed[3].f['chloroform'] := 2.5{mole/s}; |
462 |
abc_sheet.Feed[3].f['benzene'] := 0.1{mole/s}; |
463 |
abc_sheet.Distillate[3].Ftot := 2.2{mole/s}; |
464 |
abc_sheet.Column[3].rectifying_section.stot := 10; |
465 |
abc_sheet.Column[3].stripping_section.stot := 5; |
466 |
abc_sheet.feed_state[3].phi['vapor'] := 0; |
467 |
abc_sheet.Column[3].condenser.reflux_ratio := 4.0; |
468 |
abc_sheet.feed_T[3] := 298 {K}; |
469 |
abc_sheet.feed_P[3] := 1{atm}; |
470 |
RUN abc_sheet.Column[3].propagate_feed; |
471 |
|
472 |
abc_sheet.Sheet_Feed[1].f['acetone'] := 3.5{mole/s}; |
473 |
abc_sheet.Sheet_Feed[1].f['chloroform'] := 2.5{mole/s}; |
474 |
abc_sheet.Sheet_Feed[1].f['benzene'] := 4.0{mole/s}; |
475 |
abc_sheet.sheet_feed_T[1] := 298 {K}; |
476 |
abc_sheet.sheet_feed_P[1] := 1{atm}; |
477 |
|
478 |
abc_sheet.z_on[1..n_columns] := FALSE; |
479 |
abc_sheet.hat_on[1..n_columns] := FALSE; |
480 |
abc_sheet.hb_on[1..n_columns] := FALSE; |
481 |
abc_sheet.Equilibrated[1..n_columns] := FALSE; |
482 |
|
483 |
abc_sheet.Distillate[1..n_columns].saturated := FALSE; |
484 |
abc_sheet.Bottoms[1..n_columns].saturated := FALSE; |
485 |
abc_sheet.Product[1..CARD[components]+1].saturated := FALSE; |
486 |
abc_sheet.Sheet_Feed[1..abc_sheet.n_sheet_feeds].saturated := FALSE; |
487 |
(* abc_sheet.Source_Link[abc_sheet.sources][abc_sheet.sinks].saturated |
488 |
:= FALSE;*) |
489 |
|
490 |
END values; |
491 |
|
492 |
END abc_demo_sheet; |