1 #include "flash.hpp"
2 #include "bissection.cpp"
3 using namespace std;
4
flash(stream * in,stream * out_L,stream * out_V)5 flash::flash ( stream * in , stream * out_L , stream * out_V ) {
6 F = in;
7 Fcopy = new stream("Fcopy", F->nb, F->chem);
8 Tin = F->T;
9 z = new double[F->nb];
10 for ( i = 0 ; i < F->nb ; i++ )
11 z[i] = F->chem[i]->n()/F->n();
12
13 L = out_L;
14 V = out_V;
15 success = true;
16 K = new double[F->nb];
17 task=0;
18 solver = new bissection<flash>();
19 }
20
set(double p,double t)21 void flash::set(double p, double t)
22 {
23 P=p;
24 T=t;
25 for (i=0;i<F->nb;i++)
26 {
27 if(F->chem[i]->Tc<T) K[i] = F->chem[i]->Psat(T)/P;
28 else K[i]=1;
29 }
30 F->set(P,T);
31 }
32
solve()33 bool flash::solve()
34 {
35 L->purge();
36 V->purge();
37 f_x=F->quality();
38
39 if( 0.0 < f_x && f_x < 1.0)
40 {
41
42 // TOTO
43 for ( i = 0 ; i < F->nb ; i++ ) {
44 if ( F->chem[i]->Tc < T ) {
45 F->m -= F->chem[i]->m;
46 F->chem[i]->m = 0;
47 }
48 }
49
50 for ( i = 0 ; i < F->nb ; i++ )
51 z[i] = F->chem[i]->n()/F->n();
52
53 solver->set(this, 0.0, 1.0);
54
55 success=solver->run();
56
57 if (!success)
58 {
59 // if(task==0){
60 // log.open(MESSAGES, ios::app);
61 // log<<" --> Warning <-- Solver of FLASH "<<name<<" did not converge.\n";
62 // log.close();}
63 for (i=0;i<F->nb;i++)
64 {
65 if (T<F->chem[i]->Tc && T>F->chem[i]->Tboil(P)) {V->chem[i]->m=F->chem[i]->m; V->m+=V->chem[i]->m;}
66 if (T<F->chem[i]->Tc && T<=F->chem[i]->Tboil(P)) {L->chem[i]->m=F->chem[i]->m; L->m+=L->chem[i]->m;}
67 }
68 }
69 else
70 {
71
72 V->m = x*F->n();
73 L->m = F->n() - V->m;
74 //Distribute liquid components
75 for (i=0;i<L->nb;i++)
76 {
77 L->chem[i]->m = (L->m*z[i])/(1+x*(K[i]-1))*L->chem[i]->M/1000.0;
78 L->chem[i]->state=0;
79 }
80
81
82 L->m=0.0; for(i=0;i<L->nb;i++) L->m+=L->chem[i]->m;
83 //Distribute vapor components
84 for (i=0;i<V->nb;i++)
85 {
86 V->chem[i]->m = V->m*L->chem[i]->n()*K[i]/L->n()*V->chem[i]->M/1000.0;
87 V->chem[i]->state=1;
88 }
89 V->m=0.0; for(i=0;i<V->nb;i++) V->m+=V->chem[i]->m;
90 }
91 for(i=0;i<F->nb;i++)
92 if(F->chem[i]->Tc<T){V->chem[i]->m=Fcopy->chem[i]->m; V->m+=Fcopy->chem[i]->m;}
93
94 }
95 else
96 {
97 /* if(task==0)
98 {
99 log.open("runtime\\messages.r", ios::app);
100 if (T<F->dp) log<<" --> Warning <-- Mixture in "<<name<<" can't be flashed (bp="<<F->bp<<" dp="<<F->dp<<").\n";
101 log.close();
102 } */
103 for (i=0;i<F->nb;i++)
104 {
105 if (F->chem[i]->Tc<T || f_x>=1) {V->chem[i]->m=Fcopy->chem[i]->m; V->m+=V->chem[i]->m; }
106 else {L->chem[i]->m=Fcopy->chem[i]->m; L->m+=L->chem[i]->m;}
107
108 }
109 success = true;
110 }
111 L->set(P,T);
112 V->set(P,T);
113 Q = 0.0;
114 for (i=0;i<F->nb;i++)
115 {
116 Q += L->chem[i]->dH(Tin, T, P)*L->chem[i]->n();
117 Q += V->chem[i]->dH(Tin, T, P)*V->chem[i]->n();
118 }
119 F->m=0;
120 for(i=0;i<Fcopy->nb;i++) {F->chem[i]->m = Fcopy->chem[i]->m; F->m+=F->chem[i]->m;}
121 F->set(F->P,Tin);
122 // if(fabs(V->m+L->m-F->m)>sqrt(EPS))
123 // {
124 // log.open(MESSAGES, ios::app);
125 // log<<" --> Warning <-- Block "<<name<<" is not in mass balance ("<<fabs(V->m+L->m-F->m)/F->m<<").\n";
126 // log.close();
127 // }
128 // V->write();// TOTO
129 // L->write(); // TOTO
130
131 return success;
132 }
133
f(double psy)134 double flash::f(double psy)
135 {
136 x=psy;
137 f_x=0.0;
138 for(i=0;i<F->nb;i++) f_x += (z[i]*(1-K[i]))/(1+psy*(K[i]-1));
139 return f_x;
140 }
141
adiabatic()142 bool flash::adiabatic()
143 {
144 task=1;
145 F->set(P,T); T=F->dp;
146 step=-5;
147 Q=1;
148
149
150 while (fabs(step)>0.01 && fabs(Q)>0.1)
151 {
152 T+=step;
153 F->set(P,T);
154
155 for (i=0;i<F->nb;i++)
156 K[i] = F->chem[i]->Psat(T)/P;
157
158 success=solve();
159
160
161 if (Q<0 && step<0) step*=-0.5;
162 if (Q>0 && step>0) step*=-0.5;
163 }
164 if (fabs(Q)<0.1) return true;
165 else return false;
166 }
167
write()168 void flash::write() {
169 cout << "WRITE FILE " << RUNTIME << name << ".unit" << " :\n\tBEGIN\n";
170 cout << "\t>> "<<name;
171 cout << endl << "\t>> stream in : "<<F->name;
172 cout <<endl<<"\t>> streams out : "<<L->name<<" (liq.) "<<V->name<<" (vap.)";
173 cout <<endl<<"\t>> P = "<<P<<" atm, T = "<<T<<" K";
174 cout <<endl<<"\t>> Heat duty = "<<Q;
175 if (success==true) cout <<" kW (converge normally)";
176 cout << "\n\tEND\n\n";
177 cost();
178 power();
179 water();
180 }
181
182
get_cost(void)183 double flash::get_cost ( void ) {
184 vol=15.0*(L->v+V->v);
185 if(vol<0.3) vol=0.3; if(vol>520)vol=520;
186 step = 3.4974+0.4485*log10(vol)+0.1074*pow(log10(vol),2);
187 step = pow(10, step);
188 P= (P-1)*101.325/100;
189 f_x=pow(2.0*vol/pi, 1.0/3.0);
190 vol=(P+1)*f_x/(317.46*(850-0.6*(P+1)))+0.0315;
191 step *=(2.25+ 1.82*vol*2.2);
192 step = step*MS_YEAR/MS_2001;
193 return step;
194 }
195
cost()196 void flash::cost() {
197 cout << "WRITE FILE " << RUNTIME << name << ".cost" << " :\n\tBEGIN\n";
198 cout << "\t>>" << get_cost();
199 cout << "\n\tEND\n\n";
200 }
power()201 void flash::power() {
202 cout << "WRITE FILE " << RUNTIME << name << ".power" << " :\n\tBEGIN\n";
203 cout << "\t>>" << Q;
204 cout << "\n\tEND\n\n";
205 }
206
get_water(void)207 double flash::get_water ( void ) {
208 step = (Q<0.0) ? fabs(Q)/(4.185*0.10*(Tin-298)) : 0.0;
209 return step;
210 }
211
water()212 void flash::water() {
213 cout << "WRITE FILE " << RUNTIME << name << ".water" << " :\n\tBEGIN\n";
214 if(Q<0.0)
215 step= (fabs(Q)/(4.185*0.10*(Tin-298)));
216 else
217 step= 0.0;
218 cout << "\t>>" << step;
219 cout << "\n\tEND\n\n";
220 }
221