adding the parsing support for keyword WINJMULT

This commit is contained in:
Kai Bao
2022-09-29 16:35:31 +02:00
parent dd34926062
commit da17ef3174
8 changed files with 143 additions and 0 deletions

View File

@@ -746,6 +746,7 @@ namespace Opm
void handleWVFPEXP (HandlerContext&);
void handleWWPAVE (HandlerContext&);
void handleWPIMULT (HandlerContext&);
void handleWINJMULT (HandlerContext&);
void handleWPMITAB (HandlerContext&);
void handleWPOLYMER (HandlerContext&);
void handleWRFT (HandlerContext&);

View File

@@ -28,6 +28,7 @@
#include <string>
#include <vector>
#include <optional>
#include <limits>
namespace Opm {
@@ -76,6 +77,35 @@ namespace RestartIO {
Defaulted,
};
enum class InjMultMode {
WREV,
CREV,
CIRR,
NONE,
};
static InjMultMode injModeFromString(const std::string& str);
struct InjMult {
InjMultMode mode {InjMultMode::NONE};
double fracture_pressure {std::numeric_limits<double>::max()};
double multiplier_gradient {0.};
template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(mode);
serializer(fracture_pressure);
serializer(multiplier_gradient);
}
bool operator==( const InjMult& rhs ) const {
return mode == rhs.mode
&& fracture_pressure == rhs.fracture_pressure
&& multiplier_gradient == rhs.multiplier_gradient;
}
};
Connection();
Connection(int i, int j , int k ,
@@ -120,6 +150,8 @@ namespace RestartIO {
double connectionLength() const;
double skinFactor() const;
CTFKind kind() const;
InjMult injmult() const;
void setInjMult(const InjMult& inj_mult);
void setState(State state);
void setComplnum(int compnum);
@@ -163,6 +195,7 @@ namespace RestartIO {
serializer(ijk);
serializer(m_global_index);
serializer(m_ctfkind);
serializer(m_injmult);
serializer(m_sort_value);
serializer(m_perf_range);
serializer(m_defaultSatTabId);
@@ -186,6 +219,7 @@ namespace RestartIO {
std::array<int,3> ijk;
CTFKind m_ctfkind;
InjMult m_injmult;
std::size_t m_global_index;
/*
The sort_value member is a peculiar quantity. The connections are

View File

@@ -472,6 +472,7 @@ public:
bool handleWELOPENConnections(const DeckRecord& record, Connection::State status);
bool handleCOMPLUMP(const DeckRecord& record);
bool handleWPIMULT(const DeckRecord& record);
bool handleWINJMULT(const DeckRecord& record, const KeywordLocation& location);
bool applyGlobalWPIMULT(double scale_factor);
void filterConnections(const ActiveGridCells& grid);

View File

@@ -153,6 +153,8 @@ namespace Opm {
void applyWellPIScaling(const double scaleFactor,
std::vector<bool>& scalingApplicable);
bool underWREVInjMultMode() const;
template <class Serializer>
void serializeOp(Serializer& serializer)
{

View File

@@ -1950,6 +1950,24 @@ Well{0} entered with 'FIELD' parent group:
}
}
void Schedule::handleWINJMULT(Opm::Schedule::HandlerContext& handlerContext) {
for (const auto& record : handlerContext.keyword) {
const std::string& wellNamePattern = record.getItem("WELL_NAME").getTrimmedString(0);
const auto well_names = wellNames(wellNamePattern);
for (const auto& well_name : well_names) {
auto well = this->snapshots.back().wells( well_name );
if (well.isProducer()) {
const std::string reason = fmt::format("Keyword WINJMULT can only apply to injectors,"
" but Well {} is a producer", well_name);
throw OpmInputError(reason, handlerContext.keyword.location());
}
if (well.handleWINJMULT(record, handlerContext.keyword.location()))
this->snapshots.back().wells.update( std::move(well));
}
}
}
void Schedule::handleWPMITAB(HandlerContext& handlerContext) {
for (const auto& record : handlerContext.keyword) {
const std::string& wellNamePattern = record.getItem("WELL").getTrimmedString(0);
@@ -2478,6 +2496,7 @@ Well{0} entered with 'FIELD' parent group:
{ "WVFPEXP" , &Schedule::handleWVFPEXP },
{ "WWPAVE" , &Schedule::handleWWPAVE },
{ "WPIMULT" , &Schedule::handleWPIMULT },
{ "WINJMULT", &Schedule::handleWINJMULT },
{ "WPMITAB" , &Schedule::handleWPMITAB },
{ "WPOLYMER", &Schedule::handleWPOLYMER },
{ "WRFT" , &Schedule::handleWRFT },

View File

@@ -311,6 +311,7 @@ const std::optional<std::pair<double, double>>& Connection::perf_range() const {
&& this->m_re == rhs.m_re
&& this->m_connection_length == rhs.m_connection_length
&& this->m_skin_factor == rhs.m_skin_factor
&& this->m_injmult == rhs.m_injmult
&& this->m_Kh == rhs.m_Kh
&& this->sat_tableId == rhs.sat_tableId
&& this->open_state == rhs.open_state
@@ -354,6 +355,19 @@ Connection::State Connection::StateFromString( const std::string& stringValue )
throw std::invalid_argument("Unknown enum state string: " + stringValue );
}
Connection::InjMultMode Connection::injModeFromString(const std::string& str) {
if (str == "WREV")
return Connection::InjMultMode::WREV;
else if (str == "CREV")
return Connection::InjMultMode::CREV;
else if (str == "CIRR")
return Connection::InjMultMode::CIRR;
else if (str == "NONE")
return Connection::InjMultMode::NONE;
else
throw std::invalid_argument("Unknow enum INJMultMode string: " + str);
}
std::string Connection::Direction2String(const Direction enumValue)
{
@@ -442,4 +456,12 @@ Connection::CTFKind Connection::kind() const {
return m_ctfkind;
}
Connection::InjMult Connection::injmult() const {
return m_injmult;
}
void Connection::setInjMult(const Connection::InjMult& inj_mult) {
m_injmult = inj_mult;
}
}

View File

@@ -1300,6 +1300,59 @@ bool Well::handleWPIMULT(const DeckRecord& record) {
}
bool Well::handleWINJMULT(const Opm::DeckRecord& record, const KeywordLocation& location) {
// TODO: the this keyword, defaulted means it <=0.
// We need to check how the following works
auto match = [=] ( const Connection& c) -> bool {
if (!match_eq(c.getI() , record, "I", -1)) return false;
if (!match_eq(c.getJ() , record, "J", -1)) return false;
if (!match_eq(c.getK() , record, "K", -1)) return false;
return true;
};
// if this record using WREV, with the current ideas, we will rewrite the information to all the connectios regarding
// using the WINJMULT record information
// if this record use CREV or CIRR, and previoiusly, the well is using WREV, we need to discard the WREV setup for
// all the connections. For the connections not specified in the record, the injmult information will be reset.
const std::string mode = record.getItem("MODE").getTrimmedString(0);
const double fracture_pressure = record.getItem("FRACTURING_PRESSURE").get<double>(0);
const double multiple_gradient = record.getItem("MULTIPLIER_GRADIENT").get<double>(0);
auto new_connections = std::make_shared<WellConnections>(this->connections->ordering(), this->headI, this->headJ);
const Connection::InjMult inj_mult {Connection::injModeFromString(mode), fracture_pressure, multiple_gradient};
if (mode == "WREV") {
// all the connections will share the same INJMULT setup
for (auto c : *this->connections) {
c.setInjMult(inj_mult);
new_connections->add(c);
}
} else if (mode == "CREV" || mode == "CIRR"){
// check whether it was under WREV previously.
// if yes, we need to reset all the connections for injmult operation
const bool is_prev_wrev = this->connections->underWREVInjMultMode();
for (auto c : *this->connections) {
if (match(c)) {
c.setInjMult(inj_mult);
} else {
if (is_prev_wrev) {
// reset the injMult information for this connection
c.setInjMult({});
}
}
new_connections->add(c);
}
} else {
const std::string msg = fmt::format("unknown WINJMULT operation mode {} with keyword {}"
"at line {} in file {}", mode, location.keyword,
location.lineno, location.filename);
throw std::logic_error(msg);
}
return this->updateConnections(std::move(new_connections), false);
}
bool Opm::Well::applyGlobalWPIMULT(const double scaling_factor)
{
auto new_connections = std::make_shared<WellConnections>(this->connections->ordering(), this->headI, this->headJ);

View File

@@ -284,6 +284,17 @@ namespace Opm {
}
}
bool WellConnections::underWREVInjMultMode() const {
// TODO: if the first connection is under WREV, all the connections should be under WREV
// how we can guarantee that?
// and hesitate to add extra member to this class
if (this->m_connections.empty()) {
return false;
}
const bool first_con_wrev = this->m_connections[0].injmult().mode == Connection::InjMultMode::WREV;
return first_con_wrev;
}
void WellConnections::addConnection(const int i, const int j, const int k,
const std::size_t global_index,
const int complnum,