diff --git a/opm/autodiff/BlackoilPropsAd.cpp b/opm/autodiff/BlackoilPropsAd.cpp index e41cb27e2..e88e52b2d 100644 --- a/opm/autodiff/BlackoilPropsAd.cpp +++ b/opm/autodiff/BlackoilPropsAd.cpp @@ -166,6 +166,35 @@ namespace Opm return mu.col(pu_.phase_pos[Gas]); } + /// Gas viscosity. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + V BlackoilPropsAd::muGas(const V& pg, + const V& rv, + const std::vector& /*cond*/, + const Cells& cells) const + { + if (!pu_.phase_used[Gas]) { + OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); + } + const int n = cells.size(); + assert(pg.size() == n); + const int np = props_.numPhases(); + Block z = Block::Zero(n, np); + if (pu_.phase_used[Oil]) { + // Faking a z with the right ratio: + // rv = zo/zg + z.col(pu_.phase_pos[Oil]) = rv; + z.col(pu_.phase_pos[Gas]) = V::Ones(n, 1); + } + Block mu(n, np); + props_.viscosity(n, pg.data(), z.data(), cells.data(), mu.data(), 0); + return mu.col(pu_.phase_pos[Gas]); + } + /// Water viscosity. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. @@ -268,6 +297,45 @@ namespace Opm return ADB::function(mu.col(pu_.phase_pos[Gas]), jacs); #endif } + /// Gas viscosity. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n viscosity values. + ADB BlackoilPropsAd::muGas(const ADB& pg, + const ADB& rv, + const std::vector& cond, + const Cells& cells) const + { +#if 1 + return ADB::constant(muGas(pg.value(), rv.value(),cond,cells), pg.blockPattern()); +#else + if (!pu_.phase_used[Gas]) { + OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); + } + const int n = cells.size(); + assert(pg.value().size() == n); + const int np = props_.numPhases(); + Block z = Block::Zero(n, np); + if (pu_.phase_used[Oil]) { + // Faking a z with the right ratio: + // rv = zo/zg + z.col(pu_.phase_pos[Oil]) = rv; + z.col(pu_.phase_pos[Gas]) = V::Ones(n, 1); + } + Block mu(n, np); + Block dmu(n, np); + props_.viscosity(n, pg.value().data(), z.data(), cells.data(), mu.data(), dmu.data()); + ADB::M dmu_diag = spdiag(dmu.col(pu_.phase_pos[Gas])); + const int num_blocks = pg.numBlocks(); + std::vector jacs(num_blocks); + for (int block = 0; block < num_blocks; ++block) { + jacs[block] = dmu_diag * pg.derivative()[block]; + } + return ADB::function(mu.col(pu_.phase_pos[Gas]), jacs); +#endif + } // ------ Formation volume factor (b) ------ @@ -357,6 +425,36 @@ namespace Opm return matrix.col(gi*np + gi); } + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + V BlackoilPropsAd::bGas(const V& pg, + const V& rv, + const std::vector& /*cond*/, + const Cells& cells) const + { + if (!pu_.phase_used[Gas]) { + OPM_THROW(std::runtime_error, "Cannot call bGas(): gas phase not present."); + } + const int n = cells.size(); + assert(pg.size() == n); + const int np = props_.numPhases(); + Block z = Block::Zero(n, np); + if (pu_.phase_used[Oil]) { + // Faking a z with the right ratio: + // rv = zo/zg + z.col(pu_.phase_pos[Oil]) = rv; + z.col(pu_.phase_pos[Gas]) = V::Ones(n, 1); + } + Block matrix(n, np*np); + props_.matrix(n, pg.data(), z.data(), cells.data(), matrix.data(), 0); + const int gi = pu_.phase_pos[Gas]; + return matrix.col(gi*np + gi); + } + /// Water formation volume factor. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. @@ -454,6 +552,44 @@ namespace Opm return ADB::function(matrix.col(column), jacs); } + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + ADB BlackoilPropsAd::bGas(const ADB& pg, + const ADB& rv, + const std::vector& /*cond*/, + const Cells& cells) const + { + if (!pu_.phase_used[Gas]) { + OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); + } + const int n = cells.size(); + assert(pg.value().size() == n); + const int np = props_.numPhases(); + Block z = Block::Zero(n, np); + if (pu_.phase_used[Oil]) { + // Faking a z with the right ratio: + // rv = zo/zg + z.col(pu_.phase_pos[Oil]) = rv.value(); + z.col(pu_.phase_pos[Gas]) = V::Ones(n, 1); + } + Block matrix(n, np*np); + Block dmatrix(n, np*np); + props_.matrix(n, pg.value().data(), z.data(), cells.data(), matrix.data(), dmatrix.data()); + const int phase_ind = pu_.phase_pos[Gas]; + const int column = phase_ind*np + phase_ind; // Index of our sought diagonal column. + ADB::M db_diag = spdiag(dmatrix.col(column)); + const int num_blocks = pg.numBlocks(); + std::vector jacs(num_blocks); + for (int block = 0; block < num_blocks; ++block) { + jacs[block] = db_diag * pg.derivative()[block]; + } + return ADB::function(matrix.col(column), jacs); + } + // ------ Rs bubble point curve ------ @@ -461,7 +597,7 @@ namespace Opm /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. - V BlackoilPropsAd::rsMax(const V& po, + V BlackoilPropsAd::rsSat(const V& po, const Cells& cells) const { // Suppress warning about "unused parameters". @@ -475,7 +611,37 @@ namespace Opm /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. - ADB BlackoilPropsAd::rsMax(const ADB& po, + ADB BlackoilPropsAd::rsSat(const ADB& po, + const Cells& cells) const + { + // Suppress warning about "unused parameters". + static_cast(po); + static_cast(cells); + + OPM_THROW(std::runtime_error, "Method rsMax() not implemented."); + } + + // ------ Rs bubble point curve ------ + + /// Bubble point curve for Rs as function of oil pressure. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + V BlackoilPropsAd::rvSat(const V& po, + const Cells& cells) const + { + // Suppress warning about "unused parameters". + static_cast(po); + static_cast(cells); + + OPM_THROW(std::runtime_error, "Method rsMax() not implemented."); + } + + /// Bubble point curve for Rs as function of oil pressure. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + ADB BlackoilPropsAd::rvSat(const ADB& po, const Cells& cells) const { // Suppress warning about "unused parameters". diff --git a/opm/autodiff/BlackoilPropsAd.hpp b/opm/autodiff/BlackoilPropsAd.hpp index 88f5a30fd..00fc6d523 100644 --- a/opm/autodiff/BlackoilPropsAd.hpp +++ b/opm/autodiff/BlackoilPropsAd.hpp @@ -124,6 +124,17 @@ namespace Opm V muGas(const V& pg, const Cells& cells) const; + /// Gas viscosity. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n gas solution factor values. + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n viscosity values. + V muGas(const V& pg, + const V& rv, + const std::vector& cond, + const Cells& cells) const; + /// Water viscosity. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. @@ -149,6 +160,16 @@ namespace Opm ADB muGas(const ADB& pg, const Cells& cells) const; + /// Gas viscosity. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n gas solution factor values. + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n viscosity values. + ADB muGas(const ADB& pg, + const ADB& rv, + const std::vector& cond, + const Cells& cells) const; // ------ Formation volume factor (b) ------ @@ -177,6 +198,17 @@ namespace Opm V bGas(const V& pg, const Cells& cells) const; + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + V bGas(const V& pg, + const V& rv, + const std::vector& cond, + const Cells& cells) const; + /// Water formation volume factor. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. @@ -203,22 +235,47 @@ namespace Opm const Cells& cells) const; + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + ADB bGas(const ADB& pg, + const ADB& rv, + const std::vector& cond, + const Cells& cells) const; // ------ Rs bubble point curve ------ - /// Bubble point curve for Rs as function of oil pressure. + /// Solution gas/oil ratio and its derivatives at saturated condition as a function of p. /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. - V rsMax(const V& po, + V rsSat(const V& po, const Cells& cells) const; - /// Bubble point curve for Rs as function of oil pressure. + /// Solution gas/oil ratio and its derivatives at saturated condition as a function of p. /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. - ADB rsMax(const ADB& po, + ADB rsSat(const ADB& po, const Cells& cells) const; + // ------ Rv condensation curve ------ + + /// Vapor oil/gas ratio and its derivatives at saturated conditions as a function of p. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + V rvSat(const V& po, + const Cells& cells) const; + + /// Vapor oil/gas ratio and its derivatives at saturated conditions as a function of p. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + ADB rvSat(const ADB& po, + const Cells& cells) const; // ------ Relative permeability ------ diff --git a/opm/autodiff/BlackoilPropsAdFromDeck.cpp b/opm/autodiff/BlackoilPropsAdFromDeck.cpp index 8902972cd..84de6643a 100644 --- a/opm/autodiff/BlackoilPropsAdFromDeck.cpp +++ b/opm/autodiff/BlackoilPropsAdFromDeck.cpp @@ -439,6 +439,33 @@ namespace Opm return b; } + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + V BlackoilPropsAdFromDeck::bGas(const V& pg, + const V& rv, + const std::vector& cond, + const Cells& cells) const + { + if (!phase_usage_.phase_used[Gas]) { + OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); + } + const int n = cells.size(); + assert(pg.size() == n); + + V b(n); + V dbdp(n); + V dbdr(n); + + props_[phase_usage_.phase_pos[Gas]]->b(n, pg.data(), rv.data(), &cond[0], + b.data(), dbdp.data(), dbdr.data()); + + return b; + } + /// Water formation volume factor. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. @@ -519,9 +546,42 @@ namespace Opm V b(n); V dbdp(n); V dbdr(n); - const double* rs = 0; + const double* rv = 0; - props_[phase_usage_.phase_pos[Gas]]->b(n, pg.value().data(), rs, + props_[phase_usage_.phase_pos[Gas]]->b(n, pg.value().data(), rv, + b.data(), dbdp.data(), dbdr.data()); + + ADB::M dbdp_diag = spdiag(dbdp); + const int num_blocks = pg.numBlocks(); + std::vector jacs(num_blocks); + for (int block = 0; block < num_blocks; ++block) { + jacs[block] = dbdp_diag * pg.derivative()[block]; + } + return ADB::function(b, jacs); + } + + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + ADB BlackoilPropsAdFromDeck::bGas(const ADB& pg, + const ADB& rv, + const std::vector& cond, + const Cells& cells) const + { + if (!phase_usage_.phase_used[Gas]) { + OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); + } + const int n = cells.size(); + assert(pg.size() == n); + + V b(n); + V dbdp(n); + V dbdr(n); + + props_[phase_usage_.phase_pos[Gas]]->b(n, pg.value().data(), rv.value().data(), &cond[0], b.data(), dbdp.data(), dbdr.data()); ADB::M dbdp_diag = spdiag(dbdp); @@ -541,7 +601,7 @@ namespace Opm /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. - V BlackoilPropsAdFromDeck::rsMax(const V& po, + V BlackoilPropsAdFromDeck::rsSat(const V& po, const Cells& cells) const { if (!phase_usage_.phase_used[Oil]) { @@ -551,7 +611,7 @@ namespace Opm assert(po.size() == n); V rbub(n); V drbubdp(n); - props_[Oil]->rbub(n, po.data(), rbub.data(), drbubdp.data()); + props_[Oil]->rsSat(n, po.data(), rbub.data(), drbubdp.data()); return rbub; } @@ -559,7 +619,7 @@ namespace Opm /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. - ADB BlackoilPropsAdFromDeck::rsMax(const ADB& po, + ADB BlackoilPropsAdFromDeck::rsSat(const ADB& po, const Cells& cells) const { if (!phase_usage_.phase_used[Oil]) { @@ -569,7 +629,7 @@ namespace Opm assert(po.size() == n); V rbub(n); V drbubdp(n); - props_[Oil]->rbub(n, po.value().data(), rbub.data(), drbubdp.data()); + props_[Oil]->rsSat(n, po.value().data(), rbub.data(), drbubdp.data()); ADB::M drbubdp_diag = spdiag(drbubdp); const int num_blocks = po.numBlocks(); std::vector jacs(num_blocks); @@ -579,6 +639,50 @@ namespace Opm return ADB::function(rbub, jacs); } + // ------ Condensation curve ------ + + /// Condensation curve for Rv as function of oil pressure. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + V BlackoilPropsAdFromDeck::rvSat(const V& po, + const Cells& cells) const + { + if (!phase_usage_.phase_used[Gas]) { + OPM_THROW(std::runtime_error, "Cannot call rvMax(): gas phase not present."); + } + const int n = cells.size(); + assert(po.size() == n); + V rv(n); + V drvdp(n); + props_[Oil]->rvSat(n, po.data(), rv.data(), drvdp.data()); + return rv; + } + + /// Condensation curve for Rv as function of oil pressure. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + ADB BlackoilPropsAdFromDeck::rvSat(const ADB& po, + const Cells& cells) const + { + if (!phase_usage_.phase_used[Gas]) { + OPM_THROW(std::runtime_error, "Cannot call rvMax(): gas phase not present."); + } + const int n = cells.size(); + assert(po.size() == n); + V rv(n); + V drvdp(n); + props_[Oil]->rvSat(n, po.value().data(), rv.data(), drvdp.data()); + ADB::M drvdp_diag = spdiag(drvdp); + const int num_blocks = po.numBlocks(); + std::vector jacs(num_blocks); + for (int block = 0; block < num_blocks; ++block) { + jacs[block] = drvdp_diag * po.derivative()[block]; + } + return ADB::function(rv, jacs); + } + // ------ Relative permeability ------ /// Relative permeabilities for all phases. diff --git a/opm/autodiff/BlackoilPropsAdFromDeck.hpp b/opm/autodiff/BlackoilPropsAdFromDeck.hpp index 943a06f65..402ecda2d 100644 --- a/opm/autodiff/BlackoilPropsAdFromDeck.hpp +++ b/opm/autodiff/BlackoilPropsAdFromDeck.hpp @@ -178,6 +178,17 @@ namespace Opm V bGas(const V& pg, const Cells& cells) const; + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + V bGas(const V& pg, + const V& rv, + const std::vector& cond, + const Cells& cells) const; + /// Water formation volume factor. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. @@ -203,6 +214,16 @@ namespace Opm ADB bGas(const ADB& pg, const Cells& cells) const; + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + ADB bGas(const ADB& pg, + const ADB& rv, + const std::vector& cond, + const Cells& cells) const; // ------ Rs bubble point curve ------ @@ -210,16 +231,31 @@ namespace Opm /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. - V rsMax(const V& po, + V rsSat(const V& po, const Cells& cells) const; /// Bubble point curve for Rs as function of oil pressure. /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. - ADB rsMax(const ADB& po, + ADB rsSat(const ADB& po, const Cells& cells) const; + // ------ Rv condensation curve ------ + + /// Condensation curve for Rv as function of oil pressure. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + V rvSat(const V& po, + const Cells& cells) const; + + /// Condensation curve for Rv as function of oil pressure. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + ADB rvSat(const ADB& po, + const Cells& cells) const; // ------ Relative permeability ------ diff --git a/opm/autodiff/BlackoilPropsAdInterface.hpp b/opm/autodiff/BlackoilPropsAdInterface.hpp index ec98951bc..bf3dcc212 100644 --- a/opm/autodiff/BlackoilPropsAdInterface.hpp +++ b/opm/autodiff/BlackoilPropsAdInterface.hpp @@ -176,6 +176,18 @@ namespace Opm V bGas(const V& pg, const Cells& cells) const = 0; + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + virtual + V bGas(const V& pg, + const V& rv, + const std::vector& cond, + const Cells& cells) const = 0; + /// Water formation volume factor. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. @@ -204,6 +216,17 @@ namespace Opm ADB bGas(const ADB& pg, const Cells& cells) const = 0; + /// Gas formation volume factor. + /// \param[in] pg Array of n gas pressure values. + /// \param[in] rv Array of n vapor oil/gas ratio + /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n formation volume factor values. + virtual + ADB bGas(const ADB& pg, + const ADB& rv, + const std::vector& cond, + const Cells& cells) const = 0; // ------ Rs bubble point curve ------ @@ -212,7 +235,7 @@ namespace Opm /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. virtual - V rsMax(const V& po, + V rsSat(const V& po, const Cells& cells) const = 0; /// Bubble point curve for Rs as function of oil pressure. @@ -220,7 +243,25 @@ namespace Opm /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. virtual - ADB rsMax(const ADB& po, + ADB rsSat(const ADB& po, + const Cells& cells) const = 0; + + // ------ Rs bubble point curve ------ + + /// Bubble point curve for Rs as function of oil pressure. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + virtual + V rvSat(const V& po, + const Cells& cells) const = 0; + + /// Bubble point curve for Rs as function of oil pressure. + /// \param[in] po Array of n oil pressure values. + /// \param[in] cells Array of n cell indices to be associated with the pressure values. + /// \return Array of n bubble point values for Rs. + virtual + ADB rvSat(const ADB& po, const Cells& cells) const = 0; // ------ Relative permeability ------