1 |
REQUIRE "dyn_flash.a4l"; |
2 |
(* => dyn_flash.a4l, splitter.a4l, stream_holdup.a4l thermodynamics.a4l, |
3 |
* components.a4l, phases.a4l, atoms.a4l, measures.a4l, system.a4l, |
4 |
* basemodel.a4l *) |
5 |
PROVIDE "dyn_column.a4l"; |
6 |
|
7 |
(* |
8 |
* dyn_colunm.a4l |
9 |
* by Duncan Coffey |
10 |
* Part of the ASCEND Library |
11 |
* $Date: 1998/06/17 19:01:29 $ |
12 |
* $Revision: 1.2 $ |
13 |
* $Author: mthomas $ |
14 |
* $Source: /afs/cs.cmu.edu/project/ascend/Repository/models/dyn_column.a4l,v $ |
15 |
* |
16 |
* This file is part of the ASCEND Modeling Library. |
17 |
* |
18 |
* Copyright (C) 1998 Duncan Coffey |
19 |
* |
20 |
* The ASCEND Modeling Library is free software; you can redistribute |
21 |
* it and/or modify it under the terms of the GNU General Public |
22 |
* License as published by the Free Software Foundation; either |
23 |
* version 2 of the License, or (at your option) any later version. |
24 |
* |
25 |
* The ASCEND Modeling Library is distributed in hope that it |
26 |
* will be useful, but WITHOUT ANY WARRANTY; without even the implied |
27 |
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
28 |
* See the GNU General Public License for more details. |
29 |
* |
30 |
* You should have received a copy of the GNU General Public License |
31 |
* along with the program; if not, write to the Free Software |
32 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check |
33 |
* the file named COPYING. |
34 |
*) |
35 |
|
36 |
|
37 |
(********************************************************************* |
38 |
* Requires an empty ascend system. |
39 |
*********************************************************************) |
40 |
|
41 |
|
42 |
(* ***********************************+************************************ *) |
43 |
(* ******************** Reactor ********************* *) |
44 |
(* ***********************************+************************************ *) |
45 |
|
46 |
MODEL tray_stack( |
47 |
ntrays WILL_BE integer_constant; |
48 |
vapin WILL_BE stream; |
49 |
liqin WILL_BE stream; |
50 |
vapout WILL_BE stream; |
51 |
liqout WILL_BE stream; |
52 |
t WILL_BE solver_var; |
53 |
dynamic WILL_BE boolean; |
54 |
ode_offset WILL_BE ode_counter; |
55 |
obs_offset WILL_BE obs_counter; |
56 |
)WHERE( |
57 |
ntrays > 1; |
58 |
liqout.state, vapout.state WILL_NOT_BE_THE_SAME; |
59 |
vapin.state.cd, vapout.state.cd WILL_BE_THE_SAME; |
60 |
vapin.pd.phase_indicator == 'V'; |
61 |
liqin.pd.phase_indicator == 'L'; |
62 |
vapout.pd.phase_indicator == 'V'; |
63 |
liqout.pd.phase_indicator == 'L'; |
64 |
)REFINES cmumodel; |
65 |
|
66 |
cd ALIASES liqout.cd; |
67 |
pdV ALIASES vapout.pd; |
68 |
pdL ALIASES liqout.pd; |
69 |
equilibrated ALIASES liqout.equilibrated; |
70 |
pdVL IS_A phases_data('VL', vapout.pd.vapor_option, |
71 |
liqout.pd.liquid1_option, 'none'); |
72 |
|
73 |
vap_option ALIASES vapout.pd.vapor_option; |
74 |
liq_option ALIASES liqout.pd.liquid1_option; |
75 |
tmp_phaseV[2..ntrays] IS_A select_mixture_type(cd, vap_option); |
76 |
tmp_phaseL[2..ntrays] IS_A select_mixture_type(cd, liq_option); |
77 |
FOR i IN [2..ntrays] CREATE |
78 |
phaseV[i]['vapor'] ALIASES tmp_phaseV[i].phase; |
79 |
phaseL[i]['liquid1'] ALIASES tmp_phaseL[i].phase; |
80 |
END FOR; |
81 |
FOR i IN [2..ntrays] CREATE |
82 |
vapor_state[i] IS_A thermodynamics(cd,pdV,phaseV[i],equilibrated); |
83 |
liquid_state[i] IS_A thermodynamics(cd,pdL,phaseL[i],equilibrated); |
84 |
END FOR; |
85 |
FOR i IN [2..ntrays] CREATE |
86 |
tmp_vapor[i] IS_A detailed_stream(vapor_state[i]); |
87 |
tmp_liquid[i] IS_A detailed_stream(liquid_state[i]); |
88 |
END FOR; |
89 |
|
90 |
vapor[V_set_trays] |
91 |
ALIASES (vapout.Details,tmp_vapor[2..ntrays],vapin.Details) |
92 |
WHERE V_set_trays IS_A set OF integer_constant |
93 |
WITH_VALUE (1..ntrays+1); |
94 |
|
95 |
liquid[L_set_trays] |
96 |
ALIASES (liqin.Details,tmp_liquid[2..ntrays],liqout.Details) |
97 |
WHERE L_set_trays IS_A set OF integer_constant |
98 |
WITH_VALUE (1..ntrays+1); |
99 |
|
100 |
FOR i IN [1..ntrays] CREATE |
101 |
phaseVL[i][VLphases[i]] ALIASES |
102 |
(vapor[i].state.phase['vapor'],liquid[i+1].state.phase['liquid1']) |
103 |
WHERE VLphases[i] IS_A set OF symbol_constant |
104 |
WITH_VALUE ('vapor','liquid1'); |
105 |
END FOR; |
106 |
FOR i IN [1..ntrays] CREATE |
107 |
tray_state[i] IS_A thermodynamics(cd,pdVL,phaseVL[i],equilibrated); |
108 |
END FOR; |
109 |
FOR i IN [1..ntrays] CREATE |
110 |
tray[i] IS_A detailed_tray(liquid[i], vapor[i+1], liquid[i+1], |
111 |
vapor[i], tray_state[i], t, |
112 |
dynamic, ode_offset, obs_offset); |
113 |
END FOR; |
114 |
|
115 |
FOR i IN [1..ntrays] CREATE |
116 |
Vol[i] ALIASES tray[i].Vol; |
117 |
vol_liq[i] ALIASES tray[i].vol_liq; |
118 |
vol_vap[i] ALIASES tray[i].vol_vap; |
119 |
cmo_ratio[i] ALIASES tray[i].cmo_ratio; |
120 |
tray_T[i] ALIASES tray[i].T; |
121 |
tray_P[i] ALIASES tray[i].P; |
122 |
Qin[i] ALIASES tray[i].Qin; |
123 |
END FOR; |
124 |
|
125 |
METHODS |
126 |
METHOD check_self; |
127 |
FOR i IN [2..ntrays] DO |
128 |
IF (liquid[i].flow < 1e-4 {mole/s}) THEN |
129 |
STOP {liquid flow to tray i dried up}; |
130 |
END IF; |
131 |
IF (vapor[i].flow < 1e-4 {mole/s}) THEN |
132 |
STOP {vapor flow from tray i dried up}; |
133 |
END IF; |
134 |
END FOR; |
135 |
IF (abs(vapin.flow+liqin.flow - vapout.flow - liqout.flow) |
136 |
> 1.0e-4) THEN |
137 |
STOP {stack violates overall mass-balance}; |
138 |
END IF; |
139 |
RUN tray_state[1..ntrays].check_self; |
140 |
END check_self; |
141 |
|
142 |
METHOD check_all; |
143 |
IF (liqout.flow < 1e-4 {mole/s}) THEN |
144 |
STOP {Liquid flow dried up in stack}; |
145 |
END IF; |
146 |
IF (vapout.flow < 1e-4 {mole/s}) THEN |
147 |
STOP {All vapor condensed in stack}; |
148 |
END IF; |
149 |
IF (vapin.flow < 1e-4 {mole/s}) THEN |
150 |
STOP {No vapin flowing to stack}; |
151 |
END IF; |
152 |
IF (liqin.flow < 1e-4 {mole/s}) THEN |
153 |
STOP {No liqin flowing to stack}; |
154 |
END IF; |
155 |
RUN check_self; |
156 |
END check_all; |
157 |
|
158 |
METHOD default_self; |
159 |
RUN vapor[2..ntrays].default_self; |
160 |
RUN liquid[2..ntrays].default_self; |
161 |
RUN pdVL.default_self; |
162 |
RUN phaseVL[1..ntrays][VLphases[1..ntrays]].default_self; |
163 |
RUN tray_state[1..ntrays].default_self; |
164 |
RUN tray[1..ntrays].default_self; |
165 |
END default_self; |
166 |
|
167 |
METHOD default_all; |
168 |
RUN vapin.default_self; |
169 |
RUN liqin.default_self; |
170 |
RUN vapout.default_self; |
171 |
RUN liqout.default_self; |
172 |
RUN default_self; |
173 |
END default_all; |
174 |
METHOD bound_self; |
175 |
RUN vapor[2..ntrays].bound_self; |
176 |
RUN liquid[1..ntrays].bound_self; |
177 |
RUN tray_state[1..ntrays].bound_self; |
178 |
RUN tray[1..ntrays].bound_self; |
179 |
END bound_self; |
180 |
METHOD bound_all; |
181 |
RUN vapin.bound_self; |
182 |
RUN liqin.bound_self; |
183 |
RUN vapout.bound_self; |
184 |
RUN liqout.bound_self; |
185 |
RUN bound_self; |
186 |
END bound_all; |
187 |
METHOD scale_self; |
188 |
RUN vapor[2..ntrays].scale_self; |
189 |
RUN liquid[1..ntrays].scale_self; |
190 |
RUN tray_state[1..ntrays].scale_self; |
191 |
RUN tray[1..ntrays].scale_self; |
192 |
END scale_self; |
193 |
METHOD scale_all; |
194 |
RUN vapin.scale_self; |
195 |
RUN liqin.scale_self; |
196 |
RUN vapout.scale_self; |
197 |
RUN liqout.scale_self; |
198 |
RUN scale_self; |
199 |
END scale_all; |
200 |
METHOD seqmod; |
201 |
RUN tray[1..ntrays].seqmod; |
202 |
END seqmod; |
203 |
METHOD specify; |
204 |
RUN vapin.specify; |
205 |
RUN liqin.specify; |
206 |
RUN seqmod; |
207 |
END specify; |
208 |
METHOD reset_to_adiabatic; |
209 |
RUN seqmod; |
210 |
Qin[1..ntrays] :=0 {kW}; |
211 |
FREE cmo_ratio[1..ntrays]; |
212 |
FIX Qin[1..ntrays]; |
213 |
END reset_to_adiabatic; |
214 |
METHOD set_ode; |
215 |
RUN tray[1..ntrays].set_ode; |
216 |
END set_ode; |
217 |
METHOD set_obs; |
218 |
RUN tray[1..ntrays].set_obs; |
219 |
END set_obs; |
220 |
END tray_stack; |
221 |
|
222 |
MODEL column( |
223 |
vap_distillate WILL_BE stream; |
224 |
liq_distillate WILL_BE stream; |
225 |
con_partial WILL_BE boolean; |
226 |
n_trays_above WILL_BE integer_constant; |
227 |
feed WILL_BE stream; |
228 |
n_trays_below WILL_BE integer_constant; |
229 |
reboil_partial WILL_BE boolean; |
230 |
vap_bottoms WILL_BE stream; |
231 |
liq_bottoms WILL_BE stream; |
232 |
t WILL_BE solver_var; |
233 |
dynamic WILL_BE boolean; |
234 |
ode_offset WILL_BE ode_counter; |
235 |
obs_offset WILL_BE obs_counter; |
236 |
)WHERE( |
237 |
n_trays_above > 1; |
238 |
n_trays_below > 1; |
239 |
feed.state, vap_bottoms.state, vap_distillate.state, |
240 |
liq_bottoms.state, liq_distillate.state WILL_NOT_BE_THE_SAME; |
241 |
feed.state.cd, vap_distillate.state.cd, vap_bottoms.state.cd, |
242 |
liq_distillate.state.cd, liq_bottoms.state.cd WILL_BE_THE_SAME; |
243 |
(feed.pd.phase_indicator IN ['V','L','VL','VLL']) == TRUE; |
244 |
liq_bottoms.pd.phase_indicator == 'L'; |
245 |
vap_bottoms.pd.phase_indicator == 'V'; |
246 |
liq_distillate.pd.phase_indicator == 'L'; |
247 |
vap_distillate.pd.phase_indicator == 'V'; |
248 |
)REFINES cmumodel; |
249 |
|
250 |
cd ALIASES feed.cd; |
251 |
pdV ALIASES vap_distillate.pd; |
252 |
pdL ALIASES liq_distillate.pd; |
253 |
equilibrated ALIASES vap_distillate.equilibrated; |
254 |
|
255 |
tray_P[tmp1] ALIASES (top_stack.tray_P[1..n_trays_above],feed_tray.P, |
256 |
bottom_stack.tray_P[1..n_trays_below]) WHERE tmp1 IS_A set OF integer_constant |
257 |
WITH_VALUE (1..n_trays_above+n_trays_below+1); |
258 |
tray_T[tmp2] ALIASES (top_stack.tray_T[1..n_trays_above],feed_tray.T, |
259 |
bottom_stack.tray_T[1..n_trays_below]) WHERE tmp2 IS_A set OF integer_constant |
260 |
WITH_VALUE (1..n_trays_above+n_trays_below+1); |
261 |
cmo_ratio[tmp3] ALIASES (top_stack.cmo_ratio[1..n_trays_above],feed_tray.q, |
262 |
bottom_stack.cmo_ratio[1..n_trays_below]) WHERE tmp3 IS_A set OF integer_constant |
263 |
WITH_VALUE (1..n_trays_above+n_trays_below+1); |
264 |
Qin[tmp4] ALIASES (top_stack.Qin[1..n_trays_above],feed_tray.Qin, |
265 |
bottom_stack.Qin[1..n_trays_below]) WHERE tmp4 IS_A set OF integer_constant |
266 |
WITH_VALUE (1..n_trays_above+n_trays_below+1); |
267 |
|
268 |
col_feed ALIASES feed_tray.feed; |
269 |
vapor_distillate ALIASES condenser.vap_distillate; |
270 |
liquid_distillate ALIASES condenser.liq_distillate; |
271 |
reflux_ratio ALIASES condenser.reflux_ratio; |
272 |
condenser_T ALIASES condenser.T; |
273 |
condenser_P ALIASES condenser.P; |
274 |
vapor_bottoms ALIASES reboiler.vap_bottom; |
275 |
liquid_bottoms ALIASES reboiler.liq_bottom; |
276 |
reboil_ratio ALIASES reboiler.reboil_ratio; |
277 |
reboiler_T ALIASES reboiler.T; |
278 |
reboiler_P ALIASES reboiler.P; |
279 |
|
280 |
condenser_liqout IS_A stream(cd,pdL,equilibrated); |
281 |
top_stack_vapout IS_A stream(cd,pdV,equilibrated); |
282 |
top_stack_liqout IS_A stream(cd,pdL,equilibrated); |
283 |
feed_vapout IS_A stream(cd,pdV,equilibrated); |
284 |
feed_liqout IS_A stream(cd,pdL,equilibrated); |
285 |
bottom_stack_vapout IS_A stream(cd,pdV,equilibrated); |
286 |
bottom_stack_liqout IS_A stream(cd,pdL,equilibrated); |
287 |
reboiler_vapout IS_A stream(cd,pdV,equilibrated); |
288 |
|
289 |
condenser IS_A condenser(top_stack_vapout,vap_distillate,liq_distillate, |
290 |
condenser_liqout,con_partial,t,dynamic,ode_offset,obs_offset); |
291 |
|
292 |
top_stack IS_A tray_stack(n_trays_above,feed_vapout,condenser_liqout, |
293 |
top_stack_vapout,top_stack_liqout,t,dynamic,ode_offset,obs_offset); |
294 |
|
295 |
feed_tray IS_A feed_tray(feed,top_stack_liqout,bottom_stack_vapout, |
296 |
feed_liqout,feed_vapout,t,dynamic,ode_offset,obs_offset); |
297 |
|
298 |
bottom_stack IS_A tray_stack(n_trays_below,reboiler_vapout,feed_liqout, |
299 |
bottom_stack_vapout,bottom_stack_liqout,t,dynamic,ode_offset,obs_offset); |
300 |
|
301 |
reboiler IS_A reboiler(bottom_stack_liqout,vap_bottoms,liq_bottoms, |
302 |
reboiler_vapout,reboil_partial,t,dynamic,ode_offset,obs_offset); |
303 |
|
304 |
METHODS |
305 |
METHOD check_self; |
306 |
RUN condenser.check_self; |
307 |
RUN top_stack_vapout.check_self; |
308 |
RUN condenser_liqout.check_self; |
309 |
RUN top_stack.check_self; |
310 |
RUN top_stack_liqout.check_self; |
311 |
RUN feed_vapout.check_self; |
312 |
RUN feed_tray.check_self; |
313 |
RUN feed_liqout.check_self; |
314 |
RUN bottom_stack_vapout.check_self; |
315 |
RUN bottom_stack.check_self; |
316 |
RUN bottom_stack.liqout.check_self; |
317 |
RUN reboiler_vapout.check_self; |
318 |
RUN reboiler.check_self; |
319 |
IF (abs(feed.flow-vap_distillate.flow-liq_distillate.flow |
320 |
-vap_bottoms.flow-liq_bottoms.flow) > 1.0e-4) THEN |
321 |
STOP {column violates overall mass-balance}; |
322 |
END IF; |
323 |
END check_self; |
324 |
|
325 |
METHOD check_all; |
326 |
IF con_partial THEN |
327 |
IF (vap_distillate.flow < 1e-4 {mole/s}) THEN |
328 |
STOP {vapor distillate flow dried up}; |
329 |
END IF; |
330 |
ELSE |
331 |
IF (liq_distillate.flow < 1e-4 {mole/s}) THEN |
332 |
STOP {liquid distillate flow dried up}; |
333 |
END IF; |
334 |
END IF; |
335 |
IF (feed.flow < 1e-4 {mole/s}) THEN |
336 |
STOP {distillate feed flow dried up}; |
337 |
END IF; |
338 |
IF reboil_partial THEN |
339 |
IF (liq_bottoms.flow < 1e-4 {mole/s}) THEN |
340 |
STOP {liquid bottoms flow dried up}; |
341 |
END IF; |
342 |
ELSE |
343 |
IF (vap_bottoms.flow < 1e-4 {mole/s}) THEN |
344 |
STOP {vapor bottoms flow dried up}; |
345 |
END IF; |
346 |
END IF; |
347 |
RUN check_self; |
348 |
END check_all; |
349 |
METHOD default_self; |
350 |
RUN top_stack_vapout.default_self; |
351 |
RUN condenser.default_self; |
352 |
RUN condenser_liqout.default_self; |
353 |
RUN top_stack.default_self; |
354 |
RUN top_stack_liqout.default_self; |
355 |
RUN feed_vapout.default_self; |
356 |
RUN feed_liqout.default_self; |
357 |
RUN feed_tray.default_self; |
358 |
RUN bottom_stack_vapout.default_self; |
359 |
RUN bottom_stack.default_self; |
360 |
RUN bottom_stack.liqout.default_self; |
361 |
RUN reboiler_vapout.default_self; |
362 |
RUN reboiler.default_self; |
363 |
END default_self; |
364 |
METHOD default_all; |
365 |
RUN feed.default_self; |
366 |
RUN vap_distillate.default_self; |
367 |
RUN liq_distillate.default_self; |
368 |
RUN liq_bottoms.default_self; |
369 |
RUN vap_bottoms.default_self; |
370 |
RUN default_self; |
371 |
END default_all; |
372 |
METHOD bound_self; |
373 |
RUN condenser.bound_self; |
374 |
RUN top_stack_vapout.bound_self; |
375 |
RUN condenser_liqout.bound_self; |
376 |
RUN top_stack.bound_self; |
377 |
RUN top_stack_liqout.bound_self; |
378 |
RUN feed_vapout.bound_self; |
379 |
RUN feed_tray.bound_self; |
380 |
RUN feed_liqout.bound_self; |
381 |
RUN bottom_stack_vapout.bound_self; |
382 |
RUN bottom_stack.bound_self; |
383 |
RUN bottom_stack.liqout.bound_self; |
384 |
RUN reboiler_vapout.bound_self; |
385 |
RUN reboiler.bound_self; |
386 |
END bound_self; |
387 |
METHOD bound_all; |
388 |
RUN feed.bound_self; |
389 |
RUN vap_distillate.bound_self; |
390 |
RUN liq_distillate.bound_self; |
391 |
RUN liq_bottoms.bound_self; |
392 |
RUN vap_bottoms.bound_self; |
393 |
RUN bound_self; |
394 |
END bound_all; |
395 |
METHOD scale_self; |
396 |
RUN condenser.scale_self; |
397 |
RUN top_stack_vapout.scale_self; |
398 |
RUN condenser_liqout.scale_self; |
399 |
RUN top_stack.scale_self; |
400 |
RUN top_stack_liqout.scale_self; |
401 |
RUN feed_vapout.scale_self; |
402 |
RUN feed_tray.scale_self; |
403 |
RUN feed_liqout.scale_self; |
404 |
RUN bottom_stack_vapout.scale_self; |
405 |
RUN bottom_stack.scale_self; |
406 |
RUN bottom_stack.liqout.scale_self; |
407 |
RUN reboiler_vapout.scale_self; |
408 |
RUN reboiler.scale_self; |
409 |
END scale_self; |
410 |
METHOD scale_all; |
411 |
RUN feed.scale_self; |
412 |
RUN vap_distillate.scale_self; |
413 |
RUN liq_distillate.scale_self; |
414 |
RUN liq_bottoms.scale_self; |
415 |
RUN vap_bottoms.scale_self; |
416 |
RUN scale_self; |
417 |
END scale_all; |
418 |
METHOD seqmod; |
419 |
RUN condenser.seqmod; |
420 |
RUN top_stack.seqmod; |
421 |
RUN feed_tray.seqmod; |
422 |
RUN bottom_stack.seqmod; |
423 |
RUN reboiler.seqmod; |
424 |
END seqmod; |
425 |
METHOD specify; |
426 |
RUN feed.specify; |
427 |
RUN seqmod; |
428 |
END specify; |
429 |
METHOD reset_to_adiabatic; |
430 |
RUN seqmod; |
431 |
RUN top_stack.reset_to_adiabatic; |
432 |
RUN feed_tray.reset_to_adiabatic; |
433 |
RUN bottom_stack.reset_to_adiabatic; |
434 |
END reset_to_adiabatic; |
435 |
METHOD set_ode; |
436 |
RUN condenser.set_ode; |
437 |
RUN top_stack.set_ode; |
438 |
RUN feed_tray.set_ode; |
439 |
RUN bottom_stack.set_ode; |
440 |
RUN reboiler.set_ode; |
441 |
END set_ode; |
442 |
METHOD set_obs; |
443 |
RUN condenser.set_obs; |
444 |
RUN top_stack.set_obs; |
445 |
RUN feed_tray.set_obs; |
446 |
RUN bottom_stack.set_obs; |
447 |
RUN reboiler.set_obs; |
448 |
END set_obs; |
449 |
END column; |
450 |
|
451 |
|
452 |
|
453 |
(***************************************************************************) |
454 |
|
455 |
|
456 |
|
457 |
MODEL test_tray_stack() REFINES testflashmodel(); |
458 |
|
459 |
cd IS_A components_data(['methanol','ethanol','water'],'water'); |
460 |
pdV IS_A phases_data('V', 'Pitzer_vapor_mixture', 'none', 'none'); |
461 |
pdL IS_A phases_data('L', 'none', 'UNIFAC_liquid_mixture', 'none'); |
462 |
equilibrated IS_A boolean; |
463 |
vin IS_A stream(cd,pdV,equilibrated); |
464 |
lin IS_A stream(cd,pdL,equilibrated); |
465 |
lout IS_A stream(cd,pdL,equilibrated); |
466 |
vout IS_A stream(cd,pdV,equilibrated); |
467 |
ntrays IS_A integer_constant; |
468 |
ntrays :==10; |
469 |
t IS_A time; |
470 |
dynamic IS_A boolean; |
471 |
ode_offset IS_A ode_counter; |
472 |
obs_offset IS_A obs_counter; |
473 |
fl1 IS_A tray_stack(ntrays, vin, lin, vout, lout, t, |
474 |
dynamic, ode_offset, obs_offset); |
475 |
|
476 |
(* boundwidth might be unit specific *) |
477 |
boundwidth IS_A bound_width; |
478 |
|
479 |
METHODS |
480 |
|
481 |
METHOD default_all; |
482 |
RUN default_self; |
483 |
END default_all; |
484 |
|
485 |
METHOD default_self; |
486 |
boundwidth := 10; |
487 |
equilibrated :=TRUE; |
488 |
ode_offset :=1; |
489 |
obs_offset :=1; |
490 |
RUN vin.default_self; |
491 |
RUN lin.default_self; |
492 |
RUN lout.default_self; |
493 |
RUN vout.default_self; |
494 |
RUN fl1.default_self; |
495 |
END default_self; |
496 |
|
497 |
METHOD check_all; |
498 |
RUN check_self; |
499 |
END check_all; |
500 |
|
501 |
METHOD check_self; |
502 |
RUN vin.check_self; |
503 |
RUN lin.check_self; |
504 |
RUN lout.check_self; |
505 |
RUN vout.check_self; |
506 |
RUN fl1.check_self; |
507 |
END check_self; |
508 |
|
509 |
METHOD bound_all; |
510 |
RUN bound_self; |
511 |
END bound_all; |
512 |
|
513 |
METHOD bound_self; |
514 |
fl1.boundwidth := boundwidth; |
515 |
lin.boundwidth := boundwidth; |
516 |
vin.boundwidth := boundwidth; |
517 |
lout.boundwidth := boundwidth; |
518 |
vout.boundwidth := boundwidth; |
519 |
RUN fl1.bound_all; |
520 |
END bound_self; |
521 |
|
522 |
METHOD scale_self; |
523 |
RUN vin.scale_self; |
524 |
RUN lin.scale_self; |
525 |
RUN lout.scale_self; |
526 |
RUN vout.scale_self; |
527 |
RUN fl1.scale_self; |
528 |
END scale_self; |
529 |
|
530 |
METHOD specify; |
531 |
RUN fl1.specify; |
532 |
END specify; |
533 |
|
534 |
METHOD values; |
535 |
vin.P := 1 {atm}; |
536 |
vin.T := 365 {K}; |
537 |
vin.f['methanol'] := 0.01 {kmol/s}; |
538 |
vin.f['ethanol'] := 0.015 {kmol/s}; |
539 |
vin.f['water'] := 0.02 {kmol/s}; |
540 |
lin.P := 1 {atm}; |
541 |
lin.T := 365 {K}; |
542 |
lin.f['methanol'] := 0.01 {kmol/s}; |
543 |
lin.f['ethanol'] := 0.015 {kmol/s}; |
544 |
lin.f['water'] := 0.02 {kmol/s}; |
545 |
FOR i IN [1..ntrays] DO |
546 |
fl1.cmo_ratio[i] := 1; |
547 |
fl1.tray_P[i] := 1 {atm}; |
548 |
fl1.tray_T[i] := 365 {K}; |
549 |
fl1.Qin[i] := 0 {kW}; |
550 |
fl1.Vol[i] := 3 {m^3}; |
551 |
fl1.vol_liq[i] := 1 {m^3}; |
552 |
END FOR; |
553 |
END values; |
554 |
|
555 |
END test_tray_stack; |
556 |
|
557 |
MODEL test_column() REFINES testflashmodel(); |
558 |
|
559 |
cd IS_A components_data(['n_pentane','n_hexane','n_heptane'],'n_heptane'); |
560 |
pdV IS_A phases_data('V', 'Pitzer_vapor_mixture', 'none', 'none'); |
561 |
pdL IS_A phases_data('L', 'none', 'UNIFAC_liquid_mixture', 'none'); |
562 |
equilibrated IS_A boolean; |
563 |
vap_dist IS_A stream(cd,pdV,equilibrated); |
564 |
liq_dist IS_A stream(cd,pdL,equilibrated); |
565 |
liq_bot IS_A stream(cd,pdL,equilibrated); |
566 |
vap_bot IS_A stream(cd,pdV,equilibrated); |
567 |
feed IS_A stream(cd,pdL,equilibrated); |
568 |
below IS_A integer_constant; |
569 |
below :==5; |
570 |
above IS_A integer_constant; |
571 |
above :==5; |
572 |
t IS_A time; |
573 |
dynamic IS_A boolean; |
574 |
C_partial IS_A boolean; |
575 |
R_partial IS_A boolean; |
576 |
ode_offset IS_A ode_counter; |
577 |
obs_offset IS_A obs_counter; |
578 |
col IS_A column(vap_dist,liq_dist,C_partial,above,feed,below,R_partial, |
579 |
vap_bot,liq_bot,t,dynamic,ode_offset,obs_offset); |
580 |
|
581 |
(* boundwidth might be unit specific *) |
582 |
boundwidth IS_A bound_width; |
583 |
|
584 |
METHODS |
585 |
|
586 |
METHOD default_all; |
587 |
RUN default_self; |
588 |
END default_all; |
589 |
|
590 |
METHOD default_self; |
591 |
boundwidth := 10; |
592 |
equilibrated :=FALSE; |
593 |
ode_offset :=1; |
594 |
obs_offset :=1; |
595 |
RUN vap_dist.default_self; |
596 |
RUN liq_dist.default_self; |
597 |
RUN feed.default_self; |
598 |
RUN vap_bot.default_self; |
599 |
RUN liq_bot.default_self; |
600 |
RUN col.default_self; |
601 |
END default_self; |
602 |
|
603 |
METHOD check_all; |
604 |
RUN check_self; |
605 |
END check_all; |
606 |
|
607 |
METHOD check_self; |
608 |
IF C_partial THEN |
609 |
RUN vap_dist.check_self; |
610 |
ELSE |
611 |
RUN liq_dist.check_self; |
612 |
END IF; |
613 |
RUN feed.check_self; |
614 |
IF R_partial THEN |
615 |
RUN liq_bot.check_self; |
616 |
ELSE |
617 |
RUN vap_bot.check_self; |
618 |
END IF; |
619 |
RUN col.check_self; |
620 |
END check_self; |
621 |
|
622 |
METHOD bound_all; |
623 |
RUN bound_self; |
624 |
END bound_all; |
625 |
|
626 |
METHOD bound_self; |
627 |
vap_dist.boundwidth := boundwidth; |
628 |
liq_dist.boundwidth := boundwidth; |
629 |
feed.boundwidth := boundwidth; |
630 |
liq_bot.boundwidth := boundwidth; |
631 |
vap_bot.boundwidth := boundwidth; |
632 |
RUN col.bound_all; |
633 |
END bound_self; |
634 |
|
635 |
METHOD scale_self; |
636 |
RUN vap_dist.scale_self; |
637 |
RUN liq_dist.scale_self; |
638 |
RUN feed.scale_self; |
639 |
RUN vap_bot.scale_self; |
640 |
RUN liq_bot.scale_self; |
641 |
RUN col.scale_self; |
642 |
END scale_self; |
643 |
|
644 |
METHOD scale_all; |
645 |
RUN scale_self; |
646 |
END scale_all; |
647 |
|
648 |
METHOD specify; |
649 |
RUN col.specify; |
650 |
END specify; |
651 |
|
652 |
METHOD values; |
653 |
feed.P := 1 {atm}; |
654 |
feed.T := 365 {K}; |
655 |
feed.f['n_pentane'] := 0.01 {kmol/s}; |
656 |
feed.f['n_hexane'] := 0.01 {kmol/s}; |
657 |
feed.f['n_heptane'] := 0.01 {kmol/s}; |
658 |
vap_dist.flow :=0 {mol/s}; |
659 |
vap_bot.flow :=0 {mol/s}; |
660 |
col.condenser.Vol :=3 {m^3}; |
661 |
col.condenser.vol_liq :=1 {m^3}; |
662 |
col.reflux_ratio :=1.5; |
663 |
col.feed_tray.Vol :=1 {m^3}; |
664 |
col.feed_tray.vol_liq :=0.3 {m^3}; |
665 |
col.feed_tray.q :=1; |
666 |
col.top_stack.Vol[1..above] :=1 {m^3}; |
667 |
col.top_stack.vol_liq[1..above] :=0.3 {m^3}; |
668 |
col.bottom_stack.Vol[1..above] :=1 {m^3}; |
669 |
col.bottom_stack.vol_liq[1..above] :=0.3 {m^3}; |
670 |
col.reboiler.Vol :=3 {m^3}; |
671 |
col.reboiler.vol_liq :=1 {m^3}; |
672 |
col.reboil_ratio :=2; |
673 |
END values; |
674 |
|
675 |
END test_column; |