Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When checking for zero target rates, also check wells under group control where required #5232

Merged
merged 2 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 8 additions & 15 deletions opm/simulators/wells/BlackoilWellModel_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ namespace Opm {
// This is done only for producers, as injectors will only have a single
// nonzero phase anyway.
for (auto& well : well_container_) {
const bool zero_target = well->stopppedOrZeroRateTarget(summaryState, this->wellState());
const bool zero_target = well->stoppedOrZeroRateTarget(simulator_, this->wellState(), local_deferredLogger);
if (well->isProducer() && !zero_target) {
well->updateWellStateRates(simulator_, this->wellState(), local_deferredLogger);
}
Expand Down Expand Up @@ -1076,8 +1076,7 @@ namespace Opm {
}
++iter;
for (auto& well : this->well_container_) {
const auto& summary_state = this->simulator_.vanguard().summaryState();
well->solveEqAndUpdateWellState(summary_state, well_state, deferred_logger);
well->solveEqAndUpdateWellState(simulator_, well_state, deferred_logger);
}
this->initPrimaryVariablesEvaluation();
} while (iter < max_iter);
Expand Down Expand Up @@ -1711,9 +1710,8 @@ namespace Opm {
DeferredLogger local_deferredLogger;
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
const auto& summary_state = simulator_.vanguard().summaryState();
for (auto& well : well_container_) {
well->recoverWellSolutionAndUpdateWellState(summary_state, x, this->wellState(), local_deferredLogger);
well->recoverWellSolutionAndUpdateWellState(simulator_, x, this->wellState(), local_deferredLogger);
}
}
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
Expand All @@ -1731,10 +1729,9 @@ namespace Opm {
// try/catch here, as this function is not called in
// parallel but for each individual domain of each rank.
DeferredLogger local_deferredLogger;
const auto& summary_state = this->simulator_.vanguard().summaryState();
for (auto& well : well_container_) {
if (well_domain_.at(well->name()) == domain.index) {
well->recoverWellSolutionAndUpdateWellState(summary_state, x,
well->recoverWellSolutionAndUpdateWellState(simulator_, x,
this->wellState(),
local_deferredLogger);
}
Expand Down Expand Up @@ -1782,15 +1779,14 @@ namespace Opm {
const std::vector<Scalar>& B_avg,
DeferredLogger& local_deferredLogger) const
{
const auto& summary_state = simulator_.vanguard().summaryState();
const int iterationIdx = simulator_.model().newtonMethod().numIterations();
const bool relax_tolerance = iterationIdx > param_.strict_outer_iter_wells_;

ConvergenceReport report;
for (const auto& well : well_container_) {
if ((well_domain_.at(well->name()) == domain.index)) {
if (well->isOperableAndSolvable() || well->wellIsStopped()) {
report += well->getWellConvergence(summary_state,
report += well->getWellConvergence(simulator_,
this->wellState(),
B_avg,
local_deferredLogger,
Expand Down Expand Up @@ -1833,9 +1829,8 @@ namespace Opm {
const int iterationIdx = simulator_.model().newtonMethod().numIterations();
for (const auto& well : well_container_) {
if (well->isOperableAndSolvable() || well->wellIsStopped()) {
const auto& summary_state = simulator_.vanguard().summaryState();
local_report += well->getWellConvergence(
summary_state, this->wellState(), B_avg, local_deferredLogger,
simulator_, this->wellState(), B_avg, local_deferredLogger,
iterationIdx > param_.strict_outer_iter_wells_);
} else {
ConvergenceReport report;
Expand Down Expand Up @@ -2356,8 +2351,7 @@ namespace Opm {
auto& events = this->wellState().well(well->indexOfWell()).events;
if (events.hasEvent(WellState<Scalar>::event_mask)) {
well->updateWellStateWithTarget(simulator_, this->groupState(), this->wellState(), deferred_logger);
const auto& summary_state = simulator_.vanguard().summaryState();
well->updatePrimaryVariables(summary_state, this->wellState(), deferred_logger);
well->updatePrimaryVariables(simulator_, this->wellState(), deferred_logger);
well->initPrimaryVariablesEvaluation();
// There is no new well control change input within a report step,
// so next time step, the well does not consider to have effective events anymore.
Expand Down Expand Up @@ -2441,8 +2435,7 @@ namespace Opm {
updatePrimaryVariables(DeferredLogger& deferred_logger)
{
for (const auto& well : well_container_) {
const auto& summary_state = simulator_.vanguard().summaryState();
well->updatePrimaryVariables(summary_state, this->wellState(), deferred_logger);
well->updatePrimaryVariables(simulator_, this->wellState(), deferred_logger);
}
}

Expand Down
10 changes: 5 additions & 5 deletions opm/simulators/wells/MultisegmentWell.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ namespace Opm {
DeferredLogger& deferred_logger) const override;

/// check whether the well equations get converged for this well
ConvergenceReport getWellConvergence(const SummaryState& summary_state,
ConvergenceReport getWellConvergence(const Simulator& simulator,
const WellState<Scalar>& well_state,
const std::vector<Scalar>& B_avg,
DeferredLogger& deferred_logger,
Expand All @@ -107,7 +107,7 @@ namespace Opm {

/// using the solution x to recover the solution xw for wells and applying
/// xw to update Well State
void recoverWellSolutionAndUpdateWellState(const SummaryState& summary_state,
void recoverWellSolutionAndUpdateWellState(const Simulator& simulator,
const BVector& x,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) override;
Expand All @@ -118,11 +118,11 @@ namespace Opm {
std::vector<Scalar>& well_potentials,
DeferredLogger& deferred_logger) override;

void updatePrimaryVariables(const SummaryState& summary_state,
void updatePrimaryVariables(const Simulator& simulator,
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) override;

void solveEqAndUpdateWellState(const SummaryState& summary_state,
void solveEqAndUpdateWellState(const Simulator& simulator,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) override; // const?

Expand Down Expand Up @@ -174,7 +174,7 @@ namespace Opm {
mutable int debug_cost_counter_ = 0;

// updating the well_state based on well solution dwells
void updateWellState(const SummaryState& summary_state,
void updateWellState(const Simulator& simulator,
const BVectorWell& dwells,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger,
Expand Down
3 changes: 2 additions & 1 deletion opm/simulators/wells/MultisegmentWellAssemble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ assembleControlEq(const WellState<Scalar>& well_state,
const Scalar rho,
const PrimaryVariables& primary_variables,
Equations& eqns1,
const bool stopped_or_zero_target,
DeferredLogger& deferred_logger) const
{
static constexpr int Gas = BlackoilPhases::Vapour;
Expand All @@ -116,7 +117,7 @@ assembleControlEq(const WellState<Scalar>& well_state,
return rates;
};

if (well_.stopppedOrZeroRateTarget(summaryState, well_state)) {
if (stopped_or_zero_target) {
control_eq = primary_variables.getWQTotal();
} else if (well_.isInjector() ) {
// Find scaling factor to get injection rate,
Expand Down
1 change: 1 addition & 0 deletions opm/simulators/wells/MultisegmentWellAssemble.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class MultisegmentWellAssemble
const Scalar rho,
const PrimaryVariables& primary_variables,
Equations& eqns,
const bool stopped_or_zero_target,
DeferredLogger& deferred_logger) const;

//! \brief Assemble piece of the acceleration term
Expand Down
51 changes: 28 additions & 23 deletions opm/simulators/wells/MultisegmentWell_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,11 @@ namespace Opm
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
updatePrimaryVariables(const SummaryState& summary_state,
updatePrimaryVariables(const Simulator& simulator,
const WellState<Scalar>& well_state,
DeferredLogger& /* deferred_logger */)
DeferredLogger& deferred_logger)
{
const bool stop_or_zero_rate_target = this->stopppedOrZeroRateTarget(summary_state, well_state);
const bool stop_or_zero_rate_target = this->stoppedOrZeroRateTarget(simulator, well_state, deferred_logger);
this->primary_variables_.update(well_state, stop_or_zero_rate_target);
}

Expand Down Expand Up @@ -199,7 +199,7 @@ namespace Opm
template <typename TypeTag>
ConvergenceReport
MultisegmentWell<TypeTag>::
getWellConvergence(const SummaryState& /* summary_state */,
getWellConvergence(const Simulator& /* simulator */,
const WellState<Scalar>& well_state,
const std::vector<Scalar>& B_avg,
DeferredLogger& deferred_logger,
Expand Down Expand Up @@ -260,7 +260,7 @@ namespace Opm
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
recoverWellSolutionAndUpdateWellState(const SummaryState& summary_state,
recoverWellSolutionAndUpdateWellState(const Simulator& simulator,
const BVector& x,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
Expand All @@ -271,7 +271,7 @@ namespace Opm

BVectorWell xw(1);
this->linSys_.recoverSolutionWell(x, xw);
updateWellState(summary_state, xw, well_state, deferred_logger);
updateWellState(simulator, xw, well_state, deferred_logger);
}


Expand Down Expand Up @@ -578,7 +578,7 @@ namespace Opm
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
solveEqAndUpdateWellState(const SummaryState& summary_state,
solveEqAndUpdateWellState(const Simulator& simulator,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
{
Expand All @@ -589,7 +589,7 @@ namespace Opm
try{
const BVectorWell dx_well = this->linSys_.solve();

updateWellState(summary_state, dx_well, well_state, deferred_logger);
updateWellState(simulator, dx_well, well_state, deferred_logger);
}
catch(const NumericalProblem& exp) {
// Add information about the well and log to deferred logger
Expand Down Expand Up @@ -681,7 +681,7 @@ namespace Opm
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
updateWellState(const SummaryState& summary_state,
updateWellState(const Simulator& simulator,
const BVectorWell& dwells,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger,
Expand All @@ -691,15 +691,20 @@ namespace Opm

const Scalar dFLimit = this->param_.dwell_fraction_max_;
const Scalar max_pressure_change = this->param_.max_pressure_change_ms_wells_;
const bool stop_or_zero_rate_target = this->stopppedOrZeroRateTarget(summary_state, well_state);
const bool stop_or_zero_rate_target =
this->stoppedOrZeroRateTarget(simulator, well_state, deferred_logger);
this->primary_variables_.updateNewton(dwells,
relaxation_factor,
dFLimit,
stop_or_zero_rate_target,
max_pressure_change);

this->primary_variables_.copyToWellState(*this, getRefDensity(), stop_or_zero_rate_target,
well_state, summary_state, deferred_logger);
const auto& summary_state = simulator.vanguard().summaryState();
this->primary_variables_.copyToWellState(*this, getRefDensity(),
stop_or_zero_rate_target,
well_state,
summary_state,
deferred_logger);

{
auto& ws = well_state.well(this->index_of_well_);
Expand All @@ -720,8 +725,7 @@ namespace Opm
const WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
{
const auto& summary_state = simulator.vanguard().summaryState();
updatePrimaryVariables(summary_state, well_state, deferred_logger);
updatePrimaryVariables(simulator, well_state, deferred_logger);
initPrimaryVariablesEvaluation();
computePerfCellPressDiffs(simulator);
computeInitialSegmentFluids(simulator);
Expand Down Expand Up @@ -1489,8 +1493,7 @@ namespace Opm
this->regularize_ = true;
}

const auto& summary_state = simulator.vanguard().summaryState();
const auto report = getWellConvergence(summary_state, well_state, Base::B_avg_, deferred_logger, relax_convergence);
const auto report = getWellConvergence(simulator, well_state, Base::B_avg_, deferred_logger, relax_convergence);
if (report.converged()) {
converged = true;
break;
Expand Down Expand Up @@ -1526,7 +1529,7 @@ namespace Opm
++stagnate_count;
if (stagnate_count == 6) {
sstr << " well " << this->name() << " observes severe stagnation and/or oscillation. We relax the tolerance and check for convergence. \n";
const auto reportStag = getWellConvergence(summary_state, well_state, Base::B_avg_, deferred_logger, true);
const auto reportStag = getWellConvergence(simulator, well_state, Base::B_avg_, deferred_logger, true);
if (reportStag.converged()) {
converged = true;
sstr << " well " << this->name() << " manages to get converged with relaxed tolerances in " << it << " inner iterations";
Expand All @@ -1553,7 +1556,7 @@ namespace Opm
this->regularize_ = true;
deferred_logger.debug(sstr.str());
}
updateWellState(summary_state, dx_well, well_state, deferred_logger, relaxation_factor);
updateWellState(simulator, dx_well, well_state, deferred_logger, relaxation_factor);
initPrimaryVariablesEvaluation();
}

Expand Down Expand Up @@ -1635,7 +1638,7 @@ namespace Opm
const bool allow_open = this->well_ecl_.getStatus() == WellStatus::OPEN &&
well_state.well(this->index_of_well_).status == WellStatus::OPEN;
// don't allow switcing for wells under zero rate target or requested fixed status and control
const bool allow_switching = !this->wellUnderZeroRateTarget(summary_state, well_state) &&
const bool allow_switching = !this->wellUnderZeroRateTarget(simulator, well_state, deferred_logger) &&
(!fixed_control || !fixed_status) && allow_open;
bool changed = false;
bool final_check = false;
Expand Down Expand Up @@ -1673,7 +1676,7 @@ namespace Opm
this->regularize_ = true;
}

const auto report = getWellConvergence(summary_state, well_state, Base::B_avg_, deferred_logger, relax_convergence);
const auto report = getWellConvergence(simulator, well_state, Base::B_avg_, deferred_logger, relax_convergence);
converged = report.converged();
if (converged) {
// if equations are sufficiently linear they might converge in less than min_its_after_switch
Expand Down Expand Up @@ -1717,7 +1720,7 @@ namespace Opm
if (false) { // this disables the usage of the relaxed tolerance
fmt::format_to(std::back_inserter(message), " Well {} observes severe stagnation and/or oscillation."
" We relax the tolerance and check for convergence. \n", this->name());
const auto reportStag = getWellConvergence(summary_state, well_state, Base::B_avg_,
const auto reportStag = getWellConvergence(simulator, well_state, Base::B_avg_,
deferred_logger, true);
if (reportStag.converged()) {
converged = true;
Expand Down Expand Up @@ -1745,7 +1748,7 @@ namespace Opm
deferred_logger.debug(message);
}
}
updateWellState(summary_state, dx_well, well_state, deferred_logger, relaxation_factor);
updateWellState(simulator, dx_well, well_state, deferred_logger, relaxation_factor);
initPrimaryVariablesEvaluation();
}

Expand Down Expand Up @@ -1906,10 +1909,11 @@ namespace Opm
}
}

// the fourth dequation, the pressure drop equation
// the fourth equation, the pressure drop equation
if (seg == 0) { // top segment, pressure equation is the control equation
const auto& summaryState = simulator.vanguard().summaryState();
const Schedule& schedule = simulator.vanguard().schedule();
const bool stopped_or_zero_target = this->stoppedOrZeroRateTarget(simulator, well_state, deferred_logger);
MultisegmentWellAssemble(*this).
assembleControlEq(well_state,
group_state,
Expand All @@ -1920,6 +1924,7 @@ namespace Opm
getRefDensity(),
this->primary_variables_,
this->linSys_,
stopped_or_zero_target,
deferred_logger);
} else {
const UnitSystem& unit_system = simulator.vanguard().eclState().getDeckUnitSystem();
Expand Down