/* Copyright 2010, 2011, 2012 SINTEF ICT, Applied Mathematics. This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #include "config.h" #include #include #include #include namespace Opm { using Opm::linearInterpolation; using Opm::linearInterpolationDerivative; using Opm::tableIndex; //------------------------------------------------------------------------ // Member functions //------------------------------------------------------------------------- PvtLiveOil::PvtLiveOil(Opm::DeckKeywordConstPtr pvtoKeyword) { int numTables = Opm::PvtoTable::numTables(pvtoKeyword); saturated_oil_table_.resize(numTables); undersat_oil_tables_.resize(numTables); for (int pvtTableIdx = 0; pvtTableIdx < numTables; ++pvtTableIdx) { Opm::PvtoTable pvtoTable(pvtoKeyword, pvtTableIdx); const auto saturatedPvto = pvtoTable.getOuterTable(); // OIL, PVTO saturated_oil_table_[pvtTableIdx].resize(4); const int sz = saturatedPvto->numRows(); for (int k=0; k<4; ++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 } 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); 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 } } // Complete undersaturated tables by extrapolating from existing data // as is done in Eclipse and Mrst int iNext = -1; for (int i=0; i 1) { continue; } // Look ahead for next record containing undersaturated data if (iNext < i) { iNext = i+1; while (iNext > >::size_type sz_t; for (sz_t j=1; j= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = linearInterpolationDerivative(undersat_oil_tables_[pvtTableIdx][is][0], undersat_oil_tables_[pvtTableIdx][is][item], press); double val2 = linearInterpolationDerivative(undersat_oil_tables_[pvtTableIdx][is+1][0], undersat_oil_tables_[pvtTableIdx][is+1][item], press); double val = val1 + w*(val2 - val1); return val; } } else { if (Rval < maxR ) { // 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], maxR); double w = (maxR - 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; } } } double PvtLiveOil::miscible_oil(const double press, const double r, const int pvtTableIdx, const int item, const int deriv) const { int section; double Rval = linearInterpolation(saturated_oil_table_[pvtTableIdx][0], saturated_oil_table_[pvtTableIdx][3], press, section); // derivative with respect to frist component (pressure) if (deriv == 1) { if (Rval <= r ) { // Saturated case return linearInterpolationDerivative(saturated_oil_table_[pvtTableIdx][0], 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]); assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = linearInterpolationDerivative(undersat_oil_tables_[pvtTableIdx][is][0], undersat_oil_tables_[pvtTableIdx][is][item], press); double val2 = linearInterpolationDerivative(undersat_oil_tables_[pvtTableIdx][is+1][0], undersat_oil_tables_[pvtTableIdx][is+1][item], press); double val = val1 + w*(val2 - val1); return val; } // derivative with respect to second component (r) } else if (deriv == 2) { if (Rval <= r ) { // Saturated case return 0; } else { // Undersaturated case int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], r); 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 = (val2 - val1)/(saturated_oil_table_[pvtTableIdx][3][is+1]-saturated_oil_table_[pvtTableIdx][3][is]); return val; } } else { if (Rval <= r ) { // 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; } } } double PvtLiveOil::miscible_oil(const double press, const double r, const PhasePresence& cond, const int pvtTableIdx, const int item, const int deriv) const { const bool isSat = cond.hasFreeGas(); // derivative with respect to frist component (pressure) if (deriv == 1) { if (isSat) { // Saturated case return linearInterpolationDerivative(saturated_oil_table_[pvtTableIdx][0], 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]); assert(undersat_oil_tables_[pvtTableIdx][is][0].size() >= 2); assert(undersat_oil_tables_[pvtTableIdx][is+1][0].size() >= 2); double val1 = linearInterpolationDerivative(undersat_oil_tables_[pvtTableIdx][is][0], undersat_oil_tables_[pvtTableIdx][is][item], press); double val2 = linearInterpolationDerivative(undersat_oil_tables_[pvtTableIdx][is+1][0], undersat_oil_tables_[pvtTableIdx][is+1][item], press); double val = val1 + w*(val2 - val1); return val; } // derivative with respect to second component (r) } else if (deriv == 2) { if (isSat) { // Saturated case return 0; } else { // Undersaturated case int is = tableIndex(saturated_oil_table_[pvtTableIdx][3], r); 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 = (val2 - val1)/(saturated_oil_table_[pvtTableIdx][3][is+1]-saturated_oil_table_[pvtTableIdx][3][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; } } } } // namespace Opm