From 6b2c372f110e8b75515ce4f451659cb3a0e14eec Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 6 Dec 2023 17:31:51 +0100 Subject: [PATCH] allow individual well constraints before rebasing moved common thp calculation to updateWellControls Small fix clean up and improvements according reviewer comments clean up and improvements according reviewer comments, part 2 changed assessing safe THP range rebasing fixes removed unused argument rebasing --- .../wells/BlackoilWellModelGeneric.cpp | 1 + .../wells/BlackoilWellModel_impl.hpp | 38 ++++++++++++++++--- opm/simulators/wells/GroupState.cpp | 5 ++- opm/simulators/wells/WellBhpThpCalculator.hpp | 18 +++++++++ opm/simulators/wells/WellInterfaceGeneric.cpp | 7 ++++ opm/simulators/wells/WellInterface_impl.hpp | 4 +- 6 files changed, 64 insertions(+), 9 deletions(-) diff --git a/opm/simulators/wells/BlackoilWellModelGeneric.cpp b/opm/simulators/wells/BlackoilWellModelGeneric.cpp index 155118159..9df44e7a6 100644 --- a/opm/simulators/wells/BlackoilWellModelGeneric.cpp +++ b/opm/simulators/wells/BlackoilWellModelGeneric.cpp @@ -1546,6 +1546,7 @@ updateNetworkPressures(const int reportStepIdx, const Scalar damping_factor) } for (auto& well : well_container_generic_) { + // Producers only, since we so far only support the // "extended" network model (properties defined by // BRANPROP and NODEPROP) which only applies to producers. diff --git a/opm/simulators/wells/BlackoilWellModel_impl.hpp b/opm/simulators/wells/BlackoilWellModel_impl.hpp index e78f01077..747b7af07 100644 --- a/opm/simulators/wells/BlackoilWellModel_impl.hpp +++ b/opm/simulators/wells/BlackoilWellModel_impl.hpp @@ -55,6 +55,7 @@ #include #endif + #if HAVE_MPI #include #endif @@ -1234,9 +1235,6 @@ namespace Opm { BlackoilWellModel:: updateWellControlsAndNetwork(const bool mandatory_network_balance, const double dt, DeferredLogger& local_deferredLogger) { - // PJPE: calculate common THP for subsea manifold well group (item 3 of NODEPROP set to YES) - computeWellGroupThp(local_deferredLogger); - // not necessarily that we always need to update once of the network solutions bool do_network_update = true; bool well_group_control_changed = false; @@ -1331,6 +1329,7 @@ namespace Opm { const auto& balance = this->schedule()[reportStepIdx].network_balance(); const Scalar thp_tolerance = balance.thp_tolerance(); + if (!network.active()) { return; } @@ -1346,6 +1345,7 @@ namespace Opm { const auto ctrl = group.productionControls(summary_state); const auto cmode = ctrl.cmode; const auto pu = this->phase_usage_; + //TODO: Auto choke combined with RESV control is not supported std::vector resv_coeff(pu.num_phases, 1.0); Scalar gratTargetFromSales = 0.0; @@ -1376,6 +1376,31 @@ namespace Opm { return (group_rate - orig_target)/orig_target; }; + double min_thp, max_thp; + std::array range_initial; + //Find an initial bracket + if (!this->well_group_thp_calc_.has_value()){ + // Retrieve the terminal pressure of the associated root of the manifold group + std::string node_name = nodeName; + while (!network.node(node_name).terminal_pressure().has_value()) { + auto branch = network.uptree_branch(node_name).value(); + node_name = branch.uptree_node(); + } + + min_thp = network.node(node_name).terminal_pressure().value(); + std::optional approximate_solution0; + WellBhpThpCalculator::bruteForceBracketCommonTHP(mismatch, min_thp, max_thp, local_deferredLogger); + + // Narrow down the bracket + double low1, high1; + std::array range = {0.9*min_thp, 1.1*max_thp}; + std::optional appr_sol; + WellBhpThpCalculator::bruteForceBracketCommonTHP(mismatch, range, low1, high1, appr_sol, 0.0, local_deferredLogger); + min_thp = low1; + max_thp = high1; + range_initial = {min_thp, max_thp}; + } + const auto upbranch = network.uptree_branch(nodeName); const auto it = this->node_pressures_.find((*upbranch).uptree_node()); const Scalar nodal_pressure = it->second; @@ -1446,6 +1471,7 @@ namespace Opm { for (auto& well : this->well_container_) { std::string well_name = well->name(); if (group.hasWell(well_name)) { + well->setDynamicThpLimit(well_group_thp); } } @@ -2686,10 +2712,10 @@ namespace Opm { const std::string msg = "Compute initial well solution for " + well->name() + " initially failed. Continue with the previous rates"; deferred_logger.warning("WELL_INITIAL_SOLVE_FAILED", msg); } - // If we're using local well solves that include control switches, they also update - // operability, so reset before main iterations begin - well->resetWellOperability(); } + // If we're using local well solves that include control switches, they also update + // operability, so reset before main iterations begin + well->resetWellOperability(); } updatePrimaryVariables(deferred_logger); diff --git a/opm/simulators/wells/GroupState.cpp b/opm/simulators/wells/GroupState.cpp index 262d33a72..d73c7ed63 100644 --- a/opm/simulators/wells/GroupState.cpp +++ b/opm/simulators/wells/GroupState.cpp @@ -105,8 +105,9 @@ GroupState::production_rates(const std::string& gname) const } //------------------------------------------------------------------------- + template -bool GroupState:: +void GroupState:: GroupState::update_well_group_thp(const std::string& gname, const double& thp) { this->group_thp[gname] = thp; @@ -123,6 +124,8 @@ GroupState::well_group_thp(const std::string& gname) const return group_iter->second; } +//------------------------------------------------------------------------- + template void GroupState:: GroupState::update_well_group_thp(const std::string& gname, const double& thp) diff --git a/opm/simulators/wells/WellBhpThpCalculator.hpp b/opm/simulators/wells/WellBhpThpCalculator.hpp index 4ece9168a..a8ca0b735 100644 --- a/opm/simulators/wells/WellBhpThpCalculator.hpp +++ b/opm/simulators/wells/WellBhpThpCalculator.hpp @@ -130,6 +130,24 @@ public: static bool bruteForceBracketCommonTHP(const std::function& eq, Scalar& min_thp, Scalar& max_thp); + //! \brief Find limits using brute-force solver. + static bool bruteForceBracket(const std::function& eq, + const std::array& range, + double& low, double& high, + DeferredLogger& deferred_logger); + + //! \brief Find limits using brute-force solver. + static bool bruteForceBracketCommonTHP(const std::function& eq, + const std::array& range, + double& low, double& high, + std::optional& approximate_solution, + const double& limit, + DeferredLogger& deferred_logger); + + //! \brief Find limits using brute-force solver. + static bool bruteForceBracketCommonTHP(const std::function& eq, + double& min_thp, double& max_thp); + private: //! \brief Compute BHP from THP limit for an injector - implementation. template diff --git a/opm/simulators/wells/WellInterfaceGeneric.cpp b/opm/simulators/wells/WellInterfaceGeneric.cpp index 8a9748768..07c2cb3b4 100644 --- a/opm/simulators/wells/WellInterfaceGeneric.cpp +++ b/opm/simulators/wells/WellInterfaceGeneric.cpp @@ -518,6 +518,13 @@ WellInterfaceGeneric::getDynamicThpLimit() const return dynamic_thp_limit_; } +template +void WellInterfaceGeneric:: +setDynamicThpLimit(const std::optional thp_limit) +{ + dynamic_thp_limit_ = thp_limit; +} + template void WellInterfaceGeneric:: updatePerforatedCell(std::vector& is_cell_perforated) diff --git a/opm/simulators/wells/WellInterface_impl.hpp b/opm/simulators/wells/WellInterface_impl.hpp index 0b05c2a12..af95e9cd4 100644 --- a/opm/simulators/wells/WellInterface_impl.hpp +++ b/opm/simulators/wells/WellInterface_impl.hpp @@ -1480,11 +1480,11 @@ namespace Opm } ws.trivial_target = false; } else { - ws.trivial_target = true; + ws.trivial_target = true; } break; - } + } case Well::ProducerCMode::CMODE_UNDEFINED: case Well::ProducerCMode::NONE: {