mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
move (most of) updatePrimaryVariables to StandardWellPrimaryVariables
This commit is contained in:
@@ -248,104 +248,10 @@ void
|
||||
StandardWellEval<FluidSystem,Indices,Scalar>::
|
||||
updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger) const
|
||||
{
|
||||
static constexpr int Gas = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Gas;
|
||||
static constexpr int Oil = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Oil;
|
||||
static constexpr int Water = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Water;
|
||||
if (!baseif_.isOperableAndSolvable() && !baseif_.wellIsStopped())
|
||||
return;
|
||||
|
||||
if (!baseif_.isOperableAndSolvable() && !baseif_.wellIsStopped()) return;
|
||||
|
||||
const int well_index = baseif_.indexOfWell();
|
||||
const int np = baseif_.numPhases();
|
||||
const auto& pu = baseif_.phaseUsage();
|
||||
const auto& ws = well_state.well(well_index);
|
||||
// the weighted total well rate
|
||||
double total_well_rate = 0.0;
|
||||
for (int p = 0; p < np; ++p) {
|
||||
total_well_rate += baseif_.scalingFactor(p) * ws.surface_rates[p];
|
||||
}
|
||||
|
||||
// Not: for the moment, the first primary variable for the injectors is not G_total. The injection rate
|
||||
// under surface condition is used here
|
||||
if (baseif_.isInjector()) {
|
||||
switch (baseif_.wellEcl().injectorType()) {
|
||||
case InjectorType::WATER:
|
||||
primary_variables_.value_[WQTotal] = ws.surface_rates[pu.phase_pos[Water]];
|
||||
break;
|
||||
case InjectorType::GAS:
|
||||
primary_variables_.value_[WQTotal] = ws.surface_rates[pu.phase_pos[Gas]];
|
||||
break;
|
||||
case InjectorType::OIL:
|
||||
primary_variables_.value_[WQTotal] = ws.surface_rates[pu.phase_pos[Oil]];
|
||||
break;
|
||||
case InjectorType::MULTI:
|
||||
// Not supported.
|
||||
deferred_logger.warning("MULTI_PHASE_INJECTOR_NOT_SUPPORTED",
|
||||
"Multi phase injectors are not supported, requested for well " + baseif_.name());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
primary_variables_.value_[WQTotal] = total_well_rate;
|
||||
}
|
||||
|
||||
if (std::abs(total_well_rate) > 0.) {
|
||||
if constexpr (has_wfrac_variable) {
|
||||
primary_variables_.value_[WFrac] = baseif_.scalingFactor(pu.phase_pos[Water]) * ws.surface_rates[pu.phase_pos[Water]] / total_well_rate;
|
||||
}
|
||||
if constexpr (has_gfrac_variable) {
|
||||
primary_variables_.value_[GFrac] = baseif_.scalingFactor(pu.phase_pos[Gas]) * (ws.surface_rates[pu.phase_pos[Gas]]
|
||||
- (Indices::enableSolvent ? ws.sum_solvent_rates() : 0.0) ) / total_well_rate ;
|
||||
}
|
||||
if constexpr (Indices::enableSolvent) {
|
||||
primary_variables_.value_[SFrac] = baseif_.scalingFactor(pu.phase_pos[Gas]) * ws.sum_solvent_rates() / total_well_rate ;
|
||||
}
|
||||
} else { // total_well_rate == 0
|
||||
if (baseif_.isInjector()) {
|
||||
// only single phase injection handled
|
||||
if constexpr (has_wfrac_variable) {
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
|
||||
auto phase = baseif_.wellEcl().getInjectionProperties().injectorType;
|
||||
if (phase == InjectorType::WATER) {
|
||||
primary_variables_.value_[WFrac] = 1.0;
|
||||
} else {
|
||||
primary_variables_.value_[WFrac] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if constexpr (has_gfrac_variable) {
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
||||
auto phase = baseif_.wellEcl().getInjectionProperties().injectorType;
|
||||
if (phase == InjectorType::GAS) {
|
||||
primary_variables_.value_[GFrac] = (1.0 - baseif_.rsRvInj());
|
||||
if constexpr (Indices::enableSolvent) {
|
||||
primary_variables_.value_[GFrac] = 1.0 - baseif_.rsRvInj() - baseif_.wsolvent();
|
||||
primary_variables_.value_[SFrac] = baseif_.wsolvent();
|
||||
}
|
||||
} else {
|
||||
primary_variables_.value_[GFrac] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: it is possible to leave injector as a oil well,
|
||||
// when F_w and F_g both equals to zero, not sure under what kind of circumstance
|
||||
// this will happen.
|
||||
} else if (baseif_.isProducer()) { // producers
|
||||
// TODO: the following are not addressed for the solvent case yet
|
||||
if constexpr (has_wfrac_variable) {
|
||||
primary_variables_.value_[WFrac] = 1.0 / np;
|
||||
}
|
||||
|
||||
if constexpr (has_gfrac_variable) {
|
||||
primary_variables_.value_[GFrac] = 1.0 / np;
|
||||
}
|
||||
} else {
|
||||
OPM_DEFLOG_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well", deferred_logger);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// BHP
|
||||
primary_variables_.value_[Bhp] = ws.bhp;
|
||||
this->primary_variables_.update(well_state, deferred_logger);
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <opm/models/blackoil/blackoilonephaseindices.hh>
|
||||
#include <opm/models/blackoil/blackoiltwophaseindices.hh>
|
||||
|
||||
#include <opm/simulators/utils/DeferredLogger.hpp>
|
||||
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
|
||||
|
||||
#include <opm/simulators/wells/WellInterfaceIndices.hpp>
|
||||
#include <opm/simulators/wells/WellState.hpp>
|
||||
@@ -61,6 +61,107 @@ resize(const int numWellEq)
|
||||
numWellEq_ = numWellEq;
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
void StandardWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
||||
update(const WellState& well_state, DeferredLogger& deferred_logger)
|
||||
{
|
||||
static constexpr int Water = BlackoilPhases::Aqua;
|
||||
static constexpr int Oil = BlackoilPhases::Liquid;
|
||||
static constexpr int Gas = BlackoilPhases::Vapour;
|
||||
|
||||
const int well_index = well_.indexOfWell();
|
||||
const int np = well_.numPhases();
|
||||
const auto& pu = well_.phaseUsage();
|
||||
const auto& ws = well_state.well(well_index);
|
||||
// the weighted total well rate
|
||||
double total_well_rate = 0.0;
|
||||
for (int p = 0; p < np; ++p) {
|
||||
total_well_rate += well_.scalingFactor(p) * ws.surface_rates[p];
|
||||
}
|
||||
|
||||
// Not: for the moment, the first primary variable for the injectors is not G_total. The injection rate
|
||||
// under surface condition is used here
|
||||
if (well_.isInjector()) {
|
||||
switch (well_.wellEcl().injectorType()) {
|
||||
case InjectorType::WATER:
|
||||
value_[WQTotal] = ws.surface_rates[pu.phase_pos[Water]];
|
||||
break;
|
||||
case InjectorType::GAS:
|
||||
value_[WQTotal] = ws.surface_rates[pu.phase_pos[Gas]];
|
||||
break;
|
||||
case InjectorType::OIL:
|
||||
value_[WQTotal] = ws.surface_rates[pu.phase_pos[Oil]];
|
||||
break;
|
||||
case InjectorType::MULTI:
|
||||
// Not supported.
|
||||
deferred_logger.warning("MULTI_PHASE_INJECTOR_NOT_SUPPORTED",
|
||||
"Multi phase injectors are not supported, requested for well " + well_.name());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
value_[WQTotal] = total_well_rate;
|
||||
}
|
||||
|
||||
if (std::abs(total_well_rate) > 0.) {
|
||||
if constexpr (has_wfrac_variable) {
|
||||
value_[WFrac] = well_.scalingFactor(pu.phase_pos[Water]) * ws.surface_rates[pu.phase_pos[Water]] / total_well_rate;
|
||||
}
|
||||
if constexpr (has_gfrac_variable) {
|
||||
value_[GFrac] = well_.scalingFactor(pu.phase_pos[Gas]) *
|
||||
(ws.surface_rates[pu.phase_pos[Gas]] -
|
||||
(Indices::enableSolvent ? ws.sum_solvent_rates() : 0.0) ) / total_well_rate ;
|
||||
}
|
||||
if constexpr (Indices::enableSolvent) {
|
||||
value_[SFrac] = well_.scalingFactor(pu.phase_pos[Gas]) * ws.sum_solvent_rates() / total_well_rate ;
|
||||
}
|
||||
} else { // total_well_rate == 0
|
||||
if (well_.isInjector()) {
|
||||
// only single phase injection handled
|
||||
if constexpr (has_wfrac_variable) {
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
|
||||
auto phase = well_.wellEcl().getInjectionProperties().injectorType;
|
||||
if (phase == InjectorType::WATER) {
|
||||
value_[WFrac] = 1.0;
|
||||
} else {
|
||||
value_[WFrac] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if constexpr (has_gfrac_variable) {
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
||||
auto phase = well_.wellEcl().getInjectionProperties().injectorType;
|
||||
if (phase == InjectorType::GAS) {
|
||||
value_[GFrac] = (1.0 - well_.rsRvInj());
|
||||
if constexpr (Indices::enableSolvent) {
|
||||
value_[GFrac] = 1.0 - well_.rsRvInj() - well_.wsolvent();
|
||||
value_[SFrac] = well_.wsolvent();
|
||||
}
|
||||
} else {
|
||||
value_[GFrac] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: it is possible to leave injector as a oil well,
|
||||
// when F_w and F_g both equals to zero, not sure under what kind of circumstance
|
||||
// this will happen.
|
||||
} else if (well_.isProducer()) { // producers
|
||||
// TODO: the following are not addressed for the solvent case yet
|
||||
if constexpr (has_wfrac_variable) {
|
||||
value_[WFrac] = 1.0 / np;
|
||||
}
|
||||
|
||||
if constexpr (has_gfrac_variable) {
|
||||
value_[GFrac] = 1.0 / np;
|
||||
}
|
||||
} else {
|
||||
OPM_DEFLOG_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well", deferred_logger);
|
||||
}
|
||||
}
|
||||
|
||||
// BHP
|
||||
value_[Bhp] = ws.bhp;
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
void StandardWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
||||
@@ -81,22 +182,6 @@ updatePolyMW(const BVectorWell& dwells)
|
||||
}
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
void StandardWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
||||
copyToWellStatePolyMW(WellState& well_state) const
|
||||
{
|
||||
if (well_.isInjector()) {
|
||||
auto& ws = well_state.well(well_.indexOfWell());
|
||||
auto& perf_data = ws.perf_data;
|
||||
auto& perf_water_velocity = perf_data.water_velocity;
|
||||
auto& perf_skin_pressure = perf_data.skin_pressure;
|
||||
for (int perf = 0; perf < well_.numPerfs(); ++perf) {
|
||||
perf_water_velocity[perf] = value_[Bhp + 1 + perf];
|
||||
perf_skin_pressure[perf] = value_[Bhp + 1 + well_.numPerfs() + perf];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
void StandardWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
||||
copyToWellState(WellState& well_state,
|
||||
@@ -197,6 +282,22 @@ copyToWellState(WellState& well_state,
|
||||
}
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
void StandardWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
||||
copyToWellStatePolyMW(WellState& well_state) const
|
||||
{
|
||||
if (well_.isInjector()) {
|
||||
auto& ws = well_state.well(well_.indexOfWell());
|
||||
auto& perf_data = ws.perf_data;
|
||||
auto& perf_water_velocity = perf_data.water_velocity;
|
||||
auto& perf_skin_pressure = perf_data.skin_pressure;
|
||||
for (int perf = 0; perf < well_.numPerfs(); ++perf) {
|
||||
perf_water_velocity[perf] = value_[Bhp + 1 + perf];
|
||||
perf_skin_pressure[perf] = value_[Bhp + 1 + well_.numPerfs() + perf];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define INSTANCE(...) \
|
||||
template class StandardWellPrimaryVariables<BlackOilFluidSystem<double,BlackOilDefaultIndexTraits>,__VA_ARGS__,double>;
|
||||
|
||||
|
||||
@@ -108,6 +108,9 @@ public:
|
||||
//! \brief Returns number of well equations.
|
||||
int numWellEq() const { return numWellEq_; }
|
||||
|
||||
//! \brief Copy values from well state.
|
||||
void update(const WellState& well_state, DeferredLogger& deferred_logger);
|
||||
|
||||
//! \brief Update polymer molecular weight values from solution vector.
|
||||
void updatePolyMW(const BVectorWell& dwells);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user