89void Bmix(
const double T,
const std::vector<double> &
xGrs,
const double HCH,
double &B,
double &C,
int &ierr, std::string &herr);
91void PressureGross(
const double T,
const double D,
const std::vector<double> &
xGrs,
const double HCH,
double &P,
double &Z,
int &ierr, std::string &herr);
92void DensityGross(
const double T,
const double P,
const std::vector<double> &
xGrs,
const double HCH,
double &D,
int &ierr, std::string &herr);
93void GrossHv(
const std::vector<double> &x, std::vector<double> &
xGrs,
double &HN,
double &HCH);
94void GrossInputs(
const double T,
const double P,
const std::vector<double> &x, std::vector<double> &
xGrs,
double &Gr,
double &HN,
double &HCH,
int &ierr, std::string &herr);
131static double c0[4][4][4],
c1[4][4][4],
c2[4][4][4];
159 for(std::size_t i = 1; i <=
NcGross; ++i){
183void PressureGross(
const double T,
const double D,
const std::vector<double> &
xGrs,
const double HCH,
double &P,
double &Z,
int &ierr, std::string &herr)
205 double B = 1e30, C = 1e30;
208 Bmix(T,
xGrs, HCH, B, C, ierr, herr);
209 if (ierr > 0) {
return; }
210 Z = 1 + B*D + C*pow(D, 2);
215 herr =
"Pressure is negative in the GROSS method.";
236void DensityGross(
const double T,
const double P,
const std::vector<double> &
xGrs,
const double HCH,
double &D,
int &ierr, std::string &herr)
256 double plog, vlog, P2, Z, dpdlv, vdiff, tolr;
267 for(
int it = 1; it <= 20; ++it){
268 if(vlog < -7 || vlog > 100){
270 herr =
"Calculation failed to converge in GROSS method, ideal gas density returned.";
276 if (ierr > 0){
return; }
285 vdiff = (log(P2) - plog) * P2 / dpdlv;
287 if (std::abs(vdiff) < tolr){
290 herr =
"Calculation failed to converge in the GROSS method, ideal gas density returned.";
301 herr =
"Calculation failed to converge in the GROSS method, ideal gas density returned.";
317void GrossHv(
const std::vector<double> &x, std::vector<double> &
xGrs,
double &HN,
double &HCH)
332 xGrs[1] = 1 - x[2] - x[3];
336 for(std::size_t i = 1; i <=
NcGross; ++i){
364void GrossInputs(
const double T,
const double P,
const std::vector<double> &x, std::vector<double> &
xGrs,
double &Gr,
double &HN,
double &HCH,
int &ierr, std::string &herr)
385 double Bref, Zref, Mref, Z, D, Mm;
390 Bref = -0.12527 + 0.000591*T - 0.000000662*pow(T, 2);
391 Zref = 1 + Bref*P/
RGross/T;
397 Gr = Mm * Zref / Mref / Z;
412void Bmix(
const double T,
const std::vector<double> &
xGrs,
const double HCH,
double &B,
double &C,
int &ierr, std::string &herr)
429 double bCH[3], cCH[3], BB[4][4], CC[4][4][4];
430 const double onethrd = 1.0 / 3.0;
438 for (
int i = 0; i <= 2; ++i){
439 bCH[i] =
bCHx[0][i] +
bCHx[1][i]*T +
bCHx[2][i]*pow(T, 2);
440 cCH[i] =
cCHx[0][i] +
cCHx[1][i]*T +
cCHx[2][i]*pow(T, 2);
444 for(
int i = 2; i <= 3; ++i){
445 for(
int j = i; j <= 3; ++j){
446 BB[i][j] =
b0[i][j] +
b1[i][j] * T +
b2[i][j]*pow(T, 2);
447 for(
int k = j; k <= 3; ++k){
448 CC[i][j][k] =
c0[i][j][k] +
c1[i][j][k] * T +
c2[i][j][k]*pow(T, 2);
454 BB[1][1] = bCH[0] + bCH[1]*HCH + bCH[2]*pow(HCH, 2);
455 BB[1][2] = (0.72 + 0.00001875 * pow(320 - T, 2))*(BB[1][1] + BB[2][2])/2.0;
456 if (BB[1][1]*BB[3][3] < 0){
457 ierr = 4; herr =
"Invalid input in Bmix routine";
460 BB[1][3] = -0.865 * sqrt(BB[1][1] * BB[3][3]);
463 CC[1][1][1] = cCH[0] + cCH[1] * HCH + cCH[2] * pow(HCH, 2);
464 if (CC[1][1][1] < 0 || CC[3][3][3] < 0){
465 ierr = 5; herr =
"Invalid input in Bmix routine";
468 CC[1][1][2] = (0.92 + 0.0013 * (T - 270)) * pow(pow(CC[1][1][1], 2) * CC[2][2][2], onethrd);
469 CC[1][2][2] = (0.92 + 0.0013 * (T - 270)) * pow(pow(CC[2][2][2], 2) * CC[1][1][1], onethrd);
470 CC[1][1][3] = 0.92 * pow(pow(CC[1][1][1], 2) * CC[3][3][3], onethrd);
471 CC[1][3][3] = 0.92 * pow(pow(CC[3][3][3], 2) * CC[1][1][1], onethrd);
472 CC[1][2][3] = 1.1 * pow(CC[1][1][1] * CC[2][2][2] * CC[3][3][3], onethrd);
475 for (std::size_t i = 1; i <= 3; ++i){
476 for(std::size_t j = i; j <= 3; ++j){
478 B += BB[i][i]*pow(
xGrs[i], 2);
483 for(std::size_t k = j; k <= 3; ++k){
484 if (i == j && j == k) {
485 C += CC[i][i][i]*pow(
xGrs[i], 3);
487 else if (i != j && j != k && i != k){
517void GrossMethod1(
const double Th,
const double Td,
const double Pd, std::vector<double> &
xGrs,
const double Gr,
const double Hv,
double & Mm,
double &HCH,
double &HN,
int &ierr, std::string &herr)
540 double xCH, xN2, xCO2, Zd, Zold, G1, G2, Bref, Zref, B, C;
544 if (Gr <
epsilon){ierr = 1; herr =
"Invalid input for relative density";
return;}
545 if (Hv <
epsilon){ierr = 2; herr =
"Invalid input for heating value";
return;}
551 Bref = -0.12527 + 0.000591*Td - 0.000000662*pow(Td, 2);
552 Zref = (1 + Pd /
RGross / Td * Bref);
553 for (
int i = 0; i < 20; ++i){
555 HN = Zd*
RGross*Td/Pd*Hv*(1 + 0.0001027*(Th - 298.15));
556 Mm = Gr*Zd*28.9625 / Zref;
557 xCH = (Mm + (xCO2 - 1) *
mN2 - xCO2 *
mCO2 - G2 * HN) / (G1 -
mN2);
558 xN2 = 1 - xCH - xCO2;
560 ierr = 3; herr =
"Negative nitrogen value in GROSS method 1 setup";
566 Bmix(Td,
xGrs, HCH, B, C, ierr, herr);
571 if(std::abs(Zold - Zd) < 0.0000001) {
break; }
594void GrossMethod2(
const double Th,
const double Td,
const double Pd, std::vector<double> &
xGrs,
const double Gr,
double &Hv,
double &Mm,
double &HCH,
double &HN,
int &ierr, std::string &herr)
617 double xCH, Z, Zold, Bref, Zref, MrCH, G1, G2, B, C, xN2, xCO2;
620 if (Gr <
epsilon){ ierr = 1; herr =
"Invalid input for relative density";
return; }
624 xCH = 1 - xN2 - xCO2;
629 Bref = -0.12527 + 0.000591*Td - 0.000000662*pow(Td, 2);
630 Zref = (1 + Pd /
RGross / Td * Bref);
631 for (
int i = 0; i < 20; ++i){
633 Mm = Gr*Z*28.9625/Zref;
634 MrCH = (Mm - xN2 *
mN2 - xCO2 *
mCO2)/xCH;
635 HCH = (MrCH - G1) / G2;
636 Bmix(Td,
xGrs, HCH, B, C, ierr, herr);
637 if (ierr > 0){
return; }
638 Z = 1 + B * Pd /
RGross / Td;
639 if (std::abs(Zold - Z) < 0.0000001){
break; };
642 Hv = HN / Z /
RGross / Td * Pd / (1 + 0.0001027 * (Th - 298.15));
680 b0[2][2] = -0.1446;
b1[2][2] = 0.00074091;
b2[2][2] = -0.00000091195;
681 b0[2][3] = -0.339693;
b1[2][3] = 0.00161176;
b2[2][3] = -0.00000204429;
682 b0[3][3] = -0.86834;
b1[3][3] = 0.0040376;
b2[3][3] = -0.0000051657;
683 c0[2][2][2] = 0.0078498;
c1[2][2][2] = -0.000039895;
c2[2][2][2] = 0.000000061187;
684 c0[2][2][3] = 0.00552066;
c1[2][2][3] = -0.0000168609;
c2[2][2][3] = 0.0000000157169;
685 c0[2][3][3] = 0.00358783;
c1[2][3][3] = 0.00000806674;
c2[2][3][3] = -0.0000000325798;
686 c0[3][3][3] = 0.0020513;
c1[3][3][3] = 0.000034888;
c2[3][3][3] = -0.000000083703;
687 bCHx[0][0] = -0.425468;
bCHx[1][0] = 0.002865;
bCHx[2][0] = -0.00000462073;
688 bCHx[0][1] = 0.000877118;
bCHx[1][1] = -0.00000556281;
bCHx[2][1] = 0.0000000088151;
689 bCHx[0][2] = -0.000000824747;
bCHx[1][2] = 0.00000000431436;
bCHx[2][2] = -6.08319E-12;
690 cCHx[0][0] = -0.302488;
cCHx[1][0] = 0.00195861;
cCHx[2][0] = -0.00000316302;
691 cCHx[0][1] = 0.000646422;
cCHx[1][1] = -0.00000422876;
cCHx[2][1] = 0.00000000688157;
692 cCHx[0][2] = -0.000000332805;
cCHx[1][2] = 0.0000000022316;
cCHx[2][2] = -3.67713E-12;
750 double _x[] = {0.77824, 0.02, 0.06, 0.08, 0.03, 0.0015, 0.003, 0.0005, 0.00165, 0.00215, 0.00088, 0.00024, 0.00015, 0.00009, 0.004, 0.005, 0.002, 0.0001, 0.0025, 0.007, 0.001};
752 x.insert(x.begin(), 0.0);
760 double T = 300, P = 10000, Td = 273.15, Th = 298.15, Pd = 101.325, D = 6.35826, pp = -1, Hv = -1, Hv2 = -1, Gr, HN, HCH, Z=-1;
761 printf(
"Inputs-----\n");
762 printf(
"Temperature [K]: 300.0000000000000 != %0.16g\n",T);
763 printf(
"Pressure [kPa]: 10000.00000000000 != %0.16g\n",P);
764 printf(
"Th [K]: 298.1500000000000 != %0.16g\n",Th);
765 printf(
"Td [K]: 273.1500000000000 != %0.16g\n",Td);
766 printf(
"Pd [kPa]: 101.3250000000000 != %0.16g\n",Pd);
771 printf(
"Outputs-----\n");
772 printf(
"Molar mass [g/mol]: 20.54333051000000 != %0.16g\n",mm);
773 printf(
"Molar density [mol/l]: 5.117641317088482 != %0.16g\n",D);
774 printf(
"Pressure [kPa]: 9999.999999999998 != %0.16g\n",P);
775 printf(
"Compressibility factor: 0.7833795701012788 != %0.16g\n",Z);
781 printf(
"Relative density: 0.7112387718599272 != %0.16g\n",Gr);
782 printf(
"Molar heating value (kJ/mol, 25 C): 924.3591780000000 != %0.16g\n", HN);
783 printf(
"HCH (kJ/mol, 25 C): 1004.738236956522 != %0.16g\n",HCH);
784 printf(
"Equivalent hydrocarbon fraction: 0.9199999999999999 != %0.16g\n",
xGrs[1]);
785 printf(
"nitrogen mole fraction: 2.000000000000000E-02 != %0.16g\n",
xGrs[2]);
786 printf(
"CO2 mole fraction: 6.000000000000000E-02 != %0.16g\n",
xGrs[3]);
787 printf(
"Volumetric heating value at Td,Pd: 41.37676728724603 != %0.16g\n",Hv);
791 GrossMethod2(Th, Td, Pd,
xGrs, Gr, Hv2, mm, HCH, HN, ierr, herr);
793 printf(
"Gross method 2-----\n");
794 printf(
"Molar density [mol/l]: 5.197833636353455 != %0.16g\n", D);
795 printf(
"Volumetric heating value at Td,Pd: 42.15440903329388 != %0.16g\n", Hv2);
799 GrossMethod1(Th,Td,Pd,
xGrs,Gr,Hv,mm,HCH,HN,ierr,herr);
801 printf(
"Gross method 1-----\n");
802 printf(
"Molar density [mol/l]: 5.144374668159809 != %0.16g\n", D);
static const double epsilon
void GrossHv(const std::vector< double > &x, std::vector< double > &xGrs, double &HN, double &HCH)
Calculate ideal heating values based on composition.
static double c1[4][4][4]
static double c0[4][4][4]
static double c2[4][4][4]
void GrossMethod2(const double Th, const double Td, const double Pd, std::vector< double > &xGrs, const double Gr, double &Hv, double &Mm, double &HCH, double &HN, int &ierr, std::string &herr)
Initialize variables required in the GROSS equation with Method 2 of the AGA 8 Part 1 publication.
static double xHN[MaxFlds+1]
void DensityGross(const double T, const double P, const std::vector< double > &xGrs, const double HCH, double &D, int &ierr, std::string &herr)
Calculate density as a function of temperature and pressure.
void PressureGross(const double T, const double D, const std::vector< double > &xGrs, const double HCH, double &P, double &Z, int &ierr, std::string &herr)
Calculate pressure as a function of temperature and density.
void GrossMethod1(const double Th, const double Td, const double Pd, std::vector< double > &xGrs, const double Gr, const double Hv, double &Mm, double &HCH, double &HN, int &ierr, std::string &herr)
Initialize variables required in the GROSS equation with Method 1 of the AGA 8 Part 1 publication.
void SetupGross()
Initialize all the constants and parameters in the GROSS model.
static double MMiGross[MaxFlds+1]
void Bmix(const double T, const std::vector< double > &xGrs, const double HCH, double &B, double &C, int &ierr, std::string &herr)
Calculate 2nd and 3rd virial coefficients for the mixture at T.
void GrossInputs(const double T, const double P, const std::vector< double > &x, std::vector< double > &xGrs, double &Gr, double &HN, double &HCH, int &ierr, std::string &herr)
Calculate relative density and heating values based on composition.
void MolarMassGross(const std::vector< double > &x, double &Mm)
Calculate molar mass of the mixture with the compositions contained in the x() input array.