00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00056
00057
00058
00059
00060
00061 #define NMOS 2
00062 #define NP 17
00063 #define NRC 0
00064 #define NRCE 0
00065
00066 #define NPR 0
00067 #define NLSQ 4
00068
00069 #ifdef PSEUDO_STATES
00070 #define NXD 84
00071 #else
00072 #define NXD 82
00073 #endif
00074
00075 #define NXA 122
00076 #define NU 2
00077 #define NW 1
00078
00079
00080
00081 #define qF 1
00082 #define Nfeed 20
00083
00084 #define A1 23.48
00085 #define B1 3626.6
00086 #define C1 -34.29
00087
00088 #define A2 22.437
00089 #define B2 3166.4
00090 #define C2 -80.15
00091
00092 #define Rconst 8.3147
00093
00094 #define T14s (70)
00095 #define T28s (88)
00096
00097 #define QT14 1
00098 #define QT28 1
00099
00100 #define R11 (2/2)
00101 #define R22 (0.1/2)
00102 #define RPENALTY (0.1)
00103
00104
00105 typedef struct {
00106
00107 double x[42];
00108 double n[42];
00109 double L[42];
00110 double V[42];
00111 double Temp[42];
00112
00113 double refvol[42];
00114 double Pres[42];
00115 double P1[42];
00116 double P2[42];
00117 double y[42];
00118
00119 double F;
00120 double xF;
00121
00122
00123 double nvolB;
00124 double nvolD;
00125 double nvolM;
00126 double nvolK;
00127 double flowwidth;
00128
00129 double alphastrip;
00130 double alpharect;
00131 double Ptop;
00132 double DPstrip;
00133 double DPrect;
00134 double Tfeed;
00135 double Tcond;
00136
00137 } Parameters;
00138
00139 static Parameters par;
00140
00141
00142
00143
00144 static double T_x(double T, double x)
00145
00146
00147
00148
00149
00150 {
00151 double P1,P2,P1_T,P2_T, F_T, F_x, T_x;
00152
00153 P1 = exp(A1-B1/(C1+T));
00154 P1_T = P1 * B1/(C1+T)/(C1+T);
00155
00156 P2 = exp(A2-B2/(C2+T));
00157 P2_T = P2 * B2/(C2+T)/(C2+T);
00158
00159 F_T=x*P1_T+(1-x)*P2_T;
00160 F_x=P1-P2;
00161
00162 T_x=- 1/F_T*F_x;
00163 return T_x;
00164 }
00165
00166
00167 static void enthalpies_1(double Temp, double Pres, double *hL1, double *hV1, double *hL1_T)
00168
00169
00170
00171
00172 {
00173 const double h11 = 18.31 ;
00174 const double h21 = 1.713E-2 ;
00175 const double h31 = 6.399E-5 ;
00176 const double Tc1 = 512.6 ;
00177 const double Pc1 = 8.096E6 ;
00178 const double OMEGA1 = 0.557 ;
00179
00180 double TR1, PR1, Dhv1;
00181
00182 TR1=Temp/Tc1;
00183 PR1=Pres/Pc1;
00184 Dhv1 = Rconst*Tc1*sqrt(1-PR1/pow(TR1,3))*(6.09648-1.28862*TR1+
00185 1.016*pow(TR1,7)+OMEGA1*(15.6875-13.4721*TR1+2.615*pow(TR1,7)));
00186 *hL1=(h11*(Temp-273.15)+h21*pow(Temp-273.15,2)+h31*pow(Temp-273.15,3))*4.186;
00187 *hV1=*hL1+Dhv1;
00188 *hL1_T=(h11+h21*2*(Temp-273.15)+h31*3*pow(Temp-273.15,2))*4.186;
00189 }
00190
00191 static void enthalpies_2(double Temp, double Pres, double *hL2, double *hV2, double *hL2_T)
00192
00193
00194
00195
00196 {
00197 const double h12 = 31.92 ;
00198 const double h22 = 4.49E-2 ;
00199 const double h32 = 9.663E-5 ;
00200 const double Tc2 = 536.7 ;
00201 const double Pc2 = 5.166E6 ;
00202 const double OMEGA2 = 0.612 ;
00203
00204 double TR2, PR2, Dhv2;
00205
00206 TR2=Temp/Tc2;
00207 PR2=Pres/Pc2;
00208 Dhv2 = Rconst*Tc2*sqrt(1-PR2/pow(TR2,3))*(6.09648-1.28862*TR2+
00209 1.016*pow(TR2,7)+OMEGA2*(15.6875-13.4721*TR2+2.615*pow(TR2,7)));
00210 *hL2=(h12*(Temp-273.15)+h22*pow(Temp-273.15,2)+h32*pow(Temp-273.15,3))*4.186;
00211 *hV2=*hL2+Dhv2;
00212 *hL2_T=(h12+h22*2*(Temp-273.15)+h32*3*pow(Temp-273.15,2))*4.186;
00213 }
00214
00215
00216
00217 static void enthalpies(double Temp, double Pres, double x, double y,
00218 double *hL, double *hV, double *hL_x_total)
00219
00220
00221
00222
00223
00224
00225 {
00226 double hL1, hV1, hL1_T, hL2, hV2, hL2_T, hL_x, hL_T;
00227 enthalpies_1(Temp, Pres, &hL1,&hV1, &hL1_T);
00228 enthalpies_2(Temp, Pres, &hL2,&hV2, &hL2_T);
00229 *hL=hL1*x+hL2*(1-x);
00230 *hV=hV1*y+hV2*(1-y);
00231 hL_x=hL1-hL2;
00232 hL_T=hL1_T*x+hL2_T*(1-x);
00233 *hL_x_total=hL_x
00234 +hL_T*T_x(Temp,x)
00235 ;
00236 }
00237
00238
00239 static double litre_per_kmol(double TK, double x_m)
00240
00241
00242
00243
00244
00245
00246
00247 {
00248 double d_m, vm, d_p, vp, vol_p, vol_m, vol_sum, v_mix;
00249 d_m = 2.288/ pow(0.2685,(1+ pow((1 - TK/512.4),0.2453)));
00250 vm = 1/d_m;
00251
00252 d_p = 1.235/ pow(0.27136, (1+ pow((1- TK/536.4),0.24)));
00253 vp = 1/d_p;
00254
00255 vol_m = x_m*vm;
00256 vol_p = (1-x_m)*vp;
00257 vol_sum = vol_m + vol_p;
00258 v_mix= vol_sum*1000;
00259
00260 return v_mix;
00261 }
00262
00263
00264 static double ramp(double x)
00265 {
00266
00267
00268
00269 const double R=20;
00270 double xo;
00271 if (x<-R) xo=0;
00272 else if (x<R) xo=0.5*(x+log(2*cosh(x)));
00273 else xo=x;
00274
00275 return xo;
00276
00277 }
00278 static double kmol_per_sec_outflow(double n, double TK, double x_m, double refvol,
00279 double flowwidth)
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 {
00290 double volumeholdup, volumeoutflow, outflow, l_per_kmol;
00291 const double alpha=500;
00292 l_per_kmol=litre_per_kmol(TK, x_m);
00293 volumeholdup=l_per_kmol * n;
00294 volumeoutflow = flowwidth*(
00295 pow(1/alpha*ramp(alpha*(volumeholdup-refvol)),1.5)
00296
00297 );
00298 outflow=volumeoutflow / l_per_kmol;
00299
00300
00301
00302
00303
00304 return outflow;
00305 }
00306
00307
00308
00309 static void insert(double *xd,
00310 double *xa,
00311 double *u,
00312 double *p
00313 )
00314
00315
00316
00317
00318
00319
00320
00321
00322 {
00323 double Lc, Vc;
00324 double Q;
00325 double L_lh,F_lh;
00326
00327 double holdup = 0.0;
00328 double dummy, hL, hV, deltaH, Qloss;
00329 long i;
00330 extern Parameters par;
00331
00332 L_lh = u[0];
00333 Q = u[1];
00334
00335 par.alpharect = p[2];
00336 par.alphastrip = p[3];
00337
00338 Qloss = p[5];
00339
00340 par.nvolB = p[6];
00341 par.nvolD = p[7];
00342 par.nvolM = p[0];
00343 par.nvolK = p[0];
00344 par.flowwidth = p[4];
00345
00346
00347 par.Ptop = p[8];
00348 par.DPstrip = p[9];
00349 par.DPrect = p[9];
00350
00351 #ifdef PSEUDO_STATES
00352 F_lh = xd[82];
00353 par.xF = xd[83];
00354 #else
00355 F_lh = p[10];
00356 par.xF = p[11];
00357 #endif
00358
00359
00360 par.Tfeed = p[12] +273.15;
00361 par.Tcond = p[13] +273.15;
00362
00363
00364
00365 for (i=0; i<= 39; i++)
00366 {
00367 par.L[i+1]=xa[i];
00368 par.V[i+1]=xa[40+i];
00369 par.Temp[i]=xa[80+i];
00370 }
00371 par.Temp[40]=xa[120];
00372 par.Temp[41]=xa[121];
00373
00374 for (i=0; i<= 41; i++)
00375 par.x[i]=xd[i];
00376
00377 for (i=1; i<= 40; i++)
00378 par.n[i]=xd[41+i];
00379
00380
00381
00382 par.Pres[41]=par.Ptop;
00383 for (i=41; i>=1; i--)
00384 {
00385 if (i>Nfeed)
00386 {par.Pres[i-1]=par.Pres[i]+par.DPrect;}
00387 else
00388 {par.Pres[i-1]=par.Pres[i]+par.DPstrip;}
00389 }
00390
00391
00392 for (i=0; i<= 41; i++)
00393 {
00394 par.P1[i] = exp(A1-B1/(C1+par.Temp[i]));
00395 par.P2[i] = exp(A2-B2/(C2+par.Temp[i]));
00396 par.y[i]=par.P1[i]*par.x[i]/par.Pres[i];
00397 }
00398
00399 for (i=1; i<= Nfeed; i++)
00400 par.y[i]=par.alphastrip*par.y[i]+(1-par.alphastrip)*par.y[i-1];
00401
00402 for (i=Nfeed+1; i<= 40; i++)
00403 par.y[i]=par.alpharect*par.y[i]+(1-par.alpharect)*par.y[i-1];
00404
00405
00406 par.y[41]=par.x[41];
00407
00408
00409 par.F = F_lh / (litre_per_kmol(par.Tfeed, par.xF)*3600);
00410 Lc = L_lh / (litre_per_kmol(par.Tcond, par.x[41])*3600);
00411
00412
00413 par.L[41]=Lc;
00414
00415
00416 i=0;
00417 enthalpies(par.Temp[i], par.Pres[i], par.x[i], par.y[i], &hL,&hV, &dummy);
00418 deltaH=hV-hL;
00419 Vc = (Q-Qloss)/deltaH;
00420 par.V[0]=Vc;
00421
00422 for (i=0; i<= 41; i++)
00423 {
00424 if (i==0) holdup=par.nvolB;
00425 else if (i<Nfeed) holdup=par.nvolK;
00426 if (i==Nfeed) holdup=par.nvolM;
00427 else if (i<41) holdup=par.nvolK;
00428 else if (i==41) holdup=par.nvolD;
00429
00430 par.refvol[i]=holdup;
00431 }
00432 par.n[0] =par.refvol[0]/litre_per_kmol(par.Temp[0], par.x[0]);
00433 par.n[41]=par.refvol[41]/litre_per_kmol(par.Temp[41], par.x[41]);
00434
00435
00436 par.L[0]=1/litre_per_kmol(par.Temp[0], par.x[0])
00437 * ( litre_per_kmol(par.Temp[0], par.x[1]) * par.L[1]
00438 - litre_per_kmol(par.Temp[0], par.y[0]) * par.V[0]
00439 );
00440
00441
00442 par.V[41]=1/litre_per_kmol(par.Temp[41], par.y[41])
00443 * ( litre_per_kmol(par.Temp[41], par.y[40]) * par.V[40]
00444 - litre_per_kmol(par.Temp[41], par.x[41]) * par.L[41]
00445 );
00446
00447 }
00448
00449 static void diffeq(
00450 double *dx,
00451 double *dn
00452 )
00453
00454
00455
00456
00457
00458 {
00459
00460 extern Parameters par;
00461 long i;
00462 double Vmol, dVmol_x;
00463
00464
00465 i=0;
00466 Vmol=litre_per_kmol(par.Temp[i], par.x[i]);
00467 dVmol_x=litre_per_kmol(par.Temp[i], 1.0)-litre_per_kmol(par.Temp[i], 0.0);
00468
00469 dx[i] = 1 / (par.n[i]*(1 + dVmol_x * par.x[i] / Vmol) )
00470 * (par.L[i+1]*par.x[i+1] - par.V[i]*par.y[i] - par.L[i]*par.x[i]);
00471
00472
00473
00474 for (i=1; i<=40; i++)
00475 {
00476 dx[i] = -(1/par.n[i])*par.V[i]*(par.y[i]-par.x[i]);
00477 dn[i-1] = -par.V[i]-par.L[i];
00478
00479 dx[i] += (1/par.n[i])*par.L[i+1]*(par.x[i+1]-par.x[i]);
00480 dn[i-1] += par.L[i+1];
00481
00482 dx[i] += (1/par.n[i])*par.V[i-1]*(par.y[i-1]-par.x[i]);
00483 dn[i-1] += par.V[i-1];
00484
00485 if (i==Nfeed)
00486 {
00487 dx[i] += (1/par.n[i])*par.F*(par.xF-par.x[i]);
00488 dn[i-1] += par.F;
00489 }
00490 }
00491
00492
00493 i=41;
00494 Vmol=litre_per_kmol(par.Temp[i], par.x[i]);
00495 dVmol_x=litre_per_kmol(par.Temp[i], 1.0)-litre_per_kmol(par.Temp[i], 0.0);
00496
00497 dx[i] = 1 / (par.n[i]*(1 + dVmol_x * par.x[i] / Vmol) )
00498 * (par.V[i-1]*par.y[i-1] - par.V[i]*par.y[i] - par.L[i]*par.x[i]);
00499 }
00500
00501
00502 static void ffcn( double *t, double *xd, double *xa, double *u,
00503 double *p, double *rhs ){
00504
00505 long i;
00506 #ifdef PSEUDO_STATES
00507 double xdcopy[84];
00508 #else
00509 double xdcopy[82];
00510 #endif
00511 double xacopy[122];
00512
00513 for(i=0;i<42;i++)
00514 xdcopy[i]=xd[i];
00515 for(i=42;i<82;i++)
00516 xdcopy[i]=xd[i]*1e-3;
00517 #ifdef PSEUDO_STATES
00518 xdcopy[82]=xd[82];
00519 xdcopy[83]=xd[83];
00520 #endif
00521 for(i=0;i<80;i++)
00522 xacopy[i]=xa[i]*1e-5;
00523 for(i=80;i<122;i++)
00524 xacopy[i]=xa[i]+273.15;
00525
00526 insert(xdcopy, xacopy, u, p);
00527 diffeq(rhs, &rhs[42]);
00528
00529
00530 for(i=42;i<82;i++)
00531 rhs[i]=rhs[i]/1e-3;
00532
00533 #ifdef PSEUDO_STATES
00534 rhs[82]=0;
00535 rhs[83]=0;
00536 #endif
00537
00538 }
00539
00540
00541
00542 static void gfcn(double *t, double *xd, double *xa, double *u,
00543 double *p, double *rhs ){
00544
00545 extern Parameters par;
00546
00547 long i;
00548 double hL_x[42], hL[42], hV[42];
00549 double dx[42],dn[42];
00550 double Pfeed, yfeed, P1, P2, dummy;
00551 double hLfeed, hVfeed;
00552
00553 #ifdef PSEUDO_STATES
00554 double xdcopy[84];
00555 #else
00556 double xdcopy[82];
00557 #endif
00558 double xacopy[122];
00559
00560
00561 for(i=0;i<42;i++)
00562 xdcopy[i]=xd[i];
00563 for(i=42;i<82;i++)
00564 xdcopy[i]=xd[i]*1e-3;
00565 #ifdef PSEUDO_STATES
00566 xdcopy[82]=xd[82];
00567 xdcopy[83]=xd[83];
00568 #endif
00569
00570 for(i=0;i<80;i++)
00571 xacopy[i]=xa[i]*1e-5;
00572
00573 for(i=80;i<122;i++)
00574 xacopy[i]=xa[i]+273.15;
00575
00576
00577
00578 insert(xdcopy, xacopy, u, p);
00579 diffeq(dx, dn);
00580
00581
00582 for (i=0; i<= 41; i++)
00583 {
00584 enthalpies(par.Temp[i], par.Pres[i], par.x[i], par.y[i], &hL[i],&hV[i], &hL_x[i]);
00585 }
00586
00587
00588
00589 P1 = exp(A1-B1/(C1+par.Tfeed));
00590 P2 = exp(A2-B2/(C2+par.Tfeed));
00591 Pfeed=P1*par.xF+(1-par.xF)*P2;
00592 yfeed=P1*par.xF/Pfeed;
00593
00594 enthalpies(par.Tfeed, Pfeed, par.xF, yfeed, &hLfeed,&hVfeed, &dummy);
00595
00596
00597 i=41;
00598 par.Temp[i]=par.Tcond;
00599 enthalpies(par.Temp[i], par.Pres[i], par.x[i], par.y[i], &hL[i],&hV[i], &hL_x[i]);
00600
00601
00602
00603
00604
00605
00606
00607 for (i=1; i<=40; i++)
00608 {
00609 rhs[i-1] = par.L[i]-kmol_per_sec_outflow(par.n[i], par.Temp[i], par.x[i],
00610 par.refvol[i], par.flowwidth);
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 rhs[40+i-1] = par.V[i-1]*(hV[i-1] - hL[i])
00625 - par.V[i]*(hV[i] -hL[i])
00626 + par.L[i+1]*(hL[i+1]-hL[i])
00627 - par.n[i]*hL_x[i]*dx[i];
00628 if (i==Nfeed)
00629 {
00630 rhs[40+i-1] += par.F*(hLfeed - hL[i]) + (1-qF)*hVfeed;
00631 }
00632
00633 }
00634
00635
00636 for (i=0; i<= 41; i++)
00637 rhs[80+i]=1-par.P1[i]/par.Pres[i]*par.x[i]-(1-par.x[i])*par.P2[i]/par.Pres[i];
00638
00639
00640 for(i=0;i<40;i++)
00641 rhs[i]=rhs[i]/1e-5;
00642 }
00643