Merge pull request #2042 from joakim-hove/well-reperf

Changes to well reference depth
This commit is contained in:
Bård Skaflestad 2020-10-23 16:49:08 +02:00 committed by GitHub
commit 9fc6948e05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 153 additions and 27 deletions

View File

@ -376,7 +376,7 @@ namespace Opm
int headI,
int headJ,
Phase preferredPhase,
double refDepth,
const std::optional<double>& refDepth,
double drainageRadius,
bool allowCrossFlow,
bool automaticShutIn,

View File

@ -463,7 +463,7 @@ public:
std::size_t insert_index,
int headI,
int headJ,
double ref_depth,
const std::optional<double>& ref_depth,
const WellType& wtype_arg,
ProducerCMode whistctl_cmode,
Connection::Order ordering,
@ -552,7 +552,8 @@ public:
bool updateCrossFlow(bool allow_cross_flow);
bool updatePVTTable(int pvt_table);
bool updateHead(int I, int J);
bool updateRefDepth(double ref_dpeth);
void updateRefDepth();
bool updateRefDepth(const std::optional<double>& ref_dpeth);
bool updateDrainageRadius(double drainage_radius);
void updateSegments(std::shared_ptr<WellSegments> segments_arg);
bool updateConnections(std::shared_ptr<WellConnections> connections);
@ -651,7 +652,7 @@ private:
std::size_t insert_index;
int headI;
int headJ;
double ref_depth;
std::optional<double> ref_depth;
double drainage_radius;
bool allow_cross_flow;
bool automatic_shutin;

View File

@ -143,6 +143,7 @@ namespace {
}
void Schedule::handleCOMPDAT(const HandlerContext& handlerContext, const ParseContext& parseContext, ErrorGuard& errors) {
std::unordered_set<std::string> wells;
for (const auto& record : handlerContext.keyword) {
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
auto wellnames = this->wellNames(wellNamePattern, handlerContext.currentStep);
@ -153,14 +154,24 @@ namespace {
auto well2 = std::shared_ptr<Well>(new Well( this->getWell(name, handlerContext.currentStep)));
auto connections = std::shared_ptr<WellConnections>( new WellConnections( well2->getConnections()));
connections->loadCOMPDAT(record, handlerContext.grid, handlerContext.fieldPropsManager);
if (well2->updateConnections(connections, handlerContext.grid, handlerContext.fieldPropsManager.get_int("PVTNUM")))
if (well2->updateConnections(connections, handlerContext.grid, handlerContext.fieldPropsManager.get_int("PVTNUM"))) {
this->updateWell(std::move(well2), handlerContext.currentStep);
wells.insert( name );
}
this->addWellGroupEvent(name, ScheduleEvents::COMPLETION_CHANGE, handlerContext.currentStep);
}
}
m_events.addEvent(ScheduleEvents::COMPLETION_CHANGE, handlerContext.currentStep);
// In the case the wells reference depth has been defaulted in the
// WELSPECS keyword we need to force a calculation of the wells
// reference depth exactly when the COMPDAT keyword has been completely
// processed.
for (const auto& wname : wells) {
const auto& dynamic_state = this->wells_static.at(wname);
auto& well_ptr = dynamic_state.get(handlerContext.currentStep);
well_ptr->updateRefDepth();
}
}
void Schedule::handleCOMPLUMP(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
@ -1200,18 +1211,19 @@ namespace {
const auto& refDepthItem = record.getItem<ParserKeywords::WELSPECS::REF_DEPTH>();
int pvt_table = record.getItem<ParserKeywords::WELSPECS::P_TABLE>().get<int>(0);
double drainageRadius = record.getItem<ParserKeywords::WELSPECS::D_RADIUS>().getSIDouble(0);
double refDepth = refDepthItem.hasValue(0)
? refDepthItem.getSIDouble(0)
: -1.0;
std::optional<double> ref_depth;
if (refDepthItem.hasValue(0))
ref_depth = refDepthItem.getSIDouble(0);
{
bool update = false;
auto well2 = std::shared_ptr<Well>(new Well( this->getWell(wellName, handlerContext.currentStep)));
update = well2->updateHead(headI, headJ);
update |= well2->updateRefDepth(refDepth);
update = well2->updateHead(headI, headJ);
update |= well2->updateRefDepth(ref_depth);
update |= well2->updateDrainageRadius(drainageRadius);
update |= well2->updatePVTTable(pvt_table);
if (update) {
well2->updateRefDepth();
this->updateWell(std::move(well2), handlerContext.currentStep);
this->addWellGroupEvent(wellName, ScheduleEvents::WELL_WELSPECS_UPDATE, handlerContext.currentStep);
}

View File

@ -799,9 +799,9 @@ private:
}
}
const auto& refDepthItem = record.getItem("REF_DEPTH");
double refDepth = refDepthItem.hasValue( 0 )
? refDepthItem.getSIDouble( 0 )
: -1.0;
std::optional<double> ref_depth;
if (refDepthItem.hasValue( 0 ))
ref_depth = refDepthItem.getSIDouble( 0 );
double drainageRadius = record.getItem( "D_RADIUS" ).getSIDouble(0);
@ -825,7 +825,7 @@ private:
headI,
headJ,
preferredPhase,
refDepth,
ref_depth,
drainageRadius,
allowCrossFlow,
automaticShutIn,
@ -854,7 +854,7 @@ private:
int headI,
int headJ,
Phase preferredPhase,
double refDepth,
const std::optional<double>& ref_depth,
double drainageRadius,
bool allowCrossFlow,
bool automaticShutIn,
@ -869,7 +869,7 @@ private:
timeStep,
0,
headI, headJ,
refDepth,
ref_depth,
WellType(preferredPhase),
this->global_whistctl_mode[timeStep],
wellConnectionOrder,

View File

@ -309,7 +309,7 @@ Well::Well(const std::string& wname_arg,
std::size_t insert_index_arg,
int headI_arg,
int headJ_arg,
double ref_depth_arg,
const std::optional<double>& ref_depth_arg,
const WellType& wtype_arg,
ProducerCMode whistctl_cmode,
Connection::Order ordering_arg,
@ -638,7 +638,7 @@ bool Well::updateStatus(Status well_state, bool update_connections) {
}
bool Well::updateRefDepth(double ref_depth_arg) {
bool Well::updateRefDepth(const std::optional<double>& ref_depth_arg) {
if (this->ref_depth != ref_depth_arg) {
this->ref_depth = ref_depth_arg;
return true;
@ -798,16 +798,21 @@ bool Well::getAllowCrossFlow() const {
}
double Well::getRefDepth() const {
if( this->ref_depth >= 0.0 )
return this->ref_depth;
if (!this->ref_depth.has_value())
throw std::logic_error(fmt::format("Well: {} - tried to access not initialized well reference depth", this->name()));
return *this->ref_depth;
}
// ref depth was defaulted and we get the depth of the first completion
if( this->connections->empty() ) {
throw std::invalid_argument( "No completions defined for well: "
+ name()
void Well::updateRefDepth() {
if( !this->ref_depth ) {
// ref depth was defaulted and we get the depth of the first completion
if( this->connections->empty() )
throw std::invalid_argument( "No completions defined for well: "
+ name()
+ ". Can not infer reference depth" );
this->ref_depth = this->connections->get(0).depth();
}
return this->connections->get(0).depth();
}

View File

@ -1354,3 +1354,111 @@ END
BOOST_CHECK_MESSAGE(wellP.getConnections() == wellQ.getConnections(),
"P and Q must have same WellConnections VALUE");
}
BOOST_AUTO_TEST_CASE(REPERF) {
const auto deck = Parser{}.parseString(R"(RUNSPEC
START
7 OCT 2020 /
DIMENS
10 10 4 /
GRID
DXV
10*100.0 /
DYV
10*100.0 /
DZV
4*10.0 /
DEPTHZ
121*2000.0 /
PERMX
400*100.0 /
PERMY
400*100.0 /
PERMZ
400*10.0 /
PORO
400*0.3 /
SCHEDULE
WELSPECS
'W1' 'G' 1 1 1* 'OIL' 2* 'STOP' 4* /
/
COMPDAT
'W1' 1 1 4 4 'OPEN' 1* 34.720 0.216 3095.832 2* 'Y' 12.828 /
'W1' 1 1 3 3 'OPEN' 1* 34.720 0.216 3095.832 2* 'Y' 12.828 /
/
-- W0
TSTEP
1 /
COMPDAT
'W1' 1 1 2 2 'OPEN' 1* 25.620 0.216 2086.842 2* 'Y' 8.486 /
/
-- W1
TSTEP
1 /
WELSPECS
'W1' 'G' 1 1 2005 'LIQ' /
/
-- W2
TSTEP
1 /
WELSPECS
'W1' 'G' 1 1 1* 'LIQ' /
/
-- W3
TSTEP
1 /
COMPDAT
'W1' 1 1 1 1 'OPEN' 1* 25.620 0.216 2086.842 2* 'Y' 8.486 /
/
-- W4
TSTEP
1 /
WELSPECS
'W1' 'G' 1 1 1* 'LIQ' /
/
-- W5
END
)");
const auto es = EclipseState{ deck };
const auto& grid = es.getInputGrid();
const auto sched = Schedule{ deck, es };
const auto& w0 = sched.getWell("W1", 0);
const auto& w1 = sched.getWell("W1", 1);
const auto& w2 = sched.getWell("W1", 2);
const auto& w3 = sched.getWell("W1", 3);
const auto& w4 = sched.getWell("W1", 4);
const auto& w5 = sched.getWell("W1", 5);
BOOST_CHECK_EQUAL(w0.getRefDepth(), grid.getCellDepth(0,0,2));
BOOST_CHECK_EQUAL(w1.getRefDepth(), w0.getRefDepth());
BOOST_CHECK_EQUAL(w2.getRefDepth(), 2005 );
BOOST_CHECK_EQUAL(w3.getRefDepth(), grid.getCellDepth(0,0,1));
BOOST_CHECK_EQUAL(w4.getRefDepth(), w3.getRefDepth());
BOOST_CHECK_EQUAL(w5.getRefDepth(), grid.getCellDepth(0,0,0));
}