Merge pull request #3313 from GitPaean/support_cake_filteration
A simple cake model to simulate formation damage due to suspended solids in injection water
This commit is contained in:
commit
4fb2a3557b
@ -201,6 +201,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/Tuning.cpp
|
||||
src/opm/input/eclipse/Schedule/WriteRestartFileEvents.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/Connection.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/FilterCake.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/injection.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/NameOrder.cpp
|
||||
src/opm/input/eclipse/Schedule/Well/PAvg.cpp
|
||||
@ -1219,6 +1220,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/Schedule/VFPInjTable.hpp
|
||||
opm/input/eclipse/Schedule/VFPProdTable.hpp
|
||||
opm/input/eclipse/Schedule/Well/Connection.hpp
|
||||
opm/input/eclipse/Schedule/Well/FilterCake.hpp
|
||||
opm/input/eclipse/Schedule/Well/PAvg.hpp
|
||||
opm/input/eclipse/Schedule/Well/PAvgCalculator.hpp
|
||||
opm/input/eclipse/Schedule/Well/PAvgCalculatorCollection.hpp
|
||||
|
@ -747,6 +747,9 @@ namespace Opm
|
||||
void handleWVFPEXP (HandlerContext&);
|
||||
void handleWWPAVE (HandlerContext&);
|
||||
void handleWPIMULT (HandlerContext&);
|
||||
void handleWINJCLN (HandlerContext&);
|
||||
void handleWINJDAM (HandlerContext&);
|
||||
void handleWINJFCNC (HandlerContext&);
|
||||
void handleWINJMULT (HandlerContext&);
|
||||
void handleWPMITAB (HandlerContext&);
|
||||
void handleWPOLYMER (HandlerContext&);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <optional>
|
||||
#include <limits>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/Well/FilterCake.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WINJMULT.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@ -125,6 +126,11 @@ namespace RestartIO {
|
||||
const InjMult& injmult() const;
|
||||
bool activeInjMult() const;
|
||||
void setInjMult(const InjMult& inj_mult);
|
||||
void setFilterCake(const FilterCake& filter_cake);
|
||||
const FilterCake& getFilterCake() const;
|
||||
bool filterCakeActive() const;
|
||||
double getFilterCakeRadius() const;
|
||||
double getFilterCakeArea() const;
|
||||
|
||||
void setState(State state);
|
||||
void setComplnum(int compnum);
|
||||
@ -174,6 +180,7 @@ namespace RestartIO {
|
||||
serializer(m_defaultSatTabId);
|
||||
serializer(segment_number);
|
||||
serializer(m_subject_to_welpi);
|
||||
serializer(m_filter_cake);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -257,6 +264,8 @@ namespace RestartIO {
|
||||
// Whether or not this Connection is subject to WELPI scaling.
|
||||
bool m_subject_to_welpi = false;
|
||||
|
||||
std::optional<FilterCake> m_filter_cake;
|
||||
|
||||
static std::string CTFKindToString(const CTFKind);
|
||||
};
|
||||
}
|
||||
|
76
opm/input/eclipse/Schedule/Well/FilterCake.hpp
Normal file
76
opm/input/eclipse/Schedule/Well/FilterCake.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
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_FILTERCAKE_HPP
|
||||
#define OPM_FILTERCAKE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class DeckRecord;
|
||||
class KeywordLocation;
|
||||
|
||||
struct FilterCake {
|
||||
|
||||
enum class FilterCakeGeometry {
|
||||
LINEAR,
|
||||
RADIAL,
|
||||
NONE,
|
||||
};
|
||||
|
||||
static FilterCakeGeometry filterCakeGeometryFromString(const std::string& str, const KeywordLocation& location);
|
||||
static std::string filterCakeGeometryToString(const FilterCakeGeometry& geometry);
|
||||
|
||||
FilterCakeGeometry geometry{FilterCakeGeometry::NONE};
|
||||
double perm{0.};
|
||||
double poro{0.};
|
||||
std::optional<double> radius;
|
||||
std::optional<double> flow_area;
|
||||
// skin factor multiplier
|
||||
// it is controlled by keyword WINJCLN
|
||||
double sf_multiplier{1.};
|
||||
|
||||
FilterCake() = default;
|
||||
|
||||
explicit FilterCake(const DeckRecord& record, const KeywordLocation& location);
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer) {
|
||||
serializer(geometry);
|
||||
serializer(perm);
|
||||
serializer(poro);
|
||||
serializer(radius);
|
||||
serializer(flow_area);
|
||||
serializer(sf_multiplier);
|
||||
}
|
||||
|
||||
static FilterCake serializationTestObject();
|
||||
|
||||
bool operator==(const FilterCake& other) const;
|
||||
|
||||
void applyCleanMultiplier(const double factor);
|
||||
|
||||
static std::string filterCakeToString(const FilterCake& fc);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //OPM_FILTERCAKE_HPP
|
@ -481,7 +481,11 @@ public:
|
||||
bool handleWELOPENConnections(const DeckRecord& record, Connection::State status);
|
||||
bool handleCOMPLUMP(const DeckRecord& record);
|
||||
bool handleWPIMULT(const DeckRecord& record);
|
||||
bool handleWINJCLN(const DeckRecord& record, const KeywordLocation& location);
|
||||
bool handleWINJDAM(const DeckRecord& record, const KeywordLocation& location);
|
||||
bool handleWINJMULT(const DeckRecord& record, const KeywordLocation& location);
|
||||
void setFilterConc(const double conc);
|
||||
double getFilterConc() const;
|
||||
bool applyGlobalWPIMULT(double scale_factor);
|
||||
|
||||
void filterConnections(const ActiveGridCells& grid);
|
||||
@ -550,6 +554,7 @@ public:
|
||||
serializer(well_temperature);
|
||||
serializer(inj_mult_mode);
|
||||
serializer(well_inj_mult);
|
||||
serializer(m_filter_concentration);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -598,6 +603,7 @@ private:
|
||||
double well_temperature;
|
||||
InjMultMode inj_mult_mode = InjMultMode::NONE;
|
||||
std::optional<InjMult> well_inj_mult;
|
||||
double m_filter_concentration = 0.;
|
||||
};
|
||||
|
||||
std::ostream& operator<<( std::ostream&, const Well::WellInjectionProperties& );
|
||||
|
@ -1976,6 +1976,46 @@ Well{0} entered with 'FIELD' parent group:
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWINJCLN(HandlerContext& handlerContext) {
|
||||
for (const auto& record : handlerContext.keyword) {
|
||||
const std::string& wellNamePattern = record.getItem<ParserKeywords::WINJCLN::WELL_NAME>().getTrimmedString(0);
|
||||
const auto well_names = this->wellNames(wellNamePattern, handlerContext);
|
||||
for (const auto& well_name: well_names) {
|
||||
auto well = this->snapshots.back().wells(well_name);
|
||||
well.handleWINJCLN(record, handlerContext.keyword.location());
|
||||
this->snapshots.back().wells.update(std::move(well));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWINJDAM(HandlerContext& handlerContext) {
|
||||
for (const auto& record : handlerContext.keyword) {
|
||||
const std::string& wellNamePattern = record.getItem<ParserKeywords::WINJDAM::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.handleWINJDAM(record, handlerContext.keyword.location())) {
|
||||
this->snapshots.back().wells.update( std::move(well) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleWINJFCNC(HandlerContext& handlerContext) {
|
||||
for (const auto& record : handlerContext.keyword) {
|
||||
const std::string& wellNamePattern = record.getItem<ParserKeywords::WINJFCNC::WELL>().getTrimmedString(0);
|
||||
const auto well_names = this->wellNames(wellNamePattern, handlerContext);
|
||||
for (const auto& well_name: well_names) {
|
||||
auto well = this->snapshots.back().wells(well_name);
|
||||
const auto filter_conc = record.getItem<ParserKeywords::WINJFCNC::VOL_CONCENTRATION>().get<double>(0);
|
||||
// the unit is ppm_vol
|
||||
well.setFilterConc(filter_conc/1.e6);
|
||||
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);
|
||||
@ -2558,6 +2598,9 @@ Well{0} entered with 'FIELD' parent group:
|
||||
{ "WVFPEXP" , &Schedule::handleWVFPEXP },
|
||||
{ "WWPAVE" , &Schedule::handleWWPAVE },
|
||||
{ "WPIMULT" , &Schedule::handleWPIMULT },
|
||||
{ "WINJDAM" , &Schedule::handleWINJDAM },
|
||||
{ "WINJFCNC", &Schedule::handleWINJFCNC },
|
||||
{ "WINJCLN", &Schedule::handleWINJCLN },
|
||||
{ "WPMITAB" , &Schedule::handleWPMITAB },
|
||||
{ "WPOLYMER", &Schedule::handleWPOLYMER },
|
||||
{ "WRFT" , &Schedule::handleWRFT },
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <opm/input/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/Connection.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/FilterCake.hpp>
|
||||
#include <opm/input/eclipse/Schedule/ScheduleGrid.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@ -136,6 +137,7 @@ Connection::Connection(const RestartIO::RstConnection& rst_connection, const Sch
|
||||
result.m_defaultSatTabId = true;
|
||||
result.segment_number = 16;
|
||||
result.m_subject_to_welpi = true;
|
||||
result.m_filter_cake = FilterCake::serializationTestObject();
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -301,6 +303,9 @@ const std::optional<std::pair<double, double>>& Connection::perf_range() const {
|
||||
if (this->m_injmult.has_value()) {
|
||||
ss << "INJMULT " << InjMult::InjMultToString(this->m_injmult.value()) << std::endl;
|
||||
}
|
||||
if (this->m_filter_cake.has_value()) {
|
||||
ss << "FilterCake " << FilterCake::filterCakeToString(this->m_filter_cake.value()) << std::endl;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
@ -323,7 +328,8 @@ const std::optional<std::pair<double, double>>& Connection::perf_range() const {
|
||||
&& this->segment_number == rhs.segment_number
|
||||
&& this->center_depth == rhs.center_depth
|
||||
&& this->m_sort_value == rhs.m_sort_value
|
||||
&& this->m_subject_to_welpi == rhs.m_subject_to_welpi;
|
||||
&& this->m_subject_to_welpi == rhs.m_subject_to_welpi
|
||||
&& this->m_filter_cake == rhs.m_filter_cake;
|
||||
}
|
||||
|
||||
bool Connection::operator!=( const Connection& rhs ) const {
|
||||
@ -461,4 +467,41 @@ void Connection::setInjMult(const InjMult& inj_mult) {
|
||||
m_injmult = inj_mult;
|
||||
}
|
||||
|
||||
|
||||
void Connection::setFilterCake(const FilterCake& filter_cake) {
|
||||
this->m_filter_cake = filter_cake;
|
||||
}
|
||||
|
||||
bool Connection::filterCakeActive() const {
|
||||
return this->m_filter_cake.has_value();
|
||||
}
|
||||
|
||||
const FilterCake& Connection::getFilterCake() const {
|
||||
assert(this->filterCakeActive());
|
||||
return this->m_filter_cake.value();
|
||||
}
|
||||
|
||||
|
||||
double Connection::getFilterCakeRadius() const {
|
||||
if (this->getFilterCake().radius.has_value()) {
|
||||
return this->getFilterCake().radius.value();
|
||||
} else {
|
||||
return this->m_rw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double Connection::getFilterCakeArea() const {
|
||||
if (this->getFilterCake().flow_area.has_value()) {
|
||||
return this->getFilterCake().flow_area.value();
|
||||
} else {
|
||||
const double radius = this->getFilterCakeRadius();
|
||||
const double length = this->m_connection_length;
|
||||
constexpr double pi = 3.14159265;
|
||||
return 2. * pi * radius * length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end of namespace Opm
|
||||
|
115
src/opm/input/eclipse/Schedule/Well/FilterCake.cpp
Normal file
115
src/opm/input/eclipse/Schedule/Well/FilterCake.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
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/input/eclipse/Deck/DeckRecord.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/W.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/FilterCake.hpp>
|
||||
|
||||
#include <opm/common/OpmLog/KeywordLocation.hpp>
|
||||
#include <opm/common/utility/OpmInputError.hpp>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace Opm {
|
||||
FilterCake::FilterCakeGeometry FilterCake::filterCakeGeometryFromString(const std::string& str,
|
||||
const KeywordLocation& location) {
|
||||
if (str == "LINEAR")
|
||||
return FilterCakeGeometry::LINEAR;
|
||||
else if (str == "RADIAL")
|
||||
return FilterCakeGeometry::RADIAL;
|
||||
else
|
||||
throw OpmInputError(fmt::format("Unknown geometry type {} is specified in WINJDAM keyword", str), location);
|
||||
}
|
||||
|
||||
std::string FilterCake::filterCakeGeometryToString(const Opm::FilterCake::FilterCakeGeometry& geometry) {
|
||||
switch (geometry) {
|
||||
case FilterCakeGeometry::LINEAR:
|
||||
return "LINEAR";
|
||||
case FilterCakeGeometry::RADIAL:
|
||||
return "RADIAL";
|
||||
case FilterCakeGeometry::NONE:
|
||||
return "NONE";
|
||||
default:
|
||||
return "unknown FileterCakeGeometry type";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FilterCake::FilterCake(const DeckRecord& record, const KeywordLocation& location) {
|
||||
this->geometry = filterCakeGeometryFromString(record.getItem<ParserKeywords::WINJDAM::GEOMETRY>().getTrimmedString(0),
|
||||
location);
|
||||
this->perm = record.getItem<ParserKeywords::WINJDAM::FILTER_CAKE_PERM>().getSIDouble(0);
|
||||
this->poro = record.getItem<ParserKeywords::WINJDAM::FILTER_CAKE_PORO>().getSIDouble(0);
|
||||
|
||||
const auto& item_radius = record.getItem<ParserKeywords::WINJDAM::FILTER_CAKE_RADIUS>();
|
||||
if (!item_radius.defaultApplied(0)) {
|
||||
this->radius = item_radius.getSIDouble(0);
|
||||
}
|
||||
|
||||
const auto& item_area = record.getItem<ParserKeywords::WINJDAM::FILTER_CAKE_AREA>();
|
||||
if (!item_area.defaultApplied(0)) {
|
||||
this->flow_area = item_area.getSIDouble(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool FilterCake::operator==(const FilterCake& other) const {
|
||||
return geometry == other.geometry
|
||||
&& perm == other.perm
|
||||
&& poro == other.poro
|
||||
&& radius == other.radius
|
||||
&& flow_area == other.flow_area
|
||||
&& sf_multiplier == other.sf_multiplier;
|
||||
}
|
||||
|
||||
void FilterCake::applyCleanMultiplier(const double factor) {
|
||||
this->sf_multiplier *= factor;
|
||||
}
|
||||
|
||||
FilterCake FilterCake::serializationTestObject() {
|
||||
FilterCake filter_cake;
|
||||
filter_cake.geometry = FilterCakeGeometry::LINEAR;
|
||||
filter_cake.perm = 1.e-8;
|
||||
filter_cake.poro = 0.2;
|
||||
filter_cake.radius = 0.1;
|
||||
filter_cake.flow_area = 20.;
|
||||
filter_cake.sf_multiplier = 0.2;
|
||||
|
||||
return filter_cake;
|
||||
}
|
||||
|
||||
std::string FilterCake::filterCakeToString(const FilterCake& fc) {
|
||||
std::string str = fmt::format("geometry type {}, perm {}, poro {}",
|
||||
filterCakeGeometryToString(fc.geometry), fc.perm, fc.poro);
|
||||
if (fc.radius.has_value()) {
|
||||
fmt::format_to(std::back_inserter(str), ", radius {}", fc.radius.value());
|
||||
} else {
|
||||
fmt::format_to(std::back_inserter(str), ", radius DEFAULT");
|
||||
}
|
||||
|
||||
if (fc.flow_area.has_value()) {
|
||||
fmt::format_to(std::back_inserter(str), ", flow_area {}", fc.flow_area.value());
|
||||
} else {
|
||||
fmt::format_to(std::back_inserter(str), ", flow_area DEFAULT");
|
||||
}
|
||||
|
||||
fmt::format_to(std::back_inserter(str), ", sf_multiplier {}.", fc.sf_multiplier);
|
||||
return str;
|
||||
}
|
||||
} // end of Opm namespace
|
||||
|
@ -536,6 +536,7 @@ Well Well::serializationTestObject()
|
||||
result.m_pavg = PAvg();
|
||||
result.well_temperature = 10.0;
|
||||
result.well_inj_mult = InjMult::serializationTestObject();
|
||||
result.m_filter_concentration = 0.1;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1303,6 +1304,54 @@ bool Well::handleWPIMULT(const DeckRecord& record) {
|
||||
return this->updateConnections(std::move(new_connections), false);
|
||||
}
|
||||
|
||||
bool Well::handleWINJCLN(const DeckRecord& record, const KeywordLocation& location) {
|
||||
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;
|
||||
};
|
||||
|
||||
const double fraction_removal = record.getItem<ParserKeywords::WINJCLN::FRAC_REMOVE>().getSIDouble(0);
|
||||
if (fraction_removal < 0. || fraction_removal > 1.) {
|
||||
const auto reason = fmt::format(" the item 2 in keyword WINJCLN must be between 0 and 1, while a "
|
||||
"value {} is given.", fraction_removal);
|
||||
throw OpmInputError(reason, location);
|
||||
}
|
||||
const double fraction_remain = 1. - fraction_removal;
|
||||
auto new_connections = std::make_shared<WellConnections>(this->connections->ordering(), this->headI, this->headJ);
|
||||
for (auto c : *(this->connections)) {
|
||||
if (match(c)) {
|
||||
auto filter_cake = c.getFilterCake();
|
||||
filter_cake.applyCleanMultiplier(fraction_remain);
|
||||
c.setFilterCake(filter_cake);
|
||||
}
|
||||
new_connections->add(c);
|
||||
}
|
||||
return this->updateConnections(std::move(new_connections), false);
|
||||
}
|
||||
|
||||
bool Well::handleWINJDAM(const DeckRecord& record, const KeywordLocation& location) {
|
||||
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;
|
||||
};
|
||||
|
||||
const FilterCake filter_cake {record, location};
|
||||
auto new_connections = std::make_shared<WellConnections>(this->connections->ordering(),
|
||||
this->headI, this->headJ);
|
||||
for (auto c : *(this->connections)) {
|
||||
if (match(c)) {
|
||||
c.setFilterCake(filter_cake);
|
||||
}
|
||||
new_connections->add(c);
|
||||
}
|
||||
return this->updateConnections(std::move(new_connections), false);
|
||||
}
|
||||
|
||||
bool Well::handleWINJMULT(const Opm::DeckRecord& record, const KeywordLocation& location) {
|
||||
// for this keyword, the default for I, J, K will be negative
|
||||
@ -1618,6 +1667,7 @@ bool Well::operator==(const Well& data) const {
|
||||
&& (this->well_temperature == data.well_temperature)
|
||||
&& (this->inj_mult_mode == data.inj_mult_mode)
|
||||
&& (this->well_inj_mult == data.well_inj_mult)
|
||||
&& (this->m_filter_concentration == data.m_filter_concentration)
|
||||
;
|
||||
}
|
||||
|
||||
@ -1713,3 +1763,10 @@ bool Opm::Well::aciveWellInjMult() const {
|
||||
}
|
||||
|
||||
|
||||
void Opm::Well::setFilterConc(const double conc) {
|
||||
this->m_filter_concentration = conc;
|
||||
}
|
||||
|
||||
double Opm::Well::getFilterConc() const {
|
||||
return this->m_filter_concentration;
|
||||
}
|
33
src/opm/input/eclipse/share/keywords/900_OPM/W/WINJCLN
Normal file
33
src/opm/input/eclipse/share/keywords/900_OPM/W/WINJCLN
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "WINJCLN",
|
||||
"sections": [
|
||||
"SCHEDULE"
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
"name": "WELL_NAME",
|
||||
"value_type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "FRAC_REMOVE",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "1",
|
||||
"default": 1.0
|
||||
},
|
||||
{
|
||||
"name": "I",
|
||||
"value_type": "INT",
|
||||
"default": -1
|
||||
},
|
||||
{
|
||||
"name": "J",
|
||||
"value_type": "INT",
|
||||
"default": -1
|
||||
},
|
||||
{
|
||||
"name": "K",
|
||||
"value_type": "INT",
|
||||
"default": -1
|
||||
}
|
||||
]
|
||||
}
|
52
src/opm/input/eclipse/share/keywords/900_OPM/W/WINJDAM
Normal file
52
src/opm/input/eclipse/share/keywords/900_OPM/W/WINJDAM
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "WINJDAM",
|
||||
"sections": [
|
||||
"SCHEDULE"
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
"name": "WELL_NAME",
|
||||
"value_type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "GEOMETRY",
|
||||
"value_type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "FILTER_CAKE_PERM",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Permeability"
|
||||
},
|
||||
{
|
||||
"name": "FILTER_CAKE_PORO",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "1",
|
||||
"default": 0.3
|
||||
},
|
||||
{
|
||||
"name": "FILTER_CAKE_RADIUS",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Length"
|
||||
},
|
||||
{
|
||||
"name": "FILTER_CAKE_AREA",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Length*Length"
|
||||
},
|
||||
{
|
||||
"name": "I",
|
||||
"value_type": "INT",
|
||||
"default": -1
|
||||
},
|
||||
{
|
||||
"name": "J",
|
||||
"value_type": "INT",
|
||||
"default": -1
|
||||
},
|
||||
{
|
||||
"name": "K",
|
||||
"value_type": "INT",
|
||||
"default": -1
|
||||
}
|
||||
]
|
||||
}
|
18
src/opm/input/eclipse/share/keywords/900_OPM/W/WINJFCNC
Normal file
18
src/opm/input/eclipse/share/keywords/900_OPM/W/WINJFCNC
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "WINJFCNC",
|
||||
"sections": [
|
||||
"SCHEDULE"
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
"name": "WELL",
|
||||
"value_type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "VOL_CONCENTRATION",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "1",
|
||||
"default" : 0
|
||||
}
|
||||
]
|
||||
}
|
@ -1153,6 +1153,9 @@ set( keywords
|
||||
900_OPM/V/VAPWAT
|
||||
900_OPM/W/WATJT
|
||||
900_OPM/W/WELTRAJ
|
||||
900_OPM/W/WINJCLN
|
||||
900_OPM/W/WINJDAM
|
||||
900_OPM/W/WINJFCNC
|
||||
900_OPM/W/WMICP
|
||||
900_OPM/W/WPMITAB
|
||||
900_OPM/W/WSKPTAB)
|
||||
|
@ -75,6 +75,7 @@
|
||||
#include <opm/input/eclipse/Schedule/MSW/WellSegments.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Network/Balance.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Network/ExtNetwork.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/FilterCake.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Network/Node.hpp>
|
||||
#include <opm/input/eclipse/Schedule/OilVaporizationProperties.hpp>
|
||||
#include <opm/input/eclipse/Schedule/RFTConfig.hpp>
|
||||
@ -229,6 +230,7 @@ TEST_FOR_TYPE(Equil)
|
||||
TEST_FOR_TYPE(TLMixpar)
|
||||
TEST_FOR_TYPE(Ppcwmax)
|
||||
TEST_FOR_TYPE(Events)
|
||||
TEST_FOR_TYPE(FilterCake)
|
||||
TEST_FOR_TYPE(Fault)
|
||||
TEST_FOR_TYPE(FaultCollection)
|
||||
TEST_FOR_TYPE(FaultFace)
|
||||
|
Loading…
Reference in New Issue
Block a user