mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Only compute well potential if needed
A boolen user parameter is added to controll the computation of well potential. This is a temporary fix to assure that no extra computation time is used on well potential calculation if it is not needed. The long term fix will require a more thorough revising of the well group implementation.
This commit is contained in:
@@ -1703,94 +1703,97 @@ namespace detail {
|
|||||||
const std::vector<ADB>& b_perfcells,
|
const std::vector<ADB>& b_perfcells,
|
||||||
WellState& well_state)
|
WellState& well_state)
|
||||||
{
|
{
|
||||||
const int nw = wells().number_of_wells;
|
//only compute well potentials if they are needed
|
||||||
const int np = wells().number_of_phases;
|
if (param_.compute_well_potentials_) {
|
||||||
const Opm::PhaseUsage pu = fluid_.phaseUsage();
|
const int nw = wells().number_of_wells;
|
||||||
V bhps = V::Zero(nw);
|
const int np = wells().number_of_phases;
|
||||||
for (int w = 0; w < nw; ++w) {
|
const Opm::PhaseUsage pu = fluid_.phaseUsage();
|
||||||
const WellControls* ctrl = wells().ctrls[w];
|
V bhps = V::Zero(nw);
|
||||||
const int nwc = well_controls_get_num(ctrl);
|
for (int w = 0; w < nw; ++w) {
|
||||||
//Loop over all controls until we find a BHP control
|
const WellControls* ctrl = wells().ctrls[w];
|
||||||
//or a THP control that specifies what we need.
|
const int nwc = well_controls_get_num(ctrl);
|
||||||
//Pick the value that gives the most restrictive flow
|
//Loop over all controls until we find a BHP control
|
||||||
for (int ctrl_index=0; ctrl_index < nwc; ++ctrl_index) {
|
//or a THP control that specifies what we need.
|
||||||
|
//Pick the value that gives the most restrictive flow
|
||||||
|
for (int ctrl_index=0; ctrl_index < nwc; ++ctrl_index) {
|
||||||
|
|
||||||
if (well_controls_iget_type(ctrl, ctrl_index) == BHP) {
|
if (well_controls_iget_type(ctrl, ctrl_index) == BHP) {
|
||||||
bhps[w] = well_controls_iget_target(ctrl, ctrl_index);
|
bhps[w] = well_controls_iget_target(ctrl, ctrl_index);
|
||||||
}
|
|
||||||
|
|
||||||
if (well_controls_iget_type(ctrl, ctrl_index) == THP) {
|
|
||||||
double aqua = 0.0;
|
|
||||||
double liquid = 0.0;
|
|
||||||
double vapour = 0.0;
|
|
||||||
|
|
||||||
if (active_[ Water ]) {
|
|
||||||
aqua = well_state.wellRates()[w*np + pu.phase_pos[ Water ] ];
|
|
||||||
}
|
|
||||||
if (active_[ Oil ]) {
|
|
||||||
liquid = well_state.wellRates()[w*np + pu.phase_pos[ Oil ] ];
|
|
||||||
}
|
|
||||||
if (active_[ Gas ]) {
|
|
||||||
vapour = well_state.wellRates()[w*np + pu.phase_pos[ Gas ] ];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int vfp = well_controls_iget_vfp(ctrl, ctrl_index);
|
if (well_controls_iget_type(ctrl, ctrl_index) == THP) {
|
||||||
const double& thp = well_controls_iget_target(ctrl, ctrl_index);
|
double aqua = 0.0;
|
||||||
const double& alq = well_controls_iget_alq(ctrl, ctrl_index);
|
double liquid = 0.0;
|
||||||
|
double vapour = 0.0;
|
||||||
|
|
||||||
//Set *BHP* target by calculating bhp from THP
|
if (active_[ Water ]) {
|
||||||
const WellType& well_type = wells().type[w];
|
aqua = well_state.wellRates()[w*np + pu.phase_pos[ Water ] ];
|
||||||
|
}
|
||||||
|
if (active_[ Oil ]) {
|
||||||
|
liquid = well_state.wellRates()[w*np + pu.phase_pos[ Oil ] ];
|
||||||
|
}
|
||||||
|
if (active_[ Gas ]) {
|
||||||
|
vapour = well_state.wellRates()[w*np + pu.phase_pos[ Gas ] ];
|
||||||
|
}
|
||||||
|
|
||||||
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
|
const int vfp = well_controls_iget_vfp(ctrl, ctrl_index);
|
||||||
|
const double& thp = well_controls_iget_target(ctrl, ctrl_index);
|
||||||
|
const double& alq = well_controls_iget_alq(ctrl, ctrl_index);
|
||||||
|
|
||||||
if (well_type == INJECTOR) {
|
//Set *BHP* target by calculating bhp from THP
|
||||||
double dp = wellhelpers::computeHydrostaticCorrection(
|
const WellType& well_type = wells().type[w];
|
||||||
wells(), w, vfp_properties_.getInj()->getTable(vfp)->getDatumDepth(),
|
|
||||||
stdWells().wellPerforationDensities(), gravity);
|
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
|
||||||
const double bhp = vfp_properties_.getInj()->bhp(vfp, aqua, liquid, vapour, thp) - dp;
|
|
||||||
// apply the strictes of the bhp controlls i.e. smallest bhp for injectors
|
if (well_type == INJECTOR) {
|
||||||
if ( bhp < bhps[w]) {
|
double dp = wellhelpers::computeHydrostaticCorrection(
|
||||||
bhps[w] = bhp;
|
wells(), w, vfp_properties_.getInj()->getTable(vfp)->getDatumDepth(),
|
||||||
|
stdWells().wellPerforationDensities(), gravity);
|
||||||
|
const double bhp = vfp_properties_.getInj()->bhp(vfp, aqua, liquid, vapour, thp) - dp;
|
||||||
|
// apply the strictes of the bhp controlls i.e. smallest bhp for injectors
|
||||||
|
if ( bhp < bhps[w]) {
|
||||||
|
bhps[w] = bhp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (well_type == PRODUCER) {
|
||||||
|
double dp = wellhelpers::computeHydrostaticCorrection(
|
||||||
|
wells(), w, vfp_properties_.getProd()->getTable(vfp)->getDatumDepth(),
|
||||||
|
stdWells().wellPerforationDensities(), gravity);
|
||||||
|
|
||||||
|
const double bhp = vfp_properties_.getProd()->bhp(vfp, aqua, liquid, vapour, thp, alq) - dp;
|
||||||
|
// apply the strictes of the bhp controlls i.e. largest bhp for injectors
|
||||||
|
if ( bhp > bhps[w]) {
|
||||||
|
bhps[w] = bhp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
OPM_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (well_type == PRODUCER) {
|
|
||||||
double dp = wellhelpers::computeHydrostaticCorrection(
|
|
||||||
wells(), w, vfp_properties_.getProd()->getTable(vfp)->getDatumDepth(),
|
|
||||||
stdWells().wellPerforationDensities(), gravity);
|
|
||||||
|
|
||||||
const double bhp = vfp_properties_.getProd()->bhp(vfp, aqua, liquid, vapour, thp, alq) - dp;
|
|
||||||
// apply the strictes of the bhp controlls i.e. largest bhp for injectors
|
|
||||||
if ( bhp > bhps[w]) {
|
|
||||||
bhps[w] = bhp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
OPM_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use bhp limit from control
|
||||||
|
SolutionState state0 = state;
|
||||||
|
asImpl().makeConstantState(state0);
|
||||||
|
state0.bhp = ADB::constant(bhps);
|
||||||
|
|
||||||
|
// compute well potentials
|
||||||
|
V aliveWells;
|
||||||
|
std::vector<ADB> well_potentials;
|
||||||
|
asImpl().stdWells().computeWellFlux(state0, fluid_.phaseUsage(), active_, mob_perfcells, b_perfcells, aliveWells, well_potentials);
|
||||||
|
|
||||||
|
// store well potentials in the well state
|
||||||
|
// transform to a single vector instead of separate vectors pr phase
|
||||||
|
const int nperf = wells().well_connpos[nw];
|
||||||
|
V cq = superset(well_potentials[0].value(), Span(nperf, np, 0), nperf*np);
|
||||||
|
for (int phase = 1; phase < np; ++phase) {
|
||||||
|
cq += superset(well_potentials[phase].value(), Span(nperf, np, phase), nperf*np);
|
||||||
|
}
|
||||||
|
well_state.wellPotentials().assign(cq.data(), cq.data() + nperf*np);
|
||||||
}
|
}
|
||||||
|
|
||||||
// use bhp limit from control
|
|
||||||
SolutionState state0 = state;
|
|
||||||
asImpl().makeConstantState(state0);
|
|
||||||
state0.bhp = ADB::constant(bhps);
|
|
||||||
|
|
||||||
// compute well potentials
|
|
||||||
V aliveWells;
|
|
||||||
std::vector<ADB> well_potentials;
|
|
||||||
asImpl().stdWells().computeWellFlux(state0, fluid_.phaseUsage(), active_, mob_perfcells, b_perfcells, aliveWells, well_potentials);
|
|
||||||
|
|
||||||
// store well potentials in the well state
|
|
||||||
// transform to a single vector instead of separate vectors pr phase
|
|
||||||
const int nperf = wells().well_connpos[nw];
|
|
||||||
V cq = superset(well_potentials[0].value(), Span(nperf, np, 0), nperf*np);
|
|
||||||
for (int phase = 1; phase < np; ++phase) {
|
|
||||||
cq += superset(well_potentials[phase].value(), Span(nperf, np, phase), nperf*np);
|
|
||||||
}
|
|
||||||
well_state.wellPotentials().assign(cq.data(), cq.data() + nperf*np);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ namespace Opm
|
|||||||
tolerance_wells_ = param.getDefault("tolerance_wells", tolerance_wells_ );
|
tolerance_wells_ = param.getDefault("tolerance_wells", tolerance_wells_ );
|
||||||
solve_welleq_initially_ = param.getDefault("solve_welleq_initially",solve_welleq_initially_);
|
solve_welleq_initially_ = param.getDefault("solve_welleq_initially",solve_welleq_initially_);
|
||||||
update_equations_scaling_ = param.getDefault("update_equations_scaling", update_equations_scaling_);
|
update_equations_scaling_ = param.getDefault("update_equations_scaling", update_equations_scaling_);
|
||||||
|
compute_well_potentials_ = param.getDefault("compute_well_potentials", compute_well_potentials_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -65,6 +66,7 @@ namespace Opm
|
|||||||
tolerance_wells_ = 1.0e-3;
|
tolerance_wells_ = 1.0e-3;
|
||||||
solve_welleq_initially_ = true;
|
solve_welleq_initially_ = true;
|
||||||
update_equations_scaling_ = false;
|
update_equations_scaling_ = false;
|
||||||
|
compute_well_potentials_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ namespace Opm
|
|||||||
/// Update scaling factors for mass balance equations
|
/// Update scaling factors for mass balance equations
|
||||||
bool update_equations_scaling_;
|
bool update_equations_scaling_;
|
||||||
|
|
||||||
|
/// Compute well potentials, needed to calculate default guide rates for group
|
||||||
|
/// controlled wells
|
||||||
|
bool compute_well_potentials_;
|
||||||
|
|
||||||
/// Construct from user parameters or defaults.
|
/// Construct from user parameters or defaults.
|
||||||
explicit BlackoilModelParameters( const parameter::ParameterGroup& param );
|
explicit BlackoilModelParameters( const parameter::ParameterGroup& param );
|
||||||
|
|
||||||
|
|||||||
@@ -222,12 +222,13 @@ namespace Opm
|
|||||||
// Increment timer, remember well state.
|
// Increment timer, remember well state.
|
||||||
++timer;
|
++timer;
|
||||||
prev_well_state = well_state;
|
prev_well_state = well_state;
|
||||||
// Compute Well potentials (only used to determine default guide rates for group controlled wells)
|
// Compute Well potentials if they are needed
|
||||||
// TODO: add some logic to avoid unnecessary calulations of well potentials.
|
// Only used to determine default guide rates for group controlled wells
|
||||||
asImpl().computeWellPotentials(wells, state, well_state, well_potentials);
|
if ( param_.getDefault("compute_well_potentials", false ) ) {
|
||||||
|
asImpl().computeWellPotentials(wells, state, well_state, well_potentials);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write final simulation state.
|
// Write final simulation state.
|
||||||
output_writer_.writeTimeStep( timer, state, prev_well_state );
|
output_writer_.writeTimeStep( timer, state, prev_well_state );
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user