mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge ad0c6c4c53
into 4b688e5945
This commit is contained in:
commit
77b95eebcf
@ -507,7 +507,7 @@ namespace Opm {
|
||||
|
||||
if (event || dyn_status_change) {
|
||||
try {
|
||||
well->updateWellStateWithTarget(simulator_, this->groupState(), this->wellState(), local_deferredLogger);
|
||||
well->updateWellStateWithTarget(simulator_, this->groupState(), this->wellState(), local_deferredLogger, /*initialize*/ true);
|
||||
well->calculateExplicitQuantities(simulator_, this->wellState(), local_deferredLogger);
|
||||
well->solveWellEquation(simulator_, this->wellState(), this->groupState(), local_deferredLogger);
|
||||
} catch (const std::exception& e) {
|
||||
@ -1846,7 +1846,7 @@ namespace Opm {
|
||||
ws.injection_cmode == Well::InjectorCMode::GRUP)
|
||||
{
|
||||
well->updateWellStateWithTarget(simulator_, this->groupState(),
|
||||
this->wellState(), deferred_logger);
|
||||
this->wellState(), deferred_logger, /*initialize*/ false);
|
||||
}
|
||||
}
|
||||
OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::updateAndCommunicate failed: ",
|
||||
@ -2067,7 +2067,7 @@ namespace Opm {
|
||||
for (const auto& well : well_container_) {
|
||||
auto& events = this->wellState().well(well->indexOfWell()).events;
|
||||
if (events.hasEvent(WellState<Scalar>::event_mask)) {
|
||||
well->updateWellStateWithTarget(simulator_, this->groupState(), this->wellState(), deferred_logger);
|
||||
well->updateWellStateWithTarget(simulator_, this->groupState(), this->wellState(), deferred_logger, /*initialize*/ true);
|
||||
well->updatePrimaryVariables(simulator_, this->wellState(), deferred_logger);
|
||||
// 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.
|
||||
|
@ -90,7 +90,8 @@ namespace Opm {
|
||||
void updateWellStateWithTarget(const Simulator& simulator,
|
||||
const GroupState<Scalar>& group_state,
|
||||
WellState<Scalar>& well_state,
|
||||
DeferredLogger& deferred_logger) const override;
|
||||
DeferredLogger& deferred_logger,
|
||||
const bool initialize = true) override;
|
||||
|
||||
/// check whether the well equations get converged for this well
|
||||
ConvergenceReport getWellConvergence(const Simulator& simulator,
|
||||
|
@ -169,15 +169,18 @@ namespace Opm
|
||||
updateWellStateWithTarget(const Simulator& simulator,
|
||||
const GroupState<Scalar>& group_state,
|
||||
WellState<Scalar>& well_state,
|
||||
DeferredLogger& deferred_logger) const
|
||||
DeferredLogger& deferred_logger,
|
||||
const bool initialize)
|
||||
{
|
||||
Base::updateWellStateWithTarget(simulator, group_state, well_state, deferred_logger);
|
||||
Base::updateWellStateWithTarget(simulator, group_state, well_state, deferred_logger, initialize);
|
||||
// scale segment rates based on the wellRates
|
||||
// and segment pressure based on bhp
|
||||
this->scaleSegmentRatesWithWellRates(this->segments_.inlets(),
|
||||
this->segments_.perforations(),
|
||||
well_state);
|
||||
this->scaleSegmentPressuresWithBhp(well_state);
|
||||
if (initialize) {
|
||||
this->scaleSegmentRatesWithWellRates(this->segments_.inlets(),
|
||||
this->segments_.perforations(),
|
||||
well_state);
|
||||
this->scaleSegmentPressuresWithBhp(well_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,7 +215,8 @@ public:
|
||||
virtual void updateWellStateWithTarget(const Simulator& simulator,
|
||||
const GroupState<Scalar>& group_state,
|
||||
WellState<Scalar>& well_state,
|
||||
DeferredLogger& deferred_logger) const;
|
||||
DeferredLogger& deferred_logger,
|
||||
const bool initialize = true);
|
||||
|
||||
virtual void computeWellRatesWithBhpIterations(const Simulator& simulator,
|
||||
const Scalar& bhp,
|
||||
|
@ -263,7 +263,7 @@ namespace Opm
|
||||
deferred_logger.debug(ss.str());
|
||||
|
||||
this->well_control_log_.push_back(from);
|
||||
updateWellStateWithTarget(simulator, group_state, well_state, deferred_logger);
|
||||
updateWellStateWithTarget(simulator, group_state, well_state, deferred_logger, /*initialize*/ false);
|
||||
updatePrimaryVariables(simulator, well_state, deferred_logger);
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ namespace Opm
|
||||
ws.production_cmode == Well::ProducerCMode::THP;
|
||||
if (!thp_controlled){
|
||||
// don't call for thp since this might trigger additional local solve
|
||||
updateWellStateWithTarget(simulator, group_state, well_state, deferred_logger);
|
||||
updateWellStateWithTarget(simulator, group_state, well_state, deferred_logger, /*initialize*/ false);
|
||||
} else {
|
||||
ws.thp = this->getTHPConstraint(summary_state);
|
||||
}
|
||||
@ -397,7 +397,7 @@ namespace Opm
|
||||
WellState<Scalar> well_state_copy = well_state;
|
||||
auto& ws = well_state_copy.well(this->indexOfWell());
|
||||
|
||||
updateWellStateWithTarget(simulator, group_state, well_state_copy, deferred_logger);
|
||||
updateWellStateWithTarget(simulator, group_state, well_state_copy, deferred_logger, /*initialize*/ true);
|
||||
calculateExplicitQuantities(simulator, well_state_copy, deferred_logger);
|
||||
updatePrimaryVariables(simulator, well_state_copy, deferred_logger);
|
||||
|
||||
@ -1147,7 +1147,8 @@ namespace Opm
|
||||
updateWellStateWithTarget(const Simulator& simulator,
|
||||
const GroupState<Scalar>& group_state,
|
||||
WellState<Scalar>& well_state,
|
||||
DeferredLogger& deferred_logger) const
|
||||
DeferredLogger& deferred_logger,
|
||||
const bool initialize)
|
||||
{
|
||||
OPM_TIMEFUNCTION();
|
||||
// only bhp and wellRates are used to initilize the primaryvariables for standard wells
|
||||
@ -1221,39 +1222,42 @@ namespace Opm
|
||||
}
|
||||
|
||||
case Well::InjectorCMode::THP:
|
||||
{
|
||||
auto rates = ws.surface_rates;
|
||||
Scalar bhp = WellBhpThpCalculator(*this).calculateBhpFromThp(well_state,
|
||||
rates,
|
||||
well,
|
||||
summaryState,
|
||||
this->getRefDensity(),
|
||||
deferred_logger);
|
||||
ws.bhp = bhp;
|
||||
{
|
||||
ws.thp = this->getTHPConstraint(summaryState);
|
||||
|
||||
// if the total rates are negative or zero
|
||||
// we try to provide a better intial well rate
|
||||
// using the well potentials
|
||||
Scalar total_rate = std::accumulate(rates.begin(), rates.end(), 0.0);
|
||||
if (total_rate <= 0.0)
|
||||
ws.surface_rates = ws.well_potentials;
|
||||
if (initialize) {
|
||||
auto rates = ws.surface_rates;
|
||||
Scalar bhp = WellBhpThpCalculator(*this).calculateBhpFromThp(well_state,
|
||||
rates,
|
||||
well,
|
||||
summaryState,
|
||||
this->getRefDensity(),
|
||||
deferred_logger);
|
||||
ws.bhp = bhp;
|
||||
|
||||
// if the total rates are negative or zero
|
||||
// we try to provide a better intial well rate
|
||||
// using the well potentials
|
||||
Scalar total_rate = std::accumulate(rates.begin(), rates.end(), 0.0);
|
||||
if (total_rate <= 0.0)
|
||||
ws.surface_rates = ws.well_potentials;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Well::InjectorCMode::BHP:
|
||||
{
|
||||
ws.bhp = controls.bhp_limit;
|
||||
Scalar total_rate = 0.0;
|
||||
for (int p = 0; p<np; ++p) {
|
||||
total_rate += ws.surface_rates[p];
|
||||
if (initialize) {
|
||||
Scalar total_rate = 0.0;
|
||||
for (int p = 0; p<np; ++p) {
|
||||
total_rate += ws.surface_rates[p];
|
||||
}
|
||||
// if the total rates are negative or zero
|
||||
// we try to provide a better intial well rate
|
||||
// using the well potentials
|
||||
if (total_rate <= 0.0)
|
||||
ws.surface_rates = ws.well_potentials;
|
||||
}
|
||||
// if the total rates are negative or zero
|
||||
// we try to provide a better intial well rate
|
||||
// using the well potentials
|
||||
if (total_rate <= 0.0)
|
||||
ws.surface_rates = ws.well_potentials;
|
||||
|
||||
break;
|
||||
}
|
||||
case Well::InjectorCMode::GRUP:
|
||||
@ -1441,41 +1445,53 @@ namespace Opm
|
||||
case Well::ProducerCMode::BHP:
|
||||
{
|
||||
ws.bhp = controls.bhp_limit;
|
||||
Scalar total_rate = 0.0;
|
||||
for (int p = 0; p<np; ++p) {
|
||||
total_rate -= ws.surface_rates[p];
|
||||
}
|
||||
// if the total rates are negative or zero
|
||||
// we try to provide a better intial well rate
|
||||
// using the well potentials
|
||||
if (total_rate <= 0.0){
|
||||
if (initialize) {
|
||||
Scalar total_rate = 0.0;
|
||||
for (int p = 0; p<np; ++p) {
|
||||
ws.surface_rates[p] = -ws.well_potentials[p];
|
||||
total_rate -= ws.surface_rates[p];
|
||||
}
|
||||
// if the total rates are negative or zero
|
||||
// we try to provide a better intial well rate
|
||||
// using the well potentials
|
||||
if (total_rate <= 0.0){
|
||||
for (int p = 0; p<np; ++p) {
|
||||
ws.surface_rates[p] = -ws.well_potentials[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Well::ProducerCMode::THP:
|
||||
{
|
||||
const bool update_success = updateWellStateWithTHPTargetProd(simulator, well_state, deferred_logger);
|
||||
|
||||
if (!update_success) {
|
||||
// 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
|
||||
auto rates = ws.surface_rates;
|
||||
this->adaptRatesForVFP(rates);
|
||||
const Scalar bhp = WellBhpThpCalculator(*this).calculateBhpFromThp(
|
||||
well_state, rates, well, summaryState, this->getRefDensity(), deferred_logger);
|
||||
ws.bhp = bhp;
|
||||
ws.thp = this->getTHPConstraint(summaryState);
|
||||
// if the total rates are negative or zero
|
||||
// we try to provide a better initial well rate
|
||||
// using the well potentials
|
||||
const Scalar total_rate = -std::accumulate(rates.begin(), rates.end(), 0.0);
|
||||
if (total_rate <= 0.0) {
|
||||
for (int p = 0; p < this->number_of_phases_; ++p) {
|
||||
ws.surface_rates[p] = -ws.well_potentials[p];
|
||||
{
|
||||
ws.thp = this->getTHPConstraint(summaryState);
|
||||
if (initialize) {
|
||||
const double dt = simulator.timeStepSize();
|
||||
auto bhp_target = estimateOperableBhp(simulator, dt, well_state, summaryState, deferred_logger);
|
||||
if (bhp_target.has_value()) {
|
||||
const Scalar bhp = std::max(bhp_target.value(), static_cast<Scalar>(controls.bhp_limit));
|
||||
solveWellWithBhp(simulator, dt, bhp, well_state, deferred_logger);
|
||||
} else {
|
||||
deferred_logger.debug("Did not find operable bhp for well " + this->name() + ", re-trying initialization." );
|
||||
const bool update_success = updateWellStateWithTHPTargetProd(simulator, well_state, deferred_logger);
|
||||
if (!update_success) {
|
||||
// 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
|
||||
auto rates = ws.surface_rates;
|
||||
this->adaptRatesForVFP(rates);
|
||||
const Scalar bhp = WellBhpThpCalculator(*this).calculateBhpFromThp(
|
||||
well_state, rates, well, summaryState, this->getRefDensity(), deferred_logger);
|
||||
ws.bhp = bhp;
|
||||
|
||||
// if the total rates are negative or zero
|
||||
// we try to provide a better initial well rate
|
||||
// using the well potentials
|
||||
const Scalar total_rate = -std::accumulate(rates.begin(), rates.end(), 0.0);
|
||||
if (total_rate <= 0.0) {
|
||||
for (int p = 0; p < this->number_of_phases_; ++p) {
|
||||
ws.surface_rates[p] = -ws.well_potentials[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user