From 174f5efec28fa28494b425105b3569807ae8b8c1 Mon Sep 17 00:00:00 2001 From: goncalvesmachadoc Date: Thu, 16 Nov 2023 16:39:59 +0100 Subject: [PATCH] parse welspecl and compadatl --- opm/input/eclipse/Schedule/Schedule.hpp | 2 + .../eclipse/Schedule/KeywordHandlers.cpp | 113 ++++++++++++++++++ .../share/keywords/000_Eclipse100/C/COMPDATL | 98 +++++++++++++++ .../share/keywords/000_Eclipse100/W/WELSPECL | 18 +++ .../eclipse/share/keywords/keyword_list.cmake | 1 + 5 files changed, 232 insertions(+) create mode 100644 src/opm/input/eclipse/share/keywords/000_Eclipse100/C/COMPDATL diff --git a/opm/input/eclipse/Schedule/Schedule.hpp b/opm/input/eclipse/Schedule/Schedule.hpp index 269b2d414..774c1065a 100644 --- a/opm/input/eclipse/Schedule/Schedule.hpp +++ b/opm/input/eclipse/Schedule/Schedule.hpp @@ -702,6 +702,7 @@ namespace Opm void handleBCProp (HandlerContext&); void handleBRANPROP (HandlerContext&); void handleCOMPDAT (HandlerContext&); + void handleCOMPDATL (HandlerContext&); void handleCOMPLUMP (HandlerContext&); void handleCOMPORD (HandlerContext&); void handleCOMPSEGS (HandlerContext&); @@ -758,6 +759,7 @@ namespace Opm void handleWELPI (HandlerContext&); void handleWELSEGS (HandlerContext&); void handleWELSPECS (HandlerContext&); + void handleWELSPECL (HandlerContext&); void handleWELTARG (HandlerContext&); void handleWELTRAJ (HandlerContext&); void handleWFOAM (HandlerContext&); diff --git a/src/opm/input/eclipse/Schedule/KeywordHandlers.cpp b/src/opm/input/eclipse/Schedule/KeywordHandlers.cpp index a68e62fa4..3c5d952c1 100644 --- a/src/opm/input/eclipse/Schedule/KeywordHandlers.cpp +++ b/src/opm/input/eclipse/Schedule/KeywordHandlers.cpp @@ -1958,6 +1958,118 @@ File {} line {}.)", wname, location.keyword, location.filename, location.lineno) const auto msg_fmt = fmt::format(R"(Well{0} parented directly to 'FIELD'; this is allowed but discouraged. Well{0} entered with 'FIELD' parent group: + * {1})", plural, fmt::join(fieldWells, "\n * ")); + + handlerContext.parseContext.handleError(ParseContext::SCHEDULE_WELL_IN_FIELD_GROUP, + msg_fmt, + handlerContext.keyword.location(), + handlerContext.errors); + } + + if (! handlerContext.keyword.empty()) { + handlerContext.record_well_structure_change(); + } + } + + void Schedule::handleWELSPECL(HandlerContext& handlerContext) + { + using Kw = ParserKeywords::WELSPECL; + + auto getTrimmedName = [&handlerContext](const auto& item) + { + return trim_wgname(handlerContext.keyword, + item.template get(0), + handlerContext.parseContext, + handlerContext.errors); + }; + + auto fieldWells = std::vector{}; + for (const auto& record : handlerContext.keyword) { + if (const auto fip_region_number = record.getItem().get(0); + fip_region_number != Kw::FIP_REGION::defaultValue) + { + const auto& location = handlerContext.keyword.location(); + const auto msg = fmt::format("Non-defaulted FIP region {} in WELSPECL keyword " + "in file {} line {} is not supported. " + "Reset to default value {}.", + fip_region_number, + location.filename, + location.lineno, + Kw::FIP_REGION::defaultValue); + OpmLog::warning(msg); + } + + if (const auto& density_calc_type = record.getItem().get(0); + density_calc_type != Kw::DENSITY_CALC::defaultValue) + { + const auto& location = handlerContext.keyword.location(); + const auto msg = fmt::format("Non-defaulted density calculation method '{}' " + "in WELSPECL keyword in file {} line {} is " + "not supported. Reset to default value {}.", + density_calc_type, + location.filename, + location.lineno, + Kw::DENSITY_CALC::defaultValue); + OpmLog::warning(msg); + } + + const auto wellName = getTrimmedName(record.getItem()); + const auto groupName = getTrimmedName(record.getItem()); + + // We might get here from an ACTIONX context, or we might get + // called on a well (list) template, to reassign certain well + // properties--e.g, the well's controlling group--so check if + // 'wellName' matches any existing well names through pattern + // matching before treating the wellName as a simple well name. + // + // An empty list of well names is okay since that means we're + // creating a new well in this case. + const auto allowEmptyWellList = true; + const auto existingWells = + this->wellNames(wellName, handlerContext, allowEmptyWellList); + + if (groupName == "FIELD") { + if (existingWells.empty()) { + fieldWells.push_back(wellName); + } + else { + for (const auto& existingWell : existingWells) { + fieldWells.push_back(existingWell); + } + } + } + + if (! this->snapshots.back().groups.has(groupName)) { + this->addGroup(groupName, handlerContext.currentStep); + } + + if (existingWells.empty()) { + // 'wellName' does not match any existing wells. Create a + // new Well object for this well. + this->welspecsCreateNewWell(record, + wellName, + groupName, + handlerContext); + } + else { + // 'wellName' matches one or more existing wells. Assign + // new properties for those wells. + this->welspecsUpdateExistingWells(record, + existingWells, + groupName, + handlerContext); + } + } + + if (! fieldWells.empty()) { + std::sort(fieldWells.begin(), fieldWells.end()); + fieldWells.erase(std::unique(fieldWells.begin(), fieldWells.end()), + fieldWells.end()); + + const auto* plural = (fieldWells.size() == 1) ? "" : "s"; + + const auto msg_fmt = fmt::format(R"(Well{0} parented directly to 'FIELD'; this is allowed but discouraged. +Well{0} entered with 'FIELD' parent group: * {1})", plural, fmt::join(fieldWells, "\n * ")); handlerContext.parseContext.handleError(ParseContext::SCHEDULE_WELL_IN_FIELD_GROUP, @@ -2932,6 +3044,7 @@ Well{0} entered with 'FIELD' parent group: { "WELPI" , &Schedule::handleWELPI }, { "WELSEGS" , &Schedule::handleWELSEGS }, { "WELSPECS", &Schedule::handleWELSPECS }, + { "WELSPECL", &Schedule::handleWELSPECL }, { "WELTARG" , &Schedule::handleWELTARG }, { "WELTRAJ" , &Schedule::handleWELTRAJ }, { "WFOAM" , &Schedule::handleWFOAM }, diff --git a/src/opm/input/eclipse/share/keywords/000_Eclipse100/C/COMPDATL b/src/opm/input/eclipse/share/keywords/000_Eclipse100/C/COMPDATL new file mode 100644 index 000000000..6164e634c --- /dev/null +++ b/src/opm/input/eclipse/share/keywords/000_Eclipse100/C/COMPDATL @@ -0,0 +1,98 @@ +{ + "name": "COMPDATL", + "sections": [ + "SCHEDULE" + ], + "items": [ + { + "item": 1, + "name": "WELL", + "value_type": "STRING" + }, + { + "item": 2, + "name": "LGR", + "value_type": "STRING" + }, + { + "item": 3, + "name": "I", + "value_type": "INT", + "default": 0 + }, + { + "item": 4, + "name": "J", + "value_type": "INT", + "default": 0 + }, + { + "item": 5, + "name": "K1", + "value_type": "INT" + }, + { + "item": 6, + "name": "K2", + "value_type": "INT" + }, + { + "item": 7, + "name": "STATE", + "value_type": "STRING", + "default": "OPEN" + }, + { + "item": 8, + "name": "SAT_TABLE", + "value_type": "INT", + "default": 0 + }, + { + "item": 9, + "name": "CONNECTION_TRANSMISSIBILITY_FACTOR", + "value_type": "DOUBLE", + "dimension": "Viscosity*ReservoirVolume/Time*Pressure" + }, + { + "item": 10, + "name": "DIAMETER", + "value_type": "DOUBLE", + "dimension": "Length" + }, + { + "item": 11, + "name": "Kh", + "value_type": "DOUBLE", + "dimension": "Permeability*Length", + "default": -1 + }, + { + "item": 12, + "name": "SKIN", + "value_type": "DOUBLE", + "dimension": "1", + "default": 0 + }, + { + "item": 13, + "name": "D_FACTOR", + "value_type": "DOUBLE", + "dimension": "Time/GasSurfaceVolume", + "default": 0 + + }, + { + "item": 14, + "name": "DIR", + "value_type": "STRING", + "default": "Z" + }, + { + "item": 15, + "name": "PR", + "value_type": "DOUBLE", + "dimension": "Length" + } + ] +} diff --git a/src/opm/input/eclipse/share/keywords/000_Eclipse100/W/WELSPECL b/src/opm/input/eclipse/share/keywords/000_Eclipse100/W/WELSPECL index 3e9458d04..d0e302019 100644 --- a/src/opm/input/eclipse/share/keywords/000_Eclipse100/W/WELSPECL +++ b/src/opm/input/eclipse/share/keywords/000_Eclipse100/W/WELSPECL @@ -5,84 +5,102 @@ ], "items": [ { + "item": 1, "name": "WELL", "value_type": "STRING" }, { + "item": 2, "name": "GROUP", "value_type": "STRING" }, { + "item": 3, "name": "LGR", "value_type": "STRING" }, { + "item": 4, "name": "HEAD_I", "value_type": "INT" }, { + "item": 5, "name": "HEAD_J", "value_type": "INT" }, { + "item": 6, "name": "REF_DEPTH", "value_type": "DOUBLE", "dimension": "Length" }, { + "item": 7, "name": "PHASE", "value_type": "STRING" }, { + "item": 8, "name": "D_RADIUS", "value_type": "DOUBLE", "default": 0, "dimension": "Length" }, { + "item": 9, "name": "INFLOW_EQ", "value_type": "STRING", "default": "STD" }, { + "item": 10, "name": "AUTO_SHUTIN", "value_type": "STRING", "default": "SHUT" }, { + "item": 11, "name": "CROSSFLOW", "value_type": "STRING", "default": "YES" }, { + "item": 12, "name": "P_TABLE", "value_type": "INT", "default": 0 }, { + "item": 13, "name": "DENSITY_CALC", "value_type": "STRING", "default": "SEG" }, { + "item": 14, "name": "FIP_REGION", "value_type": "INT", "default": 0 }, { + "item": 15, "name": "FRONTSIM1", "value_type": "STRING" }, { + "item": 16, "name": "FRONTSIM2", "value_type": "STRING" }, { + "item": 17, "name": "well_model", "value_type": "STRING", "default": "STD" }, { + "item": 18, "name": "POLYMER_TABLE", "value_type": "INT", "default": 0 diff --git a/src/opm/input/eclipse/share/keywords/keyword_list.cmake b/src/opm/input/eclipse/share/keywords/keyword_list.cmake index d4a3d1817..0ef623516 100644 --- a/src/opm/input/eclipse/share/keywords/keyword_list.cmake +++ b/src/opm/input/eclipse/share/keywords/keyword_list.cmake @@ -88,6 +88,7 @@ set( keywords 000_Eclipse100/C/COLLAPSE 000_Eclipse100/C/COLUMNS 000_Eclipse100/C/COMPDAT + 000_Eclipse100/C/COMPDATL 000_Eclipse100/C/COMPDATX 000_Eclipse100/C/COMPFLSH 000_Eclipse100/C/COMPIMB