diff --git a/opm/simulators/wells/MultisegmentWell_impl.hpp b/opm/simulators/wells/MultisegmentWell_impl.hpp index b3a6cd5e5..0e094c855 100644 --- a/opm/simulators/wells/MultisegmentWell_impl.hpp +++ b/opm/simulators/wells/MultisegmentWell_impl.hpp @@ -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); diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp index 7788fc7c4..606c298be 100644 --- a/opm/simulators/wells/StandardWell_impl.hpp +++ b/opm/simulators/wells/StandardWell_impl.hpp @@ -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; diff --git a/opm/simulators/wells/VFPProdProperties.cpp b/opm/simulators/wells/VFPProdProperties.cpp index 176784aaf..ce19ba245 100644 --- a/opm/simulators/wells/VFPProdProperties.cpp +++ b/opm/simulators/wells/VFPProdProperties.cpp @@ -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) INSTANCE(DenseAd::Evaluation) diff --git a/opm/simulators/wells/VFPProdProperties.hpp b/opm/simulators/wells/VFPProdProperties.hpp index a875505f6..d5a72975a 100644 --- a/opm/simulators/wells/VFPProdProperties.hpp +++ b/opm/simulators/wells/VFPProdProperties.hpp @@ -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 diff --git a/opm/simulators/wells/WellBhpThpCalculator.cpp b/opm/simulators/wells/WellBhpThpCalculator.cpp index 8f4e33c07..19583bfc4 100644 --- a/opm/simulators/wells/WellBhpThpCalculator.cpp +++ b/opm/simulators/wells/WellBhpThpCalculator.cpp @@ -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) diff --git a/opm/simulators/wells/WellInterface.hpp b/opm/simulators/wells/WellInterface.hpp index 115b0873d..3ea9d0b71 100644 --- a/opm/simulators/wells/WellInterface.hpp +++ b/opm/simulators/wells/WellInterface.hpp @@ -441,7 +441,6 @@ protected: std::optional estimateOperableBhp(const Simulator& ebos_simulator, const double dt, WellState& well_state, - const GroupState& group_state, const SummaryState& summary_state, DeferredLogger& deferred_logger); diff --git a/opm/simulators/wells/WellInterface_impl.hpp b/opm/simulators/wells/WellInterface_impl.hpp index ad4d5610e..72776235e 100644 --- a/opm/simulators/wells/WellInterface_impl.hpp +++ b/opm/simulators/wells/WellInterface_impl.hpp @@ -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 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; }