diff --git a/opm/core/props/pvt/PvtDead.cpp b/opm/core/props/pvt/PvtDead.cpp index d4118aaf..db9cdb39 100644 --- a/opm/core/props/pvt/PvtDead.cpp +++ b/opm/core/props/pvt/PvtDead.cpp @@ -41,6 +41,7 @@ namespace Opm // resize the attributes of the object b_.resize(numRegions); viscosity_.resize(numRegions); + inverseBmu_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::PvdoTable& pvdoTable = pvdoTables[regionIdx]; @@ -51,12 +52,19 @@ namespace Opm const std::vector& visc = pvdoTable.getViscosityColumn(); const int sz = b.size(); - std::vector bInv(sz); + std::vector inverseB(sz); for (int i = 0; i < sz; ++i) { - bInv[i] = 1.0 / b[i]; + inverseB[i] = 1.0 / b[i]; } - b_[regionIdx] = NonuniformTableLinear(press, bInv); + + std::vector inverseBmu(sz); + for (int i = 0; i < sz; ++i) { + inverseBmu[i] = 1.0 / (b[i] * visc[i]); + } + + b_[regionIdx] = NonuniformTableLinear(press, inverseB); viscosity_[regionIdx] = NonuniformTableLinear(press, visc); + inverseBmu_[regionIdx] = NonuniformTableLinear(press, inverseBmu); } } @@ -68,6 +76,7 @@ namespace Opm // resize the attributes of the object b_.resize(numRegions); viscosity_.resize(numRegions); + inverseBmu_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { const Opm::PvdgTable& pvdgTable = pvdgTables[regionIdx]; @@ -78,12 +87,19 @@ namespace Opm const std::vector& visc = pvdgTable.getViscosityColumn(); const int sz = b.size(); - std::vector bInv(sz); + std::vector inverseB(sz); for (int i = 0; i < sz; ++i) { - bInv[i] = 1.0 / b[i]; + inverseB[i] = 1.0 / b[i]; } - b_[regionIdx] = NonuniformTableLinear(press, bInv); + + std::vector inverseBmu(sz); + for (int i = 0; i < sz; ++i) { + inverseBmu[i] = 1.0 / (b[i] * visc[i]); + } + + b_[regionIdx] = NonuniformTableLinear(press, inverseB); viscosity_[regionIdx] = NonuniformTableLinear(press, visc); + inverseBmu_[regionIdx] = NonuniformTableLinear(press, inverseBmu); } } @@ -103,7 +119,9 @@ namespace Opm // #pragma omp parallel for for (int i = 0; i < n; ++i) { int regionIdx = getTableIndex_(pvtTableIdx, i); - output_mu[i] = viscosity_[regionIdx](p[i]); + double tempInvB = b_[regionIdx](p[i]); + double tempInvBmu = inverseBmu_[regionIdx](p[i]); + output_mu[i] = tempInvB / tempInvBmu; } } @@ -118,8 +136,11 @@ namespace Opm // #pragma omp parallel for for (int i = 0; i < n; ++i) { int regionIdx = getTableIndex_(pvtTableIdx, i); - output_mu[i] = viscosity_[regionIdx](p[i]); - output_dmudp[i] = viscosity_[regionIdx].derivative(p[i]); + double tempInvB = b_[regionIdx](p[i]); + double tempInvBmu = inverseBmu_[regionIdx](p[i]); + output_mu[i] = tempInvB / tempInvBmu; + output_dmudp[i] = (tempInvBmu * b_[regionIdx].derivative(p[i]) + - tempInvB * inverseBmu_[regionIdx].derivative(p[i])) / (tempInvBmu * tempInvBmu); } std::fill(output_dmudr, output_dmudr + n, 0.0); @@ -137,8 +158,12 @@ namespace Opm // #pragma omp parallel for for (int i = 0; i < n; ++i) { int regionIdx = getTableIndex_(pvtTableIdx, i); - output_mu[i] = viscosity_[regionIdx](p[i]); - output_dmudp[i] = viscosity_[regionIdx].derivative(p[i]); + double tempInvB = b_[regionIdx](p[i]); + double tempInvBmu = inverseBmu_[regionIdx](p[i]); + output_mu[i] = tempInvB / tempInvBmu; + output_dmudp[i] = (tempInvBmu * b_[regionIdx].derivative(p[i]) + - tempInvB * inverseBmu_[regionIdx].derivative(p[i])) + / (tempInvBmu * tempInvBmu); } std::fill(output_dmudr, output_dmudr + n, 0.0); diff --git a/opm/core/props/pvt/PvtDead.hpp b/opm/core/props/pvt/PvtDead.hpp index d83d4f69..ccc9acac 100644 --- a/opm/core/props/pvt/PvtDead.hpp +++ b/opm/core/props/pvt/PvtDead.hpp @@ -155,6 +155,7 @@ namespace Opm // table per PVT region. std::vector > b_; std::vector > viscosity_; + std::vector > inverseBmu_; }; } diff --git a/opm/core/props/pvt/PvtLiveGas.cpp b/opm/core/props/pvt/PvtLiveGas.cpp index cb1cb829..63446b3c 100644 --- a/opm/core/props/pvt/PvtLiveGas.cpp +++ b/opm/core/props/pvt/PvtLiveGas.cpp @@ -56,28 +56,40 @@ namespace Opm const Opm::PvtgTable& pvtgTable = pvtgTables[pvtTableIdx]; // GAS, PVTG - saturated_gas_table_[pvtTableIdx].resize(4); - saturated_gas_table_[pvtTableIdx][0] = pvtgTable.getOuterTable()->getPressureColumn(); - saturated_gas_table_[pvtTableIdx][1] = pvtgTable.getOuterTable()->getGasFormationFactorColumn(); - saturated_gas_table_[pvtTableIdx][2] = pvtgTable.getOuterTable()->getGasViscosityColumn(); - saturated_gas_table_[pvtTableIdx][3] = pvtgTable.getOuterTable()->getOilSolubilityColumn(); + // saturated_gas_table_[pvtTableIdx].resize(4); + // Adding one extra line to PVTG to store 1./(Bg*mu_g) + saturated_gas_table_[pvtTableIdx].resize(5); + saturated_gas_table_[pvtTableIdx][0] = pvtgTable.getOuterTable()->getPressureColumn(); // Pressure + saturated_gas_table_[pvtTableIdx][1] = pvtgTable.getOuterTable()->getGasFormationFactorColumn(); // Bg + saturated_gas_table_[pvtTableIdx][2] = pvtgTable.getOuterTable()->getGasViscosityColumn(); // mu_g + // The number of the columns + int nRows = saturated_gas_table_[pvtTableIdx][2].size(); + saturated_gas_table_[pvtTableIdx][3].resize(nRows); // allocate memory for 1/(Bg*mu_g) + saturated_gas_table_[pvtTableIdx][4] = pvtgTable.getOuterTable()->getOilSolubilityColumn(); // Rv int sz = pvtgTable.getOuterTable()->numRows(); undersat_gas_tables_[pvtTableIdx].resize(sz); for (int i=0; i 1/Bg for (int i=0; inumRows(); - for (int k=0; k<4; ++k) { + // for (int k=0; k<4; ++k) { + for (int k=0; k<5; ++k) { saturated_oil_table_[pvtTableIdx][k].resize(sz); } for (int i=0; igetPressureColumn()[i]; // p saturated_oil_table_[pvtTableIdx][1][i] = 1.0/saturatedPvto->getOilFormationFactorColumn()[i]; // 1/Bo saturated_oil_table_[pvtTableIdx][2][i] = saturatedPvto->getOilViscosityColumn()[i]; // mu_o - saturated_oil_table_[pvtTableIdx][3][i] = saturatedPvto->getGasSolubilityColumn()[i]; // Rs + saturated_oil_table_[pvtTableIdx][3][i] = 1.0 / (saturatedPvto->getOilFormationFactorColumn()[i] + * saturatedPvto->getOilViscosityColumn()[i]); // 1/(Bo*mu_o) + saturated_oil_table_[pvtTableIdx][4][i] = saturatedPvto->getGasSolubilityColumn()[i]; // Rs } undersat_oil_tables_[pvtTableIdx].resize(sz); for (int i=0; inumRows(); undersat_oil_tables_[pvtTableIdx][i][0].resize(tsize); undersat_oil_tables_[pvtTableIdx][i][1].resize(tsize); undersat_oil_tables_[pvtTableIdx][i][2].resize(tsize); + undersat_oil_tables_[pvtTableIdx][i][3].resize(tsize); for (int j=0; jgetPressureColumn()[j]; // p undersat_oil_tables_[pvtTableIdx][i][1][j] = 1.0/undersaturatedPvto->getOilFormationFactorColumn()[j]; // 1/Bo undersat_oil_tables_[pvtTableIdx][i][2][j] = undersaturatedPvto->getOilViscosityColumn()[j]; // mu_o + undersat_oil_tables_[pvtTableIdx][i][3][j] = 1.0 / (undersaturatedPvto->getOilFormationFactorColumn()[j] * + undersaturatedPvto->getOilViscosityColumn()[j]); // 1/(Bo*mu_o) } } // Complete undersaturated tables by extrapolating from existing data // as is done in Eclipse and Mrst + // TODO: check if the following formulations applying to 1/(Bo*mu_o) int iNext = -1; for (int i=0; i > >::size_type sz_t; for (sz_t j=1; j= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = @@ -408,9 +457,9 @@ namespace Opm press); } else { // Undersaturated case // Interpolate between table sections - int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], maxR); - double w = (maxR - saturated_oil_table_[pvtTableIdx][3][is]) / - (saturated_oil_table_[pvtTableIdx][3][is+1] - saturated_oil_table_[pvtTableIdx][3][is]); + int is = tableIndex(saturated_oil_table_[pvtTableIdx][4], maxR); + double w = (maxR - saturated_oil_table_[pvtTableIdx][4][is]) / + (saturated_oil_table_[pvtTableIdx][4][is+1] - saturated_oil_table_[pvtTableIdx][4][is]); assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = @@ -435,7 +484,7 @@ namespace Opm { int section; double Rval = linearInterpolation(saturated_oil_table_[pvtTableIdx][0], - saturated_oil_table_[pvtTableIdx][3], + saturated_oil_table_[pvtTableIdx][4], press, section); // derivative with respect to frist component (pressure) if (deriv == 1) { @@ -444,9 +493,9 @@ namespace Opm saturated_oil_table_[pvtTableIdx][item], press); } else { // Undersaturated case - int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], r); - double w = (r - saturated_oil_table_[pvtTableIdx][3][is]) / - (saturated_oil_table_[pvtTableIdx][3][is+1] - saturated_oil_table_[pvtTableIdx][3][is]); + int is = tableIndex(saturated_oil_table_[pvtTableIdx][4], r); + double w = (r - saturated_oil_table_[pvtTableIdx][4][is]) / + (saturated_oil_table_[pvtTableIdx][4][is+1] - saturated_oil_table_[pvtTableIdx][4][is]); assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = @@ -465,7 +514,7 @@ namespace Opm if (Rval <= r ) { // Saturated case return 0; } else { // Undersaturated case - int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], r); + int is = tableIndex(saturated_oil_table_[pvtTableIdx][4], r); assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = @@ -477,7 +526,7 @@ namespace Opm undersat_oil_tables_[pvtTableIdx][is+1][item], press); - double val = (val2 - val1)/(saturated_oil_table_[pvtTableIdx][3][is+1]-saturated_oil_table_[pvtTableIdx][3][is]); + double val = (val2 - val1)/(saturated_oil_table_[pvtTableIdx][4][is+1]-saturated_oil_table_[pvtTableIdx][4][is]); return val; } @@ -489,9 +538,9 @@ namespace Opm press); } else { // Undersaturated case // Interpolate between table sections - int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], r); - double w = (r - saturated_oil_table_[pvtTableIdx][3][is]) / - (saturated_oil_table_[pvtTableIdx][3][is+1] - saturated_oil_table_[pvtTableIdx][3][is]); + int is = tableIndex(saturated_oil_table_[pvtTableIdx][4], r); + double w = (r - saturated_oil_table_[pvtTableIdx][4][is]) / + (saturated_oil_table_[pvtTableIdx][4][is+1] - saturated_oil_table_[pvtTableIdx][4][is]); assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = @@ -524,9 +573,9 @@ namespace Opm saturated_oil_table_[pvtTableIdx][item], press); } else { // Undersaturated case - int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], r); - double w = (r - saturated_oil_table_[pvtTableIdx][3][is]) / - (saturated_oil_table_[pvtTableIdx][3][is+1] - saturated_oil_table_[pvtTableIdx][3][is]); + int is = tableIndex(saturated_oil_table_[pvtTableIdx][4], r); + double w = (r - saturated_oil_table_[pvtTableIdx][4][is]) / + (saturated_oil_table_[pvtTableIdx][4][is+1] - saturated_oil_table_[pvtTableIdx][4][is]); assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = @@ -545,7 +594,7 @@ namespace Opm if (isSat) { // Saturated case return 0; } else { // Undersaturated case - int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], r); + int is = tableIndex(saturated_oil_table_[pvtTableIdx][4], r); assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = @@ -557,35 +606,37 @@ namespace Opm undersat_oil_tables_[pvtTableIdx][is+1][item], press); - double val = (val2 - val1)/(saturated_oil_table_[pvtTableIdx][3][is+1]-saturated_oil_table_[pvtTableIdx][3][is]); + double val = (val2 - val1)/(saturated_oil_table_[pvtTableIdx][4][is+1]-saturated_oil_table_[pvtTableIdx][4][is]); return val; } - } else { - if (isSat) { // Saturated case - return linearInterpolation(saturated_oil_table_[pvtTableIdx][0], - saturated_oil_table_[pvtTableIdx][item], - press); - } else { // Undersaturated case - // Interpolate between table sections - int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], r); - double w = (r - saturated_oil_table_[pvtTableIdx][3][is]) / - (saturated_oil_table_[pvtTableIdx][3][is+1] - saturated_oil_table_[pvtTableIdx][3][is]); - assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); - assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); - double val1 = - linearInterpolation(undersat_oil_tables_[pvtTableIdx][is][0], - undersat_oil_tables_[pvtTableIdx][is][item], - press); - double val2 = - linearInterpolation(undersat_oil_tables_[pvtTableIdx][is+1][0], - undersat_oil_tables_[pvtTableIdx][is+1][item], - press); - double val = val1 + w*(val2 - val1); - return val; + } + // no derivative + else { + if (isSat) { // Saturated case + return linearInterpolation(saturated_oil_table_[pvtTableIdx][0], + saturated_oil_table_[pvtTableIdx][item], + press); + } else { // Undersaturated case + // Interpolate between table sections + int is = tableIndex(saturated_oil_table_[pvtTableIdx][4], r); + double w = (r - saturated_oil_table_[pvtTableIdx][4][is]) / + (saturated_oil_table_[pvtTableIdx][4][is+1] - saturated_oil_table_[pvtTableIdx][4][is]); + assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); + assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); + double val1 = + linearInterpolation(undersat_oil_tables_[pvtTableIdx][is][0], + undersat_oil_tables_[pvtTableIdx][is][item], + press); + double val2 = + linearInterpolation(undersat_oil_tables_[pvtTableIdx][is+1][0], + undersat_oil_tables_[pvtTableIdx][is+1][item], + press); + double val = val1 + w*(val2 - val1); + return val; + } } } - } } // namespace Opm diff --git a/tests/test_blackoilfluid.cpp b/tests/test_blackoilfluid.cpp index 699ebb9a..add7d495 100644 --- a/tests/test_blackoilfluid.cpp +++ b/tests/test_blackoilfluid.cpp @@ -247,8 +247,10 @@ BOOST_AUTO_TEST_CASE(test_liveoil) const int np = phase_usage_.num_phases; std::vector pvtRegionIdx(n, 0); - // the tolerance for acceptable difference in values - const double reltol = 1e-9; + // the relative tolerance in percentage for acceptable difference in values + const double reltolper = 1e-9; + // the relative tolerance in percentage for acceptable difference in values for viscosity + const double reltolpermu = 1e-1; std::vector p(n); std::vector r(n); @@ -290,13 +292,13 @@ BOOST_AUTO_TEST_CASE(test_liveoil) } - testmu(reltol, n, np, pvtRegionIdx, p, r,z, props_, condition); + testmu(reltolpermu, n, np, pvtRegionIdx, p, r,z, props_, condition); - testb(reltol,n,np,pvtRegionIdx,p,r,z,props_,condition); + testb(reltolper,n,np,pvtRegionIdx,p,r,z,props_,condition); - testrsSat(reltol,n,np,pvtRegionIdx,p,props_); + testrsSat(reltolper,n,np,pvtRegionIdx,p,props_); - testrvSat(reltol,n,np,pvtRegionIdx,p,props_); + testrvSat(reltolper,n,np,pvtRegionIdx,p,props_); } @@ -324,8 +326,10 @@ BOOST_AUTO_TEST_CASE(test_wetgas) const int np = phase_usage_.num_phases; std::vector pvtRegionIdx(n, 0); - // the tolerance for acceptable difference in values - const double reltol = 1e-9; + // the relative tolerance in percentage for acceptable difference in values + const double reltolper = 1e-9; + // the relative tolerance in percentage for acceptable difference in values for viscosity + const double reltolpermu = 1e-1; std::vector p(n); std::vector r(n); @@ -367,12 +371,12 @@ BOOST_AUTO_TEST_CASE(test_wetgas) } - testmu(reltol, n, np, pvtRegionIdx, p, r,z, props_, condition); + testmu(reltolpermu, n, np, pvtRegionIdx, p, r,z, props_, condition); - testb(reltol,n,np,pvtRegionIdx,p,r,z,props_,condition); + testb(reltolper,n,np,pvtRegionIdx,p,r,z,props_,condition); - testrsSat(reltol,n,np,pvtRegionIdx,p,props_); + testrsSat(reltolper,n,np,pvtRegionIdx,p,props_); - testrvSat(reltol,n,np,pvtRegionIdx,p,props_); + testrvSat(reltolper,n,np,pvtRegionIdx,p,props_); }