Use new method to determine operability under THP control.

This commit is contained in:
Atgeirr Flø Rasmussen 2019-10-04 16:16:04 +02:00 committed by Tor Harald Sandve
parent a536b90891
commit 6b011c1bfb
2 changed files with 5 additions and 113 deletions

View File

@ -423,15 +423,6 @@ namespace Opm
// check whether the well is operable under THP limit with current reservoir condition
void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger);
// update WellState based on IPR and associated VFP table
void updateWellStateWithTHPTargetIPR(const Simulator& ebos_simulator,
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const;
void updateWellStateWithTHPTargetIPRProducer(const Simulator& ebos_simulator,
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const;
// for a well, when all drawdown are in the wrong direction, then this well will not
// be able to produce/inject .
bool allDrawDownWrongDirection(const Simulator& ebos_simulator) const;
@ -448,11 +439,6 @@ namespace Opm
// TODO: looking for better alternative to avoid wrong-signed well rates
bool openCrossFlowAvoidSingularity(const Simulator& ebos_simulator) const;
// calculate the BHP from THP target based on IPR
// TODO: we need to check the operablility here first, if not operable, then maybe there is
// no point to do this
double calculateBHPWithTHPTargetIPR(const Well2& well, const SummaryState& summaryState, Opm::DeferredLogger& deferred_logger) const;
// relaxation factor considering only one fraction value
static double relaxationFactorFraction(const double old_value,
const double dx);

View File

@ -2039,19 +2039,18 @@ namespace Opm
StandardWell<TypeTag>::
checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger)
{
const Well2& well = Base::wellEcl();
const auto& summaryState = ebos_simulator.vanguard().summaryState();
const double obtain_bhp = calculateBHPWithTHPTargetIPR(well, summaryState, deferred_logger);
const auto obtain_bhp = robustSolveBhpAtThpLimitProd(ebos_simulator, summaryState, deferred_logger);
if (obtain_bhp > 0.) {
if (obtain_bhp) {
this->operability_status_.can_obtain_bhp_with_thp_limit = true;
const double bhp_limit = mostStrictBhpFromBhpLimits(summaryState);
this->operability_status_.obey_bhp_limit_with_thp_limit = (obtain_bhp >= bhp_limit);
this->operability_status_.obey_bhp_limit_with_thp_limit = (*obtain_bhp >= bhp_limit);
const double thp_limit = this->getTHPConstraint(summaryState);
if (obtain_bhp < thp_limit) {
const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(obtain_bhp, unit::barsa))
if (*obtain_bhp < thp_limit) {
const std::string msg = " obtained bhp " + std::to_string(unit::convert::to(*obtain_bhp, unit::barsa))
+ " bars is SMALLER than thp limit "
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
+ " bars as a producer for well " + name();
@ -2155,70 +2154,6 @@ namespace Opm
template<typename TypeTag>
void
StandardWell<TypeTag>::
updateWellStateWithTHPTargetIPR(const Simulator& ebos_simulator,
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const
{
if (well_type_ == PRODUCER) {
updateWellStateWithTHPTargetIPRProducer(ebos_simulator,
well_state,
deferred_logger);
}
if (well_type_ == INJECTOR) {
const auto& summaryState = ebos_simulator.vanguard().summaryState();
well_state.thp()[index_of_well_] = this->getTHPConstraint(summaryState);
// TODO: more work needs to be done for the injectors here, while injectors
// have been okay with the current strategy relying on well control equation directly.
}
}
template<typename TypeTag>
void
StandardWell<TypeTag>::
updateWellStateWithTHPTargetIPRProducer(const Simulator& ebos_simulator,
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const
{
const auto& summaryState = ebos_simulator.vanguard().summaryState();
well_state.thp()[index_of_well_] = this->getTHPConstraint(summaryState);
const Well2& well = Base::wellEcl();
const double bhp = calculateBHPWithTHPTargetIPR(well, summaryState, deferred_logger);
assert(bhp > 0.0);
well_state.bhp()[index_of_well_] = bhp;
// TODO: explicit quantities are always tricky for this type of situation
updatePrimaryVariables(well_state, deferred_logger);
initPrimaryVariablesEvaluation();
std::vector<double> rates;
computeWellRatesWithBhp(ebos_simulator, bhp, rates, deferred_logger);
// TODO: double checke the obtained rates
// this is another places we might obtain negative rates
for (int p = 0; p < number_of_phases_; ++p) {
well_state.wellRates()[number_of_phases_ * index_of_well_ + p] = rates[p];
}
// TODO: there will be something need to be done for the cases not the defaulted 3 phases,
// like 2 phases or solvent, polymer, etc. But we are not addressing them with THP control yet.
}
template<typename TypeTag>
void
StandardWell<TypeTag>::
@ -3020,35 +2955,6 @@ namespace Opm
template<typename TypeTag>
double
StandardWell<TypeTag>::
calculateBHPWithTHPTargetIPR(const Well2& well,
const SummaryState& summaryState,
Opm::DeferredLogger& deferred_logger) const
{
// TODO: when well is under THP control, the BHP is dependent on the rates,
// the well rates is also dependent on the BHP, so it might need to do some iteration.
// However, when group control is involved, change of the rates might impacts other wells
// so iterations on a higher level will be required. Some investigation might be needed when
// we face problems under THP control.
//assert(int(rates.size()) == 3); // the vfp related only supports three phases now.
// pick the density in the top layer
// TODO: it is possible it should be a Evaluation
const double rho = perf_densities_[0];
assert(well.isProducer());
const auto& controls = well.productionControls(summaryState);
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(controls.vfp_table_number)->getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);
return vfp_properties_->getProd()->calculateBhpWithTHPTarget(ipr_a_, ipr_b_,
controls.bhp_limit, controls.vfp_table_number, controls.thp_limit, controls.alq_value, dp);
}
template<typename TypeTag>
double
StandardWell<TypeTag>::