reading new tables for grid independent well specification

This commit is contained in:
Paul Egberts 2022-10-25 13:50:02 +02:00
parent 4ee3f9ed3e
commit 2da6dba9af
7 changed files with 237 additions and 1 deletions

View File

@ -731,11 +731,13 @@ namespace Opm
void handleWCONPROD (HandlerContext&); void handleWCONPROD (HandlerContext&);
void handleWECON (HandlerContext&); void handleWECON (HandlerContext&);
void handleWEFAC (HandlerContext&); void handleWEFAC (HandlerContext&);
void handleWELCOMPL (HandlerContext&);
void handleWELOPEN (HandlerContext&); void handleWELOPEN (HandlerContext&);
void handleWELPI (HandlerContext&); void handleWELPI (HandlerContext&);
void handleWELSEGS (HandlerContext&); void handleWELSEGS (HandlerContext&);
void handleWELSPECS (HandlerContext&); void handleWELSPECS (HandlerContext&);
void handleWELTARG (HandlerContext&); void handleWELTARG (HandlerContext&);
void handleWELTRAJ (HandlerContext&);
void handleWFOAM (HandlerContext&); void handleWFOAM (HandlerContext&);
void handleWGRUPCON (HandlerContext&); void handleWGRUPCON (HandlerContext&);
void handleWHISTCTL (HandlerContext&); void handleWHISTCTL (HandlerContext&);

View File

@ -88,6 +88,12 @@ namespace Opm {
const std::string& wname, const std::string& wname,
const KeywordLocation& location); const KeywordLocation& location);
void loadWELCOMPL(const DeckRecord& record, const ScheduleGrid& grid, const std::string& wname, const KeywordLocation& location);
void loadWELTRAJ(const DeckRecord& record, const ScheduleGrid& grid, const std::string& wname, const KeywordLocation& location);
using const_iterator = std::vector< Connection >::const_iterator;
void add(Connection); void add(Connection);
std::size_t size() const; std::size_t size() const;
bool empty() const; bool empty() const;
@ -182,6 +188,12 @@ namespace Opm {
void orderTRACK(); void orderTRACK();
void orderMSW(); void orderMSW();
void orderDEPTH(); void orderDEPTH();
Connection::Order m_ordering = Connection::Order::TRACK;
int headI, headJ;
std::vector< Connection > m_connections;
double x_coordinate;
}; };
std::optional<int> std::optional<int>

View File

@ -179,6 +179,83 @@ namespace {
} }
} }
void Schedule::handleWELTRAJ(HandlerContext& handlerContext) {
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 );
for (const auto& name : wellnames) {
auto well2 = this->snapshots.back().wells.get(name);
auto connections = std::shared_ptr<WellConnections>( new WellConnections( well2.getConnections()));
connections->loadWELTRAJ(record, handlerContext.grid, name, handlerContext.keyword.location());
//what to do here? need here something like updateTrajectory
//maybe new method WellConnection::addTrajectory?
if (well2.updateConnections(connections, handlerContext.grid)) {
this->snapshots.back().wells.update( well2 );
wells.insert( name );
}
if (connections->empty() && well2.getConnections().empty()) {
const auto& location = handlerContext.keyword.location();
auto msg = fmt::format("Problem with COMPDAT/{}\n"
"In {} line {}\n"
"Well {} is not connected to grid - will remain SHUT", name, location.filename, location.lineno, name);
OpmLog::warning(msg);
}
this->snapshots.back().wellgroup_events().addEvent( name, ScheduleEvents::COMPLETION_CHANGE);
}
}
this->snapshots.back().events().addEvent(ScheduleEvents::COMPLETION_CHANGE);
// 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) {
// auto& well = this->snapshots.back().wells.get( wname );
// well.updateRefDepth();
// this->snapshots.back().wells.update( std::move(well));
// }
}
void Schedule::handleWELCOMPL(HandlerContext& handlerContext) {
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 );
for (const auto& name : wellnames) {
auto well2 = this->snapshots.back().wells.get(name);
auto connections = std::shared_ptr<WellConnections>( new WellConnections( well2.getConnections()));
connections->loadWELCOMPL(record, handlerContext.grid, name, handlerContext.keyword.location());
// if (well2.updateConnections(connections, handlerContext.grid)) {
// this->snapshots.back().wells.update( well2 );
// wells.insert( name );
// }
// if (connections->empty() && well2.getConnections().empty()) {
// const auto& location = handlerContext.keyword.location();
// auto msg = fmt::format("Problem with COMPDAT/{}\n"
// "In {} line {}\n"
// "Well {} is not connected to grid - will remain SHUT", name, location.filename, location.lineno, name);
// OpmLog::warning(msg);
// }
// this->snapshots.back().wellgroup_events().addEvent( name, ScheduleEvents::COMPLETION_CHANGE);
}
}
this->snapshots.back().events().addEvent(ScheduleEvents::COMPLETION_CHANGE);
// 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) {
// auto& well = this->snapshots.back().wells.get( wname );
// well.updateRefDepth();
// this->snapshots.back().wells.update( std::move(well));
// }
}
void Schedule::handleCOMPLUMP(HandlerContext& handlerContext) { void Schedule::handleCOMPLUMP(HandlerContext& handlerContext) {
for (const auto& record : handlerContext.keyword) { for (const auto& record : handlerContext.keyword) {
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0); const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
@ -2298,11 +2375,13 @@ Well{0} entered with disallowed 'FIELD' parent group:
{ "WCONPROD", &Schedule::handleWCONPROD }, { "WCONPROD", &Schedule::handleWCONPROD },
{ "WECON" , &Schedule::handleWECON }, { "WECON" , &Schedule::handleWECON },
{ "WEFAC" , &Schedule::handleWEFAC }, { "WEFAC" , &Schedule::handleWEFAC },
{ "WELCOMPL", &Schedule::handleWELCOMPL },
{ "WELOPEN" , &Schedule::handleWELOPEN }, { "WELOPEN" , &Schedule::handleWELOPEN },
{ "WELPI" , &Schedule::handleWELPI }, { "WELPI" , &Schedule::handleWELPI },
{ "WELSEGS" , &Schedule::handleWELSEGS }, { "WELSEGS" , &Schedule::handleWELSEGS },
{ "WELSPECS", &Schedule::handleWELSPECS }, { "WELSPECS", &Schedule::handleWELSPECS },
{ "WELTARG" , &Schedule::handleWELTARG }, { "WELTARG" , &Schedule::handleWELTARG },
{ "WELTRAJ" , &Schedule::handleWELTRAJ },
{ "WFOAM" , &Schedule::handleWFOAM }, { "WFOAM" , &Schedule::handleWFOAM },
{ "WGRUPCON", &Schedule::handleWGRUPCON }, { "WGRUPCON", &Schedule::handleWGRUPCON },
{ "WHISTCTL", &Schedule::handleWHISTCTL }, { "WHISTCTL", &Schedule::handleWHISTCTL },

View File

@ -1,4 +1,4 @@
/* /*addConnectioncell
Copyright 2013 Statoil ASA. Copyright 2013 Statoil ASA.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@ -46,6 +46,18 @@
#include <vector> #include <vector>
#include <stddef.h> #include <stddef.h>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/utility/ActiveGridCells.hpp>
#include <opm/input/eclipse/Units/Units.hpp>
#include <opm/io/eclipse/rst/connection.hpp>
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include <opm/input/eclipse/Deck/DeckRecord.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/input/eclipse/Schedule/Well/Connection.hpp>
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
#include <opm/input/eclipse/Schedule/ScheduleGrid.hpp>
#include <opm/input/eclipse/Schedule/VFPInjTable.hpp> //testing
#include <fmt/format.h> #include <fmt/format.h>
@ -441,6 +453,55 @@ namespace Opm {
} }
} }
} }
void WellConnections::loadWELCOMPL(const DeckRecord& record,
const ScheduleGrid& grid,
const std::string& wname,
const KeywordLocation& location) {
const std::string& completionNamePattern = record.getItem("COMPLETION").getTrimmedString(0);
//Connection::State state = Connection::StateFromString( record.getItem("STATE").getTrimmedString(0) );
//based on the data of wellCOMPL and trajectory data the ijk coordinates should be derived here.
//unclear how to get trajectory data in this method
const auto& ahdepth_upper = record.getItem("AHDEPTH_UPPER");
const auto& ahdepth_lower = record.getItem("AHDEPTH_LOWER");
const auto& diameterItem = record.getItem("DIAMETER");
double skin_factor = record.getItem("SKIN").getSIDouble(0);
double rw;
if (diameterItem.hasValue(0))
rw = 0.50 * diameterItem.getSIDouble(0);
else
// The Eclipse100 manual does not specify a default value for the wellbore
// diameter, but the Opm codebase has traditionally implemented a default
// value of one foot. The same default value is used by Eclipse300.
rw = 0.5*unit::feet;
//const auto& test = grid.cells;
}
void WellConnections::loadWELTRAJ(const DeckRecord& record,
const ScheduleGrid& grid,
const std::string& wname,
const KeywordLocation& location) {
//const std::string& completionNamePattern = record.getItem("COMPLETION").getTrimmedString(0);
//Connection::State state = Connection::StateFromString( record.getItem("STATE").getTrimmedString(0) );
////should we use loadWELTRAJ we may assume (?) that only once a trajectory is created?
//(1) how to store data read in here????
//(2) how to get info from here to loadWELCOMPL???????
this->x_coordinate = record.getItem("X").getSIDouble(0);
const auto& y_coordinate = record.getItem("Y");
const int I = 8;
const int J = 8;
const int K = 2;
const CompletedCells::Cell& cell = grid.get_cell(I, J, K);
}
std::size_t WellConnections::size() const { std::size_t WellConnections::size() const {
return m_connections.size(); return m_connections.size();

View File

@ -0,0 +1,43 @@
{
"name": "WELCOMPL",
"sections": [
"SCHEDULE"
],
"items": [
{
"item": 1,
"name": "WELL",
"value_type": "STRING"
},
{
"item": 2,
"name": "COMPLETION",
"value_type": "STRING"
},
{
"item": 3,
"name": "AHDEPTH_UPPER",
"value_type": "DOUBLE",
"dimension": "Length"
},
{
"item": 4,
"name": "AHDEPTH_LOWER",
"value_type": "DOUBLE",
"dimension": "Length"
},
{
"item": 5,
"name": "DIAMETER",
"value_type": "DOUBLE",
"dimension": "Length"
},
{
"item": 6,
"name": "SKIN",
"value_type": "DOUBLE",
"dimension": "1"
}
]
}

View File

@ -0,0 +1,37 @@
{
"name": "WELTRAJ",
"sections": [
"SCHEDULE"
],
"items": [
{
"item": 1,
"name": "WELL",
"value_type": "STRING"
},
{
"item": 2,
"name": "X",
"value_type": "DOUBLE",
"dimension": "Length"
},
{
"item": 3,
"name": "Y",
"value_type": "DOUBLE",
"dimension": "Length"
},
{
"item": 4,
"name": "TVDEPTH",
"value_type": "DOUBLE",
"dimension": "Length"
},
{
"item": 5,
"name": "AHDEPTH",
"value_type": "DOUBLE",
"dimension": "Length"
}
]
}

View File

@ -1135,6 +1135,8 @@ set( keywords
900_OPM/T/TLPMIXPA 900_OPM/T/TLPMIXPA
900_OPM/V/VAPWAT 900_OPM/V/VAPWAT
900_OPM/W/WATJT 900_OPM/W/WATJT
900_OPM/W/WELTRAJ
900_OPM/W/WELCOMPL
900_OPM/W/WMICP 900_OPM/W/WMICP
900_OPM/W/WPMITAB 900_OPM/W/WPMITAB
900_OPM/W/WSKPTAB) 900_OPM/W/WSKPTAB)