Allow for different surface densities in well perforations

The surface density input in well_perforation_densities() in
WellDensitySegmented.hpp is changed from one value pr. phase to one
value pr phase and perforation. This allow for different densities in
different perforation. The test is changed accordingly.
This commit is contained in:
Tor Harald Sandve 2015-09-21 10:57:12 +02:00
parent 23f4f48df5
commit 7bdd91d78f
4 changed files with 29 additions and 8 deletions

View File

@ -777,8 +777,15 @@ namespace detail {
const V depth = cellCentroidsZToEigen(grid_);
const V pdepth = subset(depth, well_cells);
std::vector<double> perf_depth(pdepth.data(), pdepth.data() + nperf);
// Surface density.
std::vector<double> surf_dens(fluid_.surfaceDensity(), fluid_.surfaceDensity() + pu.num_phases);
DataBlock surf_dens(nperf, pu.num_phases);
for (int phase = 0; phase < pu.num_phases; ++ phase) {
surf_dens.col(phase) = V::Constant(nperf, fluid_.surfaceDensity()[pu.phase_pos[phase]]);
}
std::vector<double> surf_dens_perf(surf_dens.data(), surf_dens.data() + nperf * pu.num_phases);
// Gravity
double grav = detail::getGravity(geo_.gravity(), dimensions(grid_));
@ -786,7 +793,7 @@ namespace detail {
std::vector<double> cd =
WellDensitySegmented::computeConnectionDensities(
wells(), xw, fluid_.phaseUsage(),
b_perf, rsmax_perf, rvmax_perf, surf_dens);
b_perf, rsmax_perf, rvmax_perf, surf_dens_perf);
// 3. Compute pressure deltas
std::vector<double> cdp =

View File

@ -36,7 +36,7 @@ Opm::WellDensitySegmented::computeConnectionDensities(const Wells& wells,
const std::vector<double>& b_perf,
const std::vector<double>& rsmax_perf,
const std::vector<double>& rvmax_perf,
const std::vector<double>& surf_dens)
const std::vector<double>& surf_dens_perf)
{
// Verify that we have consistent input.
const int np = wells.number_of_phases;
@ -45,8 +45,8 @@ Opm::WellDensitySegmented::computeConnectionDensities(const Wells& wells,
if (wells.number_of_phases != phase_usage.num_phases) {
OPM_THROW(std::logic_error, "Inconsistent input: wells vs. phase_usage.");
}
if (surf_dens.size() != size_t(wells.number_of_phases)) {
OPM_THROW(std::logic_error, "Inconsistent input: surf_dens vs. phase_usage.");
if (nperf*np != int(surf_dens_perf.size())) {
OPM_THROW(std::logic_error, "Inconsistent input: wells vs. surf_dens.");
}
if (nperf*np != int(wstate.perfPhaseRates().size())) {
OPM_THROW(std::logic_error, "Inconsistent input: wells vs. wstate.");
@ -94,6 +94,7 @@ Opm::WellDensitySegmented::computeConnectionDensities(const Wells& wells,
const int oilpos = phase_usage.phase_pos[BlackoilPhases::Liquid];
std::vector<double> mix(np);
std::vector<double> x(np);
std::vector<double> surf_dens(np);
std::vector<double> dens(nperf);
for (int w = 0; w < nw; ++w) {
for (int perf = wells.well_connpos[w]; perf < wells.well_connpos[w+1]; ++perf) {
@ -130,6 +131,10 @@ Opm::WellDensitySegmented::computeConnectionDensities(const Wells& wells,
for (int phase = 0; phase < np; ++phase) {
volrat += x[phase] / b_perf[perf*np + phase];
}
for (int phase = 0; phase < np; ++phase) {
surf_dens[phase] = surf_dens_perf[perf*np + phase];
}
// Compute segment density.
dens[perf] = std::inner_product(surf_dens.begin(), surf_dens.end(), mix.begin(), 0.0) / volrat;
}

View File

@ -47,14 +47,14 @@ namespace Opm
/// \param[in] b_perf inverse ('little b') formation volume factor, size NP, P values per perforation
/// \param[in] rsmax_perf saturation point for rs (gas in oil) at each perforation, size N
/// \param[in] rvmax_perf saturation point for rv (oil in gas) at each perforation, size N
/// \param[in] surf_dens surface densities for active components, size P
/// \param[in] surf_dens surface densities for active components, size NP, P values per perforation
static std::vector<double> computeConnectionDensities(const Wells& wells,
const WellStateFullyImplicitBlackoil& wstate,
const PhaseUsage& phase_usage,
const std::vector<double>& b_perf,
const std::vector<double>& rsmax_perf,
const std::vector<double>& rvmax_perf,
const std::vector<double>& surf_dens);
const std::vector<double>& surf_dens_perf);
/// Compute pressure deltas.
/// Notation: N = number of perforations, P = number of phases.

View File

@ -88,7 +88,16 @@ BOOST_AUTO_TEST_CASE(TestPressureDeltas)
const std::vector<double> rsmax_perf = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 };
const std::vector<double> rvmax_perf = { 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 };
const std::vector<double> z_perf = { 10, 30, 50, 70, 90, 10, 30, 50, 70, 90 };
const std::vector<double> surf_dens = { 1000.0, 800.0, 10.0 };
const std::vector<double> surf_dens = { 1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0,
1000.0, 800.0, 10.0};
const double gravity = Opm::unit::gravity;
std::vector<double> cd =