Merge pull request #3636 from akva2/mech_bc

Add support for MECH boundary conditions
This commit is contained in:
Bård Skaflestad
2023-08-16 16:52:21 +02:00
committed by GitHub
4 changed files with 279 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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"
}
]
}

View File

@@ -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]);
}