Merge pull request #3636 from akva2/mech_bc
Add support for MECH boundary conditions
This commit is contained in:
@@ -28,7 +28,6 @@
|
||||
#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
|
||||
#include <opm/input/eclipse/EclipseState/Grid/GridDims.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
@@ -43,6 +42,12 @@ enum class BCType {
|
||||
NONE
|
||||
};
|
||||
|
||||
enum class BCMECHType {
|
||||
FREE,
|
||||
FIXED,
|
||||
NONE
|
||||
};
|
||||
|
||||
enum class BCComponent {
|
||||
OIL,
|
||||
GAS,
|
||||
@@ -52,6 +57,33 @@ enum class BCComponent {
|
||||
NONE
|
||||
};
|
||||
|
||||
struct MechBCValue {
|
||||
std::array<double,3> disp{};
|
||||
std::array<double,6> stress{};
|
||||
std::array<bool,3> fixeddir{};
|
||||
|
||||
static MechBCValue serializationTestObject()
|
||||
{
|
||||
return MechBCValue{{1.0, 2.0, 3.0},
|
||||
{3.0, 4.0, 5.0, 6.0, 7.0, 8.0},
|
||||
{true, false, true}};
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(disp);
|
||||
serializer(stress);
|
||||
serializer(fixeddir);
|
||||
}
|
||||
|
||||
bool operator==(const MechBCValue& other) const
|
||||
{
|
||||
return disp == other.disp &&
|
||||
stress == other.stress &&
|
||||
fixeddir == other.fixeddir;
|
||||
}
|
||||
};
|
||||
|
||||
class BCProp {
|
||||
public:
|
||||
@@ -59,11 +91,14 @@ public:
|
||||
struct BCFace {
|
||||
int index;
|
||||
BCType bctype;
|
||||
BCMECHType bcmechtype;
|
||||
BCComponent component;
|
||||
double rate;
|
||||
std::optional<double> pressure;
|
||||
std::optional<double> temperature;
|
||||
|
||||
std::optional<MechBCValue> mechbcvalue;
|
||||
|
||||
BCFace() = default;
|
||||
explicit BCFace(const DeckRecord& record);
|
||||
|
||||
@@ -76,10 +111,12 @@ public:
|
||||
{
|
||||
serializer(index);
|
||||
serializer(bctype);
|
||||
serializer(bcmechtype);
|
||||
serializer(component);
|
||||
serializer(rate);
|
||||
serializer(pressure);
|
||||
serializer(temperature);
|
||||
serializer(mechbcvalue);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -108,6 +145,4 @@ private:
|
||||
|
||||
} //namespace Opm
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,9 +45,24 @@ BCType bctype(const std::string& s) {
|
||||
if (s == "CLOSED")
|
||||
return BCType::CLOSED;
|
||||
|
||||
if (s == "NONE")
|
||||
return BCType::NONE;
|
||||
|
||||
throw std::invalid_argument("Not recognized boundary condition type: " + s);
|
||||
}
|
||||
|
||||
BCMECHType bcmechtype(const std::string& s) {
|
||||
if (s == "FREE")
|
||||
return BCMECHType::FREE;
|
||||
|
||||
if (s == "FIXED")
|
||||
return BCMECHType::FIXED;
|
||||
|
||||
if (s == "NONE")
|
||||
return BCMECHType::NONE;
|
||||
|
||||
throw std::invalid_argument("Not recognized boundary condition type: " + s);
|
||||
}
|
||||
|
||||
BCComponent component(const std::string& s) {
|
||||
if (s == "OIL")
|
||||
@@ -78,6 +93,7 @@ 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))),
|
||||
bcmechtype(fromstring::bcmechtype(record.getItem<BCKEY::MECHTYPE>().get<std::string>(0))),
|
||||
component(fromstring::component(record.getItem<BCKEY::COMPONENT>().get<std::string>(0))),
|
||||
rate(record.getItem<BCKEY::RATE>().getSIDouble(0))
|
||||
{
|
||||
@@ -87,6 +103,51 @@ BCProp::BCFace::BCFace(const DeckRecord& record) :
|
||||
if (const auto& T = record.getItem<BCKEY::TEMPERATURE>(); ! T.defaultApplied(0)) {
|
||||
temperature = T.getSIDouble(0);
|
||||
}
|
||||
|
||||
MechBCValue mechbcvaluetmp;
|
||||
bool allDefault = true;
|
||||
if (const auto& P = record.getItem<BCKEY::STRESSXX>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.stress[0] = P.getSIDouble(0);
|
||||
allDefault = false;
|
||||
}
|
||||
if (const auto& P = record.getItem<BCKEY::STRESSYY>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.stress[1] = P.getSIDouble(0);
|
||||
allDefault = false;
|
||||
}
|
||||
if (const auto& P = record.getItem<BCKEY::STRESSZZ>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.stress[2] = P.getSIDouble(0);
|
||||
allDefault = false;
|
||||
}
|
||||
mechbcvaluetmp.stress[3] = 0;
|
||||
mechbcvaluetmp.stress[4] = 0;
|
||||
mechbcvaluetmp.stress[5] = 0;
|
||||
if (const auto& P = record.getItem<BCKEY::DISPX>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.disp[0] = P.getSIDouble(0);
|
||||
allDefault = false;
|
||||
}
|
||||
if (const auto& P = record.getItem<BCKEY::DISPY>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.disp[1] = P.getSIDouble(0);
|
||||
allDefault = false;
|
||||
}
|
||||
if (const auto& P = record.getItem<BCKEY::DISPZ>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.disp[2] = P.getSIDouble(0);
|
||||
allDefault = false;
|
||||
}
|
||||
if (const auto& P = record.getItem<BCKEY::FIXEDX>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.fixeddir[0] = P.get<int>(0);
|
||||
allDefault = false;
|
||||
}
|
||||
if (const auto& P = record.getItem<BCKEY::FIXEDY>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.fixeddir[1] = P.get<int>(0);
|
||||
allDefault = false;
|
||||
}
|
||||
if (const auto& P = record.getItem<BCKEY::FIXEDZ>(); ! P.defaultApplied(0)) {
|
||||
mechbcvaluetmp.fixeddir[2] = P.get<int>(0);
|
||||
allDefault = false;
|
||||
}
|
||||
if (!allDefault) {
|
||||
mechbcvalue = mechbcvaluetmp;
|
||||
}
|
||||
}
|
||||
|
||||
BCProp::BCFace BCProp::BCFace::serializationTestObject()
|
||||
@@ -94,11 +155,12 @@ BCProp::BCFace BCProp::BCFace::serializationTestObject()
|
||||
BCFace result;
|
||||
result.index = 100;
|
||||
result.bctype = BCType::RATE;
|
||||
result.bcmechtype = BCMECHType::FIXED;
|
||||
result.component = BCComponent::GAS;
|
||||
result.rate = 101.0;
|
||||
result.pressure = 102.0;
|
||||
result.temperature = 103.0;
|
||||
|
||||
result.mechbcvalue = MechBCValue::serializationTestObject();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -106,10 +168,12 @@ BCProp::BCFace BCProp::BCFace::serializationTestObject()
|
||||
bool BCProp::BCFace::operator==(const BCProp::BCFace& other) const {
|
||||
return this->index == other.index &&
|
||||
this->bctype == other.bctype &&
|
||||
this->bcmechtype == other.bcmechtype &&
|
||||
this->component == other.component &&
|
||||
this->rate == other.rate &&
|
||||
this->pressure == other.pressure &&
|
||||
this->temperature == other.temperature;
|
||||
this->temperature == other.temperature &&
|
||||
this->mechbcvalue == other.mechbcvalue;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +187,7 @@ void BCProp::updateBCProp(const DeckRecord& record) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->m_faces.emplace_back( bcnew );
|
||||
this->m_faces.emplace_back( bcnew );
|
||||
}
|
||||
|
||||
|
||||
@@ -166,4 +230,3 @@ bool BCProp::operator==(const BCProp& other) const {
|
||||
|
||||
|
||||
} //namespace Opm
|
||||
|
||||
|
||||
@@ -33,6 +33,62 @@
|
||||
"name": "TEMPERATURE",
|
||||
"value_type": "DOUBLE",
|
||||
"dimension": "Temperature"
|
||||
},
|
||||
{
|
||||
"name": "MECHTYPE",
|
||||
"value_type": "STRING",
|
||||
"default": "NONE"
|
||||
},
|
||||
{
|
||||
"name": "FIXEDX",
|
||||
"value_type": "INT",
|
||||
"default": 1
|
||||
},
|
||||
{
|
||||
"name": "FIXEDY",
|
||||
"value_type": "INT",
|
||||
"default": 1
|
||||
},
|
||||
{
|
||||
"name": "FIXEDZ",
|
||||
"value_type": "INT",
|
||||
"default": 1
|
||||
},
|
||||
{
|
||||
"name": "STRESSXX",
|
||||
"value_type": "DOUBLE",
|
||||
"default": 0,
|
||||
"dimension": "Pressure"
|
||||
},
|
||||
{
|
||||
"name": "STRESSYY",
|
||||
"value_type": "DOUBLE",
|
||||
"default": 0,
|
||||
"dimension": "Pressure"
|
||||
},
|
||||
{
|
||||
"name": "STRESSZZ",
|
||||
"value_type": "DOUBLE",
|
||||
"default": 0,
|
||||
"dimension": "Pressure"
|
||||
},
|
||||
{
|
||||
"name": "DISPX",
|
||||
"value_type": "DOUBLE",
|
||||
"default": 0,
|
||||
"dimension": "Length"
|
||||
},
|
||||
{
|
||||
"name": "DISPY",
|
||||
"value_type": "DOUBLE",
|
||||
"default": 0,
|
||||
"dimension": "Length"
|
||||
},
|
||||
{
|
||||
"name": "DISPZ",
|
||||
"value_type": "DOUBLE",
|
||||
"default": 0,
|
||||
"dimension": "Length"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -189,3 +189,121 @@ BCPROP
|
||||
BOOST_CHECK_EQUAL(deck.getActiveUnitSystem().to_si(measure::pressure, 279.0),
|
||||
*prop[2].pressure);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Mech)
|
||||
{
|
||||
const std::string input = R"(
|
||||
RUNSPEC
|
||||
|
||||
DIMENS
|
||||
10 10 3 /
|
||||
OIL
|
||||
GAS
|
||||
WATER
|
||||
LAB
|
||||
START
|
||||
1 'JAN' 2015 /
|
||||
GRID
|
||||
DX
|
||||
300*1000 /
|
||||
DY
|
||||
300*1000 /
|
||||
DZ
|
||||
300*1000 /
|
||||
TOPS
|
||||
100*8325 /
|
||||
BCCON
|
||||
1 1* * 1 5 1 10 Y- /
|
||||
2 20 20 4* Y /
|
||||
3 10 15 1 10 4 7 Z /
|
||||
/
|
||||
SCHEDULE
|
||||
BCPROP
|
||||
1 NONE * * * * FIXED 1 0 0 1.0 * * 2.0 * * /
|
||||
2 NONE * * * * FIXED 0 1 0 * 3.0 * /
|
||||
3 NONE * * * * FREE 0 0 1 * * 4.0 * * 5.0 /
|
||||
/
|
||||
)";
|
||||
|
||||
auto deck = createDeck(input);
|
||||
Opm::BCConfig config(deck);
|
||||
const auto& kw = deck.get<Opm::ParserKeywords::BCPROP>();
|
||||
Opm::BCProp prop;
|
||||
for (const auto& record : kw.back()) {
|
||||
prop.updateBCProp(record);
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(config.size(), 3U);
|
||||
|
||||
BOOST_CHECK_EQUAL(prop.size(), 3U);
|
||||
BOOST_CHECK(prop[1].bctype == Opm::BCType::NONE);
|
||||
BOOST_CHECK(prop[1].component == Opm::BCComponent::NONE);
|
||||
using measure = Opm::UnitSystem::measure;
|
||||
BOOST_CHECK_EQUAL(0.0,
|
||||
prop[1].rate);
|
||||
BOOST_CHECK(!prop[1].pressure.has_value());
|
||||
BOOST_CHECK(!prop[1].temperature.has_value());
|
||||
BOOST_CHECK(prop[1].bcmechtype == Opm::BCMECHType::FIXED);
|
||||
BOOST_CHECK(prop[1].mechbcvalue.has_value());
|
||||
BOOST_CHECK_EQUAL(prop[1].mechbcvalue->fixeddir[0], 1);
|
||||
BOOST_CHECK_EQUAL(prop[1].mechbcvalue->fixeddir[1], 0);
|
||||
BOOST_CHECK_EQUAL(prop[1].mechbcvalue->fixeddir[2], 0);
|
||||
BOOST_CHECK_EQUAL(deck.getActiveUnitSystem().to_si(measure::pressure, 1.0),
|
||||
prop[1].mechbcvalue->stress[0]);
|
||||
BOOST_CHECK_SMALL(prop[1].mechbcvalue->stress[1], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[1].mechbcvalue->stress[2], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[1].mechbcvalue->stress[3], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[1].mechbcvalue->stress[4], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[1].mechbcvalue->stress[5], 1e-12);
|
||||
BOOST_CHECK_EQUAL(deck.getActiveUnitSystem().to_si(measure::length, 2.0),
|
||||
prop[1].mechbcvalue->disp[0]);
|
||||
BOOST_CHECK_SMALL(prop[1].mechbcvalue->disp[1], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[1].mechbcvalue->disp[2], 1e-12);
|
||||
|
||||
BOOST_CHECK(prop[2].bctype == Opm::BCType::NONE);
|
||||
BOOST_CHECK(prop[2].component == Opm::BCComponent::NONE);
|
||||
using measure = Opm::UnitSystem::measure;
|
||||
BOOST_CHECK_EQUAL(0.0,
|
||||
prop[2].rate);
|
||||
BOOST_CHECK(!prop[2].pressure.has_value());
|
||||
BOOST_CHECK(!prop[2].temperature.has_value());
|
||||
BOOST_CHECK(prop[2].bcmechtype == Opm::BCMECHType::FIXED);
|
||||
BOOST_CHECK(prop[2].mechbcvalue.has_value());
|
||||
BOOST_CHECK_EQUAL(prop[2].mechbcvalue->fixeddir[0], 0);
|
||||
BOOST_CHECK_EQUAL(prop[2].mechbcvalue->fixeddir[1], 1);
|
||||
BOOST_CHECK_EQUAL(prop[2].mechbcvalue->fixeddir[2], 0);
|
||||
BOOST_CHECK_SMALL(prop[2].mechbcvalue->stress[0], 1e-12);
|
||||
BOOST_CHECK_EQUAL(deck.getActiveUnitSystem().to_si(measure::pressure, 3.0),
|
||||
prop[2].mechbcvalue->stress[1]);
|
||||
BOOST_CHECK_SMALL(prop[2].mechbcvalue->stress[2], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[2].mechbcvalue->stress[3], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[2].mechbcvalue->stress[4], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[2].mechbcvalue->stress[5], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[2].mechbcvalue->disp[0], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[2].mechbcvalue->disp[1], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[2].mechbcvalue->disp[2], 1e-12);
|
||||
|
||||
BOOST_CHECK(prop[3].bctype == Opm::BCType::NONE);
|
||||
BOOST_CHECK(prop[3].component == Opm::BCComponent::NONE);
|
||||
using measure = Opm::UnitSystem::measure;
|
||||
BOOST_CHECK_EQUAL(0.0,
|
||||
prop[3].rate);
|
||||
BOOST_CHECK(!prop[3].pressure.has_value());
|
||||
BOOST_CHECK(!prop[3].temperature.has_value());
|
||||
BOOST_CHECK(prop[3].bcmechtype == Opm::BCMECHType::FREE);
|
||||
BOOST_CHECK(prop[3].mechbcvalue.has_value());
|
||||
BOOST_CHECK_EQUAL(prop[3].mechbcvalue->fixeddir[0], 0);
|
||||
BOOST_CHECK_EQUAL(prop[3].mechbcvalue->fixeddir[1], 0);
|
||||
BOOST_CHECK_EQUAL(prop[3].mechbcvalue->fixeddir[2], 1);
|
||||
BOOST_CHECK_SMALL(prop[3].mechbcvalue->stress[0], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[3].mechbcvalue->stress[1], 1e-12);
|
||||
BOOST_CHECK_EQUAL(deck.getActiveUnitSystem().to_si(measure::pressure, 4.0),
|
||||
prop[3].mechbcvalue->stress[2]);
|
||||
BOOST_CHECK_SMALL(prop[3].mechbcvalue->stress[3], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[3].mechbcvalue->stress[4], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[3].mechbcvalue->stress[5], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[3].mechbcvalue->disp[0], 1e-12);
|
||||
BOOST_CHECK_SMALL(prop[3].mechbcvalue->disp[1], 1e-12);
|
||||
BOOST_CHECK_EQUAL(deck.getActiveUnitSystem().to_si(measure::length, 5.0),
|
||||
prop[3].mechbcvalue->disp[2]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user