unifying interface of a few functions of Wells classes

updateWellControls()
updateWellState()
addWellControlEq()

The change of function computeWellConnectionPressures() is not done
completely. Should find a solution later.
This commit is contained in:
Kai Bao 2016-05-09 15:27:09 +02:00
parent be165a26e0
commit 4254b48b57
10 changed files with 65 additions and 109 deletions

View File

@ -219,7 +219,7 @@ namespace detail {
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
const V depth = Opm::AutoDiffGrid::cellCentroidsZToEigen(grid_);
std_wells_.init(&fluid_, &active_, &phaseCondition_, &vfp_properties_, gravity, &depth);
std_wells_.init(&fluid_, &active_, &phaseCondition_, &vfp_properties_, gravity, depth);
#if HAVE_MPI
if ( linsolver_.parallelInformation().type() == typeid(ParallelISTLInformation) )
@ -761,7 +761,6 @@ namespace detail {
using namespace Opm::AutoDiffGrid;
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
const V depth = cellCentroidsZToEigen(grid_);
// If we have VFP tables, we need the well connection
// pressures for the "simple" hydrostatic correction
@ -772,14 +771,14 @@ namespace detail {
asImpl().makeConstantState(state0);
// asImpl().computeWellConnectionPressures(state0, well_state);
// Extract well connection depths.
asImpl().stdWells().computeWellConnectionPressures(state0, well_state, depth, gravity);
asImpl().stdWells().computeWellConnectionPressures(state0, well_state);
}
// Possibly switch well controls and updating well state to
// get reasonable initial conditions for the wells
// asImpl().updateWellControls(well_state);
// asImpl().stdWells().updateWellControls(well_state);
asImpl().stdWells().updateWellControls(gravity, vfp_properties_, terminal_output_, well_state);
asImpl().stdWells().updateWellControls(terminal_output_, well_state);
// Create the primary variables.
SolutionState state = asImpl().variableState(reservoir_state, well_state);
@ -792,7 +791,7 @@ namespace detail {
// and well connection pressures.
asImpl().computeAccum(state0, 0);
// asImpl().computeWellConnectionPressures(state0, well_state);
asImpl().stdWells().computeWellConnectionPressures(state0, well_state, depth, gravity);
asImpl().stdWells().computeWellConnectionPressures(state0, well_state);
}
// OPM_AD_DISKVAL(state.pressure);
@ -826,7 +825,7 @@ namespace detail {
asImpl().stdWells().updatePerfPhaseRatesAndPressures(cq_s, state, well_state);
asImpl().stdWells().addWellFluxEq(cq_s, state, residual_);
asImpl().addWellContributionToMassBalanceEq(cq_s, state, well_state);
asImpl().stdWells().addWellControlEq(state, well_state, aliveWells, vfp_properties_, gravity, residual_);
asImpl().stdWells().addWellControlEq(state, well_state, aliveWells, residual_);
// asImpl().computeWellPotentials(state, mob_perfcells, b_perfcells, well_state);
{
SolutionState state0 = state;
@ -1032,9 +1031,6 @@ namespace detail {
}
}
// gravity
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
int it = 0;
bool converged;
do {
@ -1049,8 +1045,7 @@ namespace detail {
asImpl().stdWells().computeWellFlux(wellSolutionState, mob_perfcells_const, b_perfcells_const, aliveWells, cq_s);
asImpl().stdWells().updatePerfPhaseRatesAndPressures(cq_s, wellSolutionState, well_state);
asImpl().stdWells().addWellFluxEq(cq_s, wellSolutionState, residual_);
asImpl().stdWells().addWellControlEq(wellSolutionState, well_state, aliveWells,
vfp_properties_, gravity, residual_);
asImpl().stdWells().addWellControlEq(wellSolutionState, well_state, aliveWells, residual_);
converged = getWellConvergence(it);
if (converged) {
@ -1074,8 +1069,8 @@ namespace detail {
const Eigen::VectorXd& dx = solver.solve(total_residual_v.matrix());
assert(dx.size() == total_residual_v.size());
// asImpl().updateWellState(dx.array(), well_state);
asImpl().stdWells().updateWellState(dx.array(), gravity, dpMaxRel(), vfp_properties_, well_state);
asImpl().stdWells().updateWellControls(gravity, vfp_properties_, terminal_output_, well_state);
asImpl().stdWells().updateWellState(dx.array(), dpMaxRel(), well_state);
asImpl().stdWells().updateWellControls(terminal_output_, well_state);
}
} while (it < 15);
@ -1104,7 +1099,7 @@ namespace detail {
}
// asImpl().computeWellConnectionPressures(state, well_state);
const ADB::V depth = Opm::AutoDiffGrid::cellCentroidsZToEigen(grid_);
asImpl().stdWells().computeWellConnectionPressures(state, well_state, depth, gravity);
asImpl().stdWells().computeWellConnectionPressures(state, well_state);
}
if (!converged) {
@ -2306,9 +2301,7 @@ namespace detail {
updateWellState(const V& dwells,
WellState& well_state)
{
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
asImpl().stdWells().updateWellState(dwells, gravity, dpMaxRel(),
vfp_properties_, well_state);
asImpl().stdWells().updateWellState(dwells, dpMaxRel(), well_state);
}

View File

@ -76,7 +76,7 @@ namespace Opm {
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
const V depth = Opm::AutoDiffGrid::cellCentroidsZToEigen(grid_);
ms_wells_.init(&fluid_, &active_, &phaseCondition_, &vfp_properties_, gravity, &depth);
ms_wells_.init(&fluid_, &active_, &phaseCondition_, &vfp_properties_, gravity, depth);
// TODO: there should be a better way do the following
ms_wells_.setWellsActive(Base::wellsActive());
}
@ -231,9 +231,7 @@ namespace Opm {
const int canonicalPhaseIdx = canph_[phaseIdx];
fluid_density[phaseIdx] = fluidDensity(canonicalPhaseIdx, rq_[phaseIdx].b, state0.rs, state0.rv);
}
const ADB::V depth = Opm::AutoDiffGrid::cellCentroidsZToEigen(grid_);
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
msWells().computeWellConnectionPressures(state0, well_state, kr_adb, fluid_density, depth, gravity);
msWells().computeWellConnectionPressures(state0, well_state, kr_adb, fluid_density);
// asImpl().computeWellConnectionPressures(state0, well_state);
}
@ -327,9 +325,7 @@ namespace Opm {
const int canonicalPhaseIdx = canph_[phaseIdx];
fluid_density[phaseIdx] = fluidDensity(canonicalPhaseIdx, rq_[phaseIdx].b, state.rs, state.rv);
}
const ADB::V depth = Opm::AutoDiffGrid::cellCentroidsZToEigen(grid_);
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
msWells().computeWellConnectionPressures(state, well_state, kr_adb, fluid_density, depth, gravity);
msWells().computeWellConnectionPressures(state, well_state, kr_adb, fluid_density);
// asImpl().computeWellConnectionPressures(state, well_state);
}
@ -455,9 +451,7 @@ namespace Opm {
const int canonicalPhaseIdx = canph_[phaseIdx];
fluid_density[phaseIdx] = fluidDensity(canonicalPhaseIdx, rq_[phaseIdx].b, state.rs, state.rv);
}
const ADB::V depth = Opm::AutoDiffGrid::cellCentroidsZToEigen(grid_);
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
msWells().computeWellConnectionPressures(state, well_state, kr_adb, fluid_density, depth, gravity);
msWells().computeWellConnectionPressures(state, well_state, kr_adb, fluid_density);
// computeWellConnectionPressures(state, well_state);
}

View File

@ -221,14 +221,14 @@ namespace Opm {
const std::vector<PhasePresence>* pc_arg,
const VFPProperties* vfp_properties_arg,
const double gravity_arg,
const Vector* depth_arg)
const Vector& depth_arg)
{
fluid_ = fluid_arg;
active_ = active_arg;
phase_condition_ = pc_arg;
vfp_properties_ = vfp_properties_arg;
gravity_ = gravity_arg;
depth_ = depth_arg;
perf_cell_depth_ = subset(depth_arg, wellOps().well_cells);;
}

View File

@ -95,7 +95,7 @@ namespace Opm {
const std::vector<PhasePresence>* pc_arg,
const VFPProperties* vfp_properties_arg,
const double gravity_arg,
const Vector* depth_arg);
const Vector& depth_arg);
const std::vector<WellMultiSegmentConstPtr>& wells() const;
const MultisegmentWellOps& wellOps() const;
@ -211,9 +211,7 @@ namespace Opm {
void computeWellConnectionPressures(const SolutionState& state,
const WellState& xw,
const std::vector<ADB>& kr_adb,
const std::vector<ADB>& fluid_density,
const Vector& depth,
const double gravity);
const std::vector<ADB>& fluid_density);
protected:
// TODO: probably a wells_active_ will be required here.
@ -235,9 +233,9 @@ namespace Opm {
const std::vector<PhasePresence>* phase_condition_;
const VFPProperties* vfp_properties_;
double gravity_;
// TODO: the depth of the all the cell centers
// it can be better to store only the perforation depth and segment depth
const Vector* depth_;
// The depth of the all the cell centers
// It is different from the perforation depth in MultisegmentWells
Vector perf_cell_depth_;
// Pressure correction due to the different depth of the perforation
// and the cell center of the grid block

View File

@ -922,9 +922,7 @@ namespace Opm
computeWellConnectionPressures(const SolutionState& state,
const WellState& xw,
const std::vector<ADB>& kr_adb,
const std::vector<ADB>& fluid_density,
const Vector& depth,
const double grav)
const std::vector<ADB>& fluid_density)
{
if( ! wellsActive() ) return ;
@ -1008,8 +1006,8 @@ namespace Opm
}
// b is row major, so can just copy data.
std::vector<double> b_perf(b.data(), b.data() + nperf_total * pu.num_phases);
// Extract well connection depths.
const Vector perfcelldepth = subset(depth, well_cells);
const Vector& perfcelldepth = perf_cell_depth_;
std::vector<double> perf_cell_depth(perfcelldepth.data(), perfcelldepth.data() + nperf_total);
// Surface density.
@ -1030,7 +1028,7 @@ namespace Opm
// 3. Compute pressure deltas
std::vector<double> cdp =
WellDensitySegmented::computeConnectionPressureDelta(
wellsStruct(), perf_cell_depth, cd, grav);
wellsStruct(), perf_cell_depth, cd, gravity_);
// 4. Store the results
well_perforation_densities_ = Eigen::Map<const Vector>(cd.data(), nperf_total); // This one is not useful for segmented wells at all
@ -1094,7 +1092,7 @@ namespace Opm
const Vector perf_cell_depth_diffs = perf_depth - perfcelldepth;
well_perforation_cell_pressure_diffs_ = grav * well_perforation_cell_densities_ * perf_cell_depth_diffs;
well_perforation_cell_pressure_diffs_ = gravity_ * well_perforation_cell_densities_ * perf_cell_depth_diffs;
// Calculating the depth difference between segment nodes and perforations.

View File

@ -67,7 +67,7 @@ namespace Opm {
const std::vector<PhasePresence>* pc_arg,
const VFPProperties* vfp_properties_arg,
const double gravity_arg,
const Vector* depth_arg);
const Vector& depth_arg);
const WellOps& wellOps() const;
@ -110,15 +110,11 @@ namespace Opm {
template <class WellState>
void updateWellState(const Vector& dwells,
const double gravity,
const double dpmaxrel,
const VFPProperties& vfp_properties,
WellState& well_state);
template <class WellState>
void updateWellControls(const double gravity,
const VFPProperties& vfp_properties,
const bool terminal_output,
void updateWellControls(const bool terminal_output,
WellState& xw) const;
// TODO: should LinearisedBlackoilResidual also be a template class?
@ -132,15 +128,11 @@ namespace Opm {
void addWellControlEq(const SolutionState& state,
const WellState& xw,
const Vector& aliveWells,
const VFPProperties& vfp_properties,
const double gravity,
LinearisedBlackoilResidual& residual);
template <class SolutionState, class WellState>
void computeWellConnectionPressures(const SolutionState& state,
const WellState& xw,
const Vector& depth,
const double gravity);
const WellState& xw);
// state0 is non-constant, while it will not be used outside of the function
template <class SolutionState, class WellState>
@ -178,9 +170,9 @@ namespace Opm {
const std::vector<PhasePresence>* phase_condition_;
const VFPProperties* vfp_properties_;
double gravity_;
// TODO: the depth of the all the cell centers
// it can be better to store only the perforation depth and segment depth
const Vector* depth_;
// the depth of the all the cell centers
// for standard Wells, it the same with the perforation depth
Vector perf_cell_depth_;
Vector well_perforation_densities_;
Vector well_perforation_pressure_diffs_;

View File

@ -61,9 +61,7 @@ namespace Opm {
template <class SolutionState, class WellState>
void computeWellConnectionPressures(const SolutionState& state,
const WellState& xw,
const Vector& depth,
const double gravity);
const WellState& xw);
protected:
const SolventPropsAdFromDeck* solvent_props_;

View File

@ -198,9 +198,7 @@ namespace Opm
void
StandardWellsSolvent::
computeWellConnectionPressures(const SolutionState& state,
const WellState& xw,
const Vector& depth,
const double gravity)
const WellState& xw)
{
if( ! localWellsActive() ) return ;
// 1. Compute properties required by computeConnectionPressureDelta().
@ -212,13 +210,11 @@ namespace Opm
std::vector<double> surf_dens_perf;
computePropertiesForWellConnectionPressures(state, xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf);
// Extract well connection depths
// TODO: depth_perf should be a member of the StandardWells class
const Vector pdepth = subset(depth, wellOps().well_cells);
const Vector pdepth = perf_cell_depth_;
const int nperf = wells().well_connpos[wells().number_of_wells];
const std::vector<double> depth_perf(pdepth.data(), pdepth.data() + nperf);
computeWellConnectionDensitesPressures(xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf, depth_perf, gravity);
computeWellConnectionDensitesPressures(xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf, depth_perf, gravity_);
}

View File

@ -90,14 +90,14 @@ namespace Opm
const std::vector<PhasePresence>* pc_arg,
const VFPProperties* vfp_properties_arg,
const double gravity_arg,
const Vector* depth_arg)
const Vector& depth_arg)
{
fluid_ = fluid_arg;
active_ = active_arg;
phase_condition_ = pc_arg;
vfp_properties_ = vfp_properties_arg;
gravity_ = gravity_arg;
depth_ = depth_arg;
perf_cell_depth_ = subset(depth_arg, wellOps().well_cells);;
}
@ -308,9 +308,7 @@ namespace Opm
void
StandardWells::
computeWellConnectionPressures(const SolutionState& state,
const WellState& xw,
const Vector& depth,
const double gravity)
const WellState& xw)
{
if( ! localWellsActive() ) return ;
// 1. Compute properties required by computeConnectionPressureDelta().
@ -322,13 +320,11 @@ namespace Opm
std::vector<double> surf_dens_perf;
computePropertiesForWellConnectionPressures(state, xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf);
// Extract well connection depths
// TODO: depth_perf should be a member of the StandardWells class
const Vector pdepth = subset(depth, wellOps().well_cells);
const Vector& pdepth = perf_cell_depth_;
const int nperf = wells().well_connpos[wells().number_of_wells];
const std::vector<double> depth_perf(pdepth.data(), pdepth.data() + nperf);
computeWellConnectionDensitesPressures(xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf, depth_perf, gravity);
computeWellConnectionDensitesPressures(xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf, depth_perf, gravity_);
}
@ -574,9 +570,7 @@ namespace Opm
void
StandardWells::
updateWellState(const Vector& dwells,
const double gravity,
const double dpmaxrel,
const VFPProperties& vfp_properties,
WellState& well_state)
{
if( localWellsActive() )
@ -642,17 +636,17 @@ namespace Opm
const WellType& well_type = wells().type[w];
if (well_type == INJECTOR) {
double dp = wellhelpers::computeHydrostaticCorrection(
wells(), w, vfp_properties.getInj()->getTable(table_id)->getDatumDepth(),
wellPerforationDensities(), gravity);
wells(), w, vfp_properties_->getInj()->getTable(table_id)->getDatumDepth(),
wellPerforationDensities(), gravity_);
well_state.thp()[w] = vfp_properties.getInj()->thp(table_id, aqua, liquid, vapour, bhp[w] + dp);
well_state.thp()[w] = vfp_properties_->getInj()->thp(table_id, aqua, liquid, vapour, bhp[w] + dp);
}
else if (well_type == PRODUCER) {
double dp = wellhelpers::computeHydrostaticCorrection(
wells(), w, vfp_properties.getProd()->getTable(table_id)->getDatumDepth(),
wellPerforationDensities(), gravity);
wells(), w, vfp_properties_->getProd()->getTable(table_id)->getDatumDepth(),
wellPerforationDensities(), gravity_);
well_state.thp()[w] = vfp_properties.getProd()->thp(table_id, aqua, liquid, vapour, bhp[w] + dp, alq);
well_state.thp()[w] = vfp_properties_->getProd()->thp(table_id, aqua, liquid, vapour, bhp[w] + dp, alq);
}
else {
OPM_THROW(std::logic_error, "Expected INJECTOR or PRODUCER well");
@ -673,9 +667,7 @@ namespace Opm
template <class WellState>
void
StandardWells::
updateWellControls(const double gravity,
const VFPProperties& vfp_properties,
const bool terminal_output,
updateWellControls(const bool terminal_output,
WellState& xw) const
{
if( !localWellsActive() ) return ;
@ -758,17 +750,17 @@ namespace Opm
if (well_type == INJECTOR) {
double dp = wellhelpers::computeHydrostaticCorrection(
wells(), w, vfp_properties.getInj()->getTable(vfp)->getDatumDepth(),
wellPerforationDensities(), gravity);
wells(), w, vfp_properties_->getInj()->getTable(vfp)->getDatumDepth(),
wellPerforationDensities(), gravity_);
xw.bhp()[w] = vfp_properties.getInj()->bhp(vfp, aqua, liquid, vapour, thp) - dp;
xw.bhp()[w] = vfp_properties_->getInj()->bhp(vfp, aqua, liquid, vapour, thp) - dp;
}
else if (well_type == PRODUCER) {
double dp = wellhelpers::computeHydrostaticCorrection(
wells(), w, vfp_properties.getProd()->getTable(vfp)->getDatumDepth(),
wellPerforationDensities(), gravity);
wells(), w, vfp_properties_->getProd()->getTable(vfp)->getDatumDepth(),
wellPerforationDensities(), gravity_);
xw.bhp()[w] = vfp_properties.getProd()->bhp(vfp, aqua, liquid, vapour, thp, alq) - dp;
xw.bhp()[w] = vfp_properties_->getProd()->bhp(vfp, aqua, liquid, vapour, thp, alq) - dp;
}
else {
OPM_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well");
@ -857,11 +849,9 @@ namespace Opm
template <class SolutionState, class WellState>
void
StandardWells::addWellControlEq(const SolutionState& state,
const WellState& xw,
const Vector& aliveWells,
const VFPProperties& vfp_properties,
const double gravity,
LinearisedBlackoilResidual& residual)
const WellState& xw,
const Vector& aliveWells,
LinearisedBlackoilResidual& residual)
{
if( ! localWellsActive() ) return;
@ -937,7 +927,7 @@ namespace Opm
thp_inj_target_v[w] = target;
alq_v[w] = -1e100;
vfp_ref_depth_v[w] = vfp_properties.getInj()->getTable(table_id)->getDatumDepth();
vfp_ref_depth_v[w] = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth();
thp_inj_elems.push_back(w);
}
@ -946,7 +936,7 @@ namespace Opm
thp_prod_target_v[w] = target;
alq_v[w] = well_controls_iget_alq(wc, current);
vfp_ref_depth_v[w] = vfp_properties.getProd()->getTable(table_id)->getDatumDepth();
vfp_ref_depth_v[w] = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth();
thp_prod_elems.push_back(w);
}
@ -984,12 +974,11 @@ namespace Opm
const ADB thp_inj_target = ADB::constant(thp_inj_target_v);
const ADB thp_prod_target = ADB::constant(thp_prod_target_v);
const ADB alq = ADB::constant(alq_v);
const ADB bhp_from_thp_inj = vfp_properties.getInj()->bhp(inj_table_id, aqua, liquid, vapour, thp_inj_target);
const ADB bhp_from_thp_prod = vfp_properties.getProd()->bhp(prod_table_id, aqua, liquid, vapour, thp_prod_target, alq);
const ADB bhp_from_thp_inj = vfp_properties_->getInj()->bhp(inj_table_id, aqua, liquid, vapour, thp_inj_target);
const ADB bhp_from_thp_prod = vfp_properties_->getProd()->bhp(prod_table_id, aqua, liquid, vapour, thp_prod_target, alq);
//Perform hydrostatic correction to computed targets
// double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
const Vector dp_v = wellhelpers::computeHydrostaticCorrection(wells(), vfp_ref_depth_v, wellPerforationDensities(), gravity);
const Vector dp_v = wellhelpers::computeHydrostaticCorrection(wells(), vfp_ref_depth_v, wellPerforationDensities(), gravity_);
const ADB dp = ADB::constant(dp_v);
const ADB dp_inj = superset(subset(dp, thp_inj_elems), thp_inj_elems, nw);
const ADB dp_prod = superset(subset(dp, thp_prod_elems), thp_prod_elems, nw);

View File

@ -498,10 +498,8 @@ namespace Opm {
// Possibly switch well controls and updating well state to
// get reasonable initial conditions for the wells
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
const V depth = cellCentroidsZToEigen(grid_);
// updateWellControls(well_state);
stdWells().updateWellControls(gravity, vfp_properties_, terminal_output_, well_state);
stdWells().updateWellControls(terminal_output_, well_state);
// Create the primary variables.
SolutionState state = variableState(reservoir_state, well_state);
@ -514,7 +512,7 @@ namespace Opm {
// and well connection pressures.
computeAccum(state0, 0);
// computeWellConnectionPressures(state0, well_state);
stdWells().computeWellConnectionPressures(state0, well_state, depth, gravity);
stdWells().computeWellConnectionPressures(state0, well_state);
}
// OPM_AD_DISKVAL(state.pressure);
@ -577,7 +575,7 @@ namespace Opm {
stdWells().updatePerfPhaseRatesAndPressures(cq_s, state, well_state);
stdWells().addWellFluxEq(cq_s, state, residual_);
addWellContributionToMassBalanceEq(cq_s, state, well_state);
stdWells().addWellControlEq(state, well_state, aliveWells, vfp_properties_, gravity, residual_);
stdWells().addWellControlEq(state, well_state, aliveWells, residual_);
}