Make MULTREGT work for NNC.
The region multipliers are no longer added to the cartesian logical MULT[XYZ] structure. Instead a new method getRegionMultiplier(globalIndex1, globalIndex2,FaceDir) is added that return the multiplier between globalIndex1 cell and globalIndex2 cell. The face direction is added to support directional dependent MULTREGT input. This implementation of MULTREGT also supports restricting the multipliers to only apply for NNC or NONNNC.
This commit is contained in:
parent
b924f6cd02
commit
bb40baa96f
@ -360,13 +360,13 @@ namespace Opm {
|
||||
|
||||
void EclipseState::initMULTREGT(DeckConstPtr deck, ParserLogPtr /*parserLog*/) {
|
||||
EclipseGridConstPtr grid = getEclipseGrid();
|
||||
std::shared_ptr<MULTREGTScanner> scanner = std::make_shared<MULTREGTScanner>();
|
||||
|
||||
std::vector<Opm::DeckKeywordConstPtr> keywords;
|
||||
{
|
||||
std::shared_ptr<Opm::GRIDSection> gridSection(new Opm::GRIDSection(deck) );
|
||||
for (size_t index=0; index < gridSection->count("MULTREGT"); index++) {
|
||||
DeckKeywordConstPtr multregtKeyword = gridSection->getKeyword("MULTREGT" , index);
|
||||
scanner->addKeyword( multregtKeyword );
|
||||
keywords.push_back( multregtKeyword );
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,11 +375,12 @@ namespace Opm {
|
||||
std::shared_ptr<Opm::EDITSection> editSection(new Opm::EDITSection(deck) );
|
||||
for (size_t index=0; index < editSection->count("MULTREGT"); index++) {
|
||||
DeckKeywordConstPtr multregtKeyword = editSection->getKeyword("MULTREGT" , index);
|
||||
scanner->addKeyword( multregtKeyword );
|
||||
keywords.push_back( multregtKeyword );
|
||||
}
|
||||
}
|
||||
std::shared_ptr<MULTREGTScanner> scanner = std::make_shared<MULTREGTScanner>( m_intGridProperties, keywords);
|
||||
|
||||
m_transMult->applyMULTREGT( scanner , m_intGridProperties);
|
||||
m_transMult->setMultregtScanner( scanner );
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,8 +94,68 @@ namespace Opm {
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
/*
|
||||
Observe that the (REGION1 -> REGION2) pairs behave like keys;
|
||||
i.e. for the MULTREGT keyword
|
||||
|
||||
MULTREGT
|
||||
2 4 0.75 Z ALL M /
|
||||
2 4 2.50 XY ALL F /
|
||||
/
|
||||
|
||||
The first record is completely overweritten by the second
|
||||
record, this is because the both have the (2 -> 4) region
|
||||
identifiers. This behaviourt is ensured by using a map with
|
||||
std::pair<region1,region2> as key.
|
||||
|
||||
This function starts with some initial preprocessing to create a
|
||||
map which looks like this:
|
||||
|
||||
|
||||
searchMap = {"MULTNUM" : {std::pair(1,2) : std::tuple(TransFactor , Face , Region),
|
||||
std::pair(4,7) : std::tuple(TransFactor , Face , Region),
|
||||
...},
|
||||
"FLUXNUM" : {std::pair(4,8) : std::tuple(TransFactor , Face , Region),
|
||||
std::pair(1,4) : std::tuple(TransFactor , Face , Region),
|
||||
...}}
|
||||
|
||||
Then it will go through the different regions and looking for
|
||||
interface with the wanted region values.
|
||||
*/
|
||||
MULTREGTScanner::MULTREGTScanner(std::shared_ptr<GridProperties<int> > cellRegionNumbers, const std::vector<DeckKeywordConstPtr>& keywords ) :
|
||||
m_cellRegionNumbers(cellRegionNumbers) {
|
||||
|
||||
for (int indx = 0; indx < keywords.size(); indx++){
|
||||
addKeyword(keywords[indx]);
|
||||
}
|
||||
|
||||
MULTREGTSearchMap searchPairs;
|
||||
for (std::vector<MULTREGTRecord>::const_iterator record = m_records.begin(); record != m_records.end(); ++record) {
|
||||
if (cellRegionNumbers->hasKeyword( record->m_region.getValue())) {
|
||||
if (record->m_srcRegion.hasValue() && record->m_targetRegion.hasValue()) {
|
||||
int srcRegion = record->m_srcRegion.getValue();
|
||||
int targetRegion = record->m_targetRegion.getValue();
|
||||
if (srcRegion != targetRegion) {
|
||||
std::pair<int,int> pair{ srcRegion, targetRegion };
|
||||
searchPairs[pair] = &(*record);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
throw std::logic_error("MULTREGT record is based on region: " + record->m_region.getValue() + " which is not in the deck");
|
||||
}
|
||||
|
||||
|
||||
for (auto iter = searchPairs.begin(); iter != searchPairs.end(); ++iter) {
|
||||
const MULTREGTRecord * record = (*iter).second;
|
||||
std::pair<int,int> pair = (*iter).first;
|
||||
const std::string& keyword = record->m_region.getValue();
|
||||
if (m_searchMap.count(keyword) == 0)
|
||||
m_searchMap[keyword] = MULTREGTSearchMap();
|
||||
|
||||
m_searchMap[keyword][pair] = record;
|
||||
}
|
||||
|
||||
MULTREGTScanner::MULTREGTScanner() {
|
||||
|
||||
}
|
||||
|
||||
@ -104,8 +164,8 @@ namespace Opm {
|
||||
for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) {
|
||||
MULTREGTRecord record( *iter );
|
||||
|
||||
if (record.m_nncBehaviour != MULTREGT::ALL)
|
||||
throw std::invalid_argument("Sorry - currently only \'ALL\' is supported for MULTREGT NNC behaviour.");
|
||||
if (record.m_nncBehaviour == MULTREGT::NOAQUNNC)
|
||||
throw std::invalid_argument("Sorry - currently we do not support \'NOAQUNNC\' for MULTREGT.");
|
||||
|
||||
if (!record.m_srcRegion.hasValue())
|
||||
throw std::invalid_argument("Sorry - currently it is not supported with a defaulted source region value.");
|
||||
@ -166,131 +226,46 @@ namespace Opm {
|
||||
-----------
|
||||
|
||||
*/
|
||||
void MULTREGTScanner::checkConnection( MULTREGTSearchMap& map , std::vector< MULTREGTConnection >& connections, std::shared_ptr<GridProperty<int> > region, size_t globalIndex1 , size_t globalIndex2 , FaceDir::DirEnum faceDir1 ,FaceDir::DirEnum faceDir2) {
|
||||
int regionValue1 = region->iget(globalIndex1);
|
||||
int regionValue2 = region->iget(globalIndex2);
|
||||
double MULTREGTScanner::getRegionMultiplier(size_t globalIndex1 , size_t globalIndex2, FaceDir::DirEnum faceDir) const {
|
||||
|
||||
std::pair<int,int> pair{regionValue1 , regionValue2};
|
||||
if (map.count(pair) == 1) {
|
||||
const MULTREGTRecord * record = map[pair];
|
||||
if (record->m_directions & faceDir1) {
|
||||
connections.push_back( MULTREGTConnection{ globalIndex1 , faceDir1 , record->m_transMultiplier } );
|
||||
}
|
||||
}
|
||||
|
||||
pair = std::pair<int,int>{regionValue2 , regionValue1};
|
||||
if (map.count(pair) == 1) {
|
||||
const MULTREGTRecord * record = map[pair];
|
||||
if (record->m_directions & faceDir2) {
|
||||
connections.push_back( MULTREGTConnection{ globalIndex2 , faceDir2 , record->m_transMultiplier } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Observe that the (REGION1 -> REGION2) pairs behave like keys;
|
||||
i.e. for the MULTREGT keyword
|
||||
|
||||
MULTREGT
|
||||
2 4 0.75 Z ALL M /
|
||||
2 4 2.50 XY ALL F /
|
||||
/
|
||||
|
||||
The first record is completely overweritten by the second
|
||||
record, this is because the both have the (2 -> 4) region
|
||||
identifiers. This behaviourt is ensured by using a map with
|
||||
std::pair<region1,region2> as key.
|
||||
|
||||
This function starts with some initial preprocessing to create a
|
||||
map which looks like this:
|
||||
|
||||
|
||||
searchMap = {"MULTNUM" : {std::pair(1,2) : std::tuple(TransFactor , Face , Region),
|
||||
std::pair(4,7) : std::tuple(TransFactor , Face , Region),
|
||||
...},
|
||||
"FLUXNUM" : {std::pair(4,8) : std::tuple(TransFactor , Face , Region),
|
||||
std::pair(1,4) : std::tuple(TransFactor , Face , Region),
|
||||
...}}
|
||||
|
||||
Then it will go through the different regions and looking for
|
||||
interface with the wanted region values.
|
||||
*/
|
||||
|
||||
const std::vector< MULTREGTConnection > MULTREGTScanner::scanRegions( std::shared_ptr<Opm::GridProperties<int> > regions) {
|
||||
std::vector< MULTREGTConnection > connections;
|
||||
std::map<std::string , MULTREGTSearchMap> searchMap;
|
||||
{
|
||||
MULTREGTSearchMap searchPairs;
|
||||
for (std::vector<MULTREGTRecord>::const_iterator record = m_records.begin(); record != m_records.end(); ++record) {
|
||||
if (regions->hasKeyword( record->m_region.getValue())) {
|
||||
if (record->m_srcRegion.hasValue() && record->m_targetRegion.hasValue()) {
|
||||
int srcRegion = record->m_srcRegion.getValue();
|
||||
int targetRegion = record->m_targetRegion.getValue();
|
||||
if (srcRegion != targetRegion) {
|
||||
std::pair<int,int> pair{ srcRegion, targetRegion };
|
||||
searchPairs[pair] = &(*record);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
throw std::logic_error("MULTREGT record is based on region: " + record->m_region.getValue() + " which is not in the deck");
|
||||
}
|
||||
|
||||
|
||||
for (auto iter = searchPairs.begin(); iter != searchPairs.end(); ++iter) {
|
||||
const MULTREGTRecord * record = (*iter).second;
|
||||
std::pair<int,int> pair = (*iter).first;
|
||||
const std::string& keyword = record->m_region.getValue();
|
||||
if (searchMap.count(keyword) == 0)
|
||||
searchMap[keyword] = MULTREGTSearchMap();
|
||||
|
||||
searchMap[keyword][pair] = record;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through the different regions
|
||||
for (auto iter = searchMap.begin(); iter != searchMap.end(); iter++) {
|
||||
std::shared_ptr<GridProperty<int> > region = regions->getKeyword( (*iter).first );
|
||||
for (auto iter = m_searchMap.begin(); iter != m_searchMap.end(); iter++) {
|
||||
std::shared_ptr<Opm::GridProperty<int> > region = m_cellRegionNumbers->getKeyword( (*iter).first );
|
||||
MULTREGTSearchMap map = (*iter).second;
|
||||
|
||||
int regionId1 = region->iget(globalIndex1);
|
||||
int regionId2 = region->iget(globalIndex2);
|
||||
|
||||
// Iterate through all the cells in the region.
|
||||
for (size_t k=0; k < region->getNZ(); k++) {
|
||||
for (size_t j = 0; j < region->getNY(); j++) {
|
||||
for (size_t i = 0; i < region->getNX(); i++) {
|
||||
size_t globalIndex1 = i + j*region->getNX() + k*region->getNY() * region->getNX();
|
||||
|
||||
// X Direction
|
||||
if ((i + 1) < region->getNX()) {
|
||||
size_t globalIndex2 = globalIndex1 + 1;
|
||||
std::pair<int,int> pair{regionId1 , regionId2};
|
||||
if (map.count(pair) != 1 || !(map.at(pair)->m_directions & faceDir)) {
|
||||
pair = std::pair<int,int>{regionId2 , regionId1};
|
||||
if (map.count(pair) != 1 || !(map.at(pair)->m_directions & faceDir))
|
||||
continue;
|
||||
}
|
||||
const MULTREGTRecord * record = map[pair];
|
||||
|
||||
checkConnection( map , connections, region , globalIndex1 , globalIndex2 , FaceDir::XPlus , FaceDir::XMinus);
|
||||
}
|
||||
bool applyMultiplier = true;
|
||||
int i1 = globalIndex1%region->getNX();
|
||||
int i2 = globalIndex2%region->getNX();
|
||||
int j1 = globalIndex1/region->getNX()%region->getNY();
|
||||
int j2 = globalIndex2/region->getNX()%region->getNY();
|
||||
|
||||
// Y Direction
|
||||
if ((j + 1) < region->getNY()) {
|
||||
size_t globalIndex2 = globalIndex1 + region->getNX();
|
||||
if (record->m_nncBehaviour == MULTREGT::NNC){
|
||||
applyMultiplier = true;
|
||||
if ((std::abs(i1-i2) == 0 && std::abs(j1-j2) == 1) || (std::abs(i1-i2) == 1 && std::abs(j1-j2) == 0))
|
||||
applyMultiplier = false;
|
||||
}
|
||||
else if (record->m_nncBehaviour == MULTREGT::NONNC){
|
||||
applyMultiplier = false;
|
||||
if ((std::abs(i1-i2) == 0 && std::abs(j1-j2) == 1) || (std::abs(i1-i2) == 1 && std::abs(j1-j2) == 0))
|
||||
applyMultiplier = true;
|
||||
}
|
||||
|
||||
checkConnection( map , connections, region , globalIndex1 , globalIndex2 , FaceDir::YPlus , FaceDir::YMinus);
|
||||
}
|
||||
|
||||
// Z Direction
|
||||
if ((k + 1) < region->getNZ()) {
|
||||
size_t globalIndex2 = globalIndex1 + region->getNX() * region->getNY();
|
||||
|
||||
checkConnection( map , connections, region , globalIndex1 , globalIndex2 , FaceDir::ZPlus , FaceDir::ZMinus);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (applyMultiplier) {
|
||||
return record->m_transMultiplier;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return connections;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,16 +66,15 @@ namespace Opm {
|
||||
class MULTREGTScanner {
|
||||
|
||||
public:
|
||||
MULTREGTScanner();
|
||||
void addKeyword(DeckKeywordConstPtr deckKeyword);
|
||||
const std::vector< std::tuple<size_t , FaceDir::DirEnum , double> > scanRegions( std::shared_ptr<Opm::GridProperties<int> > regions);
|
||||
static void assertKeywordSupported(DeckKeywordConstPtr deckKeyword);
|
||||
MULTREGTScanner(std::shared_ptr<GridProperties<int> > cellRegionNumbers, const std::vector<DeckKeywordConstPtr>& keywords);
|
||||
double getRegionMultiplier(size_t globalCellIdx1, size_t globalCellIdx2, FaceDir::DirEnum faceDir) const;
|
||||
|
||||
private:
|
||||
void checkConnection( MULTREGTSearchMap& map , std::vector< MULTREGTConnection >& connections, std::shared_ptr<GridProperty<int> > region , size_t globalIndex1 , size_t globalIndex2 , FaceDir::DirEnum faceDir1 ,FaceDir::DirEnum faceDir2);
|
||||
|
||||
|
||||
void addKeyword(DeckKeywordConstPtr deckKeyword);
|
||||
void assertKeywordSupported(DeckKeywordConstPtr deckKeyword);
|
||||
std::vector< MULTREGTRecord > m_records;
|
||||
std::map<std::string , MULTREGTSearchMap> m_searchMap;
|
||||
std::shared_ptr<GridProperties<int> > m_cellRegionNumbers;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -73,6 +73,10 @@ namespace Opm {
|
||||
return getMultiplier__( globalIndex , faceDir );
|
||||
}
|
||||
|
||||
double TransMult::getRegionMultiplier(size_t globalCellIndex1, size_t globalCellIndex2, FaceDir::DirEnum faceDir) const {
|
||||
return m_multregtScanner->getRegionMultiplier(globalCellIndex1, globalCellIndex2, faceDir);
|
||||
}
|
||||
|
||||
|
||||
bool TransMult::hasDirectionProperty(FaceDir::DirEnum faceDir) const {
|
||||
if (m_trans.count(faceDir) == 1)
|
||||
@ -127,18 +131,7 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
void TransMult::applyMULTREGT( std::shared_ptr<MULTREGTScanner> multregtScanner , std::shared_ptr<GridProperties<int> > regions) {
|
||||
const std::vector< MULTREGTConnection > connections = multregtScanner->scanRegions( regions );
|
||||
for (auto iter = connections.begin(); iter != connections.end(); ++iter) {
|
||||
MULTREGTConnection connection = *iter;
|
||||
FaceDir::DirEnum faceDir = std::get<1>( connection );
|
||||
std::shared_ptr<GridProperty<double> > multProperty = getDirectionProperty(faceDir);
|
||||
{
|
||||
size_t globalIndex = std::get<0>( connection );
|
||||
double transMult = std::get<2>( connection );
|
||||
|
||||
multProperty->multiplyValueAtIndex( globalIndex , transMult);
|
||||
}
|
||||
}
|
||||
void TransMult::setMultregtScanner( std::shared_ptr<const MULTREGTScanner> multregtScanner) {
|
||||
m_multregtScanner = multregtScanner;
|
||||
}
|
||||
}
|
||||
|
@ -48,11 +48,12 @@ namespace Opm {
|
||||
TransMult(size_t nx , size_t ny , size_t nz);
|
||||
double getMultiplier(size_t globalIndex, FaceDir::DirEnum faceDir) const;
|
||||
double getMultiplier(size_t i , size_t j , size_t k, FaceDir::DirEnum faceDir) const;
|
||||
double getRegionMultiplier( size_t globalCellIndex1, size_t globalCellIndex2, FaceDir::DirEnum faceDir) const;
|
||||
bool hasDirectionProperty(FaceDir::DirEnum faceDir) const;
|
||||
std::shared_ptr<GridProperty<double> > getDirectionProperty(FaceDir::DirEnum faceDir);
|
||||
void applyMULT(std::shared_ptr<const GridProperty<double> > srcMultProp, FaceDir::DirEnum faceDir);
|
||||
void applyMULTFLT( std::shared_ptr<const FaultCollection> faults);
|
||||
void applyMULTREGT( std::shared_ptr<MULTREGTScanner> multregtScanner , std::shared_ptr<GridProperties<int> > regions);
|
||||
void setMultregtScanner(std::shared_ptr<const MULTREGTScanner> multregtScanner);
|
||||
|
||||
private:
|
||||
size_t getGlobalIndex(size_t i , size_t j , size_t k) const;
|
||||
@ -63,6 +64,7 @@ namespace Opm {
|
||||
size_t m_nx , m_ny , m_nz;
|
||||
std::map<FaceDir::DirEnum , std::shared_ptr<GridProperty<double> > > m_trans;
|
||||
std::map<FaceDir::DirEnum , std::string> m_names;
|
||||
std::shared_ptr<const MULTREGTScanner> m_multregtScanner;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -104,24 +104,28 @@ BOOST_AUTO_TEST_CASE(InvalidInput) {
|
||||
SupportedKeywordInfo("OPERNUM" , 1 , "1") ,
|
||||
SupportedKeywordInfo("MULTNUM" , 1 , "1") });
|
||||
|
||||
Opm::MULTREGTScanner scanner;
|
||||
|
||||
Opm::DeckPtr deck = createInvalidMULTREGTDeck();
|
||||
std::shared_ptr<Opm::EclipseGrid> grid = std::make_shared<Opm::EclipseGrid>( deck );
|
||||
std::shared_ptr<Opm::GridProperties<int> > gridProperties = std::make_shared<Opm::GridProperties<int> >(grid, supportedKeywords);
|
||||
Opm::DeckKeywordConstPtr multregtKeyword0 = deck->getKeyword("MULTREGT",0);
|
||||
Opm::DeckKeywordConstPtr multregtKeyword1 = deck->getKeyword("MULTREGT",1);
|
||||
Opm::DeckKeywordConstPtr multregtKeyword2 = deck->getKeyword("MULTREGT",2);
|
||||
|
||||
|
||||
// Invalid direction
|
||||
BOOST_CHECK_THROW( scanner.addKeyword( multregtKeyword0 ) , std::invalid_argument);
|
||||
std::vector<Opm::DeckKeywordConstPtr> keywords0;
|
||||
Opm::DeckKeywordConstPtr multregtKeyword0 = deck->getKeyword("MULTREGT",0);
|
||||
keywords0.push_back( multregtKeyword0 );
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner(gridProperties,keywords0); , std::invalid_argument);
|
||||
|
||||
// Not supported region
|
||||
BOOST_CHECK_THROW( scanner.addKeyword( multregtKeyword1 ) , std::invalid_argument);
|
||||
std::vector<Opm::DeckKeywordConstPtr> keywords1;
|
||||
Opm::DeckKeywordConstPtr multregtKeyword1 = deck->getKeyword("MULTREGT",1);
|
||||
keywords1.push_back( multregtKeyword1 );
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner(gridProperties,keywords1); , std::invalid_argument);
|
||||
|
||||
// The keyword is ok; but it refers to a region which is not in the deck.
|
||||
scanner.addKeyword( multregtKeyword2 );
|
||||
BOOST_CHECK_THROW( scanner.scanRegions( gridProperties ) , std::logic_error);
|
||||
std::vector<Opm::DeckKeywordConstPtr> keywords2;
|
||||
Opm::DeckKeywordConstPtr multregtKeyword2 = deck->getKeyword("MULTREGT",2);
|
||||
keywords2.push_back( multregtKeyword2 );
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner(gridProperties,keywords2); , std::logic_error);
|
||||
}
|
||||
|
||||
|
||||
@ -141,7 +145,7 @@ static Opm::DeckPtr createNotSupportedMULTREGTDeck() {
|
||||
"3 4 5\n"
|
||||
"/\n"
|
||||
"MULTREGT\n"
|
||||
"1 2 0.50 X NNC M / -- Not yet support NNC behaviour \n"
|
||||
"1 2 0.50 X NOAQUNNC F / -- Not support NOAQUNNC behaviour \n"
|
||||
"/\n"
|
||||
"MULTREGT\n"
|
||||
"* 2 0.50 X ALL M / -- Defaulted from region value \n"
|
||||
@ -161,28 +165,41 @@ static Opm::DeckPtr createNotSupportedMULTREGTDeck() {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(NotSupported) {
|
||||
typedef Opm::GridProperties<int>::SupportedKeywordInfo SupportedKeywordInfo;
|
||||
std::shared_ptr<std::vector<SupportedKeywordInfo> > supportedKeywords(new std::vector<SupportedKeywordInfo>{
|
||||
SupportedKeywordInfo("FLUXNUM" , 1 , "1") ,
|
||||
SupportedKeywordInfo("OPERNUM" , 1 , "1") ,
|
||||
SupportedKeywordInfo("MULTNUM" , 1 , "1") });
|
||||
Opm::DeckPtr deck = createNotSupportedMULTREGTDeck();
|
||||
Opm::DeckKeywordConstPtr multregtKeyword0 = deck->getKeyword("MULTREGT",0);
|
||||
Opm::DeckKeywordConstPtr multregtKeyword1 = deck->getKeyword("MULTREGT",1);
|
||||
Opm::DeckKeywordConstPtr multregtKeyword2 = deck->getKeyword("MULTREGT",2);
|
||||
Opm::DeckKeywordConstPtr multregtKeyword3 = deck->getKeyword("MULTREGT",3);
|
||||
Opm::MULTREGTScanner scanner;
|
||||
|
||||
// Not supported NNC behaviour
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner::assertKeywordSupported(multregtKeyword0) , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( scanner.addKeyword(multregtKeyword0) , std::invalid_argument);
|
||||
std::shared_ptr<Opm::EclipseGrid> grid = std::make_shared<Opm::EclipseGrid>( deck );
|
||||
std::shared_ptr<Opm::GridProperties<int> > gridProperties = std::make_shared<Opm::GridProperties<int> >(grid, supportedKeywords);
|
||||
|
||||
// Not support NOAQUNNC behaviour
|
||||
std::vector<Opm::DeckKeywordConstPtr> keywords0;
|
||||
Opm::DeckKeywordConstPtr multregtKeyword0 = deck->getKeyword("MULTREGT",0);
|
||||
keywords0.push_back( multregtKeyword0 );
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner(gridProperties,keywords0); , std::invalid_argument);
|
||||
|
||||
// Defaulted from value - not supported
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner::assertKeywordSupported(multregtKeyword1) , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( scanner.addKeyword(multregtKeyword1) , std::invalid_argument);
|
||||
std::vector<Opm::DeckKeywordConstPtr> keywords1;
|
||||
Opm::DeckKeywordConstPtr multregtKeyword1 = deck->getKeyword("MULTREGT",1);
|
||||
keywords1.push_back( multregtKeyword1 );
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner(gridProperties,keywords1); , std::invalid_argument);
|
||||
|
||||
// Defaulted to value - not supported
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner::assertKeywordSupported(multregtKeyword2) , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( scanner.addKeyword(multregtKeyword2) , std::invalid_argument);
|
||||
std::vector<Opm::DeckKeywordConstPtr> keywords2;
|
||||
Opm::DeckKeywordConstPtr multregtKeyword2 = deck->getKeyword("MULTREGT",2);
|
||||
keywords2.push_back( multregtKeyword2 );
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner(gridProperties,keywords2); , std::invalid_argument);
|
||||
|
||||
|
||||
// srcValue == targetValue - not supported
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner::assertKeywordSupported(multregtKeyword3) , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( scanner.addKeyword(multregtKeyword3) , std::invalid_argument);
|
||||
std::vector<Opm::DeckKeywordConstPtr> keywords3;
|
||||
Opm::DeckKeywordConstPtr multregtKeyword3 = deck->getKeyword("MULTREGT",3);
|
||||
keywords3.push_back( multregtKeyword3 );
|
||||
BOOST_CHECK_THROW( Opm::MULTREGTScanner scanner(gridProperties,keywords3); , std::invalid_argument);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -211,6 +228,10 @@ static Opm::DeckPtr createSimpleMULTREGTDeck() {
|
||||
"MULTREGT\n"
|
||||
"2 1 1.50 X ALL M / \n"
|
||||
"/\n"
|
||||
"MULTREGT\n"
|
||||
"2 1 2.50 XYZ NNC M / \n"
|
||||
"2 1 3.50 XYZ NONNC M / \n"
|
||||
"/\n"
|
||||
"EDIT\n"
|
||||
"\n";
|
||||
|
||||
@ -219,72 +240,6 @@ static Opm::DeckPtr createSimpleMULTREGTDeck() {
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SimpleMULTREGT) {
|
||||
typedef Opm::GridProperties<int>::SupportedKeywordInfo SupportedKeywordInfo;
|
||||
std::shared_ptr<std::vector<SupportedKeywordInfo> > supportedKeywords(new std::vector<SupportedKeywordInfo>{
|
||||
SupportedKeywordInfo("FLUXNUM" , 1 , "1") ,
|
||||
SupportedKeywordInfo("OPERNUM" , 1 , "1") ,
|
||||
SupportedKeywordInfo("MULTNUM" , 1 , "1") });
|
||||
|
||||
Opm::DeckPtr deck = createSimpleMULTREGTDeck();
|
||||
std::shared_ptr<Opm::EclipseGrid> grid = std::make_shared<Opm::EclipseGrid>( deck );
|
||||
std::shared_ptr<const Opm::Box> inputBox = std::make_shared<const Opm::Box>( grid->getNX() , grid->getNY() , grid->getNZ() );
|
||||
|
||||
std::shared_ptr<Opm::GridProperties<int> > gridProperties = std::make_shared<Opm::GridProperties<int> >(grid, supportedKeywords);
|
||||
std::shared_ptr<Opm::GridProperty<int> > fluxNum = gridProperties->getKeyword("FLUXNUM");
|
||||
std::shared_ptr<Opm::GridProperty<int> > multNum = gridProperties->getKeyword("MULTNUM");
|
||||
Opm::DeckKeywordConstPtr fluxnumKeyword = deck->getKeyword("FLUXNUM",0);
|
||||
Opm::DeckKeywordConstPtr multnumKeyword = deck->getKeyword("MULTNUM",0);
|
||||
|
||||
Opm::DeckKeywordConstPtr multregtKeyword0 = deck->getKeyword("MULTREGT",0);
|
||||
Opm::DeckKeywordConstPtr multregtKeyword1 = deck->getKeyword("MULTREGT",1);
|
||||
|
||||
multNum->loadFromDeckKeyword( inputBox , multnumKeyword );
|
||||
fluxNum->loadFromDeckKeyword( inputBox , fluxnumKeyword );
|
||||
|
||||
{
|
||||
Opm::MULTREGTScanner scanner;
|
||||
scanner.addKeyword(multregtKeyword0);
|
||||
|
||||
auto cells = scanner.scanRegions(gridProperties);
|
||||
|
||||
BOOST_CHECK_EQUAL( 2 , cells.size() );
|
||||
auto cell0 = cells[0];
|
||||
auto cell1 = cells[1];
|
||||
|
||||
BOOST_CHECK_EQUAL( 0 , std::get<0>(cell0));
|
||||
BOOST_CHECK_EQUAL( Opm::FaceDir::XPlus , std::get<1>(cell0));
|
||||
BOOST_CHECK_EQUAL( 0.50 , std::get<2>(cell0));
|
||||
|
||||
BOOST_CHECK_EQUAL( 2 , std::get<0>(cell1));
|
||||
BOOST_CHECK_EQUAL( Opm::FaceDir::XPlus , std::get<1>(cell1));
|
||||
BOOST_CHECK_EQUAL( 0.50 , std::get<2>(cell1));
|
||||
}
|
||||
|
||||
{
|
||||
Opm::MULTREGTScanner scanner;
|
||||
scanner.addKeyword(multregtKeyword1);
|
||||
|
||||
auto cells = scanner.scanRegions(gridProperties);
|
||||
|
||||
BOOST_CHECK_EQUAL( 2 , cells.size() );
|
||||
|
||||
auto cell0 = cells[0];
|
||||
auto cell1 = cells[1];
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( 1 , std::get<0>(cell0));
|
||||
BOOST_CHECK_EQUAL( Opm::FaceDir::XMinus , std::get<1>(cell0));
|
||||
BOOST_CHECK_EQUAL( 1.50 , std::get<2>(cell0));
|
||||
|
||||
BOOST_CHECK_EQUAL( 3 , std::get<0>(cell1));
|
||||
BOOST_CHECK_EQUAL( Opm::FaceDir::XMinus , std::get<1>(cell1));
|
||||
BOOST_CHECK_EQUAL( 1.50 , std::get<2>(cell1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static Opm::DeckPtr createCopyMULTNUMDeck() {
|
||||
const char *deckData =
|
||||
"RUNSPEC\n"
|
||||
|
@ -40,8 +40,7 @@ using namespace Opm;
|
||||
BOOST_AUTO_TEST_CASE( parse_MULTREGT_OK ) {
|
||||
ParserPtr parser(new Parser());
|
||||
DeckPtr deck = parser->parseFile("testdata/integration_tests/MULTREGT/MULTREGT");
|
||||
DeckKeywordConstPtr multregtKeyword = deck->getKeyword("MULTREGT" , 0);
|
||||
BOOST_CHECK_NO_THROW( MULTREGTScanner::assertKeywordSupported( multregtKeyword ) );
|
||||
BOOST_CHECK_NO_THROW( deck->getKeyword("MULTREGT" , 0); );
|
||||
}
|
||||
|
||||
|
||||
@ -52,14 +51,47 @@ BOOST_AUTO_TEST_CASE( MULTREGT_ECLIPSE_STATE ) {
|
||||
EclipseState state(deck);
|
||||
auto transMult = state.getTransMult();
|
||||
|
||||
BOOST_CHECK_EQUAL( 0.10 , transMult->getMultiplier( 0 , 0 , 0 , FaceDir::XPlus ));
|
||||
BOOST_CHECK_EQUAL( 0.10 , transMult->getMultiplier( 0 , 1 , 0 , FaceDir::XPlus ));
|
||||
BOOST_CHECK_EQUAL( 0.20 , transMult->getMultiplier( 1 , 0 , 0 , FaceDir::XMinus ));
|
||||
BOOST_CHECK_EQUAL( 0.20 , transMult->getMultiplier( 1 , 1 , 0 , FaceDir::XMinus ));
|
||||
BOOST_CHECK_EQUAL( 1.50 , transMult->getMultiplier( 0 , 0 , 0 , FaceDir::ZPlus ));
|
||||
BOOST_CHECK_EQUAL( 1.50 , transMult->getMultiplier( 0 , 1 , 0 , FaceDir::ZPlus ));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getMultiplier( 1 , 0 , 0 , FaceDir::ZPlus ));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getMultiplier( 1 , 1 , 0 , FaceDir::ZPlus ));
|
||||
BOOST_CHECK_EQUAL( 0.60 , transMult->getMultiplier( 1 , 0 , 1 , FaceDir::ZMinus ));
|
||||
BOOST_CHECK_EQUAL( 0.60 , transMult->getMultiplier( 1 , 1 , 1 , FaceDir::ZMinus ));
|
||||
// Test NONNC
|
||||
// cell 0 and 1 are neigbours
|
||||
BOOST_CHECK_EQUAL( 0.10 , transMult->getRegionMultiplier( 0 , 1 , FaceDir::DirEnum::XPlus));
|
||||
// cell 0 and 3 are not neigbours ==> 1
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 0 , 3 , FaceDir::DirEnum::XPlus));
|
||||
|
||||
// Test NNC
|
||||
// cell 4 and 5 are neigbours ==> 1
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 4 , 5 , FaceDir::DirEnum::XPlus));
|
||||
// cell 4 and 7 are not neigbours
|
||||
BOOST_CHECK_EQUAL( 0.50 , transMult->getRegionMultiplier( 4 , 7 , FaceDir::DirEnum::XPlus));
|
||||
|
||||
// Test direction X, returns 1 for directions other than +-X
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 0 , 1 , FaceDir::DirEnum::YPlus));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 0 , 1 , FaceDir::DirEnum::ZPlus));
|
||||
BOOST_CHECK_EQUAL( 0.10 , transMult->getRegionMultiplier( 0 , 1 , FaceDir::DirEnum::XMinus));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 0 , 1 , FaceDir::DirEnum::YMinus));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 0 , 1 , FaceDir::DirEnum::ZMinus));
|
||||
BOOST_CHECK_EQUAL( 0.20 , transMult->getRegionMultiplier( 1 , 0 , FaceDir::DirEnum::XPlus));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 1 , 0 , FaceDir::DirEnum::YPlus));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 1 , 0 , FaceDir::DirEnum::ZPlus));
|
||||
BOOST_CHECK_EQUAL( 0.20 , transMult->getRegionMultiplier( 1 , 0 , FaceDir::DirEnum::XMinus));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 1 , 0 , FaceDir::DirEnum::YMinus));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 1 , 0 , FaceDir::DirEnum::ZMinus));
|
||||
|
||||
// Multipliers between cells of the same region should return 1
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 0 , 2 , FaceDir::DirEnum::XPlus));
|
||||
BOOST_CHECK_EQUAL( 1.00 , transMult->getRegionMultiplier( 2 , 0 , FaceDir::DirEnum::XPlus));
|
||||
|
||||
// Test direcion XYZ, returns values for all directions
|
||||
BOOST_CHECK_EQUAL( 1.50 , transMult->getRegionMultiplier( 0 , 4 , FaceDir::DirEnum::XPlus));
|
||||
BOOST_CHECK_EQUAL( 1.50 , transMult->getRegionMultiplier( 0 , 4 , FaceDir::DirEnum::YPlus));
|
||||
BOOST_CHECK_EQUAL( 1.50 , transMult->getRegionMultiplier( 0 , 4 , FaceDir::DirEnum::ZPlus));
|
||||
BOOST_CHECK_EQUAL( 1.50 , transMult->getRegionMultiplier( 4 , 0 , FaceDir::DirEnum::XPlus));
|
||||
|
||||
// The first record is overwritten by the second
|
||||
BOOST_CHECK_EQUAL( 2.50 , transMult->getRegionMultiplier( 3 , 7 , FaceDir::DirEnum::XPlus));
|
||||
BOOST_CHECK_EQUAL( 2.50 , transMult->getRegionMultiplier( 3 , 7 , FaceDir::DirEnum::YPlus));
|
||||
|
||||
// The 2 4 0.75 Z input is overwritten by 2 4 2.5 XY, ==) that 2 4 Z returns the 4 2 value = 0.6
|
||||
BOOST_CHECK_EQUAL( 0.60 , transMult->getRegionMultiplier( 7 , 3 , FaceDir::DirEnum::XPlus));
|
||||
BOOST_CHECK_EQUAL( 0.60 , transMult->getRegionMultiplier( 3 , 7 , FaceDir::DirEnum::ZPlus));
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ MULTNUM
|
||||
/
|
||||
|
||||
MULTREGT
|
||||
1 2 0.10 X ALL M /
|
||||
1 2 0.10 X NONNC M /
|
||||
3 4 0.50 X NNC M /
|
||||
/
|
||||
|
||||
MULTREGT
|
||||
|
Loading…
Reference in New Issue
Block a user