mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
cleanup thp-solve
This commit is contained in:
parent
3e6732a67b
commit
44e17fa615
@ -430,13 +430,13 @@ protected:
|
|||||||
const GroupState& group_state,
|
const GroupState& group_state,
|
||||||
DeferredLogger& deferred_logger);
|
DeferredLogger& deferred_logger);
|
||||||
|
|
||||||
bool robustWellSolveWithTHP(const Simulator& ebos_simulator,
|
bool solveWellWithTHPConstraint(const Simulator& ebos_simulator,
|
||||||
const double dt,
|
const double dt,
|
||||||
const Well::InjectionControls& inj_controls,
|
const Well::InjectionControls& inj_controls,
|
||||||
const Well::ProductionControls& prod_controls,
|
const Well::ProductionControls& prod_controls,
|
||||||
WellState& well_state,
|
WellState& well_state,
|
||||||
const GroupState& group_state,
|
const GroupState& group_state,
|
||||||
DeferredLogger& deferred_logger);
|
DeferredLogger& deferred_logger);
|
||||||
|
|
||||||
std::optional<double> estimateOperableBhp(const Simulator& ebos_simulator,
|
std::optional<double> estimateOperableBhp(const Simulator& ebos_simulator,
|
||||||
const double dt,
|
const double dt,
|
||||||
|
@ -462,10 +462,11 @@ namespace Opm
|
|||||||
converged = this->iterateWellEqWithControl(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
converged = this->iterateWellEqWithControl(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
||||||
} else {
|
} else {
|
||||||
if (this->well_ecl_.isProducer() && this->wellHasTHPConstraints(summary_state)) {
|
if (this->well_ecl_.isProducer() && this->wellHasTHPConstraints(summary_state)) {
|
||||||
converged = robustWellSolveWithTHP(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
converged = solveWellWithTHPConstraint(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
||||||
} else {
|
} else {
|
||||||
converged = this->iterateWellEqWithSwitching(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
converged = this->iterateWellEqWithSwitching(ebosSimulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
||||||
}
|
}
|
||||||
|
this->updateIPRImplicit(ebosSimulator, well_state, deferred_logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (NumericalProblem& e ) {
|
} catch (NumericalProblem& e ) {
|
||||||
@ -479,99 +480,97 @@ namespace Opm
|
|||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
bool
|
bool
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
robustWellSolveWithTHP(const Simulator& ebos_simulator,
|
solveWellWithTHPConstraint(const Simulator& ebos_simulator,
|
||||||
const double dt,
|
const double dt,
|
||||||
const Well::InjectionControls& inj_controls,
|
const Well::InjectionControls& inj_controls,
|
||||||
const Well::ProductionControls& prod_controls,
|
const Well::ProductionControls& prod_controls,
|
||||||
WellState& well_state,
|
WellState& well_state,
|
||||||
const GroupState& group_state,
|
const GroupState& group_state,
|
||||||
DeferredLogger& deferred_logger)
|
DeferredLogger& deferred_logger)
|
||||||
{
|
{
|
||||||
const auto& summary_state = ebos_simulator.vanguard().summaryState();
|
const auto& summary_state = ebos_simulator.vanguard().summaryState();
|
||||||
bool is_operable = true;
|
bool is_operable = true;
|
||||||
bool converged;
|
bool converged = true;
|
||||||
|
auto& ws = well_state.well(this->index_of_well_);
|
||||||
|
// if well is stopped, check if we can reopen
|
||||||
if (this->wellIsStopped()) {
|
if (this->wellIsStopped()) {
|
||||||
this->openWell();
|
this->openWell();
|
||||||
auto bhp_target = estimateOperableBhp(ebos_simulator, dt, well_state, group_state, summary_state, deferred_logger);
|
auto bhp_target = estimateOperableBhp(ebos_simulator, dt, well_state, group_state, summary_state, deferred_logger);
|
||||||
if (!bhp_target.has_value()) {
|
if (!bhp_target.has_value()) {
|
||||||
// well can't operate using explicit fractions
|
// no intersection with ipr
|
||||||
is_operable = false;
|
is_operable = false;
|
||||||
// XXX convereged = true - iterate with closed well!
|
// solve with zero rates
|
||||||
converged = solveWellWithZeroRate(ebos_simulator, dt, well_state, deferred_logger);
|
converged = solveWellWithZeroRate(ebos_simulator, dt, well_state, deferred_logger);
|
||||||
|
this->stopWell();
|
||||||
} else {
|
} else {
|
||||||
converged = solveWellWithBhp(ebos_simulator, dt, bhp_target.value(), well_state, deferred_logger);
|
// solve well with the estimated target bhp (or limit)
|
||||||
|
const double bhp = std::max(bhp_target.value(), prod_controls.bhp_limit);
|
||||||
|
converged = solveWellWithBhp(ebos_simulator, dt, bhp, well_state, deferred_logger);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
// solve well-equation
|
||||||
|
if (is_operable) {
|
||||||
converged = this->iterateWellEqWithSwitching(ebos_simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
converged = this->iterateWellEqWithSwitching(ebos_simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
||||||
}
|
}
|
||||||
if (converged && !this->stopppedOrZeroRateTarget(summary_state, well_state) && well_state.well(this->index_of_well_).production_cmode == Well::ProducerCMode::THP) {
|
|
||||||
auto rates = well_state.well(this->index_of_well_).surface_rates;
|
|
||||||
this->adaptRatesForVFP(rates);
|
|
||||||
// FIX !!!!!!!!!!
|
|
||||||
// first, check just dbhp/dflo
|
|
||||||
|
|
||||||
// update ipr for stability-check
|
const bool isThp = ws.production_cmode == Well::ProducerCMode::THP;
|
||||||
this->updateIPRImplicit(ebos_simulator, well_state, deferred_logger);
|
// check stability of solution under thp-control
|
||||||
bool is_stable = WellBhpThpCalculator(*this).isStableSolution(well_state, this->well_ecl_, rates, summary_state, deferred_logger);
|
if (true) {
|
||||||
if (!is_stable) {
|
if (converged && !this->stopppedOrZeroRateTarget(summary_state, well_state) && isThp) {
|
||||||
// solution converged to an unstable point!
|
auto rates = well_state.well(this->index_of_well_).surface_rates;
|
||||||
this->operability_status_.use_vfpexplicit = true;
|
this->adaptRatesForVFP(rates);
|
||||||
auto bhp_stable = WellBhpThpCalculator(*this).estimateStableBhp(well_state, this->well_ecl_, rates, this->getRefDensity(), summary_state, deferred_logger);
|
this->updateIPRImplicit(ebos_simulator, well_state, deferred_logger);
|
||||||
if (!bhp_stable.has_value()) {
|
bool is_stable = WellBhpThpCalculator(*this).isStableSolution(well_state, this->well_ecl_, rates, summary_state, deferred_logger);
|
||||||
// well is not operable (no intersection)
|
if (!is_stable) {
|
||||||
// XXX convereged = true - iterate with closed well!
|
// solution converged to an unstable point!
|
||||||
//is_operable = false;
|
this->operability_status_.use_vfpexplicit = true;
|
||||||
//converged = solveWellWithZeroRate(ebos_simulator, dt, well_state, deferred_logger);
|
// msg = ...
|
||||||
} else {
|
auto bhp_stable = WellBhpThpCalculator(*this).estimateStableBhp(well_state, this->well_ecl_, rates, this->getRefDensity(), summary_state, deferred_logger);
|
||||||
// solve equations for bhp_stable (in attempt to get closer to actual solution)
|
// if we find an intersection with a sufficiently lower bhp, re-solve equations
|
||||||
const bool converged_bhp = solveWellWithBhp(ebos_simulator, dt, bhp_stable.value(), well_state, deferred_logger);
|
const bool reltol = 1e-3;
|
||||||
this->updateIPRImplicit(ebos_simulator, well_state, deferred_logger);
|
const double cur_bhp = ws.bhp;
|
||||||
auto bhp_stable1 = WellBhpThpCalculator(*this).estimateStableBhp(well_state, this->well_ecl_, rates, this->getRefDensity(), summary_state, deferred_logger);
|
if (bhp_stable.has_value() && cur_bhp - bhp_stable.value() > cur_bhp*reltol){
|
||||||
const bool converged_bhp1 = solveWellWithBhp(ebos_simulator, dt, bhp_stable.value(), well_state, deferred_logger);
|
const bool converged_bhp = solveWellWithBhp(ebos_simulator, dt, bhp_stable.value(), well_state, deferred_logger);
|
||||||
if (!converged_bhp) {
|
// re-solve with hopefully good initial guess
|
||||||
//
|
ws.thp = this->getTHPConstraint(summary_state);
|
||||||
} else {
|
|
||||||
// re-solve well equations
|
|
||||||
// XXX reset thp
|
|
||||||
well_state.well(this->index_of_well_).thp = this->getTHPConstraint(summary_state);
|
|
||||||
converged = this->iterateWellEqWithSwitching(ebos_simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
converged = this->iterateWellEqWithSwitching(ebos_simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!converged) {
|
}
|
||||||
|
|
||||||
|
if (!converged) {
|
||||||
// Well did not converge, switch to explicit fractions
|
// Well did not converge, switch to explicit fractions
|
||||||
this->operability_status_.use_vfpexplicit = true;
|
this->operability_status_.use_vfpexplicit = true;
|
||||||
//auto well_state_copy = well_state;
|
|
||||||
//
|
|
||||||
this->openWell();
|
this->openWell();
|
||||||
auto bhp_target = estimateOperableBhp(ebos_simulator, dt, well_state, group_state, summary_state, deferred_logger);
|
auto bhp_target = estimateOperableBhp(ebos_simulator, dt, well_state, group_state, summary_state, deferred_logger);
|
||||||
if (!bhp_target.has_value()) {
|
if (!bhp_target.has_value()) {
|
||||||
// well can't operate using explicit fractions
|
// well can't operate using explicit fractions
|
||||||
is_operable = false;
|
is_operable = false;
|
||||||
// XXX convereged = true - iterate with closed well!
|
// solve with zero rate
|
||||||
converged = solveWellWithZeroRate(ebos_simulator, dt, well_state, deferred_logger);
|
converged = solveWellWithZeroRate(ebos_simulator, dt, well_state, deferred_logger);
|
||||||
|
this->stopWell();
|
||||||
} else {
|
} else {
|
||||||
// first solve well equations for bhp = bhp_target which should give solution close to actual
|
// solve well with the estimated target bhp (or limit)
|
||||||
converged = solveWellWithBhp(ebos_simulator, dt, bhp_target.value(), well_state, deferred_logger);
|
const double bhp = std::max(bhp_target.value(), prod_controls.bhp_limit);
|
||||||
|
const bool converged_bhp = solveWellWithBhp(ebos_simulator, dt, bhp, well_state, deferred_logger);
|
||||||
|
ws.thp = this->getTHPConstraint(summary_state);
|
||||||
|
converged = this->iterateWellEqWithSwitching(ebos_simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
||||||
|
/*
|
||||||
if (!converged) {
|
if (!converged) {
|
||||||
// debug
|
// debug
|
||||||
} else {
|
} else {
|
||||||
// re-solve well equations
|
// re-solve well equations
|
||||||
// XXX reset thp
|
// XXX reset thp
|
||||||
well_state.well(this->index_of_well_).thp = this->getTHPConstraint(summary_state);
|
well_state.well(this->index_of_well_).thp = this->getTHPConstraint(summary_state);
|
||||||
converged = this->iterateWellEqWithSwitching(ebos_simulator, dt, inj_controls, prod_controls, well_state, group_state, deferred_logger);
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_operable) {
|
// update operability
|
||||||
this->stopWell();
|
this->operability_status_.can_obtain_bhp_with_thp_limit = is_operable;
|
||||||
if (this->wellHasTHPConstraints(summary_state)){
|
this->operability_status_.obey_thp_limit_under_bhp_limit = is_operable;
|
||||||
this->operability_status_.can_obtain_bhp_with_thp_limit = false;
|
|
||||||
this->operability_status_.obey_thp_limit_under_bhp_limit = false;
|
|
||||||
} else {
|
|
||||||
this->operability_status_.operable_under_only_bhp_limit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return converged;
|
return converged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user