1 |
REQUIRE "flash.a4l"; |
2 |
REQUIRE "simpleUnits.AWW.a4c"; |
3 |
|
4 |
(* |
5 |
|
6 |
------------ |
7 |
| | |
8 |
-------------------------->|U4: splitter|---> bleed |
9 |
| | | |
10 |
| ------------ |
11 |
| ^ |
12 |
V | |
13 |
----------- ----------- ------------ |
14 |
| | | | | | |
15 |
--->|U1: mixer |--->|U2: reactor|--->|U3: flash | |
16 |
| | | | | | |
17 |
----------- ----------- ------------ |
18 |
2C2H6 -->C4H12 | |
19 |
| |
20 |
---------> product |
21 |
|
22 |
*) |
23 |
|
24 |
|
25 |
MODEL simpleFS; |
26 |
(* this demo is a reproduction of simpleFS using |
27 |
the models in simpleUnits along with a rigorous |
28 |
flash for the separation step *) |
29 |
|
30 |
(* Set up the thermo calculations *) |
31 |
|
32 |
compsC3, compsAll IS_A set OF symbol_constant; |
33 |
compsC3 :== ['propylene', 'propane']; |
34 |
compsAll :== ['propylene', 'propane', '2_hexene_cis']; |
35 |
|
36 |
cdC3 IS_A components_data(compsC3, 'propane'); |
37 |
cdAll IS_A components_data(compsAll, 'propane'); |
38 |
|
39 |
pdV IS_A phases_data('V','Pitzer_vapor_mixture','none','none'); |
40 |
pdL IS_A phases_data('L', 'none', 'UNIFAC_liquid_mixture','none'); |
41 |
pdVL IS_A phases_data('VL','Pitzer_vapor_mixture', |
42 |
'UNIFAC_liquid_mixture','none'); |
43 |
|
44 |
equil IS_A boolean; |
45 |
|
46 |
(* define feed streams *) |
47 |
S01C3Feed IS_A stream(cdC3, pdV, equil); |
48 |
|
49 |
(* define units and their output streams *) |
50 |
|
51 |
(* U1: feed mixer and heater *) |
52 |
Qmix IS_A energy_rate; |
53 |
S12reactFeed IS_A stream(cdAll, pdVL, equil); |
54 |
U1feedMixer IS_A unitTwoInOneOut(Qmix, S01C3Feed, S51recycle, S12reactFeed); |
55 |
|
56 |
(* U2: reactor *) |
57 |
Qreactor IS_A energy_rate; |
58 |
S23reactProd IS_A stream(cdAll, pdV, equil); |
59 |
U2reactor IS_A unitOneInOneOut(Qreactor, S12reactFeed, S23reactProd); |
60 |
conv IS_A fraction; |
61 |
U2reactor.product.f['propylene'] = (1-conv)*U2reactor.feed.f['propylene']; |
62 |
|
63 |
(* U3: flash *) |
64 |
Qflash IS_A energy_rate; |
65 |
S34flashV IS_A stream(cdAll, pdV, equil); |
66 |
S30flashL IS_A stream(cdAll, pdL, equil); |
67 |
U3flash IS_A vapor_liquid_flash( |
68 |
Qflash, equil, S23reactProd, S34flashV, S30flashL); |
69 |
|
70 |
(* U4: splitter *) |
71 |
Qsplitter IS_A energy_rate; |
72 |
S40bleed IS_A stream(cdAll, pdV, equil); |
73 |
S45compFeed IS_A stream(cdAll, pdV, equil); |
74 |
U4splitter IS_A unitOneInTwoOut(Qsplitter, S34flashV, S45compFeed, S40bleed); |
75 |
(* merge all splits for simple stream splitter *) |
76 |
splitRecycle IS_A fraction; |
77 |
splitRecycle, U4splitter.split[compsAll] ARE_THE_SAME; |
78 |
|
79 |
(* U5: compressor *) |
80 |
Qcomp IS_A energy_rate; |
81 |
effU5 IS_A fraction; |
82 |
compRatioU5 IS_A factor; |
83 |
S51recycle IS_A stream(cdAll, pdV, equil); |
84 |
U5compressor IS_A simpleCompressor(Qcomp, compRatioU5, effU5, S45compFeed, S51recycle); |
85 |
|
86 |
(* recycle pressure should be that of the feed *) |
87 |
U5compressor.product.P = U1feedMixer.feed1.P; |
88 |
|
89 |
|
90 |
(* various objectives we can optimize *) |
91 |
MaxHexeneProd: MAXIMIZE S30flashL.f['2_hexene_cis']; |
92 |
|
93 |
METHODS |
94 |
|
95 |
METHOD default_self; |
96 |
RUN U1feedMixer.default_self; |
97 |
RUN U2reactor.default_self; |
98 |
RUN U3flash.default_self; |
99 |
RUN U4splitter.default_self; |
100 |
RUN U5compressor.default_self; |
101 |
END default_self; |
102 |
|
103 |
METHOD values; |
104 |
equil := FALSE; |
105 |
|
106 |
(* feed streams *) |
107 |
S01C3Feed.f['propylene'] := 0.98 {mol/s}; |
108 |
S01C3Feed.f['propane'] := 0.02 {mol/s}; |
109 |
S01C3Feed.T := 423.15 {K}; (* 150 degC *) |
110 |
S01C3Feed.P := 20 {bar}; |
111 |
|
112 |
(* U1 feed mixer *) |
113 |
(* set a pressure drop for the unit *) |
114 |
U1feedMixer.delP1 := -5.0 {psia}; |
115 |
|
116 |
(* U2 reactor *) |
117 |
U2reactor.delP := -5.0 {psia}; |
118 |
U2reactor.stoichCoef['propylene'] := -2; |
119 |
U2reactor.stoichCoef['2_hexene_cis'] := 1; |
120 |
conv := 0.8; |
121 |
|
122 |
(* U3 flash *) |
123 |
U3flash.liqout.P := 10 {bar}; |
124 |
U3flash.liqout.T := 400 {K}; |
125 |
U3flash.alpha['propylene'] := 7; |
126 |
U3flash.alpha['propane'] := 8; |
127 |
U3flash.alpha['2_hexene_cis'] := 1; |
128 |
U3flash.state.phase_fraction['vapor'] := 0.5; |
129 |
|
130 |
(* U4 splitter *) |
131 |
splitRecycle := 0.98; |
132 |
|
133 |
(* U5 compressor *) |
134 |
U5compressor.efficiency := 0.95; |
135 |
END values; |
136 |
|
137 |
METHOD specify; |
138 |
(* Each unit runs the specify method for each of its |
139 |
streams. It then releases the fixed flags for |
140 |
the component flows, T and P of its product |
141 |
streams. |
142 |
|
143 |
Only the recycle stream is overspecified |
144 |
after running the unit specify methods if |
145 |
we run them in the reverse order *) |
146 |
|
147 |
RUN U5compressor.specify; |
148 |
RUN U4splitter.specify; |
149 |
RUN U3flash.specify; |
150 |
RUN U2reactor.specify; |
151 |
RUN U1feedMixer.specify; |
152 |
|
153 |
(* release specs set by splitter for flash vapor *) |
154 |
S34flashV.f[compsAll].fixed := FALSE; |
155 |
|
156 |
(* release specs for recycle stream *) |
157 |
S51recycle.f[compsAll].fixed := FALSE; |
158 |
S51recycle.T.fixed := FALSE; |
159 |
S51recycle.P.fixed := FALSE; |
160 |
|
161 |
(* U1: feed mixer *) |
162 |
(* fix product temperature of feed mixer *) |
163 |
U1feedMixer.delT1.fixed := TRUE; |
164 |
U1feedMixer.Qin.fixed := FALSE; |
165 |
|
166 |
(* U2: reactor *) |
167 |
(* fix conversion *) |
168 |
conv.fixed := TRUE; |
169 |
U2reactor.turnover.fixed := FALSE; |
170 |
(* product temperature is same as that of feed *) |
171 |
U2reactor.delT.fixed := TRUE; |
172 |
U2reactor.Qin.fixed := FALSE; |
173 |
|
174 |
(* U3: flash *) |
175 |
(* flash P and vapor fraction already fixed *) |
176 |
|
177 |
(* U4: splitter *) |
178 |
|
179 |
(* U5: compressor *) |
180 |
U5compressor.compressionRatio.fixed := FALSE; |
181 |
|
182 |
END specify; |
183 |
|
184 |
END simpleFS; |