check controls in getWellConvergence

This commit is contained in:
Tor Harald Sandve 2022-09-09 14:23:20 +02:00
parent 36ca7d11e9
commit d25dc4e795
5 changed files with 67 additions and 21 deletions

View File

@ -982,7 +982,7 @@ namespace Opm {
// Get convergence reports for reservoir and wells.
std::vector<Scalar> B_avg(numEq, 0.0);
auto report = getReservoirConvergence(timer.currentStepLength(), iteration, B_avg, residual_norms);
report += wellModel().getWellConvergence(B_avg);
report += wellModel().getWellConvergence(B_avg, /*checkWellGroupControls*/report.converged());
return report;
}

View File

@ -260,7 +260,7 @@ namespace Opm {
void applyScaleAdd(const Scalar alpha, const BVector& x, BVector& Ax) const;
// Check if well equations is converged.
ConvergenceReport getWellConvergence(const std::vector<Scalar>& B_avg, const bool checkGroupConvergence = false) const;
ConvergenceReport getWellConvergence(const std::vector<Scalar>& B_avg, const bool checkWellGroupControls = false);
const SimulatorReportSingle& lastReport() const;
@ -280,8 +280,12 @@ namespace Opm {
// at the beginning of each time step (Not report step)
void prepareTimeStep(DeferredLogger& deferred_logger);
void initPrimaryVariablesEvaluation() const;
<<<<<<< HEAD
bool shouldBalanceNetwork(const int reportStepIndex, const int iterationIdx) const;
std::pair<bool, double> updateWellControls(DeferredLogger& deferred_logger, const bool checkGroupControls);
=======
bool updateWellControls(DeferredLogger& deferred_logger);
>>>>>>> check controls in getWellConvergence
void updateAndCommunicate(const int reportStepIdx,
const int iterationIdx,

View File

@ -899,7 +899,7 @@ namespace Opm {
DeferredLogger& local_deferredLogger)
{
const auto [network_changed, network_imbalance] = updateWellControls(local_deferredLogger, /* check group controls */ true);
const auto [network_changed, network_imbalance] = updateWellControls(local_deferredLogger);
bool alq_updated = false;
OPM_BEGIN_PARALLEL_TRY_CATCH();
@ -1389,7 +1389,7 @@ namespace Opm {
template<typename TypeTag>
ConvergenceReport
BlackoilWellModel<TypeTag>::
getWellConvergence(const std::vector<Scalar>& B_avg, bool checkGroupConvergence) const
getWellConvergence(const std::vector<Scalar>& B_avg, bool checkWellGroupControls)
{
DeferredLogger local_deferredLogger;
@ -1406,7 +1406,7 @@ namespace Opm {
local_report += report;
}
}
const Opm::Parallel::Communication comm = grid().comm();
DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm);
if (terminal_output_) {
@ -1415,6 +1415,10 @@ namespace Opm {
ConvergenceReport report = gatherConvergenceReport(local_report, comm);
if (report.converged() && checkWellGroupControls) {
bool violated = updateWellControls(local_deferredLogger);
report.setGroupConverged(!violated);
}
// Log debug messages for NaN or too large residuals.
if (terminal_output_) {
for (const auto& f : report.wellFailures()) {
@ -1425,15 +1429,6 @@ namespace Opm {
}
}
}
if (checkGroupConvergence) {
const int reportStepIdx = ebosSimulator_.episodeIndex();
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
bool violated = checkGroupConstraints(fieldGroup,
ebosSimulator_.episodeIndex(),
global_deferredLogger);
report.setGroupConverged(!violated);
}
return report;
}
@ -1458,6 +1453,7 @@ namespace Opm {
template<typename TypeTag>
bool
<<<<<<< HEAD
BlackoilWellModel<TypeTag>::
shouldBalanceNetwork(const int reportStepIdx, const int iterationIdx) const
{
@ -1482,13 +1478,19 @@ namespace Opm {
template<typename TypeTag>
std::pair<bool, double>
=======
>>>>>>> check controls in getWellConvergence
BlackoilWellModel<TypeTag>::
updateWellControls(DeferredLogger& deferred_logger, const bool checkGroupControls)
updateWellControls(DeferredLogger& deferred_logger)
{
// Even if there are no wells active locally, we cannot
// return as the DeferredLogger uses global communication.
// For no well active globally we simply return.
<<<<<<< HEAD
if( !wellsActive() ) return { false, 0.0 };
=======
if( !wellsActive() ) return false ;
>>>>>>> check controls in getWellConvergence
const int episodeIdx = ebosSimulator_.episodeIndex();
const int iterationIdx = ebosSimulator_.model().newtonMethod().numIterations();
@ -1502,6 +1504,7 @@ namespace Opm {
const double network_imbalance = comm.max(local_network_imbalance);
std::set<std::string> switched_wells;
<<<<<<< HEAD
if (checkGroupControls) {
@ -1522,10 +1525,42 @@ namespace Opm {
switched_wells.insert(well->name());
changed_well_group = changed_well || changed_well_group;
}
=======
bool changed = false;
// Check group individual constraints.
bool changed_individual = updateGroupIndividualControls(deferred_logger,
episodeIdx, iterationIdx);
if (changed_individual) {
updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
changed = true;
}
// Check group's constraints from higher levels.
bool changed_higher = updateGroupHigherControls(deferred_logger,
episodeIdx);
if (changed_higher) {
updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
changed = true;
}
// Check wells' group constraints and communicate.
bool changed_well_group = false;
for (const auto& well : well_container_) {
const auto mode = WellInterface<TypeTag>::IndividualOrGroup::Group;
const bool changed_well = well->updateWellControl(ebosSimulator_, mode, this->wellState(), this->groupState(), deferred_logger);
if (changed_well) {
switched_wells.insert(well->name());
changed_well_group = changed_well || changed_well_group;
>>>>>>> check controls in getWellConvergence
}
changed_well_group = comm.sum(changed_well_group);
if (changed_well_group)
updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
}
changed_well_group = comm.sum(changed_well_group);
if (changed_well_group) {
updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
changed = true;
}
// Check individual well constraints and communicate.
@ -1541,14 +1576,21 @@ namespace Opm {
}
}
changed_well_individual = comm.sum(changed_well_individual);
if (changed_well_individual)
if (changed_well_individual) {
updateAndCommunicate(episodeIdx, iterationIdx, deferred_logger);
changed = true;
}
// update wsolvent fraction for REIN wells
const Group& fieldGroup = schedule().getGroup("FIELD", episodeIdx);
updateWsolvent(fieldGroup, episodeIdx, this->nupcolWellState());
<<<<<<< HEAD
return { network_changed, network_imbalance };
=======
return changed;
>>>>>>> check controls in getWellConvergence
}

View File

@ -230,7 +230,7 @@ namespace Opm
const GroupState& group_state,
DeferredLogger& deferred_logger) /* const */
{
if (this->wellIsStopped()) {
if (!this->isOperableAndSolvable() || this->wellIsStopped()) {
return false;
}

View File

@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(G1)
Opm::DeferredLogger deferred_logger;
well_model.calculateExplicitQuantities(deferred_logger);
well_model.prepareTimeStep(deferred_logger);
well_model.updateWellControls(deferred_logger, /* check group controls */ true);
well_model.updateWellControls(deferred_logger);
well_model.initPrimaryVariablesEvaluation();
Opm::WellInterface<TypeTag> *well_ptr = well_model.getWell("B-1H").get();
StdWell *std_well = dynamic_cast<StdWell *>(well_ptr);