mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-21 16:57:25 -06:00
Use new method to determine operability under THP control.
This commit is contained in:
parent
a536b90891
commit
6b011c1bfb
@ -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);
|
||||
|
@ -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>::
|
||||
|
Loading…
Reference in New Issue
Block a user