double PvtLiveOil::miscible_oil(const double press, const double* surfvol, const int pvtTableIdx, const int item, const bool deriv) const { int section; double Rval = linearInterpolation(saturated_oil_table_[pvtTableIdx][0], saturated_oil_table_[pvtTableIdx][3], press, section); double maxR = (surfvol[phase_pos_[Liquid]] == 0.0) ? 0.0 : surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]]; if (deriv) { if (Rval < maxR ) { // 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], 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 = 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; } } }
/// Gas resolution and its derivatives at bublepoint as a function of p. void SinglePvtLiveGas::rvSat(const int n, const double* p, double* output_rvSat, double* output_drvSatdp) const { for (int i = 0; i < n; ++i) { output_rvSat[i] = linearInterpolation(saturated_gas_table_[0], saturated_gas_table_[3],p[i]); output_drvSatdp[i] = linearInterpolationDerivative(saturated_gas_table_[0], saturated_gas_table_[3],p[i]); } }
void PvtLiveOil::rsSat(const int n, const int* pvtTableIdx, const double* p, double* output_rsSat, double* output_drsSatdp) const { for (int i = 0; i < n; ++i) { int tableIdx = getTableIndex_(pvtTableIdx, i); output_rsSat[i] = linearInterpolation(saturated_oil_table_[tableIdx][0], saturated_oil_table_[tableIdx][3],p[i]); output_drsSatdp[i] = linearInterpolationDerivative(saturated_oil_table_[tableIdx][0], saturated_oil_table_[tableIdx][3],p[i]); } }
void SinglePvtLiveOil::evalRDeriv(const double press, const double* surfvol, double& Rval, double& dRdpval) const { if (surfvol[phase_pos_[Vapour]] == 0.0) { Rval = 0.0; dRdpval = 0.0; return; } Rval = linearInterpolation(saturated_oil_table_[0], saturated_oil_table_[3], press); double maxR = surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]]; if (Rval < maxR ) { // Saturated case dRdpval = linearInterpolationDerivative(saturated_oil_table_[0], saturated_oil_table_[3], press); } else { // Undersaturated case Rval = maxR; dRdpval = 0.0; } }
void SinglePvtLiveGas::evalRDeriv(const double press, const double* surfvol, double& Rval, double& dRdpval) const { if (surfvol[phase_pos_[Liquid]] == 0.0) { // To handle no-gas case. Rval = 0.0; dRdpval = 0.0; return; } double satR = linearInterpolation(saturated_gas_table_[0], saturated_gas_table_[3], press); double maxR = surfvol[phase_pos_[Liquid]]/surfvol[phase_pos_[Vapour]]; if (satR < maxR ) { // Saturated case Rval = satR; dRdpval = linearInterpolationDerivative(saturated_gas_table_[0], saturated_gas_table_[3], press); } else { // Undersaturated case Rval = maxR; dRdpval = 0.0; } }
double SinglePvtLiveGas::miscible_gas(const double press, const double* surfvol, const int item, const bool deriv) const { int section; double Rval = linearInterpolation(saturated_gas_table_[0], saturated_gas_table_[3], press, section); double maxR = surfvol[phase_pos_[Liquid]]/surfvol[phase_pos_[Vapour]]; if (deriv) { if (Rval < maxR ) { // Saturated case return linearInterpolationDerivative(saturated_gas_table_[0], saturated_gas_table_[item], press); } else { // Undersaturated case int is = section; if (undersat_gas_tables_[is][0].size() < 2) { double val = (saturated_gas_table_[item][is+1] - saturated_gas_table_[item][is]) / (saturated_gas_table_[0][is+1] - saturated_gas_table_[0][is]); return val; } double val1 = linearInterpolation(undersat_gas_tables_[is][0], undersat_gas_tables_[is][item], maxR); double val2 = linearInterpolation(undersat_gas_tables_[is+1][0], undersat_gas_tables_[is+1][item], maxR); double val = (val2 - val1)/ (saturated_gas_table_[0][is+1] - saturated_gas_table_[0][is]); return val; } } else { if (Rval < maxR ) { // Saturated case return linearInterpolation(saturated_gas_table_[0], saturated_gas_table_[item], press); } else { // Undersaturated case int is = section; // Extrapolate from first table section if (is == 0 && press < saturated_gas_table_[0][0]) { return linearInterpolation(undersat_gas_tables_[0][0], undersat_gas_tables_[0][item], maxR); } // Extrapolate from last table section int ltp = saturated_gas_table_[0].size() - 1; if (is+1 == ltp && press > saturated_gas_table_[0][ltp]) { return linearInterpolation(undersat_gas_tables_[ltp][0], undersat_gas_tables_[ltp][item], maxR); } // Interpolate between table sections double w = (press - saturated_gas_table_[0][is]) / (saturated_gas_table_[0][is+1] - saturated_gas_table_[0][is]); if (undersat_gas_tables_[is][0].size() < 2) { double val = saturated_gas_table_[item][is] + w*(saturated_gas_table_[item][is+1] - saturated_gas_table_[item][is]); return val; } double val1 = linearInterpolation(undersat_gas_tables_[is][0], undersat_gas_tables_[is][item], maxR); double val2 = linearInterpolation(undersat_gas_tables_[is+1][0], undersat_gas_tables_[is+1][item], maxR); double val = val1 + w*(val2 - val1); return val; } } }
double SinglePvtLiveOil::miscible_oil(const double press, const double r, const PhasePresence& cond, 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_[0], saturated_oil_table_[item], press); } else { // Undersaturated case int is = tableIndex(saturated_oil_table_[3], r); double w = (r - saturated_oil_table_[3][is]) / (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); assert(undersat_oil_tables_[is][0].size() >= 2); assert(undersat_oil_tables_[is+1][0].size() >= 2); double val1 = linearInterpolationDerivative(undersat_oil_tables_[is][0], undersat_oil_tables_[is][item], press); double val2 = linearInterpolationDerivative(undersat_oil_tables_[is+1][0], undersat_oil_tables_[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_[3], r); assert(undersat_oil_tables_[is][0].size() >= 2); assert(undersat_oil_tables_[is+1][0].size() >= 2); double val1 = linearInterpolation(undersat_oil_tables_[is][0], undersat_oil_tables_[is][item], press); double val2 = linearInterpolation(undersat_oil_tables_[is+1][0], undersat_oil_tables_[is+1][item], press); double val = (val2 - val1)/(saturated_oil_table_[3][is+1]-saturated_oil_table_[3][is]); return val; } } else { if (isSat) { // Saturated case return linearInterpolation(saturated_oil_table_[0], saturated_oil_table_[item], press); } else { // Undersaturated case // Interpolate between table sections int is = tableIndex(saturated_oil_table_[3], r); double w = (r - saturated_oil_table_[3][is]) / (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); assert(undersat_oil_tables_[is][0].size() >= 2); assert(undersat_oil_tables_[is+1][0].size() >= 2); double val1 = linearInterpolation(undersat_oil_tables_[is][0], undersat_oil_tables_[is][item], press); double val2 = linearInterpolation(undersat_oil_tables_[is+1][0], undersat_oil_tables_[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 SinglePvtLiveGas::miscible_gas(const double press, const double r, const PhasePresence& cond, const int item, const int deriv) const { const bool isSat = cond.hasFreeOil(); // Derivative w.r.t p if (deriv == 1) { if (isSat) { // Saturated case return linearInterpolationDerivative(saturated_gas_table_[0], saturated_gas_table_[item], press); } else { // Undersaturated case int is = tableIndex(saturated_gas_table_[0], press); if (undersat_gas_tables_[is][0].size() < 2) { double val = (saturated_gas_table_[item][is+1] - saturated_gas_table_[item][is]) / (saturated_gas_table_[0][is+1] - saturated_gas_table_[0][is]); return val; } double val1 = linearInterpolation(undersat_gas_tables_[is][0], undersat_gas_tables_[is][item], r); double val2 = linearInterpolation(undersat_gas_tables_[is+1][0], undersat_gas_tables_[is+1][item], r); double val = (val2 - val1)/ (saturated_gas_table_[0][is+1] - saturated_gas_table_[0][is]); return val; } } else if (deriv == 2){ if (isSat) { return 0; } else { int is = tableIndex(saturated_gas_table_[0], press); double w = (press - saturated_gas_table_[0][is]) / (saturated_gas_table_[0][is+1] - saturated_gas_table_[0][is]); assert(undersat_gas_tables_[is][0].size() >= 2); assert(undersat_gas_tables_[is+1][0].size() >= 2); double val1 = linearInterpolationDerivative(undersat_gas_tables_[is][0], undersat_gas_tables_[is][item], r); double val2 = linearInterpolationDerivative(undersat_gas_tables_[is+1][0], undersat_gas_tables_[is+1][item], r); double val = val1 + w * (val2 - val1); return val; } } else { if (isSat) { // Saturated case return linearInterpolation(saturated_gas_table_[0], saturated_gas_table_[item], press); } else { // Undersaturated case int is = tableIndex(saturated_gas_table_[0], press); // Extrapolate from first table section if (is == 0 && press < saturated_gas_table_[0][0]) { return linearInterpolation(undersat_gas_tables_[0][0], undersat_gas_tables_[0][item], r); } // Extrapolate from last table section //int ltp = saturated_gas_table_[0].size() - 1; //if (is+1 == ltp && press > saturated_gas_table_[0][ltp]) { // return linearInterpolation(undersat_gas_tables_[ltp][0], // undersat_gas_tables_[ltp][item], // r); //} // Interpolate between table sections double w = (press - saturated_gas_table_[0][is]) / (saturated_gas_table_[0][is+1] - saturated_gas_table_[0][is]); if (undersat_gas_tables_[is][0].size() < 2) { double val = saturated_gas_table_[item][is] + w*(saturated_gas_table_[item][is+1] - saturated_gas_table_[item][is]); return val; } double val1 = linearInterpolation(undersat_gas_tables_[is][0], undersat_gas_tables_[is][item], r); double val2 = linearInterpolation(undersat_gas_tables_[is+1][0], undersat_gas_tables_[is+1][item], r); double val = val1 + w*(val2 - val1); return val; } } }