Merge pull request #3577 from GitPaean/fixing_winjmult
separating the WINJMULT for well and connections
This commit is contained in:
@@ -221,6 +221,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/Well/WellTestState.cpp
|
||||
src/opm/input/eclipse/Schedule/WellTraj/RigEclipseWellLogExtractor.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WellTracerProperties.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WINJMULT.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WList.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WListManager.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/WVFPDP.cpp
|
||||
@@ -1233,6 +1234,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/Schedule/Well/WellMICPProperties.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellPolymerProperties.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellTracerProperties.hpp
|
||||
opm/input/eclipse/Schedule/Well/WINJMULT.hpp
|
||||
opm/input/eclipse/Schedule/Well/WVFPDP.hpp
|
||||
opm/input/eclipse/Schedule/Well/WVFPEXP.hpp
|
||||
opm/input/eclipse/Schedule/Well/WellTestConfig.hpp
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <optional>
|
||||
#include <limits>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/Well/WINJMULT.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace RestartIO {
|
||||
@@ -77,34 +79,6 @@ namespace RestartIO {
|
||||
Defaulted,
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct InjMult {
|
||||
bool is_active {false};
|
||||
double fracture_pressure {std::numeric_limits<double>::max()};
|
||||
double multiplier_gradient {0.};
|
||||
|
||||
bool active() const
|
||||
{
|
||||
return is_active;
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(is_active);
|
||||
serializer(fracture_pressure);
|
||||
serializer(multiplier_gradient);
|
||||
}
|
||||
|
||||
bool operator==( const InjMult& rhs ) const {
|
||||
return is_active == rhs.is_active
|
||||
&& fracture_pressure == rhs.fracture_pressure
|
||||
&& multiplier_gradient == rhs.multiplier_gradient;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Connection();
|
||||
Connection(int i, int j , int k ,
|
||||
std::size_t global_index,
|
||||
@@ -149,9 +123,8 @@ namespace RestartIO {
|
||||
double skinFactor() const;
|
||||
CTFKind kind() const;
|
||||
const InjMult& injmult() const;
|
||||
bool activeInjMult() const;
|
||||
void setInjMult(const InjMult& inj_mult);
|
||||
// remove the injMult setting and INJMULT is not active for this connection
|
||||
void clearInjMult();
|
||||
|
||||
void setState(State state);
|
||||
void setComplnum(int compnum);
|
||||
@@ -219,7 +192,7 @@ namespace RestartIO {
|
||||
|
||||
std::array<int,3> ijk;
|
||||
CTFKind m_ctfkind;
|
||||
InjMult m_injmult;
|
||||
std::optional<InjMult> m_injmult;
|
||||
std::size_t m_global_index;
|
||||
/*
|
||||
The sort_value member is a peculiar quantity. The connections are
|
||||
|
||||
59
opm/input/eclipse/Schedule/Well/WINJMULT.hpp
Normal file
59
opm/input/eclipse/Schedule/Well/WINJMULT.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 2023 Equinor.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_WINJMULT_HPP
|
||||
#define OPM_WINJMULT_HPP
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class KeywordLocation;
|
||||
|
||||
struct InjMult {
|
||||
|
||||
enum class InjMultMode {
|
||||
WREV,
|
||||
CREV,
|
||||
CIRR,
|
||||
NONE,
|
||||
};
|
||||
|
||||
double fracture_pressure {std::numeric_limits<double>::max()};
|
||||
double multiplier_gradient {0.};
|
||||
|
||||
static InjMultMode injMultModeFromString(const std::string& str, const KeywordLocation& location);
|
||||
|
||||
template <class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(fracture_pressure);
|
||||
serializer(multiplier_gradient);
|
||||
}
|
||||
|
||||
bool operator==(const InjMult& rhs) const;
|
||||
|
||||
static InjMult serializationTestObject();
|
||||
static std::string InjMultToString(const InjMult&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // OPM_WINJMULT_HPP
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <opm/input/eclipse/Schedule/Well/WellEnums.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellInjectionControls.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellProductionControls.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WINJMULT.hpp>
|
||||
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@@ -76,14 +77,10 @@ class Well {
|
||||
public:
|
||||
using Status = WellStatus;
|
||||
|
||||
enum class InjMultMode {
|
||||
WREV,
|
||||
CREV,
|
||||
CIRR,
|
||||
NONE,
|
||||
};
|
||||
|
||||
static InjMultMode injMultModeFromString(const std::string& str, const KeywordLocation& location);
|
||||
/*
|
||||
* The mode for the keyword WINJMULT. It can have four different values: WREV, CREV, CIRR and NONE.
|
||||
*/
|
||||
using InjMultMode = InjMult::InjMultMode;
|
||||
|
||||
/*
|
||||
The elements in this enum are used as bitmasks to keep track
|
||||
@@ -393,6 +390,8 @@ public:
|
||||
const std::string& groupName() const;
|
||||
Phase getPreferredPhase() const;
|
||||
InjMultMode getInjMultMode() const;
|
||||
const InjMult& getWellInjMult() const;
|
||||
bool aciveWellInjMult() const;
|
||||
|
||||
bool hasConnections() const;
|
||||
const std::vector<const Connection *> getConnections(int completion) const;
|
||||
@@ -550,6 +549,7 @@ public:
|
||||
serializer(m_pavg);
|
||||
serializer(well_temperature);
|
||||
serializer(inj_mult_mode);
|
||||
serializer(well_inj_mult);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -597,6 +597,7 @@ private:
|
||||
PAvg m_pavg;
|
||||
double well_temperature;
|
||||
InjMultMode inj_mult_mode = InjMultMode::NONE;
|
||||
std::optional<InjMult> well_inj_mult;
|
||||
};
|
||||
|
||||
std::ostream& operator<<( std::ostream&, const Well::WellInjectionProperties& );
|
||||
|
||||
@@ -131,6 +131,7 @@ Connection::Connection(const RestartIO::RstConnection& rst_connection, const Sch
|
||||
result.m_ctfkind = CTFKind::Defaulted;
|
||||
result.m_global_index = 12;
|
||||
result.m_perf_range = std::make_pair(14,15);
|
||||
result.m_injmult = InjMult::serializationTestObject();
|
||||
result.m_sort_value = 14;
|
||||
result.m_defaultSatTabId = true;
|
||||
result.segment_number = 16;
|
||||
@@ -297,6 +298,9 @@ const std::optional<std::pair<double, double>>& Connection::perf_range() const {
|
||||
ss << "segment_nr " << this->segment_number << std::endl;
|
||||
ss << "center_depth " << this->center_depth << std::endl;
|
||||
ss << "sort_value" << this->m_sort_value<< std::endl;
|
||||
if (this->m_injmult.has_value()) {
|
||||
ss << "INJMULT " << InjMult::InjMultToString(this->m_injmult.value()) << std::endl;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
@@ -444,16 +448,17 @@ Connection::CTFKind Connection::kind() const {
|
||||
return m_ctfkind;
|
||||
}
|
||||
|
||||
const Connection::InjMult& Connection::injmult() const {
|
||||
return m_injmult;
|
||||
const InjMult& Connection::injmult() const {
|
||||
assert(this->activeInjMult());
|
||||
return m_injmult.value();
|
||||
}
|
||||
|
||||
void Connection::setInjMult(const Connection::InjMult& inj_mult) {
|
||||
bool Connection::activeInjMult() const {
|
||||
return this->m_injmult.has_value();
|
||||
}
|
||||
|
||||
void Connection::setInjMult(const InjMult& inj_mult) {
|
||||
m_injmult = inj_mult;
|
||||
}
|
||||
|
||||
void Connection::clearInjMult() {
|
||||
this->setInjMult({});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
63
src/opm/input/eclipse/Schedule/Well/WINJMULT.cpp
Normal file
63
src/opm/input/eclipse/Schedule/Well/WINJMULT.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright 2023 Equinor.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <opm/common/OpmLog/KeywordLocation.hpp>
|
||||
#include <opm/common/utility/OpmInputError.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/Well/WINJMULT.hpp>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
InjMult::InjMultMode InjMult::injMultModeFromString(const std::string& str, const KeywordLocation& location) {
|
||||
if (str == "WREV")
|
||||
return InjMultMode::WREV;
|
||||
else if (str == "CREV")
|
||||
return InjMultMode::CREV;
|
||||
else if (str == "CIRR")
|
||||
return InjMultMode::CIRR;
|
||||
else
|
||||
throw OpmInputError(fmt::format("Unknown mode {} is specified in WINJMULT keyword", str), location);
|
||||
}
|
||||
|
||||
|
||||
bool InjMult::operator==(const InjMult& rhs) const
|
||||
{
|
||||
return fracture_pressure == rhs.fracture_pressure
|
||||
&& multiplier_gradient == rhs.multiplier_gradient;
|
||||
}
|
||||
|
||||
|
||||
InjMult InjMult::serializationTestObject() {
|
||||
InjMult result;
|
||||
result.fracture_pressure = 1.e9;
|
||||
result.multiplier_gradient = 2.;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::string InjMult::InjMultToString(const InjMult& mult) {
|
||||
std::string ss = fmt::format("fracture_pressure {}, multiplier_gradient {}",
|
||||
mult.fracture_pressure, mult.multiplier_gradient);
|
||||
return ss;
|
||||
}
|
||||
|
||||
} // end of namespace Opm
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
#include "../MSW/Compsegs.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
@@ -310,7 +311,8 @@ Well::Well(const RestartIO::RstWell& rst_well,
|
||||
wvfpdp(std::make_shared<WVFPDP>()),
|
||||
wvfpexp(explicitTHPOptions(rst_well)),
|
||||
status(status_from_int(rst_well.well_status)),
|
||||
well_temperature(Metric::TemperatureOffset + ParserKeywords::STCOND::TEMPERATURE::defaultValue)
|
||||
well_temperature(Metric::TemperatureOffset + ParserKeywords::STCOND::TEMPERATURE::defaultValue),
|
||||
well_inj_mult(std::nullopt)
|
||||
{
|
||||
if (this->wtype.producer()) {
|
||||
auto p = std::make_shared<WellProductionProperties>(this->unit_system, wname);
|
||||
@@ -489,8 +491,8 @@ Well::Well(const std::string& wname_arg,
|
||||
wvfpdp(std::make_shared<WVFPDP>()),
|
||||
wvfpexp(std::make_shared<WVFPEXP>()),
|
||||
status(Status::SHUT),
|
||||
well_temperature(Metric::TemperatureOffset + ParserKeywords::STCOND::TEMPERATURE::defaultValue)
|
||||
|
||||
well_temperature(Metric::TemperatureOffset + ParserKeywords::STCOND::TEMPERATURE::defaultValue),
|
||||
well_inj_mult(std::nullopt)
|
||||
{
|
||||
auto p = std::make_shared<WellProductionProperties>(this->unit_system, this->wname);
|
||||
p->whistctl_cmode = whistctl_cmode;
|
||||
@@ -533,6 +535,7 @@ Well Well::serializationTestObject()
|
||||
result.wvfpexp = std::make_shared<WVFPEXP>(WVFPEXP::serializationTestObject());
|
||||
result.m_pavg = PAvg();
|
||||
result.well_temperature = 10.0;
|
||||
result.well_inj_mult = InjMult::serializationTestObject();
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -565,17 +568,6 @@ bool Well::updateWellGuideRate(double guide_rate_arg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Well::InjMultMode Well::injMultModeFromString(const std::string& str, const KeywordLocation& location) {
|
||||
if (str == "WREV")
|
||||
return InjMultMode::WREV;
|
||||
else if (str == "CREV")
|
||||
return InjMultMode::CREV;
|
||||
else if (str == "CIRR")
|
||||
return InjMultMode::CIRR;
|
||||
else
|
||||
throw OpmInputError(fmt::format("Unknown mode {} is specified in WINJMULT keyword", str), location);
|
||||
}
|
||||
|
||||
|
||||
bool Well::updateFoamProperties(std::shared_ptr<WellFoamProperties> foam_properties_arg) {
|
||||
if (this->wtype.producer()) {
|
||||
@@ -1327,11 +1319,8 @@ bool Well::handleWINJMULT(const Opm::DeckRecord& record, const KeywordLocation&
|
||||
return true;
|
||||
};
|
||||
|
||||
// check whether it was under WREV previously.
|
||||
// if yes, we need to reset all the connections for INJMULT specification
|
||||
const bool is_prev_wrev = this->inj_mult_mode == InjMultMode::WREV;
|
||||
using Kw = ParserKeywords::WINJMULT;
|
||||
const InjMultMode mode = injMultModeFromString(record.getItem<Kw::MODE>().getTrimmedString(0), location);
|
||||
const InjMultMode mode = InjMult::injMultModeFromString(record.getItem<Kw::MODE>().getTrimmedString(0), location);
|
||||
const bool mode_change = (this->inj_mult_mode != mode);
|
||||
if (mode_change) {
|
||||
this->inj_mult_mode = mode;
|
||||
@@ -1339,33 +1328,26 @@ bool Well::handleWINJMULT(const Opm::DeckRecord& record, const KeywordLocation&
|
||||
const double fracture_pressure = record.getItem<Kw::FRACTURING_PRESSURE>().getSIDouble(0);
|
||||
const double multiple_gradient = record.getItem<Kw::MULTIPLIER_GRADIENT>().getSIDouble(0);
|
||||
auto new_connections = std::make_shared<WellConnections>(this->connections->ordering(), this->headI, this->headJ);
|
||||
const Connection::InjMult inj_mult {true, fracture_pressure, multiple_gradient};
|
||||
const InjMult inj_mult {fracture_pressure, multiple_gradient};
|
||||
bool connections_update = false;
|
||||
bool well_inj_update = false;
|
||||
|
||||
if (mode == InjMultMode::WREV) {
|
||||
// all the connections will share the same INJMULT setup
|
||||
for (auto c : *this->connections) {
|
||||
c.setInjMult(inj_mult);
|
||||
new_connections->add(c);
|
||||
}
|
||||
// all the connections will share the same INJMULT setup when under WREV
|
||||
// it is stored in the Well object
|
||||
this->well_inj_mult = inj_mult;
|
||||
well_inj_update = true;
|
||||
} else if (mode == InjMultMode::CREV || mode == InjMultMode::CIRR){
|
||||
for (auto c : *this->connections) {
|
||||
if (match(c)) {
|
||||
c.setInjMult(inj_mult);
|
||||
} else {
|
||||
// if previously defined with WREV for the well, for all the connections
|
||||
// not specified in the new CREV or CIRR records, we do not consider they have
|
||||
// an active WINJMULT setup
|
||||
if (is_prev_wrev) {
|
||||
// reset the injMult information for this connection
|
||||
// basically, disable the injMult for this connection
|
||||
c.clearInjMult();
|
||||
}
|
||||
}
|
||||
new_connections->add(c);
|
||||
}
|
||||
connections_update = this->updateConnections(std::move(new_connections), false);
|
||||
}
|
||||
|
||||
return this->updateConnections(std::move(new_connections), false) || mode_change;
|
||||
return mode_change || connections_update || well_inj_update;
|
||||
}
|
||||
|
||||
|
||||
@@ -1635,6 +1617,7 @@ bool Well::operator==(const Well& data) const {
|
||||
&& (this->getInjectionProperties() == data.getInjectionProperties())
|
||||
&& (this->well_temperature == data.well_temperature)
|
||||
&& (this->inj_mult_mode == data.inj_mult_mode)
|
||||
&& (this->well_inj_mult == data.well_inj_mult)
|
||||
;
|
||||
}
|
||||
|
||||
@@ -1719,3 +1702,14 @@ int Opm::Well::eclipseControlMode(const Well& well,
|
||||
Opm::Well::InjMultMode Opm::Well::getInjMultMode() const {
|
||||
return this->inj_mult_mode;
|
||||
}
|
||||
|
||||
const Opm::InjMult& Opm::Well::getWellInjMult() const {
|
||||
assert(this->aciveWellInjMult());
|
||||
return this->well_inj_mult.value();
|
||||
}
|
||||
|
||||
bool Opm::Well::aciveWellInjMult() const {
|
||||
return this->well_inj_mult.has_value();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user