diff --git a/opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp b/opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp index 38f4008e9..13d7090f2 100644 --- a/opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp +++ b/opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp @@ -77,7 +77,8 @@ namespace Opm { const EclipseGrid& eclipseGrid); void scanSection(const Section& section, - const EclipseGrid& eclipseGrid); + const EclipseGrid& eclipseGrid, + bool edit_section); void handleADDKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager); void handleBOXKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager); @@ -96,7 +97,8 @@ namespace Opm { void handleOPERATERKeyword( const DeckKeyword& deckKeyword); void loadGridPropertyFromDeckKeyword(const Box& inputBox, - const DeckKeyword& deckKeyword); + const DeckKeyword& deckKeyword, + bool edity_section); void adjustSOGCRwithSWL(); diff --git a/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp b/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp index 7e3a63e56..87008599a 100644 --- a/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp +++ b/opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp @@ -171,8 +171,8 @@ public: DeckKeyword equals nx*ny*nz. */ - void loadFromDeckKeyword( const DeckKeyword& ); - void loadFromDeckKeyword( const Box&, const DeckKeyword& ); + void loadFromDeckKeyword( const DeckKeyword& , bool); + void loadFromDeckKeyword( const Box&, const DeckKeyword& , bool); void copyFrom( const GridProperty< T >&, const Box& ); void scale( T scaleFactor, const Box& ); @@ -305,6 +305,7 @@ public: private: const DeckItem& getDeckItem( const DeckKeyword& ); void setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem); + void mulDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem); void setElement(const typename std::vector::size_type i, const T value, const bool defaulted = false); diff --git a/src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp b/src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp index 0885f11a1..f69bdda27 100644 --- a/src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp +++ b/src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp @@ -641,14 +641,35 @@ namespace Opm { /// m_doubleGridProperties fields directly and *NOT* use the public methods /// getIntGridProperty / getDoubleGridProperty. void Eclipse3DProperties::loadGridPropertyFromDeckKeyword(const Box& inputBox, - const DeckKeyword& deckKeyword) { + const DeckKeyword& deckKeyword, + bool edit_section) { + static std::set multiply_keywords = {"MULTX", + "MULTY", + "MULTZ", + "MULTX-", + "MULTY-", + "MULTZ-"}; + /* + The opm input handling is not really section aware, some keywords + should be handled differently in the EDIT section and the GRID + section. In particular this applies top the transmissibility + multipliers MULT(XYZ) where they should be assigned and reassigned in + the GRID section, and applied multiplicatively in the EDIT section. + + Here we have special cased hack for the MULT(XYZ) keywords, there are + probably other keywords as well which also should be handled + differently in the GRID and EDIT sections, but this is handled on a + bug by bug basis. + */ + const std::string& keyword = deckKeyword.name(); + bool multiply = (edit_section && (multiply_keywords.count(keyword) == 1)); if (m_intGridProperties.supportsKeyword( keyword )) { auto& gridProperty = m_intGridProperties.getOrCreateProperty( keyword ); - gridProperty.loadFromDeckKeyword( inputBox, deckKeyword ); + gridProperty.loadFromDeckKeyword( inputBox, deckKeyword , false ); } else if (m_doubleGridProperties.supportsKeyword( keyword )) { auto& gridProperty = m_doubleGridProperties.getOrCreateProperty( keyword ); - gridProperty.loadFromDeckKeyword( inputBox, deckKeyword ); + gridProperty.loadFromDeckKeyword( inputBox, deckKeyword, multiply ); } else { throw std::logic_error( "Tried to load unsupported grid property from keyword: " + deckKeyword.name() ); } @@ -746,31 +767,33 @@ namespace Opm { const EclipseGrid& eclipseGrid) { if (Section::hasGRID(deck)) - scanSection(GRIDSection(deck), eclipseGrid); + scanSection(GRIDSection(deck), eclipseGrid, false); if (Section::hasREGIONS(deck)) - scanSection(REGIONSSection(deck), eclipseGrid); + scanSection(REGIONSSection(deck), eclipseGrid, false); if (Section::hasEDIT(deck)) - scanSection(EDITSection(deck), eclipseGrid); + scanSection(EDITSection(deck), eclipseGrid, true); if (Section::hasPROPS(deck)) - scanSection(PROPSSection(deck), eclipseGrid); + scanSection(PROPSSection(deck), eclipseGrid, false); if (Section::hasSOLUTION(deck)) - scanSection(SOLUTIONSection(deck), eclipseGrid); + scanSection(SOLUTIONSection(deck), eclipseGrid, false); } void Eclipse3DProperties::scanSection(const Section& section, - const EclipseGrid& eclipseGrid) { + const EclipseGrid& eclipseGrid, + bool edit_section) { BoxManager boxManager(eclipseGrid); for( const auto& deckKeyword : section ) { if (supportsGridProperty(deckKeyword.name()) ) loadGridPropertyFromDeckKeyword( boxManager.getActiveBox(), - deckKeyword); + deckKeyword, + edit_section); else { if (deckKeyword.name() == "BOX") handleBOXKeyword(deckKeyword, boxManager); diff --git a/src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp b/src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp index 9a17a8e45..93c25fb17 100644 --- a/src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp +++ b/src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp @@ -244,21 +244,25 @@ namespace Opm { } template< typename T > - void GridProperty< T >::loadFromDeckKeyword( const DeckKeyword& deckKeyword ) { + void GridProperty< T >::loadFromDeckKeyword( const DeckKeyword& deckKeyword, bool multiply ) { const auto& deckItem = getDeckItem(deckKeyword); const auto size = deckItem.size(); for (size_t dataPointIdx = 0; dataPointIdx < size; ++dataPointIdx) { - if (!deckItem.defaultApplied(dataPointIdx)) - setDataPoint(dataPointIdx, dataPointIdx, deckItem); + if (!deckItem.defaultApplied(dataPointIdx)) { + if (multiply) + mulDataPoint(dataPointIdx, dataPointIdx, deckItem); + else + setDataPoint(dataPointIdx, dataPointIdx, deckItem); + } } this->assigned = true; } template< typename T > - void GridProperty< T >::loadFromDeckKeyword( const Box& inputBox, const DeckKeyword& deckKeyword) { + void GridProperty< T >::loadFromDeckKeyword( const Box& inputBox, const DeckKeyword& deckKeyword, bool multiply) { if (inputBox.isGlobal()) - loadFromDeckKeyword( deckKeyword ); + loadFromDeckKeyword( deckKeyword, multiply ); else { const auto& deckItem = getDeckItem(deckKeyword); const std::vector& indexList = inputBox.getIndexList(); @@ -268,7 +272,10 @@ namespace Opm { if (sourceIdx < deckItem.size() && !deckItem.defaultApplied(sourceIdx)) { - setDataPoint(sourceIdx, targetIdx, deckItem); + if (multiply) + mulDataPoint(sourceIdx, targetIdx, deckItem); + else + setDataPoint(sourceIdx, targetIdx, deckItem); } } } else { @@ -408,11 +415,21 @@ void GridProperty::setDataPoint(size_t sourceIdx, size_t targetIdx, cons this->setElement(targetIdx, deckItem.getSIDouble(sourceIdx)); } - template - void GridProperty::setElement(const typename std::vector::size_type i, const T value, const bool defaulted) { - this->m_data[i] = value; - this->m_defaulted[i] = defaulted; - } +template +void GridProperty::setElement(const typename std::vector::size_type i, const T value, const bool defaulted) { + this->m_data[i] = value; + this->m_defaulted[i] = defaulted; +} + +template<> +void GridProperty::mulDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) { + this->m_data[targetIdx] *= deckItem.getSIDouble(sourceIdx); +} + +template<> +void GridProperty::mulDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) { + this->m_data[targetIdx] *= deckItem.get(sourceIdx); +} template<> diff --git a/tests/parser/GridPropertyTests.cpp b/tests/parser/GridPropertyTests.cpp index dfdd08fe9..7ac7cae94 100644 --- a/tests/parser/GridPropertyTests.cpp +++ b/tests/parser/GridPropertyTests.cpp @@ -120,7 +120,7 @@ BOOST_AUTO_TEST_CASE(SetFromDeckKeyword_notData_Throws) { typedef Opm::GridProperty::SupportedKeywordInfo SupportedKeywordInfo; SupportedKeywordInfo keywordInfo("TABDIMS" , 100, "1"); Opm::GridProperty gridProperty( 6 ,1,1 , keywordInfo); - BOOST_CHECK_THROW( gridProperty.loadFromDeckKeyword( tabdimsKw ) , std::invalid_argument ); + BOOST_CHECK_THROW( gridProperty.loadFromDeckKeyword( tabdimsKw, false ) , std::invalid_argument ); } @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(SetFromDeckKeyword_wrong_size_throws) { typedef Opm::GridProperty::SupportedKeywordInfo SupportedKeywordInfo; SupportedKeywordInfo keywordInfo("SATNUM" , 66, "1"); Opm::GridProperty gridProperty( 15 ,1,1, keywordInfo); - BOOST_CHECK_THROW( gridProperty.loadFromDeckKeyword( satnumKw ) , std::invalid_argument ); + BOOST_CHECK_THROW( gridProperty.loadFromDeckKeyword( satnumKw, false ) , std::invalid_argument ); } @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(SetFromDeckKeyword) { typedef Opm::GridProperty::SupportedKeywordInfo SupportedKeywordInfo; SupportedKeywordInfo keywordInfo("SATNUM" , 99, "1"); Opm::GridProperty gridProperty( 4 , 4 , 2 , keywordInfo); - gridProperty.loadFromDeckKeyword( satnumKw ); + gridProperty.loadFromDeckKeyword( satnumKw, false ); const std::vector& data = gridProperty.getData(); for (size_t k=0; k < 2; k++) { for (size_t j=0; j < 4; j++) { diff --git a/tests/parser/TransMultTests.cpp b/tests/parser/TransMultTests.cpp index e0322c919..44f5900d9 100644 --- a/tests/parser/TransMultTests.cpp +++ b/tests/parser/TransMultTests.cpp @@ -25,6 +25,9 @@ #include #include +#include +#include +#include #include #include #include @@ -44,3 +47,31 @@ BOOST_AUTO_TEST_CASE(Empty) { BOOST_CHECK_EQUAL( transMult.getMultiplier(9,9,9, Opm::FaceDir::YMinus) , 1.0 ); BOOST_CHECK_EQUAL( transMult.getMultiplier(100 , Opm::FaceDir::ZMinus) , 1.0 ); } + + +BOOST_AUTO_TEST_CASE(GridAndEdit) { + const std::string deck_string = R"( +RUNSPEC +GRIDOPTS + 'YES' 2 / + +DIMENS + 5 5 5 / +GRID +MULTZ + 125*2 / +EDIT +MULTZ + 125*2 / +)"; + + Opm::Parser parser; + Opm::Deck deck = parser.parseString(deck_string); + Opm::TableManager tables(deck); + Opm::EclipseGrid grid(5,5,5); + Opm::Eclipse3DProperties props(deck, tables, grid); + Opm::TransMult transMult(grid, deck, props); + + transMult.applyMULT(props.getDoubleGridProperty("MULTZ"), Opm::FaceDir::ZPlus); + BOOST_CHECK_EQUAL( transMult.getMultiplier(0,0,0 , Opm::FaceDir::ZPlus) , 4.0 ); +}