@@ -161,6 +161,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/input/eclipse/Schedule/Action/State.cpp
|
||||
src/opm/input/eclipse/Schedule/Action/WGNames.cpp
|
||||
src/opm/input/eclipse/Schedule/ArrayDimChecker.cpp
|
||||
src/opm/input/eclipse/Schedule/BCProp.cpp
|
||||
src/opm/input/eclipse/Schedule/CompletedCells.cpp
|
||||
src/opm/input/eclipse/Schedule/eval_uda.cpp
|
||||
src/opm/input/eclipse/Schedule/Events.cpp
|
||||
@@ -1209,6 +1210,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/input/eclipse/Schedule/Action/State.hpp
|
||||
opm/input/eclipse/Schedule/Action/WGNames.hpp
|
||||
opm/input/eclipse/Schedule/ArrayDimChecker.hpp
|
||||
opm/input/eclipse/Schedule/BCProp.hpp
|
||||
opm/input/eclipse/Schedule/GasLiftOpt.hpp
|
||||
opm/input/eclipse/Schedule/Network/Balance.hpp
|
||||
opm/input/eclipse/Schedule/Network/Branch.hpp
|
||||
|
||||
@@ -33,59 +33,34 @@ namespace Opm {
|
||||
class Deck;
|
||||
class DeckRecord;
|
||||
|
||||
enum class BCType {
|
||||
RATE,
|
||||
FREE,
|
||||
DIRICHLET,
|
||||
THERMAL
|
||||
};
|
||||
|
||||
enum class BCComponent {
|
||||
OIL,
|
||||
GAS,
|
||||
WATER,
|
||||
SOLVENT,
|
||||
POLYMER,
|
||||
NONE
|
||||
};
|
||||
|
||||
|
||||
class BCConfig {
|
||||
public:
|
||||
|
||||
struct BCFace {
|
||||
struct BCRegion {
|
||||
int index;
|
||||
int i1,i2;
|
||||
int j1,j2;
|
||||
int k1,k2;
|
||||
BCType bctype;
|
||||
FaceDir::DirEnum dir;
|
||||
BCComponent component;
|
||||
double rate;
|
||||
std::optional<double> pressure;
|
||||
std::optional<double> temperature;
|
||||
|
||||
BCFace() = default;
|
||||
explicit BCFace(const DeckRecord& record, const GridDims& grid);
|
||||
BCRegion() = default;
|
||||
explicit BCRegion(const DeckRecord& record, const GridDims& grid);
|
||||
|
||||
static BCFace serializationTestObject();
|
||||
static BCRegion serializationTestObject();
|
||||
|
||||
bool operator==(const BCFace& other) const;
|
||||
bool operator==(const BCRegion& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(index);
|
||||
serializer(i1);
|
||||
serializer(i2);
|
||||
serializer(j1);
|
||||
serializer(j2);
|
||||
serializer(k1);
|
||||
serializer(k2);
|
||||
serializer(bctype);
|
||||
serializer(dir);
|
||||
serializer(component);
|
||||
serializer(rate);
|
||||
serializer(pressure);
|
||||
serializer(temperature);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -96,8 +71,8 @@ public:
|
||||
static BCConfig serializationTestObject();
|
||||
|
||||
std::size_t size() const;
|
||||
std::vector<BCFace>::const_iterator begin() const;
|
||||
std::vector<BCFace>::const_iterator end() const;
|
||||
std::vector<BCRegion>::const_iterator begin() const;
|
||||
std::vector<BCRegion>::const_iterator end() const;
|
||||
bool operator==(const BCConfig& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
@@ -107,7 +82,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<BCFace> m_faces;
|
||||
std::vector<BCRegion> m_faces;
|
||||
};
|
||||
|
||||
} //namespace Opm
|
||||
|
||||
113
opm/input/eclipse/Schedule/BCProp.hpp
Normal file
113
opm/input/eclipse/Schedule/BCProp.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
Copyright 2023 Equinor ASA.
|
||||
Copyright 2023 Norce.
|
||||
|
||||
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_BC_PROP_HPP
|
||||
#define OPM_BC_PROP_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
class DeckRecord;
|
||||
|
||||
enum class BCType {
|
||||
RATE,
|
||||
FREE,
|
||||
DIRICHLET,
|
||||
THERMAL,
|
||||
CLOSED,
|
||||
NONE
|
||||
};
|
||||
|
||||
enum class BCComponent {
|
||||
OIL,
|
||||
GAS,
|
||||
WATER,
|
||||
SOLVENT,
|
||||
POLYMER,
|
||||
NONE
|
||||
};
|
||||
|
||||
|
||||
class BCProp {
|
||||
public:
|
||||
|
||||
struct BCFace {
|
||||
int index;
|
||||
BCType bctype;
|
||||
BCComponent component;
|
||||
double rate;
|
||||
std::optional<double> pressure;
|
||||
std::optional<double> temperature;
|
||||
|
||||
BCFace() = default;
|
||||
explicit BCFace(const DeckRecord& record);
|
||||
|
||||
static BCFace serializationTestObject();
|
||||
|
||||
bool operator==(const BCFace& other) const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(index);
|
||||
serializer(bctype);
|
||||
serializer(component);
|
||||
serializer(rate);
|
||||
serializer(pressure);
|
||||
serializer(temperature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BCProp() = default;
|
||||
|
||||
static BCProp serializationTestObject();
|
||||
|
||||
std::size_t size() const;
|
||||
std::vector<BCFace>::const_iterator begin() const;
|
||||
std::vector<BCFace>::const_iterator end() const;
|
||||
bool operator==(const BCProp& other) const;
|
||||
const BCFace& operator[](int index) const;
|
||||
|
||||
void updateBCProp(const DeckRecord& record);
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(m_faces);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<BCFace> m_faces;
|
||||
};
|
||||
|
||||
} //namespace Opm
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -679,6 +679,7 @@ namespace Opm
|
||||
void handleAQUCT (HandlerContext&);
|
||||
void handleAQUFETP (HandlerContext&);
|
||||
void handleAQUFLUX (HandlerContext&);
|
||||
void handleBCProp (HandlerContext&);
|
||||
void handleBRANPROP (HandlerContext&);
|
||||
void handleCOMPDAT (HandlerContext&);
|
||||
void handleCOMPLUMP (HandlerContext&);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <opm/input/eclipse/Schedule/Tuning.hpp>
|
||||
#include <opm/input/eclipse/Schedule/OilVaporizationProperties.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Events.hpp>
|
||||
#include <opm/input/eclipse/Schedule/BCProp.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Group/Group.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellEnums.hpp>
|
||||
#include <opm/input/eclipse/Schedule/MessageLimits.hpp>
|
||||
@@ -482,6 +483,7 @@ namespace Opm {
|
||||
map_member<std::string, Well> wells;
|
||||
// constant flux aquifers
|
||||
std::unordered_map<int, SingleAquiferFlux> aqufluxs;
|
||||
BCProp bcprop;
|
||||
std::unordered_map<std::string, double> target_wellpi;
|
||||
std::optional<NextStep> next_tstep;
|
||||
|
||||
@@ -510,6 +512,7 @@ namespace Opm {
|
||||
serializer(m_whistctl_mode);
|
||||
serializer(target_wellpi);
|
||||
serializer(aqufluxs);
|
||||
serializer(bcprop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,73 +22,22 @@
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/B.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/SimulationConfig/BCConfig.hpp>
|
||||
#include <opm/common/utility/OpmInputError.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
namespace {
|
||||
|
||||
namespace fromstring {
|
||||
|
||||
BCType bctype(const std::string& s) {
|
||||
if (s == "RATE")
|
||||
return BCType::RATE;
|
||||
|
||||
if (s == "FREE")
|
||||
return BCType::FREE;
|
||||
|
||||
if (s == "DIRICHLET")
|
||||
return BCType::DIRICHLET;
|
||||
|
||||
if (s == "THERMAL")
|
||||
return BCType::THERMAL;
|
||||
|
||||
throw std::invalid_argument("Not recognized boundary condition type: " + s);
|
||||
}
|
||||
|
||||
|
||||
BCComponent component(const std::string& s) {
|
||||
if (s == "OIL")
|
||||
return BCComponent::OIL;
|
||||
|
||||
if (s == "GAS")
|
||||
return BCComponent::GAS;
|
||||
|
||||
if (s == "WATER")
|
||||
return BCComponent::WATER;
|
||||
|
||||
if (s == "SOLVENT")
|
||||
return BCComponent::SOLVENT;
|
||||
|
||||
if (s == "POLYMER")
|
||||
return BCComponent::POLYMER;
|
||||
|
||||
if (s == "NONE")
|
||||
return BCComponent::NONE;
|
||||
|
||||
throw std::invalid_argument("Not recognized boundary condition compononet: " + s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using BC = ParserKeywords::BC;
|
||||
BCConfig::BCFace::BCFace(const DeckRecord& record, const GridDims& grid) :
|
||||
using BC = ParserKeywords::BCCON;
|
||||
BCConfig::BCRegion::BCRegion(const DeckRecord& record, const GridDims& grid) :
|
||||
index(record.getItem<BC::INDEX>().get<int>(0)),
|
||||
i1(0),
|
||||
i2(grid.getNX() - 1),
|
||||
j1(0),
|
||||
j2(grid.getNY() - 1),
|
||||
k1(0),
|
||||
k2(grid.getNZ() - 1),
|
||||
bctype(fromstring::bctype(record.getItem<BC::TYPE>().get<std::string>(0))),
|
||||
dir(FaceDir::FromString(record.getItem<BC::DIRECTION>().get<std::string>(0))),
|
||||
component(fromstring::component(record.getItem<BC::COMPONENT>().get<std::string>(0))),
|
||||
rate(record.getItem<BC::RATE>().getSIDouble(0))
|
||||
dir(FaceDir::FromString(record.getItem<BC::DIRECTION>().get<std::string>(0)))
|
||||
{
|
||||
if (const auto& P = record.getItem<BC::PRESSURE>(); ! P.defaultApplied(0)) {
|
||||
pressure = P.getSIDouble(0);
|
||||
}
|
||||
if (const auto& T = record.getItem<BC::TEMPERATURE>(); ! T.defaultApplied(0)) {
|
||||
temperature = T.getSIDouble(0);
|
||||
}
|
||||
if (const auto& I1 = record.getItem<BC::I1>(); ! I1.defaultApplied(0)) {
|
||||
this->i1 = I1.get<int>(0) - 1;
|
||||
}
|
||||
@@ -109,46 +58,48 @@ BCConfig::BCFace::BCFace(const DeckRecord& record, const GridDims& grid) :
|
||||
}
|
||||
}
|
||||
|
||||
BCConfig::BCFace BCConfig::BCFace::serializationTestObject()
|
||||
BCConfig::BCRegion BCConfig::BCRegion::serializationTestObject()
|
||||
{
|
||||
BCFace result;
|
||||
result.i1 = 10;
|
||||
result.i2 = 11;
|
||||
result.j1 = 12;
|
||||
result.j2 = 13;
|
||||
result.k1 = 14;
|
||||
result.k2 = 15;
|
||||
result.bctype = BCType::RATE;
|
||||
BCRegion result;
|
||||
result.index = 10;
|
||||
result.i1 = 12;
|
||||
result.i2 = 13;
|
||||
result.j1 = 13;
|
||||
result.j2 = 14;
|
||||
result.k1 = 15;
|
||||
result.k2 = 16;
|
||||
result.dir = FaceDir::XPlus;
|
||||
result.component = BCComponent::GAS;
|
||||
result.rate = 100.0;
|
||||
result.pressure = 101.0;
|
||||
result.temperature = 102.0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool BCConfig::BCFace::operator==(const BCConfig::BCFace& other) const {
|
||||
return this->i1 == other.i1 &&
|
||||
bool BCConfig::BCRegion::operator==(const BCConfig::BCRegion& other) const {
|
||||
return this->index == other.index &&
|
||||
this->i1 == other.i1 &&
|
||||
this->i2 == other.i2 &&
|
||||
this->j1 == other.j1 &&
|
||||
this->j2 == other.j2 &&
|
||||
this->k1 == other.k1 &&
|
||||
this->k2 == other.k2 &&
|
||||
this->bctype == other.bctype &&
|
||||
this->dir == other.dir &&
|
||||
this->component == other.component &&
|
||||
this->rate == other.rate &&
|
||||
this->pressure == other.pressure &&
|
||||
this->temperature == other.temperature;
|
||||
this->dir == other.dir;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BCConfig::BCConfig(const Deck& deck) {
|
||||
|
||||
if(deck.hasKeyword<ParserKeywords::BC>()){
|
||||
for (const auto* keyword : deck.getKeywordList<ParserKeywords::BC>()) {
|
||||
const std::string reason = "ERROR: The BC keyword is obsolete. \n "
|
||||
"Instead use BCCON in the GRID section to specify the connections. \n "
|
||||
"And BCPROP in the SCHEDULE section to specify the type and values. \n"
|
||||
"Check the OPM manual for details.";
|
||||
throw OpmInputError { reason, keyword->location()};
|
||||
}
|
||||
}
|
||||
|
||||
GridDims grid( deck );
|
||||
for (const auto& kw: deck.getKeywordList<ParserKeywords::BC>()) {
|
||||
for (const auto& kw: deck.getKeywordList<ParserKeywords::BCCON>()) {
|
||||
for (const auto& record : *kw)
|
||||
this->m_faces.emplace_back( record, grid );
|
||||
}
|
||||
@@ -158,7 +109,7 @@ BCConfig::BCConfig(const Deck& deck) {
|
||||
BCConfig BCConfig::serializationTestObject()
|
||||
{
|
||||
BCConfig result;
|
||||
result.m_faces = {BCFace::serializationTestObject()};
|
||||
result.m_faces = {BCRegion::serializationTestObject()};
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -168,11 +119,11 @@ std::size_t BCConfig::size() const {
|
||||
return this->m_faces.size();
|
||||
}
|
||||
|
||||
std::vector<BCConfig::BCFace>::const_iterator BCConfig::begin() const {
|
||||
std::vector<BCConfig::BCRegion>::const_iterator BCConfig::begin() const {
|
||||
return this->m_faces.begin();
|
||||
}
|
||||
|
||||
std::vector<BCConfig::BCFace>::const_iterator BCConfig::end() const {
|
||||
std::vector<BCConfig::BCRegion>::const_iterator BCConfig::end() const {
|
||||
return this->m_faces.end();
|
||||
}
|
||||
|
||||
|
||||
169
src/opm/input/eclipse/Schedule/BCProp.cpp
Normal file
169
src/opm/input/eclipse/Schedule/BCProp.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
Copyright 2023 Equinor ASA.
|
||||
Copyright 2023 Norce.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/input/eclipse/Parser/ParserKeywords/B.hpp>
|
||||
#include <opm/input/eclipse/Schedule/BCProp.hpp>
|
||||
|
||||
namespace Opm {
|
||||
namespace {
|
||||
|
||||
namespace fromstring {
|
||||
|
||||
BCType bctype(const std::string& s) {
|
||||
if (s == "RATE")
|
||||
return BCType::RATE;
|
||||
|
||||
if (s == "FREE")
|
||||
return BCType::FREE;
|
||||
|
||||
if (s == "DIRICHLET")
|
||||
return BCType::DIRICHLET;
|
||||
|
||||
if (s == "THERMAL")
|
||||
return BCType::THERMAL;
|
||||
|
||||
if (s == "CLOSED")
|
||||
return BCType::CLOSED;
|
||||
|
||||
throw std::invalid_argument("Not recognized boundary condition type: " + s);
|
||||
}
|
||||
|
||||
|
||||
BCComponent component(const std::string& s) {
|
||||
if (s == "OIL")
|
||||
return BCComponent::OIL;
|
||||
|
||||
if (s == "GAS")
|
||||
return BCComponent::GAS;
|
||||
|
||||
if (s == "WATER")
|
||||
return BCComponent::WATER;
|
||||
|
||||
if (s == "SOLVENT")
|
||||
return BCComponent::SOLVENT;
|
||||
|
||||
if (s == "POLYMER")
|
||||
return BCComponent::POLYMER;
|
||||
|
||||
if (s == "NONE")
|
||||
return BCComponent::NONE;
|
||||
|
||||
throw std::invalid_argument("Not recognized boundary condition compononet: " + s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using BCKEY = ParserKeywords::BCPROP;
|
||||
BCProp::BCFace::BCFace(const DeckRecord& record) :
|
||||
index(record.getItem<BCKEY::INDEX>().get<int>(0)),
|
||||
bctype(fromstring::bctype(record.getItem<BCKEY::TYPE>().get<std::string>(0))),
|
||||
component(fromstring::component(record.getItem<BCKEY::COMPONENT>().get<std::string>(0))),
|
||||
rate(record.getItem<BCKEY::RATE>().getSIDouble(0))
|
||||
{
|
||||
if (const auto& P = record.getItem<BCKEY::PRESSURE>(); ! P.defaultApplied(0)) {
|
||||
pressure = P.getSIDouble(0);
|
||||
}
|
||||
if (const auto& T = record.getItem<BCKEY::TEMPERATURE>(); ! T.defaultApplied(0)) {
|
||||
temperature = T.getSIDouble(0);
|
||||
}
|
||||
}
|
||||
|
||||
BCProp::BCFace BCProp::BCFace::serializationTestObject()
|
||||
{
|
||||
BCFace result;
|
||||
result.index = 100;
|
||||
result.bctype = BCType::RATE;
|
||||
result.component = BCComponent::GAS;
|
||||
result.rate = 101.0;
|
||||
result.pressure = 102.0;
|
||||
result.temperature = 103.0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool BCProp::BCFace::operator==(const BCProp::BCFace& other) const {
|
||||
return this->index == other.index &&
|
||||
this->bctype == other.bctype &&
|
||||
this->component == other.component &&
|
||||
this->rate == other.rate &&
|
||||
this->pressure == other.pressure &&
|
||||
this->temperature == other.temperature;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BCProp::updateBCProp(const DeckRecord& record) {
|
||||
const BCProp::BCFace bcnew( record );
|
||||
for (auto& bc : m_faces) {
|
||||
if (bc.index == bcnew.index && bc.component == bcnew.component)
|
||||
{
|
||||
bc = bcnew;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->m_faces.emplace_back( bcnew );
|
||||
}
|
||||
|
||||
|
||||
|
||||
BCProp BCProp::serializationTestObject()
|
||||
{
|
||||
BCProp result;
|
||||
result.m_faces = {BCFace::serializationTestObject()};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::size_t BCProp::size() const {
|
||||
return this->m_faces.size();
|
||||
}
|
||||
|
||||
std::vector<BCProp::BCFace>::const_iterator BCProp::begin() const {
|
||||
return this->m_faces.begin();
|
||||
}
|
||||
|
||||
std::vector<BCProp::BCFace>::const_iterator BCProp::end() const {
|
||||
return this->m_faces.end();
|
||||
}
|
||||
|
||||
const BCProp::BCFace& BCProp::operator[](int index) const {
|
||||
for (auto& bc : m_faces) {
|
||||
if (bc.index == index)
|
||||
{
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
// add throw
|
||||
return this->m_faces[0];
|
||||
}
|
||||
|
||||
bool BCProp::operator==(const BCProp& other) const {
|
||||
return this->m_faces == other.m_faces;
|
||||
}
|
||||
|
||||
|
||||
} //namespace Opm
|
||||
|
||||
@@ -145,6 +145,13 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleBCProp(Schedule::HandlerContext& handlerContext) {
|
||||
auto& bcprop = this->snapshots.back().bcprop;
|
||||
for (const auto& record : handlerContext.keyword) {
|
||||
bcprop.updateBCProp(record);
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::handleBRANPROP(HandlerContext& handlerContext) {
|
||||
auto ext_network = this->snapshots.back().network.get();
|
||||
|
||||
@@ -2466,6 +2473,7 @@ Well{0} entered with 'FIELD' parent group:
|
||||
{ "AQUCT", &Schedule::handleAQUCT },
|
||||
{ "AQUFETP", &Schedule::handleAQUFETP },
|
||||
{ "AQUFLUX", &Schedule::handleAQUFLUX },
|
||||
{ "BCPROP", &Schedule::handleBCProp },
|
||||
{ "BOX", &Schedule::handleGEOKeyword},
|
||||
{ "BRANPROP", &Schedule::handleBRANPROP },
|
||||
{ "COMPDAT" , &Schedule::handleCOMPDAT },
|
||||
|
||||
40
src/opm/input/eclipse/share/keywords/900_OPM/B/BCCON
Normal file
40
src/opm/input/eclipse/share/keywords/900_OPM/B/BCCON
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "BCCON",
|
||||
"sections": [
|
||||
"GRID"
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
"name": "INDEX",
|
||||
"value_type": "INT"
|
||||
},
|
||||
{
|
||||
"name": "I1",
|
||||
"value_type": "INT"
|
||||
},
|
||||
{
|
||||
"name": "I2",
|
||||
"value_type": "INT"
|
||||
},
|
||||
{
|
||||
"name": "J1",
|
||||
"value_type": "INT"
|
||||
},
|
||||
{
|
||||
"name": "J2",
|
||||
"value_type": "INT"
|
||||
},
|
||||
{
|
||||
"name": "K1",
|
||||
"value_type": "INT"
|
||||
},
|
||||
{
|
||||
"name": "K2",
|
||||
"value_type": "INT"
|
||||
},
|
||||
{
|
||||
"name": "DIRECTION",
|
||||
"value_type": "STRING"
|
||||
}
|
||||
]
|
||||
}
|
||||
38
src/opm/input/eclipse/share/keywords/900_OPM/B/BCPROP
Normal file
38
src/opm/input/eclipse/share/keywords/900_OPM/B/BCPROP
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "BCPROP",
|
||||
"sections": [
|
||||
"SCHEDULE"
|
||||
],
|
||||
"items": [
|
||||
{
|
||||
"name": "INDEX",
|
||||
"value_type": "INT"
|
||||
},
|
||||
{
|
||||
"name": "TYPE",
|
||||
"value_type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "COMPONENT",
|
||||
"value_type": "STRING",
|
||||
"default": "NONE"
|
||||
},
|
||||
{
|
||||
"name": "RATE",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Mass/Time*Length*Length",
|
||||
"default": 0
|
||||
},
|
||||
{
|
||||
"name": "PRESSURE",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Pressure",
|
||||
"default": 1
|
||||
},
|
||||
{
|
||||
"name": "TEMPERATURE",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Temperature"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1104,6 +1104,8 @@ set( keywords
|
||||
002_Frontsim/N/NOGRAV
|
||||
|
||||
900_OPM/B/BC
|
||||
900_OPM/B/BCCON
|
||||
900_OPM/B/BCPROP
|
||||
900_OPM/C/CO2STOR
|
||||
900_OPM/C/COMPTRAJ
|
||||
900_OPM/D/DISGASW
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include <opm/input/eclipse/Schedule/Well/WellPolymerProperties.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WellTestConfig.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Well/WVFPEXP.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/SimulationConfig/BCConfig.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/input/eclipse/Deck/DeckItem.hpp>
|
||||
@@ -70,6 +71,7 @@
|
||||
#include <opm/input/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/input/eclipse/Units/Dimension.hpp>
|
||||
#include <opm/input/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/input/eclipse/Units/Units.hpp>
|
||||
|
||||
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
|
||||
#include <opm/input/eclipse/Schedule/Group/GuideRate.hpp>
|
||||
@@ -5436,3 +5438,43 @@ END
|
||||
BOOST_CHECK(wvfpexp2.prevent());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(createDeckWithBC) {
|
||||
std::string input = R"(
|
||||
START -- 0
|
||||
19 JUN 2007 /
|
||||
|
||||
SOLUTION
|
||||
|
||||
SCHEDULE
|
||||
|
||||
BCPROP
|
||||
1 RATE GAS 100.0 /
|
||||
2 FREE /
|
||||
/
|
||||
|
||||
DATES -- 1
|
||||
10 OKT 2008 /
|
||||
/
|
||||
BCPROP
|
||||
1 RATE GAS 200.0 /
|
||||
2 FREE 4* /
|
||||
/
|
||||
)";
|
||||
|
||||
const auto& schedule = make_schedule(input);
|
||||
{
|
||||
size_t currentStep = 0;
|
||||
const auto& bc = schedule[currentStep].bcprop;
|
||||
BOOST_CHECK_EQUAL(bc.size(), 2);
|
||||
const auto& bcface0 = bc[0];
|
||||
BOOST_CHECK_CLOSE(bcface0.rate * Opm::unit::day, 100, 1e-8 );
|
||||
}
|
||||
|
||||
{
|
||||
size_t currentStep = 1;
|
||||
const auto& bc = schedule[currentStep].bcprop;
|
||||
BOOST_CHECK_EQUAL(bc.size(), 2);
|
||||
const auto& bcface0 = bc[0];
|
||||
BOOST_CHECK_CLOSE(bcface0.rate * Opm::unit::day, 200, 1e-8 );
|
||||
}
|
||||
}
|
||||
@@ -119,6 +119,30 @@ GRID
|
||||
REGIONS
|
||||
)";
|
||||
|
||||
const std::string& inputStr_bc = R"(
|
||||
RUNSPEC
|
||||
DIMENS
|
||||
10 3 4 /
|
||||
GRID
|
||||
SOLUTION
|
||||
BC
|
||||
1 1 1 1 1 10 X- FREE GAS/
|
||||
/
|
||||
REGIONS
|
||||
)";
|
||||
|
||||
const std::string& inputStr_bccon = R"(
|
||||
RUNSPEC
|
||||
DIMENS
|
||||
10 3 4 /
|
||||
GRID
|
||||
BCCON
|
||||
1 1 1 1 1 1 1 X- /
|
||||
2 10 10 4* X /
|
||||
/
|
||||
REGIONS
|
||||
)";
|
||||
|
||||
namespace {
|
||||
std::string simDeckStringTEMP()
|
||||
{
|
||||
@@ -150,6 +174,23 @@ static Deck createDeck(const std::string& input) {
|
||||
return parser.parseString(input);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimulationConfigBCCON) {
|
||||
auto deck = createDeck(inputStr_bccon);
|
||||
BCConfig bcconfig(deck);
|
||||
std::vector<int> i1s = { 1, 10};
|
||||
std::vector<int> k2s = { 1, 4};
|
||||
std::vector<Opm::FaceDir::DirEnum> dirs = { Opm::FaceDir::XMinus , Opm::FaceDir::XPlus};
|
||||
for (const auto bc : bcconfig) {
|
||||
BOOST_CHECK(bc.i1 == (i1s[bc.index - 1 ]) - 1);
|
||||
BOOST_CHECK(bc.k2 == (k2s[bc.index - 1 ]) - 1);
|
||||
BOOST_CHECK(bc.dir == dirs[bc.index -1 ]);
|
||||
}
|
||||
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(SimulationConfigBC) {
|
||||
BOOST_CHECK_THROW( BCConfig(createDeck(inputStr_bc)), OpmInputError );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimulationConfigGetThresholdPressureTableTest) {
|
||||
auto deck = createDeck(inputStr);
|
||||
|
||||
Reference in New Issue
Block a user