mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-12-22 07:23:27 -06:00
Changed well initialization and property calculation.
Bhp is now initialized to bhp target for bhp-controlled wells. Mobilities and pvt properties are now calculated from well perforation pressure and injection specifications for injectors, producers still use cell properties as before.
This commit is contained in:
parent
bdcf0291e0
commit
fa6b772972
@ -36,6 +36,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm
|
||||||
{
|
{
|
||||||
@ -446,7 +447,7 @@ namespace Opm
|
|||||||
/// Compute per-iteration dynamic properties for wells.
|
/// Compute per-iteration dynamic properties for wells.
|
||||||
void CompressibleTpfa::computeWellDynamicData(const double /*dt*/,
|
void CompressibleTpfa::computeWellDynamicData(const double /*dt*/,
|
||||||
const BlackoilState& /*state*/,
|
const BlackoilState& /*state*/,
|
||||||
const WellState& /*well_state*/)
|
const WellState& well_state)
|
||||||
{
|
{
|
||||||
// These are the variables that get computed by this function:
|
// These are the variables that get computed by this function:
|
||||||
//
|
//
|
||||||
@ -458,18 +459,42 @@ namespace Opm
|
|||||||
wellperf_A_.resize(nperf*np*np);
|
wellperf_A_.resize(nperf*np*np);
|
||||||
wellperf_phasemob_.resize(nperf*np);
|
wellperf_phasemob_.resize(nperf*np);
|
||||||
// The A matrix is set equal to the perforation grid cells'
|
// The A matrix is set equal to the perforation grid cells'
|
||||||
// matrix, for both injectors and producers.
|
// matrix for producers, computed from bhp and injection
|
||||||
|
// component fractions from
|
||||||
// The mobilities are set equal to the perforation grid cells'
|
// The mobilities are set equal to the perforation grid cells'
|
||||||
// mobilities, for both injectors and producers.
|
// mobilities for producers.
|
||||||
|
std::vector<double> mu(np);
|
||||||
for (int w = 0; w < nw; ++w) {
|
for (int w = 0; w < nw; ++w) {
|
||||||
|
bool producer = (wells_->type[w] == PRODUCER);
|
||||||
|
const double* comp_frac = &wells_->comp_frac[np*w];
|
||||||
for (int j = wells_->well_connpos[w]; j < wells_->well_connpos[w+1]; ++j) {
|
for (int j = wells_->well_connpos[w]; j < wells_->well_connpos[w+1]; ++j) {
|
||||||
const int c = wells_->well_cells[j];
|
const int c = wells_->well_cells[j];
|
||||||
const double* cA = &cell_A_[np*np*c];
|
|
||||||
double* wpA = &wellperf_A_[np*np*j];
|
double* wpA = &wellperf_A_[np*np*j];
|
||||||
|
double* wpM = &wellperf_phasemob_[np*j];
|
||||||
|
if (producer) {
|
||||||
|
const double* cA = &cell_A_[np*np*c];
|
||||||
std::copy(cA, cA + np*np, wpA);
|
std::copy(cA, cA + np*np, wpA);
|
||||||
const double* cM = &cell_phasemob_[np*c];
|
const double* cM = &cell_phasemob_[np*c];
|
||||||
double* wpM = &wellperf_phasemob_[np*j];
|
|
||||||
std::copy(cM, cM + np, wpM);
|
std::copy(cM, cM + np, wpM);
|
||||||
|
} else {
|
||||||
|
const double bhp = well_state.bhp()[w];
|
||||||
|
double perf_p = bhp;
|
||||||
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
|
perf_p += wellperf_gpot_[np*j + phase]*comp_frac[phase];
|
||||||
|
}
|
||||||
|
// Hack warning: comp_frac is used as a component
|
||||||
|
// surface-volume variable in calls to matrix() and
|
||||||
|
// viscosity(), but as a saturation in the call to
|
||||||
|
// relperm(). This is probably ok as long as injectors
|
||||||
|
// only inject pure fluids.
|
||||||
|
props_.matrix(1, &perf_p, comp_frac, &c, wpA, NULL);
|
||||||
|
props_.viscosity(1, &perf_p, comp_frac, &c, &mu[0], NULL);
|
||||||
|
ASSERT(std::fabs(std::accumulate(comp_frac, comp_frac + np, 0.0) - 1.0) < 1e-6);
|
||||||
|
props_.relperm (1, comp_frac, &c, wpM , NULL);
|
||||||
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
|
wpM[phase] /= mu[phase];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,11 +37,18 @@ namespace Opm
|
|||||||
if (wells) {
|
if (wells) {
|
||||||
const int nw = wells->number_of_wells;
|
const int nw = wells->number_of_wells;
|
||||||
bhp_.resize(nw);
|
bhp_.resize(nw);
|
||||||
// Initialize bhp to be pressure in first perforation cell.
|
// Initialize bhp to be target pressure
|
||||||
|
// if bhp-controlled well, otherwise set
|
||||||
|
// to pressure in first perforation cell.
|
||||||
for (int w = 0; w < nw; ++w) {
|
for (int w = 0; w < nw; ++w) {
|
||||||
|
const WellControls* ctrl = wells->ctrls[w];
|
||||||
|
if (ctrl->type[ctrl->current] == BHP) {
|
||||||
|
bhp_[w] = ctrl->target[ctrl->current];
|
||||||
|
} else {
|
||||||
const int cell = wells->well_cells[wells->well_connpos[w]];
|
const int cell = wells->well_cells[wells->well_connpos[w]];
|
||||||
bhp_[w] = state.pressure()[cell];
|
bhp_[w] = state.pressure()[cell];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
perfrates_.resize(wells->well_connpos[nw]);
|
perfrates_.resize(wells->well_connpos[nw]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user