@@ -104,6 +104,16 @@ public double calcCriticalViscosity(double molarMass, double density) {
104
104
* 1e-7 ;
105
105
}
106
106
107
+ @ Override
108
+ public double calcRacketZ (SystemInterface thermoSystem , double molarMass , double density ) {
109
+ throw new RuntimeException ("calcm() method not defined" );
110
+ }
111
+
112
+ @ Override
113
+ public double calcm (double molarMass , double density ) {
114
+ throw new RuntimeException ("calcm() method not defined" );
115
+ }
116
+
107
117
@ Override
108
118
public boolean isCalcm () {
109
119
return calcm ;
@@ -154,13 +164,11 @@ public double calcPC(double molarMass, double density) {
154
164
public double calcm (double molarMass , double density ) {
155
165
if (molarMass < 1120 ) {
156
166
TBPfractionCoefs = TBPfractionCoefOil ;
157
- return TBPfractionCoefs [2 ][0 ] + TBPfractionCoefs [2 ][1 ] * molarMass
158
- + TBPfractionCoefs [2 ][2 ] * density + TBPfractionCoefs [2 ][3 ] * Math .pow (molarMass , 2.0 );
159
167
} else {
160
168
TBPfractionCoefs = TBPfractionCoefsHeavyOil ;
161
- return TBPfractionCoefs [2 ][0 ] + TBPfractionCoefs [2 ][1 ] * Math .log (molarMass )
162
- + TBPfractionCoefs [2 ][2 ] * density + TBPfractionCoefs [2 ][3 ] * Math .sqrt (molarMass );
163
169
}
170
+ return TBPfractionCoefs [2 ][0 ] + TBPfractionCoefs [2 ][1 ] * molarMass
171
+ + TBPfractionCoefs [2 ][2 ] * density + TBPfractionCoefs [2 ][3 ] * Math .pow (molarMass , 2.0 );
164
172
}
165
173
166
174
@ Override
@@ -312,6 +320,167 @@ public double calcAcentricFactor(double molarMass, double density) {
312
320
}
313
321
}
314
322
323
+ /**
324
+ * Lee-Kesler property estimation method
325
+ */
326
+ public class LeeKesler extends TBPBaseModel {
327
+ private static final long serialVersionUID = 1000 ;
328
+
329
+ public LeeKesler () {
330
+ calcm = false ;
331
+ }
332
+
333
+ @ Override
334
+ public double calcTC (double molarMass , double density ) {
335
+ double sg = density ;
336
+ double TB = calcTB (molarMass , density );
337
+ double TC =
338
+ 189.8 + 450.6 * sg + (0.4244 + 0.1174 * sg ) * TB + (0.1441 - 1.0069 * sg ) * 1e5 / TB ;
339
+ return TC ;
340
+ }
341
+
342
+ @ Override
343
+ public double calcPC (double molarMass , double density ) {
344
+ double sg = density ;
345
+ double TB = calcTB (molarMass , density );
346
+ double logpc =
347
+ 3.3864 - 0.0566 / sg - ((0.43639 + 4.1216 / sg + 0.21343 / sg / sg ) * 1e-3 * TB )
348
+ + ((0.47579 + 1.182 / sg + 0.15302 / sg / sg ) * 1e-6 * TB * TB )
349
+ - ((2.4505 + 9.9099 / sg / sg ) * 1e-10 * TB * TB * TB );
350
+ double PC = Math .exp (logpc ) * 10 ;
351
+ return PC ;
352
+ }
353
+
354
+ public double calcAcentricFactor (double molarMass , double density ) {
355
+ return super .calcAcentricFactorKeslerLee (molarMass , density );
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Two property estimation method
361
+ */
362
+ public class TwuModel extends TBPBaseModel {
363
+ private static final long serialVersionUID = 1000 ;
364
+
365
+ public TwuModel () {
366
+ calcm = false ;
367
+ }
368
+
369
+ @ Override
370
+ public double calcTC (double molarMass , double density ) {
371
+ double sg = density ;
372
+ double TB = calcTB (molarMass , density );
373
+ double MW = solveMW (TB );
374
+ double Tcnalkane = TB * 1.0 / (0.533272 + 0.343831e-3 * TB + 2.526167e-7 * TB * TB
375
+ - 1.65848e-10 * TB * TB * TB + 4.60774e24 * Math .pow (TB , -13 ));
376
+ double phi = 1.0 - TB / Tcnalkane ;
377
+ double SGalkane =
378
+ 0.843593 - 0.128624 * phi - 3.36159 * Math .pow (phi , 3 ) - 13749 * Math .pow (phi , 12 );
379
+ double PCnalkane = Math .pow (0.318317 + 0.099334 * Math .sqrt (phi ) + 2.89698 * phi
380
+ + 3.0054 * phi * phi + 8.65163 * Math .pow (phi , 4 ), 2 );
381
+ double VCnalkane = Math .pow (
382
+ (0.82055 + 0.715468 * phi + 2.21266 * phi * phi * phi + 13411.1 * Math .pow (phi , 14 )), -8 );
383
+ double deltaST = Math .exp (5.0 * (SGalkane - sg )) - 1.0 ;
384
+ double fT = deltaST * (-0.270159 * Math .pow (TB , -0.5 )
385
+ + (0.0398285 - 0.706691 * Math .pow (TB , -0.5 ) * deltaST ));
386
+ double TC = Tcnalkane * Math .pow (((1 + 2 * fT ) / (1 - 2 * fT )), 2 );
387
+ return TC ;
388
+ }
389
+
390
+ public double calculateTfunc (double MW_alkane , double TB ) {
391
+ double phi = Math .log (MW_alkane );
392
+ return Math
393
+ .exp (5.1264 + 2.71579 * phi - 0.28659 * phi * phi - 39.8544 / phi - 0.122488 / phi / phi )
394
+ - 13.7512 * phi + 19.6197 * phi * phi - TB ;
395
+ }
396
+
397
+ public double computeGradient (double MW_alkane , double TB ) {
398
+ double delta = 1 ;
399
+ double TfuncPlus = calculateTfunc (MW_alkane + delta , TB );
400
+ double TfuncMinus = calculateTfunc (MW_alkane - delta , TB );
401
+ return (TfuncPlus - TfuncMinus ) / (2 * delta );
402
+ }
403
+
404
+ public double solveMW (double TB ) {
405
+ double MW_alkane = TB / (5.8 - 0.0052 * TB );
406
+ double tolerance = 1e-6 ;
407
+ double prevMW_alkane ;
408
+ double error = 1.0 ;
409
+ int iter = 0 ;
410
+
411
+ do {
412
+ iter ++;
413
+ prevMW_alkane = MW_alkane ;
414
+ double gradient = computeGradient (MW_alkane , TB );
415
+ MW_alkane -= 0.5 * calculateTfunc (MW_alkane , TB ) / gradient ;
416
+ error = Math .abs (MW_alkane - prevMW_alkane );
417
+ } while (Math .abs (error ) > tolerance && iter < 1000 || iter < 3 );
418
+
419
+ return MW_alkane ;
420
+ }
421
+
422
+ @ Override
423
+ public double calcPC (double molarMass , double density ) {
424
+ double sg = density ;
425
+ double TB = calcTB (molarMass , density );
426
+ double MW = solveMW (TB );
427
+ double Tcnalkane = TB * 1.0 / (0.533272 + 0.343831e-3 * TB + 2.526167e-7 * TB * TB
428
+ - 1.65848e-10 * TB * TB * TB + 4.60774e24 * Math .pow (TB , -13 ));
429
+ double phi = 1.0 - TB / Tcnalkane ;
430
+ double SGalkane =
431
+ 0.843593 - 0.128624 * phi - 3.36159 * Math .pow (phi , 3 ) - 13749 * Math .pow (phi , 12 );
432
+ double PCnalkane = Math .pow (0.318317 + 0.099334 * Math .sqrt (phi ) + 2.89698 * phi
433
+ + 3.0054 * phi * phi + 8.65163 * Math .pow (phi , 4 ), 2 );
434
+ double VCnalkane = Math .pow (
435
+ (0.82055 + 0.715468 * phi + 2.21266 * phi * phi * phi + 13411.1 * Math .pow (phi , 14 )), -8 );
436
+ double deltaST = Math .exp (5.0 * (SGalkane - sg )) - 1.0 ;
437
+ double fT = deltaST * (-0.270159 * Math .pow (TB , -0.5 )
438
+ + (0.0398285 - 0.706691 * Math .pow (TB , -0.5 ) * deltaST ));
439
+ double TC = Tcnalkane * Math .pow (((1 + 2 * fT ) / (1 - 2 * fT )), 2 );
440
+ double deltaSP = Math .exp (0.5 * (SGalkane - sg )) - 1.0 ;
441
+ double deltaSV = Math .exp (4.0 * (SGalkane * SGalkane - sg * sg )) - 1.0 ;
442
+ double fV = deltaSV
443
+ * (0.347776 * Math .pow (TB , -0.5 ) + (-0.182421 + 2.24890 * Math .pow (TB , -0.5 )) * deltaSV );
444
+ double VC = VCnalkane * Math .pow (((1 + 2 * fV ) / (1 - 2 * fV )), 2 );
445
+ double fP = deltaSP * ((2.53262 - 34.4321 * Math .pow (TB , -0.5 ) - 0.00230193 * TB )
446
+ + (-11.4277 + 187.934 * Math .pow (TB , -0.5 ) + 0.00414963 * TB ) * deltaSP );
447
+ double PC = PCnalkane * (TC / Tcnalkane ) * (VCnalkane / VC )
448
+ * Math .pow (((1 + 2 * fP ) / (1 - 2 * fP )), 2 );
449
+ return PC * 10.0 ; // * 10 due to conversion MPa to bar
450
+ }
451
+
452
+ @ Override
453
+ public double calcCriticalVolume (double molarMass , double density ) {
454
+ double sg = density ;
455
+ double TB = calcTB (molarMass , density );
456
+ double MW = solveMW (TB );
457
+ double Tcnalkane = TB * 1.0 / (0.533272 + 0.343831e-3 * TB + 2.526167e-7 * TB * TB
458
+ - 1.65848e-10 * TB * TB * TB + 4.60774e24 * Math .pow (TB , -13 ));
459
+ double phi = 1.0 - TB / Tcnalkane ;
460
+ double SGalkane =
461
+ 0.843593 - 0.128624 * phi - 3.36159 * Math .pow (phi , 3 ) - 13749 * Math .pow (phi , 12 );
462
+ double PCnalkane = Math .pow (0.318317 + 0.099334 * Math .sqrt (phi ) + 2.89698 * phi
463
+ + 3.0054 * phi * phi + 8.65163 * Math .pow (phi , 4 ), 2 );
464
+ double VCnalkane = Math .pow (
465
+ (0.82055 + 0.715468 * phi + 2.21266 * phi * phi * phi + 13411.1 * Math .pow (phi , 14 )), -8 );
466
+ double deltaST = Math .exp (5.0 * (SGalkane - sg )) - 1.0 ;
467
+ double fT = deltaST * (-0.270159 * Math .pow (TB , -0.5 )
468
+ + (0.0398285 - 0.706691 * Math .pow (TB , -0.5 ) * deltaST ));
469
+ double TC = Tcnalkane * Math .pow (((1 + 2 * fT ) / (1 - 2 * fT )), 2 );
470
+ double deltaSP = Math .exp (0.5 * (SGalkane - sg )) - 1.0 ;
471
+ double deltaSV = Math .exp (4.0 * (SGalkane * SGalkane - sg * sg )) - 1.0 ;
472
+ double fV = deltaSV
473
+ * (0.347776 * Math .pow (TB , -0.5 ) + (-0.182421 + 2.24890 * Math .pow (TB , -0.5 )) * deltaSV );
474
+ double VC = VCnalkane * Math .pow (((1 + 2 * fV ) / (1 - 2 * fV )), 2 );
475
+ double fP = deltaSP * ((2.53262 - 34.4321 * Math .pow (TB , -0.5 ) - 0.00230193 * TB )
476
+ + (-11.4277 + 187.934 * Math .pow (TB , -0.5 ) + 0.00414963 * TB ) * deltaSP );
477
+ double PC = PCnalkane * (TC / Tcnalkane ) * (VCnalkane / VC )
478
+ * Math .pow (((1 + 2 * fP ) / (1 - 2 * fP )), 2 );
479
+ return VC * 1e3 ; // m3/mol
480
+ }
481
+
482
+ }
483
+
315
484
/**
316
485
* <p>
317
486
* getModel.
@@ -334,6 +503,10 @@ public TBPModelInterface getModel(String name) {
334
503
return new PedersenTBPModelPRHeavyOil ();
335
504
} else if (name .equals ("RiaziDaubert" )) {
336
505
return new RiaziDaubert ();
506
+ } else if (name .equals ("Lee-Kesler" )) {
507
+ return new LeeKesler ();
508
+ } else if (name .equals ("Twu" )) {
509
+ return new TwuModel ();
337
510
} else {
338
511
// System.out.println("not a valid TBPModelName.................");
339
512
return new PedersenTBPModelSRK ();
0 commit comments