This commit is contained in:
Stein Krogstad 2023-11-08 21:58:26 +01:00
parent 5083052a3f
commit 2121373e4f
7 changed files with 14 additions and 87 deletions

View File

@ -1327,7 +1327,7 @@ namespace Opm
const auto msg = fmt::format("updateIPRImplicit: Well {} has zero rate, IPRs might be problematic", this->name());
deferred_logger.debug(msg);
/*
// could revert to standard approach here
// could revert to standard approach here:
updateIPR(ebos_simulator, deferred_logger);
for (int comp_idx = 0; comp_idx < this->num_components_; ++comp_idx){
const int idx = this->ebosCompIdxToFlowCompIdx(comp_idx);
@ -1589,8 +1589,6 @@ namespace Opm
const bool fixed_control /*false*/,
const bool fixed_status /*false*/)
{
//if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return true;
const int max_iter_number = this->param_.max_inner_iter_ms_wells_;
{
@ -1741,9 +1739,6 @@ namespace Opm
} else {
this->operability_status_.operable_under_only_bhp_limit = !is_stopped;
}
// We reset the well status to it's original state. Status is updated
// on the outside based on operability status
// this->wellStatus_ = well_status;
}
std::string message = fmt::format(" Well {} converged in {} inner iterations ("
"{} control/status switches).", this->name(), it, switch_count);

View File

@ -856,7 +856,7 @@ namespace Opm
const auto msg = fmt::format("updateIPRImplicit: Well {} has zero rate, IPRs might be probelmatic", this->name());
deferred_logger.debug(msg);
/*
// could revert to standard approach here
// could revert to standard approach here:
updateIPR(ebos_simulator, deferred_logger);
for (int comp_idx = 0; comp_idx < this->num_components_; ++comp_idx){
const int idx = this->ebosCompIdxToFlowCompIdx(comp_idx);
@ -2341,14 +2341,7 @@ namespace Opm
allow_switching = allow_switching && (!fixed_control || !fixed_status);
bool changed = false;
bool final_check = false;
/*
if (allow_switching) {
// ??????????????????????????????????????????
this->operability_status_.can_obtain_bhp_with_thp_limit = true;
this->operability_status_.obey_thp_limit_under_bhp_limit = true;
this->operability_status_.operable_under_only_bhp_limit = true;
}
*/
do {
its_since_last_switch++;
if (allow_switching && its_since_last_switch >= min_its_after_switch){
@ -2411,14 +2404,6 @@ namespace Opm
} else {
this->operability_status_.operable_under_only_bhp_limit = !is_stopped;
}
// We reset the well status to its original state. Status is updated
// on the outside based on operability status
// \Note for future reference: For the well to update its status to stop/shut,
// the flag changed_to_stopped_this_step_ in prepareWellBeforeAssembling needs to be set to true.
// For this to happen, isOperableAndSolvable() must change from true to false,
// and (until the most recent commit) the well needs to be open for this to trigger.
// Hence, the resetting of status.
//this->wellStatus_ = well_status;
}
} else {
this->wellStatus_ = well_status_orig;

View File

@ -90,8 +90,7 @@ double VFPProdProperties::bhp(int table_id,
const double& alq,
const double& explicit_wfr,
const double& explicit_gfr,
const bool use_expvfp,
const double ipr_slope) const {
const bool use_expvfp) const {
const VFPProdTable& table = detail::getTable(m_tables, table_id);
detail::VFPEvaluation retval = detail::bhp(table, aqua, liquid, vapour, thp_arg, alq, explicit_wfr,explicit_gfr, use_expvfp);
@ -168,8 +167,7 @@ EvalWell VFPProdProperties::bhp(const int table_id,
const double& alq,
const double& explicit_wfr,
const double& explicit_gfr,
const bool use_expvfp,
const double ipr_slope /*=0*/) const
const bool use_expvfp) const
{
//Get the table
const VFPProdTable& table = detail::getTable(m_tables, table_id);
@ -202,7 +200,7 @@ EvalWell VFPProdProperties::bhp(const int table_id,
#define INSTANCE(...) \
template __VA_ARGS__ VFPProdProperties::bhp<__VA_ARGS__>(const int, \
const __VA_ARGS__&, const __VA_ARGS__&, const __VA_ARGS__&, \
const double&, const double&, const double&, const double&, const bool, const double) const;
const double&, const double&, const double&, const double&, const bool) const;
INSTANCE(DenseAd::Evaluation<double, -1, 4u>)
INSTANCE(DenseAd::Evaluation<double, -1, 5u>)

View File

@ -68,8 +68,7 @@ public:
const double& alq,
const double& explicit_wfr,
const double& explicit_gfr,
const bool use_expvfp,
const double ipr_slope = 0.0) const;
const bool use_expvfp) const;
/**
* Linear interpolation of bhp as a function of the input parameters
@ -91,8 +90,7 @@ public:
const double& alq,
const double& explicit_wfr,
const double& explicit_gfr,
const bool use_expvfp,
const double ipr_slope = 0.0) const;
const bool use_expvfp) const;
/**
* Linear interpolation of thp as a function of the input parameters

View File

@ -365,16 +365,12 @@ calculateBhpFromThp(const WellState& well_state,
const auto& wfr = well_.vfpProperties()->getExplicitWFR(controls.vfp_table_number, well_.indexOfWell());
const auto& gfr = well_.vfpProperties()->getExplicitGFR(controls.vfp_table_number, well_.indexOfWell());
const bool use_vfpexplicit = well_.useVfpExplicit();
double ipr_slope = 0.0;
if (use_vfpexplicit) {
const auto ipr = getFloIPR(well_state, well, summaryState);
ipr_slope = -1/ipr.second;
}
bhp_tab = well_.vfpProperties()->getProd()->bhp(controls.vfp_table_number,
aqua, liquid, vapour,
thp_limit,
well_.getALQ(well_state),
wfr, gfr, use_vfpexplicit, ipr_slope);
wfr, gfr, use_vfpexplicit);
}
else {
OPM_DEFLOG_THROW(std::logic_error, "Expected INJECTOR or PRODUCER for well " + well_.name(), deferred_logger);
@ -896,11 +892,6 @@ isStableSolution(const WellState& well_state,
const auto& table = well_.vfpProperties()->getProd()->getTable(controls.vfp_table_number);
const bool use_vfpexplicit = well_.useVfpExplicit();
//const double vfp_ref_depth = well_.vfpProperties()->getProd()->getTable(controls.vfp_table_number).getDatumDepth();
//const auto bhp_adjustment = getVfpBhpAdjustment(well_state.well(well_.indexOfWell()).bhp, thp);
// XXX this needs to be fixed
//assert(bhp_adjustment == 0.0);
detail::VFPEvaluation bhp = detail::bhp(table, aqua, liquid, vapour, thp, well_.getALQ(well_state), wfr, gfr, use_vfpexplicit);
bhp.value = bhp.value + getVfpBhpAdjustment(bhp.value, thp);
@ -953,7 +944,6 @@ estimateStableBhp(const WellState& well_state,
auto bhp_adjusted = [this, &thp, &dp_hydro](const double bhp) {
return bhp - dp_hydro + getVfpBhpAdjustment(bhp, thp);
};
//const auto retval = detail::intersectWithIPR(table, thp, wfr, gfr, well_.getALQ(well_state), ipr.first+ipr.second*dp_hydro, ipr.second);
const auto retval = detail::intersectWithIPR(table, thp, wfr, gfr, well_.getALQ(well_state), ipr.first, ipr.second, bhp_adjusted);
if (retval.has_value()) {
// returned pair is (flo, bhp)

View File

@ -441,7 +441,6 @@ protected:
std::optional<double> estimateOperableBhp(const Simulator& ebos_simulator,
const double dt,
WellState& well_state,
const GroupState& group_state,
const SummaryState& summary_state,
DeferredLogger& deferred_logger);

View File

@ -289,7 +289,6 @@ namespace Opm
prod_controls.hasControl(Well::ProducerCMode::GRUP);
changed = this->checkIndividualConstraints(ws, summary_state, deferred_logger, inj_controls, prod_controls);
// TODO: with current way, the checkGroupConstraints might overwrite the result from checkIndividualConstraints, which remains to be investigated
if (hasGroupControl) {
changed = changed || this->checkGroupConstraints(well_state, group_state, schedule, summary_state,deferred_logger);
}
@ -315,16 +314,12 @@ namespace Opm
double inj_limit = inj_controls.bhp_limit;
const bool has_thp = this->wellHasTHPConstraints(summary_state);
if (has_thp){
// calculate bhp from thp-limit (using explicit fractions zince zero rate)
// TODO: this will often be too strict condition for re-opening, a better
// option is probably minimum bhp on current vfp-curve, but some more functionality
// is needed for this option to be robustly implemented.
std::vector<double> rates(this->num_components_);
//const double bhp_thp = WellBhpThpCalculator(*this).calculateBhpFromThp(well_state, rates, this->well_ecl_, summary_state, this->getRefDensity(), deferred_logger);
if (this->isInjector()){
const double bhp_thp = WellBhpThpCalculator(*this).calculateBhpFromThp(well_state, rates, this->well_ecl_, summary_state, this->getRefDensity(), deferred_logger);
inj_limit = std::min(bhp_thp, inj_controls.bhp_limit);
} else {
// if the well can operate, it must at least be able to produce at the lowest bhp of the bhp-curve (explicit fractions)
const double bhp_min = WellBhpThpCalculator(*this).calculateMinimumBhpFromThp(well_state, this->well_ecl_, summary_state, this->getRefDensity());
prod_limit = std::max(bhp_min, prod_controls.bhp_limit);
//auto prates = well_state.well(this->index_of_well_).prev_surface_rates;
@ -494,7 +489,7 @@ namespace Opm
// if well is stopped, check if we can reopen
if (this->wellIsStopped()) {
this->openWell();
auto bhp_target = estimateOperableBhp(ebos_simulator, dt, well_state, group_state, summary_state, deferred_logger);
auto bhp_target = estimateOperableBhp(ebos_simulator, dt, well_state, summary_state, deferred_logger);
if (!bhp_target.has_value()) {
// no intersection with ipr
const auto msg = fmt::format("estimateOperableBhp: Did not find operable BHP for well {}", this->name());
@ -547,7 +542,7 @@ namespace Opm
// Well did not converge, switch to explicit fractions
this->operability_status_.use_vfpexplicit = true;
this->openWell();
auto bhp_target = estimateOperableBhp(ebos_simulator, dt, well_state, group_state, summary_state, deferred_logger);
auto bhp_target = estimateOperableBhp(ebos_simulator, dt, well_state, summary_state, deferred_logger);
if (!bhp_target.has_value()) {
// well can't operate using explicit fractions
is_operable = false;
@ -557,19 +552,9 @@ namespace Opm
} else {
// solve well with the estimated target bhp (or limit)
const double bhp = std::max(bhp_target.value(), prod_controls.bhp_limit);
const bool converged_bhp = solveWellWithBhp(ebos_simulator, dt, bhp, well_state, deferred_logger);
solveWellWithBhp(ebos_simulator, dt, bhp, well_state, deferred_logger);
ws.thp = this->getTHPConstraint(summary_state);
converged = this->iterateWellEqWithSwitching(ebos_simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
/*
if (!converged) {
// debug
} else {
// re-solve well equations
// XXX reset thp
well_state.well(this->index_of_well_).thp = this->getTHPConstraint(summary_state);
}
*/
}
}
// update operability
@ -585,7 +570,6 @@ namespace Opm
estimateOperableBhp(const Simulator& ebos_simulator,
const double dt,
WellState& well_state,
const GroupState& group_state,
const SummaryState& summary_state,
DeferredLogger& deferred_logger)
{
@ -654,30 +638,8 @@ namespace Opm
auto group_state = GroupState(); // empty group
auto inj_controls = Well::InjectionControls(0);
auto prod_controls = Well::ProductionControls(0);
/*
auto& ws = well_state.well(this->index_of_well_);
auto cmode_inj = ws.injection_cmode;
auto cmode_prod = ws.production_cmode;
if (this->isInjector()) {
assert(false);
//inj_controls.addControl(Well::InjectorCMode::BHP);
//inj_controls.bhp_limit = bhp;
//inj_controls.cmode = Well::InjectorCMode::BHP;
//ws.injection_cmode = Well::InjectorCMode::BHP;
} else {
prod_controls.addControl(Well::ProducerCMode::ORAT);
prod_controls.oil_rate = 0.0;
prod_controls.cmode = Well::ProducerCMode::ORAT;
ws.production_cmode = Well::ProducerCMode::ORAT;
}
*/
// update well-state
//ws.bhp = bhp;
// solve
const bool converged = this->iterateWellEqWithSwitching(ebos_simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger, /*fixed_control*/true, /*fixed_status*/ true);
this->wellStatus_ = well_status_orig;
//ws.injection_cmode = cmode_inj;
//ws.production_cmode = cmode_prod;
return converged;
}