From 2152ac64656c768eb8ca0bc4d3a3f458ff9427ea Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Wed, 1 Mar 2023 16:47:11 +0100 Subject: [PATCH] make sure computeWellRatesWithBhpIterations honor bhp limit for StandardWell --- opm/simulators/wells/StandardWell.hpp | 2 + opm/simulators/wells/StandardWellAssemble.cpp | 6 +-- opm/simulators/wells/StandardWellAssemble.hpp | 4 ++ opm/simulators/wells/StandardWell_impl.hpp | 42 ++++++++++++------- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/opm/simulators/wells/StandardWell.hpp b/opm/simulators/wells/StandardWell.hpp index 6bbc63fb8..c9253c2c7 100644 --- a/opm/simulators/wells/StandardWell.hpp +++ b/opm/simulators/wells/StandardWell.hpp @@ -374,6 +374,8 @@ namespace Opm void assembleWellEqWithoutIterationImpl(const Simulator& ebosSimulator, const double dt, + const Well::InjectionControls& inj_controls, + const Well::ProductionControls& prod_controls, WellState& well_state, const GroupState& group_state, DeferredLogger& deferred_logger); diff --git a/opm/simulators/wells/StandardWellAssemble.cpp b/opm/simulators/wells/StandardWellAssemble.cpp index cdecb8cfd..ed568497c 100644 --- a/opm/simulators/wells/StandardWellAssemble.cpp +++ b/opm/simulators/wells/StandardWellAssemble.cpp @@ -87,6 +87,8 @@ assembleControlEq(const WellState& well_state, const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, + const Well::InjectionControls& inj_controls, + const Well::ProductionControls& prod_controls, const PrimaryVariables& primary_variables, const double rho, StandardWellEquations& eqns1, @@ -129,8 +131,6 @@ assembleControlEq(const WellState& well_state, deferred_logger); }; - // Call generic implementation. - const auto& inj_controls = well.injectionControls(summaryState); WellAssemble(well_). assembleControlEqInj(well_state, group_state, @@ -154,8 +154,6 @@ assembleControlEq(const WellState& well_state, rho, deferred_logger); }; - // Call generic implementation. - const auto& prod_controls = well.productionControls(summaryState); WellAssemble(well_). assembleControlEqProd(well_state, group_state, diff --git a/opm/simulators/wells/StandardWellAssemble.hpp b/opm/simulators/wells/StandardWellAssemble.hpp index 55c6de9e9..97107a50b 100644 --- a/opm/simulators/wells/StandardWellAssemble.hpp +++ b/opm/simulators/wells/StandardWellAssemble.hpp @@ -23,6 +23,8 @@ #ifndef OPM_STANDARDWELL_ASSEMBLE_HEADER_INCLUDED #define OPM_STANDARDWELL_ASSEMBLE_HEADER_INCLUDED +#include + namespace Opm { @@ -53,6 +55,8 @@ public: const GroupState& group_state, const Schedule& schedule, const SummaryState& summaryState, + const Well::InjectionControls& inj_controls, + const Well::ProductionControls& prod_controls, const PrimaryVariables& primary_variables, const double rho, StandardWellEquations& eqns, diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp index 0131bc75a..c3c07fb77 100644 --- a/opm/simulators/wells/StandardWell_impl.hpp +++ b/opm/simulators/wells/StandardWell_impl.hpp @@ -476,8 +476,8 @@ namespace Opm StandardWell:: assembleWellEqWithoutIteration(const Simulator& ebosSimulator, const double dt, - const Well::InjectionControls& /*inj_controls*/, - const Well::ProductionControls& /*prod_controls*/, + const Well::InjectionControls& inj_controls, + const Well::ProductionControls& prod_controls, WellState& well_state, const GroupState& group_state, DeferredLogger& deferred_logger) @@ -489,7 +489,7 @@ namespace Opm // clear all entries this->linSys_.clear(); - assembleWellEqWithoutIterationImpl(ebosSimulator, dt, well_state, group_state, deferred_logger); + assembleWellEqWithoutIterationImpl(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger); } @@ -500,6 +500,8 @@ namespace Opm StandardWell:: assembleWellEqWithoutIterationImpl(const Simulator& ebosSimulator, const double dt, + const Well::InjectionControls& inj_controls, + const Well::ProductionControls& prod_controls, WellState& well_state, const GroupState& group_state, DeferredLogger& deferred_logger) @@ -603,6 +605,7 @@ namespace Opm StandardWellAssemble(*this). assembleControlEq(well_state, group_state, schedule, summaryState, + inj_controls, prod_controls, this->primary_variables_, this->connections_.rho(), this->linSys_, @@ -1705,18 +1708,32 @@ namespace Opm std::vector& well_flux, DeferredLogger& deferred_logger) const { + // creating a copy of the well itself, to avoid messing up the explicit information + // during this copy, the only information not copied properly is the well controls + StandardWell well_copy(*this); // iterate to get a more accurate well density // create a copy of the well_state to use. If the operability checking is sucessful, we use this one // to replace the original one WellState well_state_copy = ebosSimulator.problem().wellModel().wellState(); const auto& group_state = ebosSimulator.problem().wellModel().groupState(); - auto& ws = well_state_copy.well(this->index_of_well_); + + // Get the current controls. + const auto& summary_state = ebosSimulator.vanguard().summaryState(); + auto inj_controls = well_copy.well_ecl_.isInjector() + ? well_copy.well_ecl_.injectionControls(summary_state) + : Well::InjectionControls(0); + auto prod_controls = well_copy.well_ecl_.isProducer() + ? well_copy.well_ecl_.productionControls(summary_state) : + Well::ProductionControls(0); // Set current control to bhp, and bhp value in state, modify bhp limit in control object. - if (this->well_ecl_.isInjector()) { + auto& ws = well_state_copy.well(this->index_of_well_); + if (well_copy.well_ecl_.isInjector()) { + inj_controls.bhp_limit = bhp; ws.injection_cmode = Well::InjectorCMode::BHP; } else { + prod_controls.bhp_limit = bhp; ws.production_cmode = Well::ProducerCMode::BHP; } ws.bhp = bhp; @@ -1728,22 +1745,19 @@ namespace Opm well_state_copy.wellRates(this->index_of_well_)[phase] = sign * ws.well_potentials[phase]; } - // creating a copy of the well itself, to avoid messing up the explicit informations - // during this copy, the only information not copied properly is the well controls - StandardWell well(*this); - well.calculateExplicitQuantities(ebosSimulator, well_state_copy, deferred_logger); + well_copy.calculateExplicitQuantities(ebosSimulator, well_state_copy, deferred_logger); const double dt = ebosSimulator.timeStepSize(); - bool converged = well.iterateWellEquations(ebosSimulator, dt, well_state_copy, group_state, deferred_logger); + const bool converged = well_copy.iterateWellEqWithControl(ebosSimulator, dt, inj_controls, prod_controls, well_state_copy, group_state, deferred_logger); if (!converged) { const std::string msg = " well " + name() + " did not get converged during well potential calculations " " potentials are computed based on unconverged solution"; deferred_logger.debug(msg); } - well.updatePrimaryVariables(well_state_copy, deferred_logger); - well.computeWellConnectionPressures(ebosSimulator, well_state_copy, deferred_logger); - well.initPrimaryVariablesEvaluation(); - well.computeWellRatesWithBhp(ebosSimulator, bhp, well_flux, deferred_logger); + well_copy.updatePrimaryVariables(well_state_copy, deferred_logger); + well_copy.computeWellConnectionPressures(ebosSimulator, well_state_copy, deferred_logger); + well_copy.initPrimaryVariablesEvaluation(); + well_copy.computeWellRatesWithBhp(ebosSimulator, bhp, well_flux, deferred_logger); }