mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #635 from GitPaean/wells_refactoring
A first step towards Wells refactoring
This commit is contained in:
commit
cebc393caf
@ -269,11 +269,42 @@ namespace Opm {
|
|||||||
ADB mob; // Phase mobility (per cell)
|
ADB mob; // Phase mobility (per cell)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WellOps {
|
class StandardWells {
|
||||||
WellOps(const Wells* wells);
|
protected:
|
||||||
Eigen::SparseMatrix<double> w2p; // well -> perf (scatter)
|
struct WellOps {
|
||||||
Eigen::SparseMatrix<double> p2w; // perf -> well (gather)
|
explicit WellOps(const Wells* wells);
|
||||||
std::vector<int> well_cells; // the set of perforated cells
|
Eigen::SparseMatrix<double> w2p; // well -> perf (scatter)
|
||||||
|
Eigen::SparseMatrix<double> p2w; // perf -> well (gather)
|
||||||
|
std::vector<int> well_cells; // the set of perforated cells
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StandardWells(const Wells* wells);
|
||||||
|
|
||||||
|
const Wells& wells() const;
|
||||||
|
|
||||||
|
// return true if wells are available in the reservoir
|
||||||
|
bool wellsActive() const;
|
||||||
|
void setWellsActive(const bool wells_active);
|
||||||
|
// return true if wells are available on this process
|
||||||
|
bool localWellsActive() const;
|
||||||
|
|
||||||
|
const WellOps& wellOps() const;
|
||||||
|
|
||||||
|
//Density of each well perforation
|
||||||
|
V& wellPerforationDensities();
|
||||||
|
const V& wellPerforationDensities() const;
|
||||||
|
|
||||||
|
// Diff to bhp for each well perforation.
|
||||||
|
V& wellPerforationPressureDiffs();
|
||||||
|
const V& wellPerforationPressureDiffs() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool wells_active_;
|
||||||
|
const Wells* wells_;
|
||||||
|
const WellOps wops_;
|
||||||
|
V well_perforation_densities_;
|
||||||
|
V well_perforation_pressure_diffs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------- Data members ---------
|
// --------- Data members ---------
|
||||||
@ -282,7 +313,7 @@ namespace Opm {
|
|||||||
const BlackoilPropsAdInterface& fluid_;
|
const BlackoilPropsAdInterface& fluid_;
|
||||||
const DerivedGeology& geo_;
|
const DerivedGeology& geo_;
|
||||||
const RockCompressibility* rock_comp_props_;
|
const RockCompressibility* rock_comp_props_;
|
||||||
const Wells* wells_;
|
StandardWells std_wells_;
|
||||||
VFPProperties vfp_properties_;
|
VFPProperties vfp_properties_;
|
||||||
const NewtonIterationBlackoilInterface& linsolver_;
|
const NewtonIterationBlackoilInterface& linsolver_;
|
||||||
// For each canonical phase -> true if active
|
// For each canonical phase -> true if active
|
||||||
@ -291,13 +322,11 @@ namespace Opm {
|
|||||||
const std::vector<int> canph_;
|
const std::vector<int> canph_;
|
||||||
const std::vector<int> cells_; // All grid cells
|
const std::vector<int> cells_; // All grid cells
|
||||||
HelperOps ops_;
|
HelperOps ops_;
|
||||||
const WellOps wops_;
|
|
||||||
const bool has_disgas_;
|
const bool has_disgas_;
|
||||||
const bool has_vapoil_;
|
const bool has_vapoil_;
|
||||||
|
|
||||||
ModelParameters param_;
|
ModelParameters param_;
|
||||||
bool use_threshold_pressure_;
|
bool use_threshold_pressure_;
|
||||||
bool wells_active_;
|
|
||||||
V threshold_pressures_by_connection_;
|
V threshold_pressures_by_connection_;
|
||||||
|
|
||||||
std::vector<ReservoirResidualQuant> rq_;
|
std::vector<ReservoirResidualQuant> rq_;
|
||||||
@ -305,8 +334,6 @@ namespace Opm {
|
|||||||
V isRs_;
|
V isRs_;
|
||||||
V isRv_;
|
V isRv_;
|
||||||
V isSg_;
|
V isSg_;
|
||||||
V well_perforation_densities_; //Density of each well perforation
|
|
||||||
V well_perforation_pressure_diffs_; // Diff to bhp for each well perforation.
|
|
||||||
|
|
||||||
LinearisedBlackoilResidual residual_;
|
LinearisedBlackoilResidual residual_;
|
||||||
|
|
||||||
@ -338,12 +365,18 @@ namespace Opm {
|
|||||||
return static_cast<const Implementation&>(*this);
|
return static_cast<const Implementation&>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if wells are available in the reservoir
|
/// return the StandardWells object
|
||||||
bool wellsActive() const { return wells_active_; }
|
StandardWells& stdWells() { return std_wells_; }
|
||||||
// return true if wells are available on this process
|
const StandardWells& stdWells() const { return std_wells_; }
|
||||||
bool localWellsActive() const { return wells_ ? (wells_->number_of_wells > 0 ) : false; }
|
|
||||||
// return wells object
|
/// return the Well struct in the StandardWells
|
||||||
const Wells& wells () const { assert( bool(wells_ != 0) ); return *wells_; }
|
const Wells& wells() const { return std_wells_.wells(); }
|
||||||
|
|
||||||
|
/// return true if wells are available in the reservoir
|
||||||
|
bool wellsActive() const { return std_wells_.wellsActive(); }
|
||||||
|
|
||||||
|
/// return true if wells are available on this process
|
||||||
|
bool localWellsActive() const { return std_wells_.localWellsActive(); }
|
||||||
|
|
||||||
int numWellVars() const;
|
int numWellVars() const;
|
||||||
|
|
||||||
|
@ -159,14 +159,13 @@ namespace detail {
|
|||||||
, fluid_ (fluid)
|
, fluid_ (fluid)
|
||||||
, geo_ (geo)
|
, geo_ (geo)
|
||||||
, rock_comp_props_(rock_comp_props)
|
, rock_comp_props_(rock_comp_props)
|
||||||
, wells_ (wells_arg)
|
, std_wells_ (wells_arg)
|
||||||
, vfp_properties_(eclState->getTableManager()->getVFPInjTables(), eclState->getTableManager()->getVFPProdTables())
|
, vfp_properties_(eclState->getTableManager()->getVFPInjTables(), eclState->getTableManager()->getVFPProdTables())
|
||||||
, linsolver_ (linsolver)
|
, linsolver_ (linsolver)
|
||||||
, active_(detail::activePhases(fluid.phaseUsage()))
|
, active_(detail::activePhases(fluid.phaseUsage()))
|
||||||
, canph_ (detail::active2Canonical(fluid.phaseUsage()))
|
, canph_ (detail::active2Canonical(fluid.phaseUsage()))
|
||||||
, cells_ (detail::buildAllCells(Opm::AutoDiffGrid::numCells(grid)))
|
, cells_ (detail::buildAllCells(Opm::AutoDiffGrid::numCells(grid)))
|
||||||
, ops_ (grid, geo.nnc())
|
, ops_ (grid, geo.nnc())
|
||||||
, wops_ (wells_)
|
|
||||||
, has_disgas_(has_disgas)
|
, has_disgas_(has_disgas)
|
||||||
, has_vapoil_(has_vapoil)
|
, has_vapoil_(has_vapoil)
|
||||||
, param_( param )
|
, param_( param )
|
||||||
@ -195,9 +194,10 @@ namespace detail {
|
|||||||
// Only rank 0 does print to std::cout if terminal_output is enabled
|
// Only rank 0 does print to std::cout if terminal_output is enabled
|
||||||
terminal_output_ = (info.communicator().rank()==0);
|
terminal_output_ = (info.communicator().rank()==0);
|
||||||
}
|
}
|
||||||
int local_number_of_wells = wells_ ? wells_->number_of_wells : 0;
|
int local_number_of_wells = localWellsActive() ? wells().number_of_wells : 0;
|
||||||
int global_number_of_wells = info.communicator().sum(local_number_of_wells);
|
int global_number_of_wells = info.communicator().sum(local_number_of_wells);
|
||||||
wells_active_ = ( wells_ && global_number_of_wells > 0 );
|
const bool wells_active = ( wells_arg && global_number_of_wells > 0 );
|
||||||
|
stdWells().setWellsActive(wells_active);
|
||||||
// Compute the global number of cells
|
// Compute the global number of cells
|
||||||
std::vector<int> v( Opm::AutoDiffGrid::numCells(grid_), 1);
|
std::vector<int> v( Opm::AutoDiffGrid::numCells(grid_), 1);
|
||||||
global_nc_ = 0;
|
global_nc_ = 0;
|
||||||
@ -205,7 +205,7 @@ namespace detail {
|
|||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
wells_active_ = ( wells_ && wells_->number_of_wells > 0 );
|
stdWells().setWellsActive( localWellsActive() );
|
||||||
global_nc_ = Opm::AutoDiffGrid::numCells(grid_);
|
global_nc_ = Opm::AutoDiffGrid::numCells(grid_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,6 +420,7 @@ namespace detail {
|
|||||||
|
|
||||||
template <class Grid, class Implementation>
|
template <class Grid, class Implementation>
|
||||||
BlackoilModelBase<Grid, Implementation>::
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::
|
||||||
WellOps::WellOps(const Wells* wells)
|
WellOps::WellOps(const Wells* wells)
|
||||||
: w2p(),
|
: w2p(),
|
||||||
p2w(),
|
p2w(),
|
||||||
@ -457,12 +458,135 @@ namespace detail {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::StandardWells(const Wells* wells_arg)
|
||||||
|
: wells_(wells_arg)
|
||||||
|
, wops_(wells_arg)
|
||||||
|
, well_perforation_densities_(V())
|
||||||
|
, well_perforation_pressure_diffs_(V())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
const Wells&
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::wells() const
|
||||||
|
{
|
||||||
|
assert(wells_ != 0);
|
||||||
|
return *(wells_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
bool
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::wellsActive() const
|
||||||
|
{
|
||||||
|
return wells_active_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
void
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::setWellsActive(const bool wells_active)
|
||||||
|
{
|
||||||
|
wells_active_ = wells_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
bool
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::localWellsActive() const
|
||||||
|
{
|
||||||
|
return wells_ ? (wells_->number_of_wells > 0 ) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
const typename BlackoilModelBase<Grid, Implementation>::StandardWells::WellOps&
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::wellOps() const
|
||||||
|
{
|
||||||
|
return wops_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
V&
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::wellPerforationDensities()
|
||||||
|
{
|
||||||
|
return well_perforation_densities_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
const V&
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::wellPerforationDensities() const
|
||||||
|
{
|
||||||
|
return well_perforation_densities_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
V&
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::wellPerforationPressureDiffs()
|
||||||
|
{
|
||||||
|
return well_perforation_pressure_diffs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class Implementation>
|
||||||
|
const V&
|
||||||
|
BlackoilModelBase<Grid, Implementation>::
|
||||||
|
StandardWells::wellPerforationPressureDiffs() const
|
||||||
|
{
|
||||||
|
return well_perforation_pressure_diffs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class Grid, class Implementation>
|
template <class Grid, class Implementation>
|
||||||
int
|
int
|
||||||
BlackoilModelBase<Grid, Implementation>::numWellVars() const
|
BlackoilModelBase<Grid, Implementation>::numWellVars() const
|
||||||
{
|
{
|
||||||
// For each well, we have a bhp variable, and one flux per phase.
|
// For each well, we have a bhp variable, and one flux per phase.
|
||||||
const int nw = localWellsActive() ? wells().number_of_wells : 0;
|
const int nw = stdWells().localWellsActive() ? wells().number_of_wells : 0;
|
||||||
return (numPhases() + 1) * nw;
|
return (numPhases() + 1) * nw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,7 +702,7 @@ namespace detail {
|
|||||||
BlackoilModelBase<Grid, Implementation>::variableWellStateInitials(const WellState& xw, std::vector<V>& vars0) const
|
BlackoilModelBase<Grid, Implementation>::variableWellStateInitials(const WellState& xw, std::vector<V>& vars0) const
|
||||||
{
|
{
|
||||||
// Initial well rates.
|
// Initial well rates.
|
||||||
if ( localWellsActive() )
|
if ( stdWells().localWellsActive() )
|
||||||
{
|
{
|
||||||
// Need to reshuffle well rates, from phase running fastest
|
// Need to reshuffle well rates, from phase running fastest
|
||||||
// to wells running fastest.
|
// to wells running fastest.
|
||||||
@ -817,7 +941,7 @@ namespace detail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<int>& well_cells = wops_.well_cells;
|
const std::vector<int>& well_cells = stdWells().wellOps().well_cells;
|
||||||
|
|
||||||
// Use cell values for the temperature as the wells don't knows its temperature yet.
|
// Use cell values for the temperature as the wells don't knows its temperature yet.
|
||||||
const ADB perf_temp = subset(state.temperature, well_cells);
|
const ADB perf_temp = subset(state.temperature, well_cells);
|
||||||
@ -887,7 +1011,7 @@ namespace detail {
|
|||||||
std::vector<double> rvmax_perf;
|
std::vector<double> rvmax_perf;
|
||||||
std::vector<double> surf_dens_perf;
|
std::vector<double> surf_dens_perf;
|
||||||
asImpl().computePropertiesForWellConnectionPressures(state, xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf);
|
asImpl().computePropertiesForWellConnectionPressures(state, xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf);
|
||||||
|
|
||||||
// 2. Compute densities
|
// 2. Compute densities
|
||||||
std::vector<double> cd =
|
std::vector<double> cd =
|
||||||
WellDensitySegmented::computeConnectionDensities(
|
WellDensitySegmented::computeConnectionDensities(
|
||||||
@ -895,7 +1019,7 @@ namespace detail {
|
|||||||
b_perf, rsmax_perf, rvmax_perf, surf_dens_perf);
|
b_perf, rsmax_perf, rvmax_perf, surf_dens_perf);
|
||||||
|
|
||||||
const int nperf = wells().well_connpos[wells().number_of_wells];
|
const int nperf = wells().well_connpos[wells().number_of_wells];
|
||||||
const std::vector<int>& well_cells = wops_.well_cells;
|
const std::vector<int>& well_cells = stdWells().wellOps().well_cells;
|
||||||
|
|
||||||
// Extract well connection depths.
|
// Extract well connection depths.
|
||||||
const V depth = cellCentroidsZToEigen(grid_);
|
const V depth = cellCentroidsZToEigen(grid_);
|
||||||
@ -911,8 +1035,8 @@ namespace detail {
|
|||||||
wells(), perf_depth, cd, grav);
|
wells(), perf_depth, cd, grav);
|
||||||
|
|
||||||
// 4. Store the results
|
// 4. Store the results
|
||||||
well_perforation_densities_ = Eigen::Map<const V>(cd.data(), nperf);
|
stdWells().wellPerforationDensities() = Eigen::Map<const V>(cd.data(), nperf);
|
||||||
well_perforation_pressure_diffs_ = Eigen::Map<const V>(cdp.data(), nperf);
|
stdWells().wellPerforationPressureDiffs() = Eigen::Map<const V>(cdp.data(), nperf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1111,7 +1235,7 @@ namespace detail {
|
|||||||
const int nc = Opm::AutoDiffGrid::numCells(grid_);
|
const int nc = Opm::AutoDiffGrid::numCells(grid_);
|
||||||
const int np = asImpl().numPhases();
|
const int np = asImpl().numPhases();
|
||||||
for (int phase = 0; phase < np; ++phase) {
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
residual_.material_balance_eq[phase] -= superset(cq_s[phase], wops_.well_cells, nc);
|
residual_.material_balance_eq[phase] -= superset(cq_s[phase], stdWells().wellOps().well_cells, nc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1134,7 +1258,7 @@ namespace detail {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
const int np = asImpl().numPhases();
|
const int np = asImpl().numPhases();
|
||||||
const std::vector<int>& well_cells = wops_.well_cells;
|
const std::vector<int>& well_cells = stdWells().wellOps().well_cells;
|
||||||
mob_perfcells.resize(np, ADB::null());
|
mob_perfcells.resize(np, ADB::null());
|
||||||
b_perfcells.resize(np, ADB::null());
|
b_perfcells.resize(np, ADB::null());
|
||||||
for (int phase = 0; phase < np; ++phase) {
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
@ -1164,17 +1288,17 @@ namespace detail {
|
|||||||
const int nperf = wells().well_connpos[nw];
|
const int nperf = wells().well_connpos[nw];
|
||||||
const Opm::PhaseUsage& pu = fluid_.phaseUsage();
|
const Opm::PhaseUsage& pu = fluid_.phaseUsage();
|
||||||
V Tw = Eigen::Map<const V>(wells().WI, nperf);
|
V Tw = Eigen::Map<const V>(wells().WI, nperf);
|
||||||
const std::vector<int>& well_cells = wops_.well_cells;
|
const std::vector<int>& well_cells = stdWells().wellOps().well_cells;
|
||||||
|
|
||||||
// pressure diffs computed already (once per step, not changing per iteration)
|
// pressure diffs computed already (once per step, not changing per iteration)
|
||||||
const V& cdp = well_perforation_pressure_diffs_;
|
const V& cdp = stdWells().wellPerforationPressureDiffs();
|
||||||
// Extract needed quantities for the perforation cells
|
// Extract needed quantities for the perforation cells
|
||||||
const ADB& p_perfcells = subset(state.pressure, well_cells);
|
const ADB& p_perfcells = subset(state.pressure, well_cells);
|
||||||
const ADB& rv_perfcells = subset(state.rv, well_cells);
|
const ADB& rv_perfcells = subset(state.rv, well_cells);
|
||||||
const ADB& rs_perfcells = subset(state.rs, well_cells);
|
const ADB& rs_perfcells = subset(state.rs, well_cells);
|
||||||
|
|
||||||
// Perforation pressure
|
// Perforation pressure
|
||||||
const ADB perfpressure = (wops_.w2p * state.bhp) + cdp;
|
const ADB perfpressure = (stdWells().wellOps().w2p * state.bhp) + cdp;
|
||||||
|
|
||||||
// Pressure drawdown (also used to determine direction of flow)
|
// Pressure drawdown (also used to determine direction of flow)
|
||||||
const ADB drawdown = p_perfcells - perfpressure;
|
const ADB drawdown = p_perfcells - perfpressure;
|
||||||
@ -1194,8 +1318,8 @@ namespace detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle cross flow
|
// Handle cross flow
|
||||||
const V numInjectingPerforations = (wops_.p2w * ADB::constant(selectInjectingPerforations)).value();
|
const V numInjectingPerforations = (stdWells().wellOps().p2w * ADB::constant(selectInjectingPerforations)).value();
|
||||||
const V numProducingPerforations = (wops_.p2w * ADB::constant(selectProducingPerforations)).value();
|
const V numProducingPerforations = (stdWells().wellOps().p2w * ADB::constant(selectProducingPerforations)).value();
|
||||||
for (int w = 0; w < nw; ++w) {
|
for (int w = 0; w < nw; ++w) {
|
||||||
if (!wells().allow_cf[w]) {
|
if (!wells().allow_cf[w]) {
|
||||||
for (int perf = wells().well_connpos[w] ; perf < wells().well_connpos[w+1]; ++perf) {
|
for (int perf = wells().well_connpos[w] ; perf < wells().well_connpos[w+1]; ++perf) {
|
||||||
@ -1246,7 +1370,7 @@ namespace detail {
|
|||||||
std::vector<ADB> wbq(np, ADB::null());
|
std::vector<ADB> wbq(np, ADB::null());
|
||||||
ADB wbqt = ADB::constant(V::Zero(nw));
|
ADB wbqt = ADB::constant(V::Zero(nw));
|
||||||
for (int phase = 0; phase < np; ++phase) {
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
const ADB& q_ps = wops_.p2w * cq_ps[phase];
|
const ADB& q_ps = stdWells().wellOps().p2w * cq_ps[phase];
|
||||||
const ADB& q_s = subset(state.qs, Span(nw, 1, phase*nw));
|
const ADB& q_s = subset(state.qs, Span(nw, 1, phase*nw));
|
||||||
Selector<double> injectingPhase_selector(q_s.value(), Selector<double>::GreaterZero);
|
Selector<double> injectingPhase_selector(q_s.value(), Selector<double>::GreaterZero);
|
||||||
const int pos = pu.phase_pos[phase];
|
const int pos = pu.phase_pos[phase];
|
||||||
@ -1258,7 +1382,7 @@ namespace detail {
|
|||||||
std::vector<ADB> cmix_s(np, ADB::null());
|
std::vector<ADB> cmix_s(np, ADB::null());
|
||||||
for (int phase = 0; phase < np; ++phase) {
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
const int pos = pu.phase_pos[phase];
|
const int pos = pu.phase_pos[phase];
|
||||||
cmix_s[phase] = wops_.w2p * notDeadWells_selector.select(ADB::constant(compi.col(pos)), wbq[phase]/wbqt);
|
cmix_s[phase] = stdWells().wellOps().w2p * notDeadWells_selector.select(ADB::constant(compi.col(pos)), wbq[phase]/wbqt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute volume ratio between connection at standard conditions
|
// compute volume ratio between connection at standard conditions
|
||||||
@ -1323,8 +1447,8 @@ namespace detail {
|
|||||||
xw.perfPhaseRates().assign(cq.data(), cq.data() + nperf*np);
|
xw.perfPhaseRates().assign(cq.data(), cq.data() + nperf*np);
|
||||||
|
|
||||||
// Update the perforation pressures.
|
// Update the perforation pressures.
|
||||||
const V& cdp = well_perforation_pressure_diffs_;
|
const V& cdp = stdWells().wellPerforationPressureDiffs();
|
||||||
const V perfpressure = (wops_.w2p * state.bhp.value().matrix()).array() + cdp;
|
const V perfpressure = (stdWells().wellOps().w2p * state.bhp.value().matrix()).array() + cdp;
|
||||||
xw.perfPress().assign(perfpressure.data(), perfpressure.data() + nperf);
|
xw.perfPress().assign(perfpressure.data(), perfpressure.data() + nperf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1347,7 +1471,7 @@ namespace detail {
|
|||||||
const int nw = wells().number_of_wells;
|
const int nw = wells().number_of_wells;
|
||||||
ADB qs = state.qs;
|
ADB qs = state.qs;
|
||||||
for (int phase = 0; phase < np; ++phase) {
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
qs -= superset(wops_.p2w * cq_s[phase], Span(nw, 1, phase*nw), nw*np);
|
qs -= superset(stdWells().wellOps().p2w * cq_s[phase], Span(nw, 1, phase*nw), nw*np);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1608,14 +1732,14 @@ namespace detail {
|
|||||||
if (well_type == INJECTOR) {
|
if (well_type == INJECTOR) {
|
||||||
double dp = detail::computeHydrostaticCorrection(
|
double dp = detail::computeHydrostaticCorrection(
|
||||||
wells(), w, vfp_properties_.getInj()->getTable(vfp)->getDatumDepth(),
|
wells(), w, vfp_properties_.getInj()->getTable(vfp)->getDatumDepth(),
|
||||||
well_perforation_densities_, gravity);
|
stdWells().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) {
|
else if (well_type == PRODUCER) {
|
||||||
double dp = detail::computeHydrostaticCorrection(
|
double dp = detail::computeHydrostaticCorrection(
|
||||||
wells(), w, vfp_properties_.getProd()->getTable(vfp)->getDatumDepth(),
|
wells(), w, vfp_properties_.getProd()->getTable(vfp)->getDatumDepth(),
|
||||||
well_perforation_densities_, gravity);
|
stdWells().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;
|
||||||
}
|
}
|
||||||
@ -1847,7 +1971,7 @@ namespace detail {
|
|||||||
case THP:
|
case THP:
|
||||||
{
|
{
|
||||||
const int perf = wells().well_connpos[w];
|
const int perf = wells().well_connpos[w];
|
||||||
rho_v[w] = well_perforation_densities_[perf];
|
rho_v[w] = stdWells().wellPerforationDensities()[perf];
|
||||||
|
|
||||||
const int table_id = well_controls_iget_vfp(wc, current);
|
const int table_id = well_controls_iget_vfp(wc, current);
|
||||||
const double target = well_controls_iget_target(wc, current);
|
const double target = well_controls_iget_target(wc, current);
|
||||||
@ -1910,7 +2034,7 @@ namespace detail {
|
|||||||
|
|
||||||
//Perform hydrostatic correction to computed targets
|
//Perform hydrostatic correction to computed targets
|
||||||
double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
|
double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
|
||||||
const ADB::V dp_v = detail::computeHydrostaticCorrection(wells(), vfp_ref_depth_v, well_perforation_densities_, gravity);
|
const ADB::V dp_v = detail::computeHydrostaticCorrection(wells(), vfp_ref_depth_v, stdWells().wellPerforationDensities(), gravity);
|
||||||
const ADB dp = ADB::constant(dp_v);
|
const ADB dp = ADB::constant(dp_v);
|
||||||
const ADB dp_inj = superset(subset(dp, thp_inj_elems), thp_inj_elems, nw);
|
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);
|
const ADB dp_prod = superset(subset(dp, thp_prod_elems), thp_prod_elems, nw);
|
||||||
@ -2351,14 +2475,14 @@ namespace detail {
|
|||||||
if (well_type == INJECTOR) {
|
if (well_type == INJECTOR) {
|
||||||
double dp = detail::computeHydrostaticCorrection(
|
double dp = detail::computeHydrostaticCorrection(
|
||||||
wells(), w, vfp_properties_.getInj()->getTable(table_id)->getDatumDepth(),
|
wells(), w, vfp_properties_.getInj()->getTable(table_id)->getDatumDepth(),
|
||||||
well_perforation_densities_, gravity);
|
stdWells().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) {
|
else if (well_type == PRODUCER) {
|
||||||
double dp = detail::computeHydrostaticCorrection(
|
double dp = detail::computeHydrostaticCorrection(
|
||||||
wells(), w, vfp_properties_.getProd()->getTable(table_id)->getDatumDepth(),
|
wells(), w, vfp_properties_.getProd()->getTable(table_id)->getDatumDepth(),
|
||||||
well_perforation_densities_, gravity);
|
stdWells().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);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,6 @@ namespace Opm {
|
|||||||
|
|
||||||
// For non-segmented wells, it should be the density calculated with AVG or SEG way.
|
// For non-segmented wells, it should be the density calculated with AVG or SEG way.
|
||||||
// while usually SEG way by default.
|
// while usually SEG way by default.
|
||||||
using Base::well_perforation_densities_; //Density of each well perforation
|
|
||||||
using Base::pvdt_;
|
using Base::pvdt_;
|
||||||
using Base::geo_;
|
using Base::geo_;
|
||||||
using Base::active_;
|
using Base::active_;
|
||||||
@ -136,10 +135,6 @@ namespace Opm {
|
|||||||
using Base::param_;
|
using Base::param_;
|
||||||
using Base::linsolver_;
|
using Base::linsolver_;
|
||||||
|
|
||||||
// Diff to bhp for each well perforation. only for usual wells.
|
|
||||||
// For segmented wells, they are zeros.
|
|
||||||
using Base::well_perforation_pressure_diffs_;
|
|
||||||
|
|
||||||
// Pressure correction due to the different depth of the perforation
|
// Pressure correction due to the different depth of the perforation
|
||||||
// and the cell center of the grid block
|
// and the cell center of the grid block
|
||||||
// For the non-segmented wells, since the perforation are forced to be
|
// For the non-segmented wells, since the perforation are forced to be
|
||||||
@ -211,11 +206,10 @@ namespace Opm {
|
|||||||
MultiSegmentWellOps wops_ms_;
|
MultiSegmentWellOps wops_ms_;
|
||||||
|
|
||||||
|
|
||||||
// return wells object
|
using Base::stdWells;
|
||||||
// TODO: remove this wells structure
|
|
||||||
using Base::wells;
|
using Base::wells;
|
||||||
using Base::updatePrimalVariableFromState;
|
|
||||||
using Base::wellsActive;
|
using Base::wellsActive;
|
||||||
|
using Base::updatePrimalVariableFromState;
|
||||||
using Base::phaseCondition;
|
using Base::phaseCondition;
|
||||||
using Base::fluidRvSat;
|
using Base::fluidRvSat;
|
||||||
using Base::fluidRsSat;
|
using Base::fluidRsSat;
|
||||||
|
@ -370,7 +370,7 @@ namespace Opm {
|
|||||||
|
|
||||||
std::vector<int>& well_cells = wops_ms_.well_cells;
|
std::vector<int>& well_cells = wops_ms_.well_cells;
|
||||||
|
|
||||||
well_perforation_densities_ = V::Zero(nperf_total);
|
stdWells().wellPerforationDensities() = V::Zero(nperf_total);
|
||||||
|
|
||||||
const V perf_press = Eigen::Map<const V>(xw.perfPress().data(), nperf_total);
|
const V perf_press = Eigen::Map<const V>(xw.perfPress().data(), nperf_total);
|
||||||
|
|
||||||
@ -471,8 +471,8 @@ namespace Opm {
|
|||||||
wells(), perf_cell_depth, cd, grav);
|
wells(), perf_cell_depth, cd, grav);
|
||||||
|
|
||||||
// 4. Store the results
|
// 4. Store the results
|
||||||
well_perforation_densities_ = Eigen::Map<const V>(cd.data(), nperf_total); // This one is not useful for segmented wells at all
|
stdWells().wellPerforationDensities() = Eigen::Map<const V>(cd.data(), nperf_total); // This one is not useful for segmented wells at all
|
||||||
well_perforation_pressure_diffs_ = Eigen::Map<const V>(cdp.data(), nperf_total);
|
stdWells().wellPerforationPressureDiffs() = Eigen::Map<const V>(cdp.data(), nperf_total);
|
||||||
|
|
||||||
if ( !wops_ms_.has_multisegment_wells ) {
|
if ( !wops_ms_.has_multisegment_wells ) {
|
||||||
well_perforation_cell_densities_ = V::Zero(nperf_total);
|
well_perforation_cell_densities_ = V::Zero(nperf_total);
|
||||||
@ -698,7 +698,7 @@ namespace Opm {
|
|||||||
|
|
||||||
// Compute drawdown.
|
// Compute drawdown.
|
||||||
ADB h_nc = msperf_selector.select(well_segment_perforation_pressure_diffs_,
|
ADB h_nc = msperf_selector.select(well_segment_perforation_pressure_diffs_,
|
||||||
ADB::constant(well_perforation_pressure_diffs_));
|
ADB::constant( stdWells().wellPerforationPressureDiffs() ));
|
||||||
const V h_cj = msperf_selector.select(well_perforation_cell_pressure_diffs_, V::Zero(nperf));
|
const V h_cj = msperf_selector.select(well_perforation_cell_pressure_diffs_, V::Zero(nperf));
|
||||||
|
|
||||||
// Special handling for when we are called from solveWellEq().
|
// Special handling for when we are called from solveWellEq().
|
||||||
@ -862,7 +862,7 @@ namespace Opm {
|
|||||||
// we need th concept of preforation pressures
|
// we need th concept of preforation pressures
|
||||||
xw.perfPress().resize(nperf_total, -1.e100);
|
xw.perfPress().resize(nperf_total, -1.e100);
|
||||||
|
|
||||||
const V& cdp = well_perforation_pressure_diffs_;
|
const V& cdp = stdWells().wellPerforationPressureDiffs();
|
||||||
int start_segment = 0;
|
int start_segment = 0;
|
||||||
int start_perforation = 0;
|
int start_perforation = 0;
|
||||||
for (int i = 0; i < nw; ++i) {
|
for (int i = 0; i < nw; ++i) {
|
||||||
|
@ -110,13 +110,11 @@ namespace Opm {
|
|||||||
using Base::fluid_;
|
using Base::fluid_;
|
||||||
using Base::geo_;
|
using Base::geo_;
|
||||||
using Base::rock_comp_props_;
|
using Base::rock_comp_props_;
|
||||||
using Base::wells_;
|
|
||||||
using Base::linsolver_;
|
using Base::linsolver_;
|
||||||
using Base::active_;
|
using Base::active_;
|
||||||
using Base::canph_;
|
using Base::canph_;
|
||||||
using Base::cells_;
|
using Base::cells_;
|
||||||
using Base::ops_;
|
using Base::ops_;
|
||||||
using Base::wops_;
|
|
||||||
using Base::has_disgas_;
|
using Base::has_disgas_;
|
||||||
using Base::has_vapoil_;
|
using Base::has_vapoil_;
|
||||||
using Base::param_;
|
using Base::param_;
|
||||||
@ -124,7 +122,6 @@ namespace Opm {
|
|||||||
using Base::threshold_pressures_by_connection_;
|
using Base::threshold_pressures_by_connection_;
|
||||||
using Base::rq_;
|
using Base::rq_;
|
||||||
using Base::phaseCondition_;
|
using Base::phaseCondition_;
|
||||||
using Base::well_perforation_pressure_diffs_;
|
|
||||||
using Base::residual_;
|
using Base::residual_;
|
||||||
using Base::terminal_output_;
|
using Base::terminal_output_;
|
||||||
using Base::primalVariable_;
|
using Base::primalVariable_;
|
||||||
@ -133,7 +130,7 @@ namespace Opm {
|
|||||||
// --------- Protected methods ---------
|
// --------- Protected methods ---------
|
||||||
|
|
||||||
// Need to declare Base members we want to use here.
|
// Need to declare Base members we want to use here.
|
||||||
using Base::wellsActive;
|
using Base::stdWells;
|
||||||
using Base::wells;
|
using Base::wells;
|
||||||
using Base::variableState;
|
using Base::variableState;
|
||||||
using Base::computeGasPressure;
|
using Base::computeGasPressure;
|
||||||
|
@ -180,7 +180,7 @@ namespace Opm {
|
|||||||
BlackoilSolventModel<Grid>::variableStateExtractVars(const ReservoirState& x,
|
BlackoilSolventModel<Grid>::variableStateExtractVars(const ReservoirState& x,
|
||||||
const std::vector<int>& indices,
|
const std::vector<int>& indices,
|
||||||
std::vector<ADB>& vars) const
|
std::vector<ADB>& vars) const
|
||||||
{
|
{
|
||||||
// This is more or less a copy of the base class. Refactoring is needed in the base class
|
// This is more or less a copy of the base class. Refactoring is needed in the base class
|
||||||
// to avoid unnecessary copying.
|
// to avoid unnecessary copying.
|
||||||
|
|
||||||
@ -389,7 +389,6 @@ namespace Opm {
|
|||||||
std::vector<double>& rvmax_perf,
|
std::vector<double>& rvmax_perf,
|
||||||
std::vector<double>& surf_dens_perf)
|
std::vector<double>& surf_dens_perf)
|
||||||
{
|
{
|
||||||
|
|
||||||
using namespace Opm::AutoDiffGrid;
|
using namespace Opm::AutoDiffGrid;
|
||||||
// 1. Compute properties required by computeConnectionPressureDelta().
|
// 1. Compute properties required by computeConnectionPressureDelta().
|
||||||
// Note that some of the complexity of this part is due to the function
|
// Note that some of the complexity of this part is due to the function
|
||||||
@ -765,7 +764,7 @@ namespace Opm {
|
|||||||
Base::extractWellPerfProperties(state, mob_perfcells, b_perfcells);
|
Base::extractWellPerfProperties(state, mob_perfcells, b_perfcells);
|
||||||
if (has_solvent_) {
|
if (has_solvent_) {
|
||||||
int gas_pos = fluid_.phaseUsage().phase_pos[Gas];
|
int gas_pos = fluid_.phaseUsage().phase_pos[Gas];
|
||||||
const std::vector<int>& well_cells = wops_.well_cells;
|
const std::vector<int>& well_cells = stdWells().wellOps().well_cells;
|
||||||
const int nperf = well_cells.size();
|
const int nperf = well_cells.size();
|
||||||
// Gas and solvent is combinded and solved together
|
// Gas and solvent is combinded and solved together
|
||||||
// The input in the well equation is then the
|
// The input in the well equation is then the
|
||||||
|
@ -158,13 +158,11 @@ namespace Opm {
|
|||||||
using Base::fluid_;
|
using Base::fluid_;
|
||||||
using Base::geo_;
|
using Base::geo_;
|
||||||
using Base::rock_comp_props_;
|
using Base::rock_comp_props_;
|
||||||
using Base::wells_;
|
|
||||||
using Base::linsolver_;
|
using Base::linsolver_;
|
||||||
using Base::active_;
|
using Base::active_;
|
||||||
using Base::canph_;
|
using Base::canph_;
|
||||||
using Base::cells_;
|
using Base::cells_;
|
||||||
using Base::ops_;
|
using Base::ops_;
|
||||||
using Base::wops_;
|
|
||||||
using Base::has_disgas_;
|
using Base::has_disgas_;
|
||||||
using Base::has_vapoil_;
|
using Base::has_vapoil_;
|
||||||
using Base::param_;
|
using Base::param_;
|
||||||
@ -172,7 +170,6 @@ namespace Opm {
|
|||||||
using Base::threshold_pressures_by_connection_;
|
using Base::threshold_pressures_by_connection_;
|
||||||
using Base::rq_;
|
using Base::rq_;
|
||||||
using Base::phaseCondition_;
|
using Base::phaseCondition_;
|
||||||
using Base::well_perforation_pressure_diffs_;
|
|
||||||
using Base::residual_;
|
using Base::residual_;
|
||||||
using Base::terminal_output_;
|
using Base::terminal_output_;
|
||||||
using Base::primalVariable_;
|
using Base::primalVariable_;
|
||||||
@ -181,8 +178,9 @@ namespace Opm {
|
|||||||
// --------- Protected methods ---------
|
// --------- Protected methods ---------
|
||||||
|
|
||||||
// Need to declare Base members we want to use here.
|
// Need to declare Base members we want to use here.
|
||||||
using Base::wellsActive;
|
using Base::stdWells;
|
||||||
using Base::wells;
|
using Base::wells;
|
||||||
|
using Base::wellsActive;
|
||||||
using Base::variableState;
|
using Base::variableState;
|
||||||
using Base::computePressures;
|
using Base::computePressures;
|
||||||
using Base::computeGasPressure;
|
using Base::computeGasPressure;
|
||||||
|
@ -731,8 +731,8 @@ namespace Opm {
|
|||||||
ADB b_perfcells = subset(rq_[water_pos].b, well_cells);
|
ADB b_perfcells = subset(rq_[water_pos].b, well_cells);
|
||||||
|
|
||||||
const ADB& p_perfcells = subset(state.pressure, well_cells);
|
const ADB& p_perfcells = subset(state.pressure, well_cells);
|
||||||
const V& cdp = well_perforation_pressure_diffs_;
|
const V& cdp = stdWells().wellPerforationPressureDiffs();
|
||||||
const ADB perfpressure = (wops_.w2p * state.bhp) + cdp;
|
const ADB perfpressure = (stdWells().wellOps().w2p * state.bhp) + cdp;
|
||||||
// Pressure drawdown (also used to determine direction of flow)
|
// Pressure drawdown (also used to determine direction of flow)
|
||||||
const ADB drawdown = p_perfcells - perfpressure;
|
const ADB drawdown = p_perfcells - perfpressure;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user