mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
we need to open the cross-flow to solve the sigularity
if a well is banned from cross-flow. When it is under RATE control, its BHP might be initialized in way causing all the drawdown in the wrong direction. It will cause singular well equations. here, we open the croff-flow to fix the singularity and rely on Newton iteraton to get desired result. possible alternative approach is to adust the BHP to avoid the situation that all the drawdown are in the wrong direction.
This commit is contained in:
parent
bba373c0b5
commit
90f805bf3e
@ -433,10 +433,9 @@ namespace Opm {
|
||||
|
||||
const Well* well_ecl = wells_ecl_[index_well];
|
||||
|
||||
// TODO: a new WCON keyword can re-open the well closed by physical reason
|
||||
// A new WCON keywords can re-open a well that was closed/shut due to Physical limit
|
||||
if ( wellTestState_.hasWell(well_name, WellTestConfig::Reason::PHYSICAL ) ) {
|
||||
// TODO: more checking here, to makre sure this standard more specific and complete
|
||||
// TODO: more checking here, to make sure this standard more specific and complete
|
||||
// maybe there is some WCON keywords will not open the well
|
||||
if (well_state_.effectiveEventsOccurred(w) ) {
|
||||
wellTestState_.openWell(well_name);
|
||||
@ -449,6 +448,7 @@ namespace Opm {
|
||||
wellTestState_.hasWell(well_name, WellTestConfig::Reason::PHYSICAL) ) {
|
||||
if( well_ecl->getAutomaticShutIn() ) {
|
||||
// shut wells are not added to the well container
|
||||
// TODO: make a function from well_state side to handle the following
|
||||
well_state_.thp()[w] = 0.;
|
||||
well_state_.bhp()[w] = 0.;
|
||||
const int np = numPhases();
|
||||
@ -954,7 +954,7 @@ namespace Opm {
|
||||
prepareGroupControl();
|
||||
|
||||
for (const auto& well : well_container_) {
|
||||
well->checkWellOperatability(ebosSimulator_);
|
||||
well->checkWellOperability(ebosSimulator_);
|
||||
}
|
||||
|
||||
// since the controls are all updated, we should update well_state accordingly
|
||||
@ -973,7 +973,7 @@ namespace Opm {
|
||||
// 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
|
||||
// TODO: if we can know whether this is the first time step within the report step,
|
||||
// we do not need to change this
|
||||
// we do not need to set it to false
|
||||
// TODO: we should do this at the end of the time step in case we will need it within
|
||||
// this time step somewhere
|
||||
if (well_state_.effectiveEventsOccurred(w) ) {
|
||||
|
@ -332,7 +332,7 @@ namespace Opm
|
||||
|
||||
// checking the operability of the well based on current reservoir condition
|
||||
// it is not implemented for multisegment well yet
|
||||
virtual void checkWellOperatability(const Simulator& ebos_simulator);
|
||||
virtual void checkWellOperability(const Simulator& ebos_simulator);
|
||||
|
||||
void updateWellStateFromPrimaryVariables(WellState& well_state) const;
|
||||
|
||||
|
@ -1645,10 +1645,10 @@ namespace Opm
|
||||
template <typename TypeTag>
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
checkWellOperatability(const Simulator& ebos_simulator)
|
||||
checkWellOperability(const Simulator& ebos_simulator)
|
||||
{
|
||||
const std::string msg = "Support of well operatability checking for mutlisegment wells is not yet,"
|
||||
" checkWellOperatability() for " + name() + " will do nothing";
|
||||
const std::string msg = "Support of well operatability checking for mutlisegment wells is not implemented "
|
||||
"yet, checkWellOperability() for " + name() + " will do nothing";
|
||||
OpmLog::warning("NO_OPERATABILITY_CHECKING_MS_WELLS", msg);
|
||||
}
|
||||
|
||||
|
@ -350,7 +350,7 @@ namespace Opm
|
||||
|
||||
// check whether the well is operable under the current reservoir condition
|
||||
// mostly related to BHP limit and THP limit
|
||||
virtual void checkWellOperatability(const Simulator& ebos_simulator) override;
|
||||
virtual void checkWellOperability(const Simulator& ebos_simulator) override;
|
||||
|
||||
// check whether the well is operable under BHP limit with current reservoir condition
|
||||
void checkOperabilityUnderBHPLimit(const Simulator& ebos_simulator);
|
||||
@ -367,7 +367,14 @@ namespace Opm
|
||||
|
||||
// for a well, when all drawdown are in the wrong direction, then this well will not
|
||||
// be able to produce/inject .
|
||||
bool allDrawDownWrongDirection(const Simulator& ebosSimulator) const;
|
||||
bool allDrawDownWrongDirection(const Simulator& ebos_simulator) const;
|
||||
|
||||
// turn on crossflow to avoid singular well equations
|
||||
// when the well is banned from cross-flow and the BHP is not properly initialized,
|
||||
// we turn on crossflow to avoid singular well equations. It can result in worng-signed
|
||||
// well rates, it can cause problem for THP calculation
|
||||
// TODO: looking for better alternative to avoid wrong-signed well rates
|
||||
bool openCrossFlowAvoidSingularity(const Simulator& ebos_simulator) const;
|
||||
|
||||
// calculate the BHP from THP target based on IPR
|
||||
// TODO: we need to check the operablility here first, if not operable, then maybe there is
|
||||
|
@ -440,7 +440,7 @@ namespace Opm
|
||||
WellState& well_state)
|
||||
{
|
||||
|
||||
checkWellOperatability(ebosSimulator);
|
||||
checkWellOperability(ebosSimulator);
|
||||
|
||||
if (!this->isOperable()) return;
|
||||
|
||||
@ -453,7 +453,11 @@ namespace Opm
|
||||
// TODO: it probably can be static member for StandardWell
|
||||
const double volume = 0.002831684659200; // 0.1 cu ft;
|
||||
|
||||
const bool allow_cf = getAllowCrossFlow();
|
||||
// to avoid singularity of the well equation when all the drawdown is in the wrong direction
|
||||
// TODO: make it a function, and avoid repeated calculation
|
||||
// TODO: it can be avoided through adjusting the bhp of the well
|
||||
const bool allow_cf = getAllowCrossFlow() || openCrossFlowAvoidSingularity(ebosSimulator);
|
||||
|
||||
|
||||
const EvalWell& bhp = getBhp();
|
||||
|
||||
@ -1293,12 +1297,12 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
void
|
||||
StandardWell<TypeTag>::
|
||||
checkWellOperatability(const Simulator& ebos_simulator)
|
||||
checkWellOperability(const Simulator& ebos_simulator)
|
||||
{
|
||||
// TODO: this function is probably can split another function out so that
|
||||
// wellTestingPhysical can share some code with this function
|
||||
// on solution is that this function will be called updateWellOperatability
|
||||
// and the actual checking part become another function checkWellOperatability
|
||||
// on solution is that this function will be called updateWellOperability
|
||||
// and the actual checking part become another function checkWellOperability
|
||||
// Let us wait until finishing the wellTestingPhysical first.
|
||||
|
||||
// focusing on PRODUCER for now
|
||||
@ -1428,13 +1432,13 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
bool
|
||||
StandardWell<TypeTag>::
|
||||
allDrawDownWrongDirection(const Simulator& ebosSimulator) const
|
||||
allDrawDownWrongDirection(const Simulator& ebos_simulator) const
|
||||
{
|
||||
bool all_drawdown_wrong_direction = true;
|
||||
|
||||
for (int perf = 0; perf < number_of_perforations_; ++perf) {
|
||||
const int cell_idx = well_cells_[perf];
|
||||
const auto& intQuants = *(ebosSimulator.model().cachedIntensiveQuantities(cell_idx, /*timeIdx=*/0));
|
||||
const auto& intQuants = *(ebos_simulator.model().cachedIntensiveQuantities(cell_idx, /*timeIdx=*/0));
|
||||
const auto& fs = intQuants.fluidState();
|
||||
|
||||
const double pressure = (fs.pressure(FluidSystem::oilPhaseIdx)).value();
|
||||
@ -1461,6 +1465,18 @@ namespace Opm
|
||||
|
||||
|
||||
|
||||
template<typename TypeTag>
|
||||
bool
|
||||
StandardWell<TypeTag>::
|
||||
openCrossFlowAvoidSingularity(const Simulator& ebos_simulator) const
|
||||
{
|
||||
return !getAllowCrossFlow() && allDrawDownWrongDirection(ebos_simulator);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename TypeTag>
|
||||
void
|
||||
StandardWell<TypeTag>::
|
||||
@ -2494,7 +2510,8 @@ namespace Opm
|
||||
return;
|
||||
}
|
||||
// compute the well water velocity with out shear effects.
|
||||
const bool allow_cf = getAllowCrossFlow();
|
||||
// TODO: do we need to turn on crossflow here?
|
||||
const bool allow_cf = getAllowCrossFlow() || openCrossFlowAvoidSingularity(ebos_simulator);
|
||||
const EvalWell& bhp = getBhp();
|
||||
std::vector<EvalWell> cq_s(num_components_,0.0);
|
||||
double perf_dis_gas_rate = 0.;
|
||||
|
@ -223,7 +223,7 @@ namespace Opm
|
||||
|
||||
void updatePerforatedCell(std::vector<bool>& is_cell_perforated);
|
||||
|
||||
virtual void checkWellOperatability(const Simulator& ebos_simulator) = 0;
|
||||
virtual void checkWellOperability(const Simulator& ebos_simulator) = 0;
|
||||
|
||||
// whether the well is operable
|
||||
bool isOperable() const;
|
||||
|
Loading…
Reference in New Issue
Block a user