diff --git a/opm/parser/eclipse/EclipseState/EclipseState.cpp b/opm/parser/eclipse/EclipseState/EclipseState.cpp index 39562dd76..0d3160517 100644 --- a/opm/parser/eclipse/EclipseState/EclipseState.cpp +++ b/opm/parser/eclipse/EclipseState/EclipseState.cpp @@ -120,6 +120,7 @@ namespace Opm { BoxManager boxManager(m_eclipseGrid->getNX( ) , m_eclipseGrid->getNY() , m_eclipseGrid->getNZ()); std::vector > supportedIntKeywords = {{ "SATNUM" , 0 }, { "PVTNUM" , 0 }, + { "EQLNUM" , 0 }, { "FIPNUM" , 0 }}; m_intGridProperties = std::make_shared >(m_eclipseGrid->getNX() , m_eclipseGrid->getNY() , m_eclipseGrid->getNZ() , supportedIntKeywords); @@ -132,12 +133,18 @@ namespace Opm { if (supportsGridProperty( deckKeyword->name()) ) loadGridPropertyFromDeckKeyword( boxManager.getActiveBox() , deckKeyword ); + if (deckKeyword->name() == "ADD") + handleADDKeyword(deckKeyword , boxManager); + if (deckKeyword->name() == "BOX") handleBOXKeyword(deckKeyword , boxManager); if (deckKeyword->name() == "COPY") handleCOPYKeyword(deckKeyword , boxManager); + if (deckKeyword->name() == "EQUALS") + handleEQUALSKeyword(deckKeyword , boxManager); + if (deckKeyword->name() == "ENDBOX") handleENDBOXKeyword(deckKeyword , boxManager); @@ -184,11 +191,58 @@ namespace Opm { property->scale( intFactor , boxManager.getActiveBox() ); } else throw std::invalid_argument("Fatal error processing MULTIPLY keyword. Tried to multiply not defined keyword" + field); - + } } + /* + The fine print of the manual says the ADD keyword should support + some state dependent semantics regarding endpoint scaling arrays + in the PROPS section. That is not supported. + */ + + void EclipseState::handleADDKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager) { + for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) { + DeckRecordConstPtr record = *iter; + const std::string& field = record->getItem("field")->getString(0); + double shiftValue = record->getItem("shift")->getRawDouble(0); + + setKeywordBox( record , boxManager ); + + if (m_intGridProperties->hasKeyword( field )) { + int intShift = static_cast(shiftValue); + std::shared_ptr > property = m_intGridProperties->getKeyword( field ); + + property->add( intShift , boxManager.getActiveBox() ); + } else + throw std::invalid_argument("Fatal error processing ADD keyword. Tried to multiply not defined keyword" + field); + + } + } + + + void EclipseState::handleEQUALSKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager) { + for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) { + DeckRecordConstPtr record = *iter; + const std::string& field = record->getItem("field")->getString(0); + double value = record->getItem("value")->getRawDouble(0); + + setKeywordBox( record , boxManager ); + + if (m_intGridProperties->supportsKeyword( field )) { + int intValue = static_cast(value); + std::shared_ptr > property = m_intGridProperties->getKeyword( field ); + + property->setScalar( intValue , boxManager.getActiveBox() ); + } else + throw std::invalid_argument("Fatal error processing EQUALS keyword. Tried to set not defined keyword" + field); + + } + } + + + void EclipseState::handleCOPYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager) { for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) { DeckRecordConstPtr record = *iter; diff --git a/opm/parser/eclipse/EclipseState/EclipseState.hpp b/opm/parser/eclipse/EclipseState/EclipseState.hpp index 46f6903e7..30c7d5592 100644 --- a/opm/parser/eclipse/EclipseState/EclipseState.hpp +++ b/opm/parser/eclipse/EclipseState/EclipseState.hpp @@ -51,10 +51,12 @@ namespace Opm { void initPhases(DeckConstPtr deck); void initTitle(DeckConstPtr deck); void initProperties(DeckConstPtr deck); - + + void handleADDKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager); void handleBOXKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager); void handleCOPYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager); void handleENDBOXKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager); + void handleEQUALSKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager); void handleMULTIPLYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager); void setKeywordBox(DeckRecordConstPtr deckRecord , BoxManager& boxManager); diff --git a/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp b/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp index cb0500cb3..19bd4542b 100644 --- a/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp @@ -83,12 +83,10 @@ public: void loadFromDeckKeyword(DeckKeywordConstPtr deckKeyword); - + void copyFrom(const GridProperty& src, std::shared_ptr inputBox) { if (inputBox->isGlobal()) { - for (size_t i = 0; i < m_data.size(); i++) - m_data[i] = src.m_data[i]; - //std::copy( src.m_data.begin() , src.m_data.end() , m_data.begin() ); + std::copy( src.m_data.begin() , src.m_data.end() , m_data.begin() ); } else { const std::vector& indexList = inputBox->getIndexList(); for (size_t i = 0; i < indexList.size(); i++) { @@ -111,6 +109,36 @@ public: } } } + + + void add(T scaleFactor , std::shared_ptr inputBox) { + if (inputBox->isGlobal()) { + std::transform(m_data.begin(), m_data.end(), m_data.begin(), + std::bind1st(std::plus() , scaleFactor)); + + } else { + const std::vector& indexList = inputBox->getIndexList(); + for (size_t i = 0; i < indexList.size(); i++) { + size_t targetIndex = indexList[i]; + m_data[targetIndex] += scaleFactor; + } + } + } + + + + + void setScalar(T value , std::shared_ptr inputBox) { + if (inputBox->isGlobal()) { + std::fill(m_data.begin(), m_data.end(), value); + } else { + const std::vector& indexList = inputBox->getIndexList(); + for (size_t i = 0; i < indexList.size(); i++) { + size_t targetIndex = indexList[i]; + m_data[targetIndex] = value; + } + } + } diff --git a/opm/parser/eclipse/EclipseState/Grid/tests/GridPropertyTests.cpp b/opm/parser/eclipse/EclipseState/Grid/tests/GridPropertyTests.cpp index e531f5259..ef6d628a2 100644 --- a/opm/parser/eclipse/EclipseState/Grid/tests/GridPropertyTests.cpp +++ b/opm/parser/eclipse/EclipseState/Grid/tests/GridPropertyTests.cpp @@ -160,3 +160,44 @@ BOOST_AUTO_TEST_CASE(SCALE) { } } } + + +BOOST_AUTO_TEST_CASE(SET) { + Opm::GridProperty prop( 4 , 4 , 2 , "P1" , 1); + + std::shared_ptr global = std::make_shared(4,4,2); + std::shared_ptr layer0 = std::make_shared(*global , 0,3,0,3,0,0); + + prop.setScalar( 2 , global ); + prop.setScalar( 4 , layer0 ); + + for (size_t j=0; j < 4; j++) { + for (size_t i=0; i < 4; i++) { + + BOOST_CHECK_EQUAL( prop.iget(i,j,0) , 4 ); + BOOST_CHECK_EQUAL( prop.iget(i,j,1) , 2 ); + } + } +} + + +BOOST_AUTO_TEST_CASE(ADD) { + Opm::GridProperty prop1( 4 , 4 , 2 , "P1" , 1); + Opm::GridProperty prop2( 4 , 4 , 2 , "P2" , 9); + + std::shared_ptr global = std::make_shared(4,4,2); + std::shared_ptr layer0 = std::make_shared(*global , 0,3,0,3,0,0); + + prop2.copyFrom(prop1 , layer0); + prop2.add( 2 , global ); + prop2.add( 2 , layer0 ); + + for (size_t j=0; j < 4; j++) { + for (size_t i=0; i < 4; i++) { + + BOOST_CHECK_EQUAL( prop2.iget(i,j,0) , 5 ); + BOOST_CHECK_EQUAL( prop2.iget(i,j,1) , 11 ); + } + } +} + diff --git a/opm/parser/eclipse/IntegrationTests/BoxTest.cpp b/opm/parser/eclipse/IntegrationTests/BoxTest.cpp index 8e8401a02..97b8bb738 100644 --- a/opm/parser/eclipse/IntegrationTests/BoxTest.cpp +++ b/opm/parser/eclipse/IntegrationTests/BoxTest.cpp @@ -89,3 +89,22 @@ BOOST_AUTO_TEST_CASE( PARSE_MULTIPLY_COPY ) { BOOST_AUTO_TEST_CASE( INCOMPLETE_KEYWORD_BOX) { BOOST_CHECK_THROW( makeState("testdata/integration_tests/BOX/BOXTEST2") , std::invalid_argument); } + +BOOST_AUTO_TEST_CASE( EQUAL ) { + EclipseState state = makeState("testdata/integration_tests/BOX/BOXTEST1"); + std::shared_ptr > pvtnum = state.getIntProperty("PVTNUM"); + std::shared_ptr > eqlnum = state.getIntProperty("EQLNUM"); + size_t i,j,k; + std::shared_ptr grid = state.getEclipseGrid(); + + for (k = 0; k < grid->getNZ(); k++) { + for (j = 0; j < grid->getNY(); j++) { + for (i = 0; i < grid->getNX(); i++) { + + BOOST_CHECK_EQUAL( pvtnum->iget(i,j,k) , k ); + BOOST_CHECK_EQUAL( eqlnum->iget(i,j,k) , 77 + 2 * k ); + + } + } + } +} diff --git a/testdata/integration_tests/BOX/BOXTEST1 b/testdata/integration_tests/BOX/BOXTEST1 index 94c0388ab..025f0ca7d 100644 --- a/testdata/integration_tests/BOX/BOXTEST1 +++ b/testdata/integration_tests/BOX/BOXTEST1 @@ -36,6 +36,9 @@ FLUXNUM SATNUM 1000*2 / +PVTNUM + 1000*77 / + COPY SATNUM FIPNUM / / @@ -46,6 +49,7 @@ BOX SATNUM 8*10 / + COPY SATNUM FIPNUM / / @@ -65,5 +69,115 @@ MULTIPLY ENDBOX + +EQUALS + PVTNUM 0 1 10 1 10 1 1 / + PVTNUM 1 1 10 1 10 2 2 / + PVTNUM 2 1 10 1 10 3 3 / + PVTNUM 3 1 10 1 10 4 4 / + PVTNUM 4 1 10 1 10 5 5 / + PVTNUM 5 1 10 1 10 6 6 / + PVTNUM 6 1 10 1 10 7 7 / + PVTNUM 7 1 10 1 10 8 8 / + PVTNUM 8 1 10 1 10 9 9 / + PVTNUM 9 1 10 1 10 10 10 / +/ + +EQUALS + EQLNUM 77 / +/ + +ADD + EQLNUM 0 1 10 1 10 1 1 / + EQLNUM 1 1 10 1 10 2 2 / + EQLNUM 2 1 10 1 10 3 3 / + EQLNUM 3 1 10 1 10 4 4 / + EQLNUM 4 1 10 1 10 5 5 / + EQLNUM 5 1 10 1 10 6 6 / + EQLNUM 6 1 10 1 10 7 7 / + EQLNUM 7 1 10 1 10 8 8 / + EQLNUM 8 1 10 1 10 9 9 / + EQLNUM 9 1 10 1 10 10 10 / +/ + + + + +BOX + 1 10 1 10 1 1 / + +ADD + EQLNUM 0 / +/ + +BOX + 1 10 1 10 2 2 / + +ADD + EQLNUM 1 / +/ + +BOX + 1 10 1 10 3 3 / + +ADD + EQLNUM 2 / +/ + +BOX + 1 10 1 10 4 4 / + +ADD + EQLNUM 3 / +/ + +BOX + 1 10 1 10 5 5 / + +ADD + EQLNUM 4 / +/ + +BOX + 1 10 1 10 6 6 / + +ADD + EQLNUM 5 / +/ + +BOX + 1 10 1 10 7 7 / + +ADD + EQLNUM 6 / +/ + +BOX + 1 10 1 10 8 8 / + +ADD + EQLNUM 7 / +/ + +BOX + 1 10 1 10 9 9 / + +ADD + EQLNUM 8 / +/ + +BOX + 1 10 1 10 10 10 / + +ADD + EQLNUM 9 / +/ + + + + + + + SCHEDULE