mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #3547 from totto82/makeWTESTrobust
Make wtest more robust
This commit is contained in:
commit
0b8778e432
@ -273,7 +273,7 @@ partiallySupported()
|
|||||||
{
|
{
|
||||||
"WTEST",
|
"WTEST",
|
||||||
{
|
{
|
||||||
{3,{false, allow_values<std::string> {"E", ""}, "WTEST(TEST): only the E (economic) option is currently supported – will continue"}}, // REASON
|
{3,{false, allow_values<std::string> {"E", "P", ""}, "WTEST(TEST): only the E (economic) and P (physical) option is currently supported – will continue"}}, // REASON
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -382,12 +382,10 @@ namespace Opm {
|
|||||||
{
|
{
|
||||||
const auto& wtest_config = schedule()[timeStepIdx].wtest_config();
|
const auto& wtest_config = schedule()[timeStepIdx].wtest_config();
|
||||||
if (wtest_config.size() != 0) { // there is a WTEST request
|
if (wtest_config.size() != 0) { // there is a WTEST request
|
||||||
const auto wellsForTesting = wellTestState()
|
const std::vector<std::string> wellsForTesting = wellTestState()
|
||||||
.updateWells(wtest_config, wells_ecl_, simulationTime);
|
.updateWells(wtest_config, wells_ecl_, simulationTime);
|
||||||
|
|
||||||
for (const auto& testWell : wellsForTesting) {
|
for (const std::string& well_name : wellsForTesting) {
|
||||||
const std::string& well_name = testWell.first;
|
|
||||||
|
|
||||||
// this is the well we will test
|
// this is the well we will test
|
||||||
WellInterfacePtr well = createWellForWellTest(well_name, timeStepIdx, deferred_logger);
|
WellInterfacePtr well = createWellForWellTest(well_name, timeStepIdx, deferred_logger);
|
||||||
|
|
||||||
@ -402,10 +400,7 @@ namespace Opm {
|
|||||||
well->setVFPProperties(vfp_properties_.get());
|
well->setVFPProperties(vfp_properties_.get());
|
||||||
well->setGuideRate(&guideRate_);
|
well->setGuideRate(&guideRate_);
|
||||||
|
|
||||||
const WellTestConfig::Reason testing_reason = testWell.second;
|
well->wellTesting(ebosSimulator_, simulationTime, this->wellState(), this->groupState(), wellTestState(), deferred_logger);
|
||||||
|
|
||||||
well->wellTesting(ebosSimulator_, simulationTime, timeStepIdx,
|
|
||||||
testing_reason, this->wellState(), this->groupState(), wellTestState(), deferred_logger);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,8 +234,7 @@ public:
|
|||||||
// TODO: theoretically, it should be a const function
|
// TODO: theoretically, it should be a const function
|
||||||
// Simulator is not const is because that assembleWellEq is non-const Simulator
|
// Simulator is not const is because that assembleWellEq is non-const Simulator
|
||||||
void wellTesting(const Simulator& simulator,
|
void wellTesting(const Simulator& simulator,
|
||||||
const double simulation_time, const int report_step,
|
const double simulation_time,
|
||||||
const WellTestConfig::Reason testing_reason,
|
|
||||||
/* const */ WellState& well_state, const GroupState& group_state, WellTestState& welltest_state,
|
/* const */ WellState& well_state, const GroupState& group_state, WellTestState& welltest_state,
|
||||||
DeferredLogger& deferred_logger);
|
DeferredLogger& deferred_logger);
|
||||||
|
|
||||||
@ -300,18 +299,6 @@ protected:
|
|||||||
|
|
||||||
virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const=0;
|
virtual void updateIPR(const Simulator& ebos_simulator, DeferredLogger& deferred_logger) const=0;
|
||||||
|
|
||||||
|
|
||||||
void wellTestingEconomic(const Simulator& simulator,
|
|
||||||
const double simulation_time, WellState& well_state, const GroupState& group_state,
|
|
||||||
WellTestState& welltest_state, DeferredLogger& deferred_logger);
|
|
||||||
|
|
||||||
void wellTestingPhysical(const Simulator& simulator,
|
|
||||||
const double simulation_time, const int report_step,
|
|
||||||
WellState& well_state,
|
|
||||||
const GroupState& group_state,
|
|
||||||
WellTestState& welltest_state, DeferredLogger& deferred_logger);
|
|
||||||
|
|
||||||
|
|
||||||
virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
|
virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
|
||||||
const double dt,
|
const double dt,
|
||||||
const Well::InjectionControls& inj_controls,
|
const Well::InjectionControls& inj_controls,
|
||||||
@ -335,7 +322,7 @@ protected:
|
|||||||
const GroupState& group_state,
|
const GroupState& group_state,
|
||||||
DeferredLogger& deferred_logger);
|
DeferredLogger& deferred_logger);
|
||||||
|
|
||||||
void solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, const GroupState& group_state,
|
bool solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, const GroupState& group_state,
|
||||||
DeferredLogger& deferred_logger);
|
DeferredLogger& deferred_logger);
|
||||||
|
|
||||||
bool shutUnsolvableWells() const;
|
bool shutUnsolvableWells() const;
|
||||||
|
@ -214,36 +214,13 @@ namespace Opm
|
|||||||
void
|
void
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
wellTesting(const Simulator& simulator,
|
wellTesting(const Simulator& simulator,
|
||||||
const double simulation_time, const int report_step,
|
const double simulation_time,
|
||||||
const WellTestConfig::Reason testing_reason,
|
|
||||||
/* const */ WellState& well_state,
|
/* const */ WellState& well_state,
|
||||||
const GroupState& group_state,
|
const GroupState& group_state,
|
||||||
WellTestState& well_test_state,
|
WellTestState& well_test_state,
|
||||||
DeferredLogger& deferred_logger)
|
DeferredLogger& deferred_logger)
|
||||||
{
|
{
|
||||||
if (testing_reason == WellTestConfig::Reason::PHYSICAL) {
|
deferred_logger.info(" well " + this->name() + " is being tested");
|
||||||
wellTestingPhysical(simulator, simulation_time, report_step,
|
|
||||||
well_state, group_state, well_test_state, deferred_logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (testing_reason == WellTestConfig::Reason::ECONOMIC) {
|
|
||||||
wellTestingEconomic(simulator, simulation_time,
|
|
||||||
well_state, group_state, well_test_state, deferred_logger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
|
||||||
void
|
|
||||||
WellInterface<TypeTag>::
|
|
||||||
wellTestingEconomic(const Simulator& simulator,
|
|
||||||
const double simulation_time, WellState& well_state, const GroupState& group_state,
|
|
||||||
WellTestState& welltest_state, DeferredLogger& deferred_logger)
|
|
||||||
{
|
|
||||||
deferred_logger.info(" well " + this->name() + " is being tested for economic limits");
|
|
||||||
|
|
||||||
WellState well_state_copy = well_state;
|
WellState well_state_copy = well_state;
|
||||||
auto& ws = well_state_copy.well(this->indexOfWell());
|
auto& ws = well_state_copy.well(this->indexOfWell());
|
||||||
@ -261,13 +238,27 @@ namespace Opm
|
|||||||
// untill the number of closed completions do not increase anymore.
|
// untill the number of closed completions do not increase anymore.
|
||||||
while (testWell) {
|
while (testWell) {
|
||||||
const size_t original_number_closed_completions = welltest_state_temp.sizeCompletions();
|
const size_t original_number_closed_completions = welltest_state_temp.sizeCompletions();
|
||||||
solveWellForTesting(simulator, well_state_copy, group_state, deferred_logger);
|
bool converged = solveWellForTesting(simulator, well_state_copy, group_state, deferred_logger);
|
||||||
|
if (!converged) {
|
||||||
|
const auto msg = fmt::format("WTEST: Well {} is not solvable (physical)", this->name());
|
||||||
|
deferred_logger.debug(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateWellOperability(simulator, well_state_copy, deferred_logger);
|
||||||
|
if ( !this->isOperable() ) {
|
||||||
|
const auto msg = fmt::format("WTEST: Well {} is not operable (physical)", this->name());
|
||||||
|
deferred_logger.debug(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<double> potentials;
|
std::vector<double> potentials;
|
||||||
try {
|
try {
|
||||||
computeWellPotentials(simulator, well_state_copy, potentials, deferred_logger);
|
computeWellPotentials(simulator, well_state_copy, potentials, deferred_logger);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
const std::string msg = std::string("well ") + this->name() + std::string(": computeWellPotentials() failed during testing for re-opening: ") + e.what();
|
const std::string msg = std::string("well ") + this->name() + std::string(": computeWellPotentials() failed during testing for re-opening: ") + e.what();
|
||||||
deferred_logger.info(msg);
|
deferred_logger.info(msg);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
const int np = well_state_copy.numPhases();
|
const int np = well_state_copy.numPhases();
|
||||||
for (int p = 0; p < np; ++p) {
|
for (int p = 0; p < np; ++p) {
|
||||||
@ -287,15 +278,16 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update wellTestState if the well test succeeds
|
// update wellTestState if the well test succeeds
|
||||||
if (!welltest_state_temp.hasWellClosed(this->name(), WellTestConfig::Reason::ECONOMIC)) {
|
if (!welltest_state_temp.hasWellClosed(this->name())) {
|
||||||
welltest_state.openWell(this->name(), WellTestConfig::Reason::ECONOMIC);
|
well_test_state.openWell(this->name());
|
||||||
const std::string msg = std::string("well ") + this->name() + std::string(" is re-opened through ECONOMIC testing");
|
|
||||||
|
std::string msg = std::string("well ") + this->name() + std::string(" is re-opened");
|
||||||
deferred_logger.info(msg);
|
deferred_logger.info(msg);
|
||||||
|
|
||||||
// also reopen completions
|
// also reopen completions
|
||||||
for (auto& completion : this->well_ecl_.getCompletions()) {
|
for (auto& completion : this->well_ecl_.getCompletions()) {
|
||||||
if (!welltest_state_temp.hasCompletion(this->name(), completion.first)) {
|
if (!welltest_state_temp.hasCompletion(this->name(), completion.first)) {
|
||||||
welltest_state.dropCompletion(this->name(), completion.first);
|
well_test_state.dropCompletion(this->name(), completion.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// set the status of the well_state to open
|
// set the status of the well_state to open
|
||||||
@ -306,6 +298,7 @@ namespace Opm
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
bool
|
bool
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
@ -324,7 +317,7 @@ namespace Opm
|
|||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
void
|
bool
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, const GroupState& group_state,
|
solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, const GroupState& group_state,
|
||||||
DeferredLogger& deferred_logger)
|
DeferredLogger& deferred_logger)
|
||||||
@ -335,14 +328,16 @@ namespace Opm
|
|||||||
const bool converged = iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger);
|
const bool converged = iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger);
|
||||||
if (converged) {
|
if (converged) {
|
||||||
deferred_logger.debug("WellTest: Well equation for well " + this->name() + " converged");
|
deferred_logger.debug("WellTest: Well equation for well " + this->name() + " converged");
|
||||||
} else {
|
return true;
|
||||||
const int max_iter = param_.max_welleq_iter_;
|
|
||||||
deferred_logger.debug("WellTest: Well equation for well " + this->name() + " failed converging in "
|
|
||||||
+ std::to_string(max_iter) + " iterations");
|
|
||||||
well_state = well_state0;
|
|
||||||
}
|
}
|
||||||
|
const int max_iter = param_.max_welleq_iter_;
|
||||||
|
deferred_logger.debug("WellTest: Well equation for well " + this->name() + " failed converging in "
|
||||||
|
+ std::to_string(max_iter) + " iterations");
|
||||||
|
well_state = well_state0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
void
|
void
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
@ -449,82 +444,6 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
|
||||||
void
|
|
||||||
WellInterface<TypeTag>::
|
|
||||||
wellTestingPhysical(const Simulator& ebos_simulator,
|
|
||||||
const double /* simulation_time */, const int /* report_step */,
|
|
||||||
WellState& well_state,
|
|
||||||
const GroupState& group_state,
|
|
||||||
WellTestState& welltest_state,
|
|
||||||
DeferredLogger& deferred_logger)
|
|
||||||
{
|
|
||||||
deferred_logger.info(" well " + this->name() + " is being tested for physical limits");
|
|
||||||
|
|
||||||
// some most difficult things are the explicit quantities, since there is no information
|
|
||||||
// in the WellState to do a decent initialization
|
|
||||||
|
|
||||||
// TODO: Let us assume that the simulator is updated
|
|
||||||
|
|
||||||
// Let us try to do a normal simualtion running, to keep checking the operability status
|
|
||||||
// If the well is not operable during any of the time. It means it does not pass the physical
|
|
||||||
// limit test.
|
|
||||||
|
|
||||||
// create a copy of the well_state to use. If the operability checking is sucessful, we use this one
|
|
||||||
// to replace the original one
|
|
||||||
WellState well_state_copy = well_state;
|
|
||||||
auto& ws = well_state_copy.well(this->indexOfWell());
|
|
||||||
|
|
||||||
// TODO: well state for this well is kind of all zero status
|
|
||||||
// we should be able to provide a better initialization
|
|
||||||
calculateExplicitQuantities(ebos_simulator, well_state_copy, deferred_logger);
|
|
||||||
|
|
||||||
updateWellOperability(ebos_simulator, well_state_copy, deferred_logger);
|
|
||||||
|
|
||||||
if ( !this->isOperable() ) {
|
|
||||||
const std::string msg = " well " + this->name() + " is not operable during well testing for physical reason";
|
|
||||||
deferred_logger.debug(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateWellStateWithTarget(ebos_simulator, group_state, well_state_copy, deferred_logger);
|
|
||||||
|
|
||||||
calculateExplicitQuantities(ebos_simulator, well_state_copy, deferred_logger);
|
|
||||||
|
|
||||||
const double dt = ebos_simulator.timeStepSize();
|
|
||||||
const bool converged = this->iterateWellEquations(ebos_simulator, dt, well_state_copy, group_state, deferred_logger);
|
|
||||||
|
|
||||||
if (!converged) {
|
|
||||||
const std::string msg = " well " + this->name() + " did not get converged during well testing for physical reason";
|
|
||||||
deferred_logger.debug(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->isOperable() ) {
|
|
||||||
welltest_state.openWell(this->name(), WellTestConfig::PHYSICAL );
|
|
||||||
const std::string msg = " well " + this->name() + " is re-opened through well testing for physical reason";
|
|
||||||
deferred_logger.info(msg);
|
|
||||||
// we need to populate the new well with potentials
|
|
||||||
std::vector<double> potentials;
|
|
||||||
try {
|
|
||||||
computeWellPotentials(ebos_simulator, well_state_copy, potentials, deferred_logger);
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
const std::string msg2 = std::string("well ") + this->name() + std::string(": computeWellPotentials() failed during testing for re-opening: ") + e.what();
|
|
||||||
deferred_logger.info(msg2);
|
|
||||||
}
|
|
||||||
const int np = well_state_copy.numPhases();
|
|
||||||
for (int p = 0; p < np; ++p) {
|
|
||||||
ws.well_potentials[p] = std::abs(potentials[p]);
|
|
||||||
}
|
|
||||||
//set the status of the well_state to open
|
|
||||||
ws.open();
|
|
||||||
well_state = well_state_copy;
|
|
||||||
} else {
|
|
||||||
const std::string msg = " well " + this->name() + " is not operable during well testing for physical reason";
|
|
||||||
deferred_logger.debug(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
|
Loading…
Reference in New Issue
Block a user