From bb40baa96f0ef4e068d2f5d4b0f0f69c23d9846e Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Fri, 5 Dec 2014 11:14:53 +0100 Subject: [PATCH] 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. --- .../eclipse/EclipseState/EclipseState.cpp | 9 +- .../EclipseState/Grid/MULTREGTScanner.cpp | 211 ++++++++---------- .../EclipseState/Grid/MULTREGTScanner.hpp | 13 +- .../eclipse/EclipseState/Grid/TransMult.cpp | 19 +- .../eclipse/EclipseState/Grid/TransMult.hpp | 4 +- .../Grid/tests/MULTREGTScannerTests.cpp | 135 ++++------- .../IntegrationTests/ParseMULTREGT.cpp | 56 ++++- .../integration_tests/MULTREGT/MULTREGT.DATA | 3 +- 8 files changed, 204 insertions(+), 246 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/EclipseState.cpp b/opm/parser/eclipse/EclipseState/EclipseState.cpp index 0e2240b9e..6f7c1f270 100644 --- a/opm/parser/eclipse/EclipseState/EclipseState.cpp +++ b/opm/parser/eclipse/EclipseState/EclipseState.cpp @@ -360,13 +360,13 @@ namespace Opm { void EclipseState::initMULTREGT(DeckConstPtr deck, ParserLogPtr /*parserLog*/) { EclipseGridConstPtr grid = getEclipseGrid(); - std::shared_ptr scanner = std::make_shared(); + std::vector keywords; { std::shared_ptr 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 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 scanner = std::make_shared( m_intGridProperties, keywords); - m_transMult->applyMULTREGT( scanner , m_intGridProperties); + m_transMult->setMultregtScanner( scanner ); } diff --git a/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp b/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp index 19b7d6b37..380c91454 100644 --- a/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp @@ -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 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 > cellRegionNumbers, const std::vector& keywords ) : + m_cellRegionNumbers(cellRegionNumbers) { + + for (int indx = 0; indx < keywords.size(); indx++){ + addKeyword(keywords[indx]); + } + + MULTREGTSearchMap searchPairs; + for (std::vector::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 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 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 > 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 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{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 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 > regions) { - std::vector< MULTREGTConnection > connections; - std::map searchMap; - { - MULTREGTSearchMap searchPairs; - for (std::vector::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 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 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 > region = regions->getKeyword( (*iter).first ); + for (auto iter = m_searchMap.begin(); iter != m_searchMap.end(); iter++) { + std::shared_ptr > 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 pair{regionId1 , regionId2}; + if (map.count(pair) != 1 || !(map.at(pair)->m_directions & faceDir)) { + pair = std::pair{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; } - } diff --git a/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp b/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp index f13c24cf9..d01df43a0 100644 --- a/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp @@ -66,16 +66,15 @@ namespace Opm { class MULTREGTScanner { public: - MULTREGTScanner(); - void addKeyword(DeckKeywordConstPtr deckKeyword); - const std::vector< std::tuple > scanRegions( std::shared_ptr > regions); - static void assertKeywordSupported(DeckKeywordConstPtr deckKeyword); + MULTREGTScanner(std::shared_ptr > cellRegionNumbers, const std::vector& 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 > 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 m_searchMap; + std::shared_ptr > m_cellRegionNumbers; }; } diff --git a/opm/parser/eclipse/EclipseState/Grid/TransMult.cpp b/opm/parser/eclipse/EclipseState/Grid/TransMult.cpp index 36cea8e0c..3c54809bd 100644 --- a/opm/parser/eclipse/EclipseState/Grid/TransMult.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/TransMult.cpp @@ -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 , std::shared_ptr > 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 > 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 multregtScanner) { + m_multregtScanner = multregtScanner; } } diff --git a/opm/parser/eclipse/EclipseState/Grid/TransMult.hpp b/opm/parser/eclipse/EclipseState/Grid/TransMult.hpp index d42eb713d..6b65f6a2e 100644 --- a/opm/parser/eclipse/EclipseState/Grid/TransMult.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/TransMult.hpp @@ -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 > getDirectionProperty(FaceDir::DirEnum faceDir); void applyMULT(std::shared_ptr > srcMultProp, FaceDir::DirEnum faceDir); void applyMULTFLT( std::shared_ptr faults); - void applyMULTREGT( std::shared_ptr multregtScanner , std::shared_ptr > regions); + void setMultregtScanner(std::shared_ptr 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 > > m_trans; std::map m_names; + std::shared_ptr m_multregtScanner; }; } diff --git a/opm/parser/eclipse/EclipseState/Grid/tests/MULTREGTScannerTests.cpp b/opm/parser/eclipse/EclipseState/Grid/tests/MULTREGTScannerTests.cpp index 041e82adb..6adfd38c4 100644 --- a/opm/parser/eclipse/EclipseState/Grid/tests/MULTREGTScannerTests.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/tests/MULTREGTScannerTests.cpp @@ -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 grid = std::make_shared( deck ); std::shared_ptr > gridProperties = std::make_shared >(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 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 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 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::SupportedKeywordInfo SupportedKeywordInfo; + std::shared_ptr > supportedKeywords(new std::vector{ + 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 grid = std::make_shared( deck ); + std::shared_ptr > gridProperties = std::make_shared >(grid, supportedKeywords); + + // Not support NOAQUNNC behaviour + std::vector 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 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 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 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::SupportedKeywordInfo SupportedKeywordInfo; - std::shared_ptr > supportedKeywords(new std::vector{ - SupportedKeywordInfo("FLUXNUM" , 1 , "1") , - SupportedKeywordInfo("OPERNUM" , 1 , "1") , - SupportedKeywordInfo("MULTNUM" , 1 , "1") }); - - Opm::DeckPtr deck = createSimpleMULTREGTDeck(); - std::shared_ptr grid = std::make_shared( deck ); - std::shared_ptr inputBox = std::make_shared( grid->getNX() , grid->getNY() , grid->getNZ() ); - - std::shared_ptr > gridProperties = std::make_shared >(grid, supportedKeywords); - std::shared_ptr > fluxNum = gridProperties->getKeyword("FLUXNUM"); - std::shared_ptr > 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" diff --git a/opm/parser/eclipse/IntegrationTests/ParseMULTREGT.cpp b/opm/parser/eclipse/IntegrationTests/ParseMULTREGT.cpp index 28a06b3af..f75c7272f 100644 --- a/opm/parser/eclipse/IntegrationTests/ParseMULTREGT.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParseMULTREGT.cpp @@ -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)); + } diff --git a/testdata/integration_tests/MULTREGT/MULTREGT.DATA b/testdata/integration_tests/MULTREGT/MULTREGT.DATA index 5d9241b0f..7ccb6e78e 100644 --- a/testdata/integration_tests/MULTREGT/MULTREGT.DATA +++ b/testdata/integration_tests/MULTREGT/MULTREGT.DATA @@ -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