added more timing

This commit is contained in:
Halvor M Nilsen 2025-01-22 11:04:24 +01:00
parent 7b4acb0db4
commit f2bfa1b2ef
11 changed files with 90 additions and 7 deletions

View File

@ -85,6 +85,7 @@ gasLiftOptimizationStage2(const Parallel::Communication& comm,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
GasLiftStage2 glift {episodeIndex,
comm,
schedule,

View File

@ -27,7 +27,7 @@
#include <config.h>
#include <opm/simulators/wells/BlackoilWellModelGasLift.hpp>
#endif
#include <opm/common/TimingMacros.hpp>
#include <opm/simulators/wells/GasLiftSingleWell.hpp>
#if HAVE_MPI
@ -45,6 +45,7 @@ maybeDoGasLiftOptimize(const Simulator& simulator,
GroupState<Scalar>& groupState,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
bool do_glift_optimization = false;
int num_wells_changed = 0;
const double simulation_time = simulator.time();
@ -139,6 +140,7 @@ gasLiftOptimizationStage1(const Simulator& simulator,
GLiftWellStateMap& state_map,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
auto comm = simulator.vanguard().grid().comm();
int num_procs = comm.size();
// NOTE: Gas lift optimization stage 1 seems to be difficult
@ -188,8 +190,12 @@ gasLiftOptimizationStage1(const Simulator& simulator,
}
num_rates_to_sync = groups_to_sync.size();
}
num_rates_to_sync = comm.sum(num_rates_to_sync);
{
OPM_TIMEBLOCK(WaitForGasLiftSyncGroups);
num_rates_to_sync = comm.sum(num_rates_to_sync);
}
if (num_rates_to_sync > 0) {
OPM_TIMEBLOCK(GasLiftSyncGroups);
std::vector<int> group_indexes;
group_indexes.reserve(num_rates_to_sync);
std::vector<Scalar> group_alq_rates;
@ -261,6 +267,7 @@ gasLiftOptimizationStage1SingleWell(WellInterface<TypeTag>* well,
GLiftSyncGroups& sync_groups,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const auto& summary_state = simulator.vanguard().summaryState();
auto glift = std::make_unique<GasLiftSingleWell<TypeTag>>(*well,
simulator,

View File

@ -25,6 +25,7 @@
#include <opm/simulators/wells/BlackoilWellModelGeneric.hpp>
#include <opm/common/ErrorMacros.hpp>
#include <opm/common/TimingMacros.hpp>
#include <opm/output/data/GuideRateValue.hpp>
#include <opm/output/data/Groups.hpp>
@ -1255,6 +1256,7 @@ updateAndCommunicateGroupData(const int reportStepIdx,
const Scalar tol_nupcol,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
const int nupcol = schedule()[reportStepIdx].nupcol();
@ -1268,6 +1270,7 @@ updateAndCommunicateGroupData(const int reportStepIdx,
this->wellState().updateGlobalIsGrup(comm_);
if (iterationIdx <= nupcol) {
OPM_TIMEBLOCK(updateNupcol);
this->updateNupcolWGState();
} else {
for (const auto& gr_name : schedule().groupNames(reportStepIdx)) {
@ -1276,6 +1279,7 @@ updateAndCommunicateGroupData(const int reportStepIdx,
if (this->groupState().has_injection_control(gr_name, phase)) {
if (this->groupState().injection_control(gr_name, phase) == Group::InjectionCMode::VREP ||
this->groupState().injection_control(gr_name, phase) == Group::InjectionCMode::REIN) {
OPM_TIMEBLOCK(extraIterationsAfterNupcol);
const bool is_vrep = this->groupState().injection_control(gr_name, phase) == Group::InjectionCMode::VREP;
const Group& group = schedule().getGroup(gr_name, reportStepIdx);
const int np = this->wellState().numPhases();
@ -1513,6 +1517,7 @@ template<class Scalar>
Scalar BlackoilWellModelGeneric<Scalar>::
updateNetworkPressures(const int reportStepIdx, const Scalar damping_factor)
{
OPM_TIMEFUNCTION();
// Get the network and return if inactive (no wells in network at this time)
const auto& network = schedule()[reportStepIdx].network();
if (!network.active()) {

View File

@ -1079,6 +1079,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
doPreStepNetworkRebalance(DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const double dt = this->simulator_.timeStepSize();
// TODO: should we also have the group and network backed-up here in case the solution did not get converged?
auto& well_state = this->wellState();
@ -1122,6 +1123,7 @@ namespace Opm {
assemble(const int iterationIdx,
const double dt)
{
OPM_TIMEFUNCTION();
DeferredLogger local_deferredLogger;
if constexpr (BlackoilWellModelGasLift<TypeTag>::glift_debug) {
@ -1145,6 +1147,7 @@ namespace Opm {
}
if (iterationIdx == 0 && this->wellsActive()) {
OPM_TIMEBLOCK(firstIterationAssmble);
// try-catch is needed here as updateWellControls
// contains global communication and has either to
// be reached by all processes or all need to abort
@ -1185,6 +1188,7 @@ namespace Opm {
const double dt,
DeferredLogger& local_deferredLogger)
{
OPM_TIMEFUNCTION();
// not necessarily that we always need to update once of the network solutions
bool do_network_update = true;
bool well_group_control_changed = false;
@ -1224,6 +1228,7 @@ namespace Opm {
const double dt,
DeferredLogger& local_deferredLogger)
{
OPM_TIMEFUNCTION();
auto [well_group_control_changed, more_network_update] =
updateWellControls(mandatory_network_balance,
local_deferredLogger,
@ -1281,6 +1286,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
computeWellGroupThp(const double dt, DeferredLogger& local_deferredLogger)
{
OPM_TIMEFUNCTION();
const int reportStepIdx = this->simulator_.episodeIndex();
const auto& network = this->schedule()[reportStepIdx].network();
const auto& balance = this->schedule()[reportStepIdx].network_balance();
@ -1494,6 +1500,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
assembleWellEq(const double dt, DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
for (auto& well : well_container_) {
well->assembleWellEq(simulator_, dt, this->wellState(), this->groupState(), deferred_logger);
}
@ -1518,6 +1525,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
prepareWellsBeforeAssembling(const double dt, DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
for (auto& well : well_container_) {
well->prepareWellBeforeAssembling(simulator_, dt, this->wellState(), this->groupState(), deferred_logger);
}
@ -1529,6 +1537,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
assembleWellEqWithoutIteration(const double dt, DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
// We make sure that all processes throw in case there is an exception
// on one of them (WetGasPvt::saturationPressure might throw if not converged)
OPM_BEGIN_PARALLEL_TRY_CATCH();
@ -1892,6 +1901,7 @@ namespace Opm {
DeferredLogger& deferred_logger,
const bool relax_network_tolerance)
{
OPM_TIMEFUNCTION();
const int episodeIdx = simulator_.episodeIndex();
const auto& network = this->schedule()[episodeIdx].network();
if (!this->wellsActive() && !network.active()) {
@ -1905,6 +1915,7 @@ namespace Opm {
// network related
bool more_network_update = false;
if (this->shouldBalanceNetwork(episodeIdx, iterationIdx) || mandatory_network_balance) {
OPM_TIMEBLOCK(BalanceNetowork);
const double dt = this->simulator_.timeStepSize();
// Calculate common THP for subsea manifold well group (item 3 of NODEPROP set to YES)
bool well_group_thp_updated = computeWellGroupThp(dt, deferred_logger);
@ -1932,6 +1943,7 @@ namespace Opm {
// Check wells' group constraints and communicate.
bool changed_well_to_group = false;
{
OPM_TIMEBLOCK(UpdateWellControls);
// For MS Wells a linear solve is performed below and the matrix might be singular.
// We need to communicate the exception thrown to the others and rethrow.
OPM_BEGIN_PARALLEL_TRY_CATCH()
@ -2046,6 +2058,7 @@ namespace Opm {
const int reportStepIdx,
const int iterationIdx)
{
OPM_TIMEFUNCTION();
bool changed = false;
// restrict the number of group switches but only after nupcol iterations.
const int nupcol = this->schedule()[reportStepIdx].nupcol();
@ -2085,6 +2098,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
updateWellTestState(const double& simulationTime, WellTestState& wellTestState) const
{
OPM_TIMEFUNCTION();
DeferredLogger local_deferredLogger;
for (const auto& well : well_container_) {
const auto& wname = well->name();
@ -2145,6 +2159,7 @@ namespace Opm {
ExceptionType::ExcEnum& exc_type,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const int np = this->numPhases();
std::vector<Scalar> potentials;
const auto& well = well_container_[widx];

View File

@ -18,6 +18,7 @@
*/
#include <config.h>
#include <opm/common/TimingMacros.hpp>
#include <opm/simulators/wells/GasLiftSingleWellGeneric.hpp>
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
@ -138,6 +139,7 @@ std::unique_ptr<GasLiftWellState<Scalar>>
GasLiftSingleWellGeneric<Scalar>::
runOptimize(const int iteration_idx)
{
OPM_TIMEFUNCTION();
std::unique_ptr<GasLiftWellState<Scalar>> state;
if (this->optimize_) {
if (this->debug_limit_increase_decrease_) {
@ -430,6 +432,7 @@ std::optional<typename GasLiftSingleWellGeneric<Scalar>::BasicRates>
GasLiftSingleWellGeneric<Scalar>::
computeWellRatesWithALQ_(Scalar alq) const
{
OPM_TIMEFUNCTION();
std::optional<BasicRates> rates;
auto bhp_opt = computeBhpAtThpLimit_(alq);
if (bhp_opt) {
@ -1326,6 +1329,7 @@ std::unique_ptr<GasLiftWellState<Scalar>>
GasLiftSingleWellGeneric<Scalar>::
runOptimizeLoop_(bool increase)
{
OPM_TIMEFUNCTION();
if (this->debug)
debugShowProducerControlMode();
std::unique_ptr<GasLiftWellState<Scalar>> ret_value; // nullptr initially
@ -1364,6 +1368,7 @@ runOptimizeLoop_(bool increase)
state.stop_iteration = true;
}
while (!state.stop_iteration && (++state.it <= this->max_iterations_)) {
OPM_TIMEBLOCK(GasliftOptimizationLoopStage1);
if (state.checkRatesViolated(new_rates))
break;
if (state.checkAlqOutsideLimits(temp_alq, new_rates.oil))
@ -1443,6 +1448,7 @@ template<class Scalar>
std::unique_ptr<GasLiftWellState<Scalar>>
GasLiftSingleWellGeneric<Scalar>::runOptimize1_()
{
OPM_TIMEFUNCTION();
std::unique_ptr<GasLiftWellState<Scalar>> state;
int inc_count = this->well_state_.gliftGetAlqIncreaseCount(this->well_name_);
int dec_count = this->well_state_.gliftGetAlqDecreaseCount(this->well_name_);
@ -1465,6 +1471,7 @@ template<class Scalar>
std::unique_ptr<GasLiftWellState<Scalar>>
GasLiftSingleWellGeneric<Scalar>::runOptimize2_()
{
OPM_TIMEFUNCTION();
std::unique_ptr<GasLiftWellState<Scalar>> state;
state = tryIncreaseLiftGas_();
if (!state || !(state->alqChanged())) {

View File

@ -143,6 +143,7 @@ std::optional<typename GasLiftSingleWell<TypeTag>::Scalar>
GasLiftSingleWell<TypeTag>::
computeBhpAtThpLimit_(Scalar alq, bool debug_output) const
{
OPM_TIMEFUNCTION();
auto bhp_at_thp_limit = this->well_.computeBhpAtThpLimitProdWithAlq(
this->simulator_,
this->summary_state_,

View File

@ -18,6 +18,7 @@
*/
#include <config.h>
#include <opm/common/TimingMacros.hpp>
#include <opm/simulators/wells/GasLiftStage2.hpp>
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
@ -82,6 +83,7 @@ GasLiftStage2<Scalar>::GasLiftStage2(const int report_step_idx,
template<class Scalar>
void GasLiftStage2<Scalar>::runOptimize()
{
OPM_TIMEFUNCTION();
const auto& group = this->schedule_.getGroup("FIELD", this->report_step_idx_);
optimizeGroupsRecursive_(group);
}
@ -419,6 +421,7 @@ template<class Scalar>
void GasLiftStage2<Scalar>::
optimizeGroup_(const Group& group)
{
OPM_TIMEFUNCTION();
const auto& group_name = group.name();
const auto prod_control = this->group_state_.production_control(group_name);
if ((prod_control != Group::ProductionCMode::NONE) && (prod_control != Group::ProductionCMode::FLD))
@ -445,6 +448,7 @@ template<class Scalar>
void GasLiftStage2<Scalar>::
optimizeGroupsRecursive_(const Group& group)
{
OPM_TIMEFUNCTION();
for (const std::string& group_name : group.groups()) {
if(!this->schedule_.back().groups.has(group_name))
continue;
@ -568,6 +572,7 @@ redistributeALQ_(std::vector<GasLiftSingleWell*>& wells,
std::vector<GradPair>& inc_grads,
std::vector<GradPair>& dec_grads)
{
OPM_TIMEFUNCTION();
OptimizeState state {*this, group};
if (this->comm_.size() == 1) {
// NOTE: 'inc_grads' and 'dec_grads' can never grow larger than wells.size()
@ -634,6 +639,7 @@ void GasLiftStage2<Scalar>::
removeSurplusALQ_(const Group& group,
std::vector<GradPair>& dec_grads)
{
OPM_TIMEFUNCTION();
if (dec_grads.empty()) {
displayDebugMessage_("no wells to remove ALQ from. Skipping");
return;

View File

@ -394,6 +394,7 @@ namespace Opm
std::vector<Scalar>& well_flux,
DeferredLogger& deferred_logger) const
{
OPM_TIMEFUNCTION();
// 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
MultisegmentWell<TypeTag> well_copy(*this);
@ -2107,6 +2108,7 @@ namespace Opm
DeferredLogger& deferred_logger,
bool iterate_if_no_solution) const
{
OPM_TIMEFUNCTION();
// Make the frates() function.
auto frates = [this, &simulator, &deferred_logger](const Scalar bhp) {
// Not solving the well equations here, which means we are

View File

@ -1479,7 +1479,7 @@ namespace Opm
std::vector<Scalar>& well_flux,
DeferredLogger& deferred_logger) const
{
OPM_TIMEFUNCTION();
const int np = this->number_of_phases_;
well_flux.resize(np, 0.0);
@ -2237,6 +2237,7 @@ namespace Opm
DeferredLogger& deferred_logger,
bool iterate_if_no_solution) const
{
OPM_TIMEFUNCTION();
// Make the frates() function.
auto frates = [this, &simulator, &deferred_logger](const Scalar bhp) {
// Not solving the well equations here, which means we are

View File

@ -45,7 +45,7 @@
#include <opm/simulators/wells/VFPProdProperties.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/wells/GroupState.hpp>
#include <opm/common/TimingMacros.hpp>
#include <algorithm>
#include <cassert>
#include <cstddef>
@ -335,6 +335,7 @@ updateGuideRatesForInjectionGroups(const Group& group,
GuideRate* guideRate,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateGuideRatesForInjectionGroups(groupTmp, schedule, summaryState, pu, reportStepIdx, wellState, group_state, guideRate, deferred_logger);
@ -400,6 +401,7 @@ updateGroupTargetReduction(const Group& group,
GroupState<Scalar>& group_state,
std::vector<Scalar>& groupTargetReduction)
{
OPM_TIMEFUNCTION();
const int np = wellState.numPhases();
for (const std::string& subGroupName : group.groups()) {
std::vector<Scalar> subGroupTargetReduction(np, 0.0);
@ -544,6 +546,7 @@ updateWellRatesFromGroupTargetScale(const Scalar scale,
const GroupState<Scalar>& group_state,
WellState<Scalar>& wellState)
{
OPM_TIMEFUNCTION();
for (const std::string& groupName : group.groups()) {
bool individual_control = false;
if (isInjector) {
@ -614,6 +617,7 @@ updateVREPForGroups(const Group& group,
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state)
{
OPM_TIMEFUNCTION();
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateVREPForGroups(groupTmp, schedule, reportStepIdx, wellState, group_state);
@ -640,6 +644,7 @@ updateReservoirRatesInjectionGroups(const Group& group,
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state)
{
OPM_TIMEFUNCTION();
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateReservoirRatesInjectionGroups(groupTmp, schedule, reportStepIdx, wellState, group_state);
@ -666,6 +671,7 @@ updateSurfaceRatesInjectionGroups(const Group& group,
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state)
{
OPM_TIMEFUNCTION();
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateSurfaceRatesInjectionGroups(groupTmp, schedule, reportStepIdx, wellState, group_state);
@ -692,6 +698,7 @@ updateWellRates(const Group& group,
const WellState<Scalar>& wellStateNupcol,
WellState<Scalar>& wellState)
{
OPM_TIMEFUNCTION();
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateWellRates(groupTmp, schedule, reportStepIdx, wellStateNupcol, wellState);
@ -724,6 +731,7 @@ updateGroupProductionRates(const Group& group,
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state)
{
OPM_TIMEFUNCTION();
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateGroupProductionRates(groupTmp, schedule, reportStepIdx, wellState, group_state);
@ -747,6 +755,7 @@ updateREINForGroups(const Group& group,
GroupState<Scalar>& group_state,
bool sum_rank)
{
OPM_TIMEFUNCTION();
const int np = wellState.numPhases();
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
@ -781,6 +790,7 @@ updateGpMaintTargetForGroups(const Group& group,
const WellState<Scalar>& well_state,
GroupState<Scalar>& group_state)
{
OPM_TIMEFUNCTION();
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule.getGroup(groupName, reportStepIdx);
updateGpMaintTargetForGroups(groupTmp, schedule, regional_values, reportStepIdx, dt, well_state, group_state);
@ -875,7 +885,7 @@ computeNetworkPressures(const Network::ExtNetwork& network,
const int report_time_step)
{
// TODO: Only dealing with production networks for now.
OPM_TIMEFUNCTION();
if (!network.active()) {
return {};
}
@ -969,6 +979,7 @@ computeNetworkPressures(const Network::ExtNetwork& network,
const Scalar up_press = node_pressures[(*upbranch).uptree_node()];
const auto vfp_table = (*upbranch).vfp_table();
if (vfp_table) {
OPM_TIMEBLOCK(NetworkVfpCalculations);
// The rates are here positive, but the VFP code expects the
// convention that production rates are negative, so we must
// take a copy and flip signs.
@ -1153,6 +1164,7 @@ groupControlledWells(const Schedule& schedule,
const bool is_production_group,
const Phase injection_phase)
{
OPM_TIMEFUNCTION();
const Group& group = schedule.getGroup(group_name, report_step);
int num_wells = 0;
for (const std::string& child_group : group.groups()) {
@ -1330,6 +1342,7 @@ checkGroupConstraintsProd(const std::string& name,
// NOTE: if name is a group, the rates-argument is the portion of the 'full' group rates that
// is potentially available for control by an ancestor, i.e. full rates minus reduction rates
OPM_TIMEFUNCTION();
const Group::ProductionCMode& currentGroupControl = group_state.production_control(group.name());
if (currentGroupControl == Group::ProductionCMode::FLD || currentGroupControl == Group::ProductionCMode::NONE) {
@ -1803,6 +1816,7 @@ updateGuideRates(const Group& group,
std::vector<Scalar>& pot,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
guide_rate->updateGuideRateExpiration(sim_time, report_step);
updateGuideRateForProductionGroups(group, schedule, pu, report_step, sim_time, well_state, group_state, comm, guide_rate, pot);
updateGuideRatesForInjectionGroups(group, schedule, summary_state, pu, report_step, well_state, group_state, guide_rate, deferred_logger);
@ -1822,6 +1836,7 @@ updateGuideRateForProductionGroups(const Group& group,
GuideRate* guideRate,
std::vector<Scalar>& pot)
{
OPM_TIMEFUNCTION();
const int np = pu.num_phases;
for (const std::string& groupName : group.groups()) {
std::vector<Scalar> thisPot(np, 0.0);
@ -1899,6 +1914,7 @@ updateGuideRatesForWells(const Schedule& schedule,
const Parallel::Communication& comm,
GuideRate* guideRate)
{
OPM_TIMEFUNCTION();
for (const auto& well : schedule.getWells(reportStepIdx)) {
std::array<Scalar,3> potentials{};
auto& [oilpot, gaspot, waterpot] = potentials;

View File

@ -200,6 +200,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger) /* const */
{
OPM_TIMEFUNCTION();
if (stoppedOrZeroRateTarget(simulator, well_state, deferred_logger)) {
return false;
}
@ -282,6 +283,7 @@ namespace Opm
const bool fixed_control,
const bool fixed_status)
{
OPM_TIMEFUNCTION();
const auto& summary_state = simulator.vanguard().summaryState();
const auto& schedule = simulator.vanguard().schedule();
auto& ws = well_state.well(this->index_of_well_);
@ -389,6 +391,7 @@ namespace Opm
std::map<std::string, double>& open_times,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
deferred_logger.info(" well " + this->name() + " is being tested");
WellState<Scalar> well_state_copy = well_state;
@ -499,6 +502,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const auto& summary_state = simulator.vanguard().summaryState();
const auto inj_controls = this->well_ecl_.isInjector() ? this->well_ecl_.injectionControls(summary_state) : Well::InjectionControls(0);
const auto prod_controls = this->well_ecl_.isProducer() ? this->well_ecl_.productionControls(summary_state) : Well::ProductionControls(0);
@ -534,6 +538,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const auto& summary_state = simulator.vanguard().summaryState();
bool is_operable = true;
bool converged = true;
@ -629,6 +634,7 @@ namespace Opm
const SummaryState& summary_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
// Given an unconverged well or closed well, estimate an operable bhp (if any)
// Get minimal bhp from vfp-curve
Scalar bhp_min = WellBhpThpCalculator(*this).calculateMinimumBhpFromThp(well_state, this->well_ecl_, summary_state, this->getRefDensity());
@ -652,6 +658,7 @@ namespace Opm
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
// Solve a well using single bhp-constraint (but close if not operable under this)
auto group_state = GroupState<Scalar>(); // empty group
auto inj_controls = Well::InjectionControls(0);
@ -687,6 +694,7 @@ namespace Opm
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
// Solve a well as stopped
const auto well_status_orig = this->wellStatus_;
this->stopWell();
@ -707,6 +715,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
// keep a copy of the original well state
const WellState<Scalar> well_state0 = well_state;
const double dt = simulator.timeStepSize();
@ -740,6 +749,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
if (!this->isOperableAndSolvable() && !this->wellIsStopped())
return;
@ -798,6 +808,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
prepareWellBeforeAssembling(simulator, dt, well_state, group_state, deferred_logger);
assembleWellEqWithoutIteration(simulator, dt, well_state, group_state, deferred_logger);
}
@ -813,6 +824,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const auto& summary_state = simulator.vanguard().summaryState();
const auto inj_controls = this->well_ecl_.isInjector() ? this->well_ecl_.injectionControls(summary_state) : Well::InjectionControls(0);
const auto prod_controls = this->well_ecl_.isProducer() ? this->well_ecl_.productionControls(summary_state) : Well::ProductionControls(0);
@ -832,6 +844,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const bool old_well_operable = this->operability_status_.isOperableAndSolvable();
if (this->param_.check_well_operability_iter_)
@ -956,7 +969,7 @@ namespace Opm
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
if (!this->param_.check_well_operability_) {
return;
}
@ -983,6 +996,7 @@ namespace Opm
const GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const auto& well_name = this->name();
assert(this->wellHasTHPConstraints(simulator.vanguard().summaryState()));
const auto& schedule = simulator.vanguard().schedule();
@ -1018,6 +1032,7 @@ namespace Opm
GLiftEclWells& ecl_well_map,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
const auto& summary_state = simulator.vanguard().summaryState();
const auto& well_name = this->name();
if (!this->wellHasTHPConstraints(summary_state)) {
@ -1078,6 +1093,7 @@ namespace Opm
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
if (this->param_.local_well_solver_control_switching_) {
const bool success = updateWellOperabilityFromWellEq(simulator, well_state, deferred_logger);
if (success) {
@ -1114,6 +1130,7 @@ namespace Opm
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
{
OPM_TIMEFUNCTION();
// only makes sense if we're using this parameter is true
assert(this->param_.local_well_solver_control_switching_);
this->operability_status_.resetOperability();
@ -1133,7 +1150,7 @@ namespace Opm
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const
{
OPM_TIMEFUNCTION();
// only bhp and wellRates are used to initilize the primaryvariables for standard wells
const auto& well = this->well_ecl_;
const int well_index = this->index_of_well_;
@ -1511,6 +1528,7 @@ namespace Opm
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const
{
OPM_TIMEFUNCTION();
// Check if well is under zero rate control, either directly or from group
const bool isGroupControlled = this->wellUnderGroupControl(well_state.well(this->index_of_well_));
if (!isGroupControlled) {
@ -1559,6 +1577,7 @@ namespace Opm
initialWellRateFractions(const Simulator& simulator,
const WellState<Scalar>& well_state) const
{
OPM_TIMEFUNCTION();
const int np = this->number_of_phases_;
std::vector<Scalar> scaling_factor(np);
const auto& ws = well_state.well(this->index_of_well_);
@ -1607,6 +1626,7 @@ namespace Opm
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const
{
OPM_TIMEFUNCTION();
// Check if the rates of this well only are single-phase, do nothing
// if more than one nonzero rate.
auto& ws = well_state.well(this->index_of_well_);
@ -1657,6 +1677,7 @@ namespace Opm
const Scalar trans_mult,
const SingleWellState<Scalar>& ws) const
{
OPM_TIMEFUNCTION_LOCAL();
// Add a Forchheimer term to the gas phase CTF if the run uses
// either of the WDFAC or the WDFACCOR keywords.
if (static_cast<std::size_t>(perf) >= this->well_cells_.size()) {
@ -1920,6 +1941,7 @@ namespace Opm
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const
{
OPM_TIMEFUNCTION();
const auto& summary_state = simulator.vanguard().summaryState();
auto bhp_at_thp_limit = computeBhpAtThpLimitProdWithAlq(