diff --git a/opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp b/opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp index dfd214e71..94d03479f 100644 --- a/opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp +++ b/opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp @@ -81,6 +81,8 @@ namespace Opm { void handleCOPYKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager); void handleENDBOXKeyword( BoxManager& boxManager); void handleEQUALSKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager); + void handleMAXVALUEKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager); + void handleMINVALUEKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager); void handleMULTIPLYKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager); void handleADDREGKeyword( const DeckKeyword& deckKeyword ); diff --git a/opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp b/opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp index eb3742cc9..161294efa 100644 --- a/opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp @@ -140,6 +140,8 @@ namespace Opm { */ void handleADDRecord( const DeckRecord& record, BoxManager& boxManager); + void handleMAXVALUERecord( const DeckRecord& record, BoxManager& boxManager); + void handleMINVALUERecord( const DeckRecord& record, BoxManager& boxManager); void handleMULTIPLYRecord( const DeckRecord& record, BoxManager& boxManager); void handleCOPYRecord( const DeckRecord& record, BoxManager& boxManager); void handleEQUALSRecord( const DeckRecord& record, BoxManager& boxManager); diff --git a/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp b/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp index e63f47e44..613dd0020 100644 --- a/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp @@ -130,6 +130,8 @@ public: void copyFrom( const GridProperty< T >&, const Box& ); void scale( T scaleFactor, const Box& ); + void maxvalue( T value, const Box& ); + void minvalue( T value, const Box& ); void add( T shiftValue, const Box& ); void setScalar( T value, const Box& ); diff --git a/src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp b/src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp index 799c036fd..cc9b2e5be 100644 --- a/src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp +++ b/src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp @@ -744,6 +744,12 @@ namespace Opm { else if (deckKeyword.name() == "MULTIPLY") handleMULTIPLYKeyword(deckKeyword, boxManager); + else if (deckKeyword.name() == "MAXVALUE") + handleMAXVALUEKeyword(deckKeyword, boxManager); + + else if (deckKeyword.name() == "MINVALUE") + handleMINVALUEKeyword(deckKeyword, boxManager); + else if (deckKeyword.name() == "EQUALREG") handleEQUALREGKeyword(deckKeyword); @@ -857,7 +863,37 @@ namespace Opm { } } + //Note that the MAXVALUE kqeyword is processed in place for the current value of the keyword, + // and does not "stick" as a persistent attribute of the keyword. + void Eclipse3DProperties::handleMAXVALUEKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) { + for( const auto& record : deckKeyword ) { + const std::string& field = record.getItem("field").get< std::string >(0); + if (m_doubleGridProperties.hasKeyword( field )) + m_doubleGridProperties.handleMAXVALUERecord( record , boxManager ); + else if (m_intGridProperties.hasKeyword( field )) + m_intGridProperties.handleMAXVALUERecord( record , boxManager ); + else + throw std::invalid_argument("Fatal error processing MAXVALUE keyword. Tried to limit not defined keyword " + field); + + } + } + + //Note that the MINVALUE keyword is processed in place for the current value of the keyword, + // and does not "stick" as a persistent attribute of the keyword. + void Eclipse3DProperties::handleMINVALUEKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) { + for( const auto& record : deckKeyword ) { + const std::string& field = record.getItem("field").get< std::string >(0); + + if (m_doubleGridProperties.hasKeyword( field )) + m_doubleGridProperties.handleMINVALUERecord( record , boxManager ); + else if (m_intGridProperties.hasKeyword( field )) + m_intGridProperties.handleMINVALUERecord( record , boxManager ); + else + throw std::invalid_argument("Fatal error processing MINVALUE keyword. Tried to limit not defined keyword " + field); + + } + } void Eclipse3DProperties::handleMULTIPLYKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) { @@ -869,7 +905,7 @@ namespace Opm { else if (m_intGridProperties.hasKeyword( field )) m_intGridProperties.handleMULTIPLYRecord( record , boxManager ); else - throw std::invalid_argument("Fatal error processing MULTIPLY keyword. Tried to shift not defined keyword " + field); + throw std::invalid_argument("Fatal error processing MULTIPLY keyword. Tried to scale not defined keyword " + field); } } diff --git a/src/opm/parser/eclipse/EclipseState/Grid/GridProperties.cpp b/src/opm/parser/eclipse/EclipseState/Grid/GridProperties.cpp index c899718db..57336b39a 100644 --- a/src/opm/parser/eclipse/EclipseState/Grid/GridProperties.cpp +++ b/src/opm/parser/eclipse/EclipseState/Grid/GridProperties.cpp @@ -267,6 +267,32 @@ namespace Opm { throw std::invalid_argument("Fatal error processing ADD keyword. Tried to shift not defined keyword " + field); } + template< typename T > + void GridProperties::handleMAXVALUERecord( const DeckRecord& record, BoxManager& boxManager) { + const std::string& field = record.getItem("field").get< std::string >(0); + + if (hasKeyword( field )) { + GridProperty& property = getKeyword( field ); + T value = convertInputValue( record.getItem("value").get< double >(0) ); + setKeywordBox(record, boxManager); + property.maxvalue( value , boxManager.getActiveBox() ); + } else + throw std::invalid_argument("Fatal error processing MAXVALUE keyword. Tried to limit not defined keyword " + field); + } + + template< typename T > + void GridProperties::handleMINVALUERecord( const DeckRecord& record, BoxManager& boxManager) { + const std::string& field = record.getItem("field").get< std::string >(0); + + if (hasKeyword( field )) { + GridProperty& property = getKeyword( field ); + T value = convertInputValue( record.getItem("value").get< double >(0) ); + setKeywordBox(record, boxManager); + property.minvalue( value , boxManager.getActiveBox() ); + } else + throw std::invalid_argument("Fatal error processing MINVALUE keyword. Tried to limit not defined keyword " + field); + } + template< typename T > void GridProperties::handleMULTIPLYRecord( const DeckRecord& record, BoxManager& boxManager) { const std::string& field = record.getItem("field").get< std::string >(0); @@ -277,7 +303,7 @@ namespace Opm { setKeywordBox(record, boxManager); property.scale( factor , boxManager.getActiveBox() ); } else - throw std::invalid_argument("Fatal error processing ADD keyword. Tried to shift not defined keyword " + field); + throw std::invalid_argument("Fatal error processing MULTIPLY keyword. Tried to scale not defined keyword " + field); } diff --git a/src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp b/src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp index 391bd74d1..dbd23c647 100644 --- a/src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp +++ b/src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp @@ -281,6 +281,34 @@ namespace Opm { } } + template< typename T > + void GridProperty< T >::maxvalue( T value, const Box& inputBox ) { + if (inputBox.isGlobal()) { + for (size_t i = 0; i < m_data.size(); ++i) + m_data[i] = std::min(value,m_data[i]); + } else { + const std::vector& indexList = inputBox.getIndexList(); + for (size_t i = 0; i < indexList.size(); i++) { + size_t targetIndex = indexList[i]; + m_data[targetIndex] = std::min(value,m_data[targetIndex]); + } + } + } + + template< typename T > + void GridProperty< T >::minvalue( T value, const Box& inputBox ) { + if (inputBox.isGlobal()) { + for (size_t i = 0; i < m_data.size(); ++i) + m_data[i] = std::max(value,m_data[i]); + } else { + const std::vector& indexList = inputBox.getIndexList(); + for (size_t i = 0; i < indexList.size(); i++) { + size_t targetIndex = indexList[i]; + m_data[targetIndex] = std::max(value,m_data[targetIndex]); + } + } + } + template< typename T > void GridProperty< T >::scale( T scaleFactor, const Box& inputBox ) { if (inputBox.isGlobal()) { diff --git a/tests/parser/data/integration_tests/BOX/BOXTEST1 b/tests/parser/data/integration_tests/BOX/BOXTEST1 index b71810f80..cb9def846 100644 --- a/tests/parser/data/integration_tests/BOX/BOXTEST1 +++ b/tests/parser/data/integration_tests/BOX/BOXTEST1 @@ -27,7 +27,15 @@ OPERATE NTG 1 10 6 10 2 2 'MINLIM' SWAT 2 / -- NTG = max(swat, 2 ) -- NTG 1 10 1 5 3 3 'MAXLIM' SWAT 2 / -- NTG = min(swat, 2 ) -/ +/ + +MAXVALUE +NTG 0.5 1 10 1 5 4 4 / -- NTG <= 0.5 +/ + +MINVALUE +NTG 1.5 1 10 1 5 5 5 / -- NTG >= 1.5 +/ PERMX diff --git a/tests/parser/integration/BoxTest.cpp b/tests/parser/integration/BoxTest.cpp index 9943044c9..9f41a1f05 100644 --- a/tests/parser/integration/BoxTest.cpp +++ b/tests/parser/integration/BoxTest.cpp @@ -152,5 +152,9 @@ BOOST_AUTO_TEST_CASE( OPERATE ) { BOOST_CHECK_EQUAL( ntg.iget( 0,5,1) , 4.0 ); // MINLIM BOOST_CHECK_EQUAL( ntg.iget( 0,0,2) , 2.0 ); // MAXLIM + + BOOST_CHECK_EQUAL( ntg.iget( 0,0,3) , 0.5 ); // MAXVALUE + + BOOST_CHECK_EQUAL( ntg.iget( 0,0,4) , 1.5 ); // MINVALUE }