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

For testing: Combines fixes and hacks for network #6015

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions opm/simulators/flow/BlackoilModelParameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ BlackoilModelParameters<Scalar>::BlackoilModelParameters()
local_domain_partition_imbalance_ = std::max(Scalar{1.0}, Parameters::Get<Parameters::LocalDomainsPartitioningImbalance<Scalar>>());
local_domain_partition_method_ = Parameters::Get<Parameters::LocalDomainsPartitioningMethod>();
deck_file_name_ = Parameters::Get<Parameters::EclDeckFileName>();
network_max_strict_iterations_ = Parameters::Get<Parameters::NetworkMaxStrictIterations>();
network_max_iterations_ = Parameters::Get<Parameters::NetworkMaxIterations>();
network_max_strict_iterations_ = Parameters::Get<Parameters::NetworkMaxStrictOuterIterations>();
network_max_outer_iterations_ = Parameters::Get<Parameters::NetworkMaxOuterIterations>();
network_max_sub_iterations_ = Parameters::Get<Parameters::NetworkMaxSubIterations>();
network_pressure_update_damping_factor_ = Parameters::Get<Parameters::NetworkPressureUpdateDampingFactor<Scalar>>();
network_max_pressure_update_in_bars_ = Parameters::Get<Parameters::NetworkMaxPressureUpdateInBars<Scalar>>();
Expand Down Expand Up @@ -219,10 +219,10 @@ void BlackoilModelParameters<Scalar>::registerParameters()
("Compute implict IPR for stability checks and stable solution search");
Parameters::Register<Parameters::CheckGroupConstraintsInnerWellIterations>
("Allow checking of group constraints during inner well iterations");
Parameters::Register<Parameters::NetworkMaxStrictIterations>
("Maximum iterations in network solver before relaxing tolerance");
Parameters::Register<Parameters::NetworkMaxIterations>
("Maximum number of iterations in the network solver before giving up");
Parameters::Register<Parameters::NetworkMaxStrictOuterIterations>
("Maximum outer iterations in network solver before relaxing tolerance");
Parameters::Register<Parameters::NetworkMaxOuterIterations>
("Maximum outer number of iterations in the network solver before giving up");
Parameters::Register<Parameters::NetworkMaxSubIterations>
("Maximum number of sub-iterations to update network pressures (within a single well/group control update)");
Parameters::Register<Parameters::NetworkPressureUpdateDampingFactor<Scalar>>
Expand Down
6 changes: 3 additions & 3 deletions opm/simulators/flow/BlackoilModelParameters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ struct UseImplicitIpr { static constexpr bool value = true; };
struct CheckGroupConstraintsInnerWellIterations { static constexpr bool value = true; };

// Network solver parameters
struct NetworkMaxStrictIterations { static constexpr int value = 10; };
struct NetworkMaxIterations { static constexpr int value = 20; };
struct NetworkMaxStrictOuterIterations { static constexpr int value = 3; };
struct NetworkMaxOuterIterations { static constexpr int value = 3; };
struct NetworkMaxSubIterations { static constexpr int value = 20; };
template<class Scalar>
struct NetworkPressureUpdateDampingFactor { static constexpr Scalar value = 0.1; };
Expand Down Expand Up @@ -300,7 +300,7 @@ struct BlackoilModelParameters
int network_max_strict_iterations_;

/// Maximum number of iterations in the network solver before giving up
int network_max_iterations_;
int network_max_outer_iterations_;

/// Maximum number of sub-iterations to update network pressures (within a single well/group control update)
int network_max_sub_iterations_;
Expand Down
12 changes: 4 additions & 8 deletions opm/simulators/wells/BlackoilWellModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ template<class Scalar> class WellContributions;
void prepareTimeStep(DeferredLogger& deferred_logger);

std::pair<bool, bool>
updateWellControls(const bool mandatory_network_balance, DeferredLogger& deferred_logger, const bool relax_network_tolerance = false);
updateWellControls(DeferredLogger& deferred_logger, const bool relax_network_tolerance = false);

void updateAndCommunicate(const int reportStepIdx,
const int iterationIdx,
Expand Down Expand Up @@ -396,9 +396,6 @@ template<class Scalar> class WellContributions;

SimulatorReportSingle last_report_{};

// Pre-step network solve at static reservoir conditions (group and well states might be updated)
void doPreStepNetworkRebalance(DeferredLogger& deferred_logger);

std::vector<Scalar> B_avg_{};

const EquilGrid& equilGrid() const
Expand All @@ -416,13 +413,12 @@ template<class Scalar> class WellContributions;
// the function handles one iteration of updating well controls and network pressures.
// it is possible to decouple the update of well controls and network pressures further.
// the returned two booleans are {continue_due_to_network, well_group_control_changed}, respectively
std::pair<bool, bool> updateWellControlsAndNetworkIteration(const bool mandatory_network_balance,
const bool relax_network_tolerance,
std::pair<bool, bool> updateWellControlsAndNetworkIteration(const bool relax_network_tolerance,
const double dt,
DeferredLogger& local_deferredLogger);

bool updateWellControlsAndNetwork(const bool mandatory_network_balance,
const double dt,
bool updateWellControlsAndNetwork(const double dt,
const int iterationIdx,
DeferredLogger& local_deferredLogger);

double computeWellGroupTarget(DeferredLogger& local_deferredLogger);
Expand Down
111 changes: 44 additions & 67 deletions opm/simulators/wells/BlackoilWellModel_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1076,48 +1076,6 @@ namespace Opm {



template<typename TypeTag>
void
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();
const std::size_t max_iter = param_.network_max_iterations_;
bool converged = false;
std::size_t iter = 0;
bool changed_well_group = false;
do {
changed_well_group = updateWellControlsAndNetwork(true, dt, deferred_logger);
assembleWellEqWithoutIteration(dt, deferred_logger);
converged = this->getWellConvergence(this->B_avg_, true).converged() && !changed_well_group;
if (converged) {
break;
}
++iter;
OPM_BEGIN_PARALLEL_TRY_CATCH();
for (auto& well : this->well_container_) {
well->solveEqAndUpdateWellState(simulator_, well_state, deferred_logger);
}
OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::doPreStepNetworkRebalance() failed: ",
this->simulator_.vanguard().grid().comm());
} while (iter < max_iter);

if (!converged) {
const std::string msg = fmt::format("Initial (pre-step) network balance did not get converged with {} iterations, "
"unconverged network balance result will be used", max_iter);
deferred_logger.warning(msg);
} else {
const std::string msg = fmt::format("Initial (pre-step) network balance converged with {} iterations", iter);
deferred_logger.debug(msg);
}
}




template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
Expand Down Expand Up @@ -1163,7 +1121,7 @@ namespace Opm {
this->terminal_output_, grid().comm());
}

const bool well_group_control_changed = updateWellControlsAndNetwork(false, dt, local_deferredLogger);
const bool well_group_control_changed = updateWellControlsAndNetwork(dt, iterationIdx, local_deferredLogger);

// even when there is no wells active, the network nodal pressure still need to be updated through updateWellControlsAndNetwork()
// but there is no need to assemble the well equations
Expand All @@ -1185,8 +1143,8 @@ namespace Opm {
template<typename TypeTag>
bool
BlackoilWellModel<TypeTag>::
updateWellControlsAndNetwork(const bool mandatory_network_balance,
const double dt,
updateWellControlsAndNetwork(const double dt,
const int iterationIdx,
DeferredLogger& local_deferredLogger)
{
OPM_TIMEFUNCTION();
Expand All @@ -1196,24 +1154,30 @@ namespace Opm {
// after certain number of the iterations, we use relaxed tolerance for the network update
const std::size_t iteration_to_relax = param_.network_max_strict_iterations_;
// after certain number of the iterations, we terminate
const std::size_t max_iteration = param_.network_max_iterations_;
const std::size_t max_iteration = param_.network_max_outer_iterations_;
std::size_t network_update_iteration = 0;
const int episodeIdx = simulator_.episodeIndex();
while (do_network_update) {
if (network_update_iteration >= max_iteration ) {
// only output to terminal if we at the last newton iterations where we try to balance the network.
if (this->shouldBalanceNetwork(episodeIdx, iterationIdx + 1)) {
local_deferredLogger.debug("maximum of " + std::to_string(max_iteration) + " network iterations has been used, we stop the update \n "
" and try again after the next newton iteration.");
} else {
if (this->terminal_output_) {
local_deferredLogger.info("maximum of " + std::to_string(max_iteration) + " network iterations has been used and we stop the update. "
"The simulator will continue with unconverged network results.");
}
}
break;
}
if (this->terminal_output_ && (network_update_iteration == iteration_to_relax) ) {
local_deferredLogger.info(" we begin using relaxed tolerance for network update now after " + std::to_string(iteration_to_relax) + " iterations ");
}
const bool relax_network_balance = network_update_iteration >= iteration_to_relax;
std::tie(do_network_update, well_group_control_changed) =
updateWellControlsAndNetworkIteration(mandatory_network_balance, relax_network_balance, dt,local_deferredLogger);
updateWellControlsAndNetworkIteration(relax_network_balance, dt,local_deferredLogger);
++network_update_iteration;

if (network_update_iteration >= max_iteration ) {
if (this->terminal_output_) {
local_deferredLogger.info("maximum of " + std::to_string(max_iteration) + " iterations has been used, we stop the network update now. "
"The simulation will continue with unconverged network results");
}
break;
}
}
return well_group_control_changed;
}
Expand All @@ -1224,15 +1188,13 @@ namespace Opm {
template<typename TypeTag>
std::pair<bool, bool>
BlackoilWellModel<TypeTag>::
updateWellControlsAndNetworkIteration(const bool mandatory_network_balance,
const bool relax_network_tolerance,
updateWellControlsAndNetworkIteration(const bool relax_network_tolerance,
const double dt,
DeferredLogger& local_deferredLogger)
{
OPM_TIMEFUNCTION();
auto [well_group_control_changed, more_network_update] =
updateWellControls(mandatory_network_balance,
local_deferredLogger,
auto [well_group_control_changed, inner_network_not_balanced] =
updateWellControls(local_deferredLogger,
relax_network_tolerance);

bool alq_updated = false;
Expand Down Expand Up @@ -1272,7 +1234,11 @@ namespace Opm {
pot,
local_deferredLogger);
}

// we need to re-iterate the network when the well group controls changed or gaslift/alq is changed or
// the inner iterations are did not converge
const int iterationIdx = simulator_.model().newtonMethod().numIterations();
bool more_network_update = this->shouldBalanceNetwork(reportStepIdx, iterationIdx) &&
(inner_network_not_balanced || well_group_control_changed || alq_updated);
return {more_network_update, well_group_control_changed};
}

Expand Down Expand Up @@ -1726,8 +1692,7 @@ namespace Opm {
template<typename TypeTag>
std::pair<bool, bool>
BlackoilWellModel<TypeTag>::
updateWellControls(const bool mandatory_network_balance,
DeferredLogger& deferred_logger,
updateWellControls(DeferredLogger& deferred_logger,
const bool relax_network_tolerance)
{
OPM_TIMEFUNCTION();
Expand All @@ -1743,7 +1708,7 @@ namespace Opm {

// network related
bool more_network_update = false;
if (this->shouldBalanceNetwork(episodeIdx, iterationIdx) || mandatory_network_balance) {
if (this->shouldBalanceNetwork(episodeIdx, iterationIdx)) {
OPM_TIMEBLOCK(BalanceNetowork);
const double dt = this->simulator_.timeStepSize();
// Calculate common THP for subsea manifold well group (item 3 of NODEPROP set to YES)
Expand All @@ -1761,6 +1726,21 @@ namespace Opm {
more_network_sub_update = this->networkActive() && network_imbalance > tolerance;
if (!more_network_sub_update)
break;

for (const auto& well : well_container_) {
if (well->isInjector() || !well->wellEcl().predictionMode())
continue;

const auto it = this->node_pressures_.find(well->wellEcl().groupName());
if (it != this->node_pressures_.end()) {
const auto& ws = this->wellState().well(well->indexOfWell());
const bool thp_is_limit = ws.production_cmode == Well::ProducerCMode::THP;
if (thp_is_limit) {
well->prepareWellBeforeAssembling(this->simulator_, dt, this->wellState(), this->groupState(), deferred_logger);
}
}
}
this->updateAndCommunicateGroupData(episodeIdx, iterationIdx, param_.nupcol_group_rate_tolerance_, deferred_logger);
}
more_network_update = more_network_sub_update || well_group_thp_updated;
}
Expand Down Expand Up @@ -2091,9 +2071,6 @@ namespace Opm {
well->resetWellOperability();
}
updatePrimaryVariables(deferred_logger);

// Actually do the pre-step network rebalance, using the updated well states and initial solutions
if (do_prestep_network_rebalance) doPreStepNetworkRebalance(deferred_logger);
}

template<typename TypeTag>
Expand Down
6 changes: 5 additions & 1 deletion opm/simulators/wells/MultisegmentWell_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,8 @@ namespace Opm
sstr << " well " << this->name() << " manages to get converged with relaxed tolerances in " << it << " inner iterations";
deferred_logger.debug(sstr.str());
return converged;
} else {
return false;
}
}
}
Expand Down Expand Up @@ -1728,7 +1730,7 @@ namespace Opm
std::string message;
if (relaxation_factor == min_relaxation_factor) {
++stagnate_count;
if (false) { // this disables the usage of the relaxed tolerance
if (stagnate_count == 6) { // 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(simulator, well_state, Base::B_avg_,
Expand All @@ -1738,6 +1740,8 @@ namespace Opm
fmt::format_to(std::back_inserter(message), " Well {} manages to get converged with relaxed tolerances in {} inner iterations", this->name(), it);
deferred_logger.debug(message);
return converged;
} else {
return false;
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion opm/simulators/wells/WellConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ activeProductionConstraint(const SingleWellState<Scalar>& ws,
if (well_.wellHasTHPConstraints(summaryState) && currentControl != Well::ProducerCMode::THP) {
const auto& thp = well_.getTHPConstraint(summaryState);
Scalar current_thp = ws.thp;
if (thp > current_thp && !ws.trivial_target) {
const bool dont_check = (currentControl == Well::ProducerCMode::GRUP && ws.trivial_target);
if (thp > current_thp && !dont_check) {
// If WVFPEXP item 4 is set to YES1 or YES2
// switching to THP is prevented if the well will
// produce at a higher rate with THP control
Expand Down
4 changes: 2 additions & 2 deletions opm/simulators/wells/WellInterface_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1457,9 +1457,9 @@ namespace Opm
}
case Well::ProducerCMode::THP:
{
const bool update_success = updateWellStateWithTHPTargetProd(simulator, well_state, deferred_logger);
//const bool update_success = updateWellStateWithTHPTargetProd(simulator, well_state, deferred_logger);

if (!update_success) {
if (true) {
// the following is the original way of initializing well state with THP constraint
// keeping it for robust reason in case that it fails to get a bhp value with THP constraint
// more sophisticated design might be needed in the future
Expand Down
2 changes: 1 addition & 1 deletion tests/test_glift1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(G1)
Opm::DeferredLogger deferred_logger;
well_model.calculateExplicitQuantities(deferred_logger);
well_model.prepareTimeStep(deferred_logger);
well_model.updateWellControls(false, deferred_logger);
well_model.updateWellControls(deferred_logger);
Opm::WellInterface<TypeTag> *well_ptr = well_model.getWell("B-1H").get();
StdWell *std_well = dynamic_cast<StdWell *>(well_ptr);

Expand Down