diff --git a/opm/parser/eclipse/Deck/DeckDoubleItem.cpp b/opm/parser/eclipse/Deck/DeckDoubleItem.cpp index 2e5578130..5769cbd87 100644 --- a/opm/parser/eclipse/Deck/DeckDoubleItem.cpp +++ b/opm/parser/eclipse/Deck/DeckDoubleItem.cpp @@ -28,17 +28,13 @@ namespace Opm { double DeckDoubleItem::getRawDouble(size_t index) const { - assertValueSet(); + assertSize(index); - if (index < m_data.size()) { - return m_data[index]; - } else - throw std::out_of_range("Out of range, index must be lower than " + boost::lexical_cast(m_data.size())); + return m_data[index]; } const std::vector& DeckDoubleItem::getRawDoubleData() const { - assertValueSet(); return m_data; } @@ -67,18 +63,15 @@ namespace Opm { double DeckDoubleItem::getSIDouble(size_t index) const { + assertSize(index); assertSIData(); - assertValueSet(); - if (index < m_data.size()) { - return m_SIdata[index]; - } else - throw std::out_of_range("Out of range, index must be lower than " + boost::lexical_cast(m_data.size())); + return m_SIdata[index]; } const std::vector& DeckDoubleItem::getSIDoubleData() const { assertSIData(); - assertValueSet(); + return m_SIdata; } @@ -86,6 +79,7 @@ namespace Opm { void DeckDoubleItem::push_back(std::deque data , size_t items) { for (size_t i=0; i data) { push_back( data , data.size() ); m_valueStatus |= DeckValue::SET_IN_DECK; + m_dataPointDefaulted.push_back(false); } void DeckDoubleItem::push_back(double data) { m_data.push_back( data ); m_valueStatus |= DeckValue::SET_IN_DECK; + m_dataPointDefaulted.push_back(false); } void DeckDoubleItem::push_backMultiple(double value, size_t numValues) { - for (size_t i = 0; i < numValues; i++) + for (size_t i = 0; i < numValues; i++) { m_data.push_back( value ); + m_dataPointDefaulted.push_back(false); + } m_valueStatus |= DeckValue::SET_IN_DECK; } void DeckDoubleItem::push_backDefault(double data) { m_data.push_back( data ); - m_valueStatus |= DeckValue::DEFAULT; + m_dataPointDefaulted.push_back(true); } @@ -119,7 +117,7 @@ namespace Opm { } void DeckDoubleItem::push_backDimension(std::shared_ptr activeDimension , std::shared_ptr defaultDimension) { - if (m_valueStatus == DeckValue::DEFAULT) + if (m_dataPointDefaulted.empty() || m_dataPointDefaulted.back()) m_dimensions.push_back( defaultDimension ); else m_dimensions.push_back( activeDimension ); diff --git a/opm/parser/eclipse/Deck/DeckFloatItem.cpp b/opm/parser/eclipse/Deck/DeckFloatItem.cpp index 6fcd49fcd..b4ca5a174 100644 --- a/opm/parser/eclipse/Deck/DeckFloatItem.cpp +++ b/opm/parser/eclipse/Deck/DeckFloatItem.cpp @@ -28,12 +28,9 @@ namespace Opm { float DeckFloatItem::getRawFloat(size_t index) const { - assertValueSet(); + assertSize(index); - if (index < m_data.size()) { - return m_data[index]; - } else - throw std::out_of_range("Out of range, index must be lower than " + boost::lexical_cast(m_data.size())); + return m_data[index]; } size_t DeckFloatItem::size() const { @@ -41,18 +38,15 @@ namespace Opm { } float DeckFloatItem::getSIFloat(size_t index) const { + assertSize(index); assertSIData(); - assertValueSet(); - if (index < m_data.size()) { - return m_SIdata[index]; - } else - throw std::out_of_range("Out of range, index must be lower than " + boost::lexical_cast(m_data.size())); + return m_SIdata[index]; } const std::vector& DeckFloatItem::getSIFloatData() const { assertSIData(); - assertValueSet(); + return m_SIdata; } @@ -82,6 +76,7 @@ namespace Opm { void DeckFloatItem::push_back(std::deque data , size_t items) { for (size_t i=0; i data) { push_back( data , data.size() ); m_valueStatus |= DeckValue::SET_IN_DECK; + m_dataPointDefaulted.push_back(false); } void DeckFloatItem::push_back(float data) { m_data.push_back( data ); m_valueStatus |= DeckValue::SET_IN_DECK; + m_dataPointDefaulted.push_back(false); } void DeckFloatItem::push_backMultiple(float value, size_t numValues) { - for (size_t i = 0; i < numValues; i++) + for (size_t i = 0; i < numValues; i++) { m_data.push_back( value ); + m_dataPointDefaulted.push_back(false); + } m_valueStatus |= DeckValue::SET_IN_DECK; } void DeckFloatItem::push_backDefault(float data) { m_data.push_back( data ); - m_valueStatus |= DeckValue::DEFAULT; + m_dataPointDefaulted.push_back(true); } void DeckFloatItem::push_backDimension(std::shared_ptr activeDimension , std::shared_ptr defaultDimension) { - if (m_valueStatus == DeckValue::DEFAULT) + if (m_dataPointDefaulted.empty() || m_dataPointDefaulted.back()) m_dimensions.push_back( defaultDimension ); else m_dimensions.push_back( activeDimension ); diff --git a/opm/parser/eclipse/Deck/DeckIntItem.cpp b/opm/parser/eclipse/Deck/DeckIntItem.cpp index c1e67ed26..2c38b494d 100644 --- a/opm/parser/eclipse/Deck/DeckIntItem.cpp +++ b/opm/parser/eclipse/Deck/DeckIntItem.cpp @@ -24,23 +24,20 @@ namespace Opm { int DeckIntItem::getInt(size_t index) const { - assertValueSet(); + assertSize(index); - if (index < m_data.size()) { - return m_data[index]; - } else - throw std::out_of_range("Out of range, index must be lower than " + boost::lexical_cast(m_data.size())); + return m_data[index]; } const std::vector& DeckIntItem::getIntData() const { - assertValueSet(); return m_data; } void DeckIntItem::push_back(std::deque data, size_t items) { for (size_t i = 0; i < items; i++) { m_data.push_back(data[i]); + m_dataPointDefaulted.push_back(false); } m_valueStatus |= DeckValue::SET_IN_DECK; } @@ -48,23 +45,25 @@ namespace Opm { void DeckIntItem::push_back(std::deque data) { push_back(data, data.size()); m_valueStatus |= DeckValue::SET_IN_DECK; + m_dataPointDefaulted.push_back(false); } void DeckIntItem::push_back(int data) { m_data.push_back(data); m_valueStatus |= DeckValue::SET_IN_DECK; + m_dataPointDefaulted.push_back(false); } void DeckIntItem::push_backDefault(int data) { m_data.push_back( data ); - m_valueStatus |= DeckValue::DEFAULT; + m_dataPointDefaulted.push_back(true); } - - void DeckIntItem::push_backMultiple(int value, size_t numValues) { - for (size_t i = 0; i < numValues; i++) + for (size_t i = 0; i < numValues; i++) { m_data.push_back( value ); + m_dataPointDefaulted.push_back(false); + } m_valueStatus = DeckValue::SET_IN_DECK; } diff --git a/opm/parser/eclipse/Deck/DeckItem.cpp b/opm/parser/eclipse/Deck/DeckItem.cpp index 033204f2e..4e775cc34 100644 --- a/opm/parser/eclipse/Deck/DeckItem.cpp +++ b/opm/parser/eclipse/Deck/DeckItem.cpp @@ -19,7 +19,10 @@ #include +#include + #include +#include namespace Opm { @@ -41,19 +44,19 @@ namespace Opm { return (m_valueStatus & DeckValue::SET_IN_DECK) == DeckValue::SET_IN_DECK; } + bool DeckItem::defaultApplied(size_t index) const { + assert(m_dataPointDefaulted.size() == size()); + assertSize(index); - bool DeckItem::defaultApplied(size_t /*index*/) const { - return (m_valueStatus & DeckValue::DEFAULT) == DeckValue::DEFAULT; + return m_dataPointDefaulted[index]; } - bool DeckItem::hasData(size_t index) const { - return defaultApplied(index) || wasSetInDeck(index); - } - - - void DeckItem::assertValueSet() const { - if (m_valueStatus == DeckValue::NOT_SET) - throw std::invalid_argument("Trying to access property: " + name() + " which has not been properly set - either explicitly or with a default."); + void DeckItem::assertSize(size_t index) const { + if (index >= size()) + throw std::out_of_range("Index must be smaller than " + + boost::lexical_cast(size()) + + " but is " + + boost::lexical_cast(index)); } diff --git a/opm/parser/eclipse/Deck/DeckItem.hpp b/opm/parser/eclipse/Deck/DeckItem.hpp index a12556d34..b08ee4462 100644 --- a/opm/parser/eclipse/Deck/DeckItem.hpp +++ b/opm/parser/eclipse/Deck/DeckItem.hpp @@ -34,7 +34,6 @@ namespace Opm { // These values are used as a bitmask. NOT_SET = 0 , SET_IN_DECK = 1, - DEFAULT = 2 }; } @@ -43,11 +42,17 @@ namespace Opm { public: DeckItem(const std::string& name , bool m_scalar = true); const std::string& name() const; - - bool wasSetInDeck(size_t index) const; - bool defaultApplied(size_t index) const; - bool hasData(size_t index) const; + bool wasSetInDeck(size_t index) const; + + // return true if the default value was used for a given data point + bool defaultApplied(size_t index) const; + + // if the number returned by this method is less than what is semantically + // expected (e.g. size() is less than the number of cells in the grid for + // keywords like e.g. SGL), then the remaining values are defaulted. The deck + // creates the defaulted items if all their sizes are fully specified by the + // keyword, though... virtual size_t size() const = 0; virtual int getInt(size_t /* index */) const { @@ -116,8 +121,10 @@ namespace Opm { } protected: - void assertValueSet() const; + void assertSize(size_t index) const; + int m_valueStatus; + std::vector m_dataPointDefaulted; private: std::string m_name; diff --git a/opm/parser/eclipse/Deck/DeckStringItem.cpp b/opm/parser/eclipse/Deck/DeckStringItem.cpp index 05d7f8700..604c84e62 100644 --- a/opm/parser/eclipse/Deck/DeckStringItem.cpp +++ b/opm/parser/eclipse/Deck/DeckStringItem.cpp @@ -27,31 +27,27 @@ namespace Opm { std::string DeckStringItem::getString(size_t index) const { - assertValueSet(); + assertSize(index); - if (index < m_data.size()) { - return m_data[index]; - } else - throw std::out_of_range("Out of range, index must be lower than " + boost::lexical_cast(m_data.size())); + return m_data[index]; } std::string DeckStringItem::getTrimmedString(size_t index) const { - if (index < m_data.size()) { - return boost::algorithm::trim_copy(m_data[index]); - } else - throw std::out_of_range("Out of range, index must be lower than " + boost::lexical_cast(m_data.size())); + assertSize(index); + + return boost::algorithm::trim_copy(m_data[index]); } const std::vector& DeckStringItem::getStringData() const { - assertValueSet(); - return m_data; } + void DeckStringItem::push_back(std::deque data, size_t items) { - for (size_t i = 0; i < items; i++) { + for (size_t i=0; i data) { push_back(data, data.size()); m_valueStatus |= DeckValue::SET_IN_DECK; + m_dataPointDefaulted.push_back(false); } void DeckStringItem::push_back(const std::string& data ) { m_data.push_back( data ); m_valueStatus |= DeckValue::SET_IN_DECK; + m_dataPointDefaulted.push_back(false); } void DeckStringItem::push_backMultiple(std::string value, size_t numValues) { - for (size_t i = 0; i < numValues; i++) + for (size_t i = 0; i < numValues; i++) { m_data.push_back( value ); + m_dataPointDefaulted.push_back(false); + } m_valueStatus |= DeckValue::SET_IN_DECK; } void DeckStringItem::push_backDefault(std::string data) { m_data.push_back( data ); - m_valueStatus |= DeckValue::DEFAULT; + m_dataPointDefaulted.push_back(true); } diff --git a/opm/parser/eclipse/Deck/tests/DeckDoubleItemTests.cpp b/opm/parser/eclipse/Deck/tests/DeckDoubleItemTests.cpp index 4243507b7..e78aeb2c8 100644 --- a/opm/parser/eclipse/Deck/tests/DeckDoubleItemTests.cpp +++ b/opm/parser/eclipse/Deck/tests/DeckDoubleItemTests.cpp @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(InitializeDouble) { BOOST_AUTO_TEST_CASE(GetDoubleAtIndex_NoData_ExceptionThrown) { DeckDoubleItem deckDoubleItem("TEST"); - BOOST_CHECK_THROW(deckDoubleItem.getRawDouble(0), std::invalid_argument); + BOOST_CHECK_THROW(deckDoubleItem.getRawDouble(0), std::out_of_range); deckDoubleItem.push_back(1.89); BOOST_CHECK_THROW(deckDoubleItem.getRawDouble(1), std::out_of_range); } @@ -111,6 +111,10 @@ BOOST_AUTO_TEST_CASE(PushBackDimension) { std::shared_ptr activeDimension(new Dimension("Length" , 100)); std::shared_ptr defaultDimension(new Dimension("Length" , 10)); + item.push_back(1.234); + item.push_backDimension( activeDimension , defaultDimension); + + item.push_backDefault(5.678); item.push_backDimension( activeDimension , defaultDimension); } diff --git a/opm/parser/eclipse/Deck/tests/DeckFloatItemTests.cpp b/opm/parser/eclipse/Deck/tests/DeckFloatItemTests.cpp index 98f39b40e..59d8e970a 100644 --- a/opm/parser/eclipse/Deck/tests/DeckFloatItemTests.cpp +++ b/opm/parser/eclipse/Deck/tests/DeckFloatItemTests.cpp @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(InitializeFloat) { BOOST_AUTO_TEST_CASE(GetFloatAtIndex_NoData_ExceptionThrown) { DeckFloatItem deckFloatItem("TEST"); - BOOST_CHECK_THROW(deckFloatItem.getRawFloat(0), std::invalid_argument); + BOOST_CHECK_THROW(deckFloatItem.getRawFloat(0), std::out_of_range); deckFloatItem.push_back(1.89); BOOST_CHECK_THROW(deckFloatItem.getRawFloat(1), std::out_of_range); } @@ -80,19 +80,25 @@ BOOST_AUTO_TEST_CASE(sizeFloat_correct) { BOOST_CHECK_EQUAL( 3U , deckFloatItem.size()); } - -BOOST_AUTO_TEST_CASE(SetInDeck) { +BOOST_AUTO_TEST_CASE(DefaultNotApplied) { DeckFloatItem deckFloatItem("TEST"); - BOOST_CHECK_EQUAL( false , deckFloatItem.wasSetInDeck(0) ); - deckFloatItem.push_backDefault( 1 ); - BOOST_CHECK_EQUAL( false , deckFloatItem.wasSetInDeck(0) ); - deckFloatItem.push_back( 10 ); - BOOST_CHECK_EQUAL( true , deckFloatItem.wasSetInDeck(0) ); - deckFloatItem.push_backDefault( 1 ); - BOOST_CHECK_EQUAL( true , deckFloatItem.wasSetInDeck(0) ); + BOOST_CHECK( deckFloatItem.size() == 0 ); + + deckFloatItem.push_back( 1.23 ); + BOOST_CHECK_EQUAL( deckFloatItem.size(), 1 ); + BOOST_CHECK_CLOSE( deckFloatItem.getRawFloat(0), 1.23, 1e-5 ); + BOOST_CHECK_EQUAL( deckFloatItem.defaultApplied(0), false ); } +BOOST_AUTO_TEST_CASE(DefaultApplied) { + DeckFloatItem deckFloatItem("TEST"); + BOOST_CHECK( deckFloatItem.size() == 0 ); + deckFloatItem.push_backDefault( 4.56 ); + BOOST_CHECK_EQUAL( deckFloatItem.size(), 1 ); + BOOST_CHECK_CLOSE( deckFloatItem.getRawFloat(0), 4.56, 1e-5 ); + BOOST_CHECK_EQUAL( deckFloatItem.defaultApplied(0), true ); +} BOOST_AUTO_TEST_CASE(PushBackMultiple) { DeckFloatItem item("HEI"); diff --git a/opm/parser/eclipse/Deck/tests/DeckIntItemTests.cpp b/opm/parser/eclipse/Deck/tests/DeckIntItemTests.cpp index fa0643e5b..597641c12 100644 --- a/opm/parser/eclipse/Deck/tests/DeckIntItemTests.cpp +++ b/opm/parser/eclipse/Deck/tests/DeckIntItemTests.cpp @@ -33,6 +33,7 @@ BOOST_AUTO_TEST_CASE(Initialize) { BOOST_AUTO_TEST_CASE(GetIntAtIndex_NoData_ExceptionThrown) { DeckIntItem deckIntItem("TEST"); deckIntItem.push_back(100); + BOOST_CHECK(deckIntItem.getInt(0) == 100); BOOST_CHECK_THROW(deckIntItem.getInt(1), std::out_of_range); } @@ -42,15 +43,7 @@ BOOST_AUTO_TEST_CASE(GetIntAtIndex_NoData_ExceptionThrown) { BOOST_AUTO_TEST_CASE(InitializeDefaultApplied) { DeckIntItem deckIntItem("TEST"); - BOOST_REQUIRE_NO_THROW( deckIntItem.wasSetInDeck(0) ); - BOOST_CHECK( !deckIntItem.wasSetInDeck(0)); -} - - -BOOST_AUTO_TEST_CASE(InitializeDefaultApplied_Throws_for_nonScalar) { - DeckIntItem deckIntItem("TEST" , false); - BOOST_REQUIRE_NO_THROW( deckIntItem.wasSetInDeck(0) ); - BOOST_CHECK( !deckIntItem.wasSetInDeck(0)); + BOOST_CHECK( deckIntItem.size() == 0 ); } @@ -90,31 +83,44 @@ BOOST_AUTO_TEST_CASE(size_correct) { BOOST_CHECK_EQUAL( 3U , deckIntItem.size()); } -BOOST_AUTO_TEST_CASE(SetInDeck) { +BOOST_AUTO_TEST_CASE(DefaultNotApplied) { DeckIntItem deckIntItem("TEST"); - BOOST_CHECK( !deckIntItem.wasSetInDeck(0) ); + BOOST_CHECK( deckIntItem.size() == 0 ); deckIntItem.push_back( 100 ); - BOOST_CHECK( deckIntItem.wasSetInDeck(0) ); + BOOST_CHECK( deckIntItem.size() == 1 ); + BOOST_CHECK( deckIntItem.getInt(0) == 100 ); + BOOST_CHECK( !deckIntItem.defaultApplied(0) ); + + BOOST_CHECK_THROW( deckIntItem.defaultApplied(1), std::out_of_range ); + BOOST_CHECK_THROW( deckIntItem.getInt(1), std::out_of_range ); } - -BOOST_AUTO_TEST_CASE(SetInDeckData) { +BOOST_AUTO_TEST_CASE(UseDefault) { DeckIntItem deckIntItem("TEST"); - BOOST_CHECK_EQUAL( false , deckIntItem.wasSetInDeck(0) ); - BOOST_CHECK_EQUAL( false , deckIntItem.defaultApplied(0)); - BOOST_CHECK_EQUAL( false , deckIntItem.hasData(0)); - deckIntItem.push_backDefault( 1 ); - BOOST_CHECK_EQUAL( false , deckIntItem.wasSetInDeck(0) ); - BOOST_CHECK_EQUAL( true , deckIntItem.defaultApplied(0)); - BOOST_CHECK_EQUAL( true , deckIntItem.hasData(0)); + + deckIntItem.push_backDefault( 100 ); + + BOOST_CHECK( deckIntItem.defaultApplied(0) ); + BOOST_CHECK( deckIntItem.getInt(0) == 100 ); + + BOOST_CHECK_THROW( deckIntItem.defaultApplied(1), std::out_of_range ); + BOOST_CHECK_THROW( deckIntItem.getInt(1), std::out_of_range ); +} + +BOOST_AUTO_TEST_CASE(DefaultApplied) { + DeckIntItem deckIntItem("TEST"); + BOOST_CHECK( deckIntItem.size() == 0 ); + + deckIntItem.push_backDefault( 100 ); + BOOST_CHECK( deckIntItem.size() == 1 ); + BOOST_CHECK( deckIntItem.getInt(0) == 100 ); + BOOST_CHECK( deckIntItem.defaultApplied(0) ); deckIntItem.push_back( 10 ); - BOOST_CHECK_EQUAL( true , deckIntItem.wasSetInDeck(0) ); - BOOST_CHECK_EQUAL( true , deckIntItem.defaultApplied(0)); - BOOST_CHECK_EQUAL( true , deckIntItem.hasData(0)); + BOOST_CHECK_EQUAL( false, deckIntItem.defaultApplied(1) ); deckIntItem.push_backDefault( 1 ); - BOOST_CHECK_EQUAL( true , deckIntItem.wasSetInDeck(0) ); - BOOST_CHECK_EQUAL( true , deckIntItem.hasData(0)); + BOOST_CHECK_EQUAL( true , deckIntItem.defaultApplied(2) ); + BOOST_CHECK_EQUAL( 3 , deckIntItem.size() ); } diff --git a/opm/parser/eclipse/Deck/tests/DeckStringItemTests.cpp b/opm/parser/eclipse/Deck/tests/DeckStringItemTests.cpp index ef1e8bd47..98be950aa 100644 --- a/opm/parser/eclipse/Deck/tests/DeckStringItemTests.cpp +++ b/opm/parser/eclipse/Deck/tests/DeckStringItemTests.cpp @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(InitializeString) { BOOST_AUTO_TEST_CASE(GetStringAtIndex_NoData_ExceptionThrown) { DeckStringItem deckStringItem("TEST"); - BOOST_CHECK_THROW(deckStringItem.getString(0), std::invalid_argument); + BOOST_CHECK_THROW(deckStringItem.getString(0), std::out_of_range); deckStringItem.push_back("SA"); BOOST_CHECK_THROW(deckStringItem.getString(1), std::out_of_range); } @@ -72,16 +72,24 @@ BOOST_AUTO_TEST_CASE(size_variouspushes_sizecorrect) { BOOST_CHECK_EQUAL(3U, deckStringItem.size()); } - -BOOST_AUTO_TEST_CASE(SetInDeckData) { +BOOST_AUTO_TEST_CASE(DefaultNotApplied) { DeckStringItem deckStringItem("TEST"); - BOOST_CHECK_EQUAL( false , deckStringItem.wasSetInDeck(0) ); - deckStringItem.push_backDefault( "Default" ); - BOOST_CHECK_EQUAL( false , deckStringItem.wasSetInDeck(0) ); - deckStringItem.push_back( "Value" ); - BOOST_CHECK_EQUAL( true , deckStringItem.wasSetInDeck(0) ); - deckStringItem.push_backDefault( "Deafult" ); - BOOST_CHECK_EQUAL( true , deckStringItem.wasSetInDeck(0) ); + BOOST_CHECK( deckStringItem.size() == 0 ); + + deckStringItem.push_back( "FOO" ); + BOOST_CHECK( deckStringItem.size() == 1 ); + BOOST_CHECK( deckStringItem.getString(0) == "FOO" ); + BOOST_CHECK( !deckStringItem.defaultApplied(0) ); +} + +BOOST_AUTO_TEST_CASE(DefaultApplied) { + DeckStringItem deckStringItem("TEST"); + BOOST_CHECK( deckStringItem.size() == 0 ); + + deckStringItem.push_backDefault( "FOO" ); + BOOST_CHECK( deckStringItem.size() == 1 ); + BOOST_CHECK( deckStringItem.getString(0) == "FOO" ); + BOOST_CHECK( deckStringItem.defaultApplied(0) ); } diff --git a/opm/parser/eclipse/EclipseState/EclipseState.cpp b/opm/parser/eclipse/EclipseState/EclipseState.cpp index 483812c3b..9d9064630 100644 --- a/opm/parser/eclipse/EclipseState/EclipseState.cpp +++ b/opm/parser/eclipse/EclipseState/EclipseState.cpp @@ -671,22 +671,22 @@ namespace Opm { size_t setCount = 0; - if (I1Item->wasSetInDeck(0)) + if (I1Item->size() > 0 && !I1Item->defaultApplied(0)) setCount++; - if (I2Item->wasSetInDeck(0)) + if (I2Item->size() > 0 && !I2Item->defaultApplied(0)) setCount++; - if (J1Item->wasSetInDeck(0)) + if (J1Item->size() > 0 && !J1Item->defaultApplied(0)) setCount++; - if (J2Item->wasSetInDeck(0)) + if (J2Item->size() > 0 && !J2Item->defaultApplied(0)) setCount++; - if (K1Item->wasSetInDeck(0)) + if (K1Item->size() > 0 && !K1Item->defaultApplied(0)) setCount++; - if (K2Item->wasSetInDeck(0)) + if (K2Item->size() > 0 && !K2Item->defaultApplied(0)) setCount++; if (setCount == 6) { diff --git a/opm/parser/eclipse/EclipseState/Schedule/Completion.cpp b/opm/parser/eclipse/EclipseState/Schedule/Completion.cpp index f56e9e9ad..10fd5c4ed 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Completion.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Completion.cpp @@ -71,13 +71,13 @@ namespace Opm { DeckItemConstPtr diameterItem = compdatRecord->getItem("DIAMETER"); DeckItemConstPtr skinFactorItem = compdatRecord->getItem("SKIN"); - if (connectionTransmissibilityFactorItem->hasData(0)) + if (connectionTransmissibilityFactorItem->size() > 0 && !connectionTransmissibilityFactorItem->defaultApplied(0)) connectionTransmissibilityFactor.setValue( connectionTransmissibilityFactorItem->getSIDouble(0)); - if (diameterItem->hasData(0)) + if (diameterItem->size() > 0 && !diameterItem->defaultApplied(0)) diameter.setValue( diameterItem->getSIDouble(0)); - if (skinFactorItem->hasData(0)) + if (skinFactorItem->size() > 0 && !skinFactorItem->defaultApplied(0)) skinFactor.setValue( skinFactorItem->getRawDouble(0)); } diff --git a/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp b/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp index 89a46363e..ab225c7fb 100644 --- a/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp +++ b/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp @@ -235,14 +235,14 @@ BOOST_AUTO_TEST_CASE(parse_truncatedrecords_deckFilledWithDefaults) { BOOST_CHECK_EQUAL("NAME", radfin4_1_partial->getRecord(0)->getItem(0)->getString(0)); // Default string - BOOST_CHECK_THROW( radfin4_2_nodata->getRecord(0)->getItem(0)->getString(0) , std::invalid_argument); + BOOST_CHECK_THROW(radfin4_2_nodata->getRecord(0)->getItem(0)->getString(0), std::out_of_range); // Specified in datafile BOOST_CHECK_EQUAL(213, radfin4_0_full->getRecord(0)->getItem(1)->getInt(0)); BOOST_CHECK_EQUAL(213, radfin4_1_partial->getRecord(0)->getItem(1)->getInt(0)); // Default int - BOOST_CHECK_THROW( radfin4_2_nodata->getRecord(0)->getItem(1)->getInt(0) , std::invalid_argument); + BOOST_CHECK_THROW( radfin4_2_nodata->getRecord(0)->getItem(1)->getInt(0), std::out_of_range); ParserKeywordConstPtr parserKeyword = parser->getParserKeywordFromDeckName("RADFIN4"); diff --git a/opm/parser/eclipse/IntegrationTests/ParsePVTG.cpp b/opm/parser/eclipse/IntegrationTests/ParsePVTG.cpp index 970db0460..b0d2a2c1d 100644 --- a/opm/parser/eclipse/IntegrationTests/ParsePVTG.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParsePVTG.cpp @@ -86,7 +86,6 @@ static void check_parser(ParserPtr parser) { DeckItemConstPtr item2_0 = record2->getItem("GAS_PRESSURE"); DeckItemConstPtr item2_1 = record2->getItem("DATA"); - BOOST_CHECK( !item2_0->wasSetInDeck(0)); BOOST_CHECK_EQUAL(0U , item2_1->size()); BOOST_CHECK_EQUAL(2U , record2->size()); diff --git a/opm/parser/eclipse/IntegrationTests/ParsePVTO.cpp b/opm/parser/eclipse/IntegrationTests/ParsePVTO.cpp index ccf3095ec..a86a9ecb5 100644 --- a/opm/parser/eclipse/IntegrationTests/ParsePVTO.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParsePVTO.cpp @@ -86,7 +86,6 @@ static void check_parser(ParserPtr parser) { DeckItemConstPtr item2_0 = record2->getItem("RS"); DeckItemConstPtr item2_1 = record2->getItem("DATA"); - BOOST_CHECK(!item2_0->wasSetInDeck(0)); BOOST_CHECK_EQUAL(0U , item2_1->size()); BOOST_CHECK_EQUAL(2U , record2->size()); diff --git a/opm/parser/eclipse/Parser/ParserItem.hpp b/opm/parser/eclipse/Parser/ParserItem.hpp index 3fbfce83c..7d48c077d 100644 --- a/opm/parser/eclipse/Parser/ParserItem.hpp +++ b/opm/parser/eclipse/Parser/ParserItem.hpp @@ -76,76 +76,82 @@ namespace Opm { template bool ParserItemEqual(const T * self , const ParserItem& other) { - const T * rhs = dynamic_cast(&other); - if (rhs && self->ParserItem::equal(other)) { - if (self->defaultSet()) { - if (self->getDefault() == rhs->getDefault()) - return true; - else - return false; - } else - return true; - } else - return false; + const T * rhs = dynamic_cast(&other); + if (rhs && self->ParserItem::equal(other)) { + if (self->defaultSet()) + return self->getDefault() == rhs->getDefault(); + return true; + } else + return false; } /// Scans the rawRecords data according to the ParserItems definition. /// returns a DeckItem object. /// NOTE: data are popped from the rawRecords deque! - template + template DeckItemPtr ParserItemScan(const ParserItemType * self , RawRecordPtr rawRecord) { std::shared_ptr deckItem = std::make_shared( self->name() , self->scalar() ); - if (self->sizeType() == ALL) { + if (self->sizeType() == ALL) { while (rawRecord->size() > 0) { std::string token = rawRecord->pop_front(); if (tokenContainsStar( token )) { - StarToken st(token); - valueType value; - + StarToken st(token); + ValueType value; + if (st.hasValue()) { - value = st.value(); - deckItem->push_backMultiple( value , st.multiplier() ); + value = st.value(); + deckItem->push_backMultiple( value , st.multiplier()); } else { - value = self->getDefault(); - for (size_t i=0; i < st.multiplier(); i++) - deckItem->push_backDefault( value ); + if (self->defaultSet()) { + value = self->getDefault(); + for (size_t i=0; i < st.multiplier(); i++) + deckItem->push_backDefault( value ); + } + else + throw std::invalid_argument("No default specified for item of DATA kind"); } - - } else { - valueType value = readValueToken(token); + ValueType value = readValueToken(token); deckItem->push_back(value); } } } else { - // The '*' should be interpreted as a default indicator - if (rawRecord->size() > 0) { - std::string token = rawRecord->pop_front(); - if (tokenContainsStar( token )) { - StarToken st(token); - - if (st.hasValue()) { // Probably never true - deckItem->push_back( st.value() ); - std::string stringValue = boost::lexical_cast(st.value()); - for (size_t i=1; i < st.multiplier(); i++) - rawRecord->push_front( stringValue ); - } else { - if (self->defaultSet()) - deckItem->push_backDefault( self->getDefault() ); - - for (size_t i=1; i < st.multiplier(); i++) - rawRecord->push_front( "*" ); - } - } else { - valueType value = readValueToken(token); - deckItem->push_back(value); - } - } else { + if (rawRecord->size() == 0) { + // if the record was ended prematurely, use the default value for the + // item... if (self->defaultSet()) deckItem->push_backDefault( self->getDefault() ); - + } else { + // The '*' should be interpreted as a repetition indicator, but it must + // be preceeded by an integer... + std::string token = rawRecord->pop_front(); + if (tokenContainsStar( token )) { + StarToken st(token); + + if (!st.hasValue()) { + if (self->defaultSet()) + deckItem->push_backDefault( self->getDefault() ); + } + else + deckItem->push_back(st.value()); + + // replace the first occurence of "N*FOO" by a sequence of N-1 times + // "1*FOO". this is slightly hacky, but it makes it work if the + // number of defaults pass item boundaries... + std::string singleRepetition; + if (st.hasValue()) + singleRepetition = boost::lexical_cast(st.value()); + else + singleRepetition = "1*"; + + for (size_t i=0; i < st.multiplier() - 1; i++) + rawRecord->push_front(singleRepetition); + } else { + ValueType value = readValueToken(token); + deckItem->push_back(value); + } } } return deckItem; diff --git a/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp b/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp index 0ce1cda75..3cb35ae90 100644 --- a/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp @@ -102,7 +102,8 @@ BOOST_AUTO_TEST_CASE(scan_PreMatureTerminator_defaultUsed) { RawRecordPtr rawRecord1(new RawRecord("/")); DeckItemConstPtr defaulted = itemInt.scan(rawRecord1); - BOOST_CHECK_THROW(defaulted->getInt(0) , std::invalid_argument); + BOOST_CHECK_THROW(defaulted->defaultApplied(0), std::out_of_range); + BOOST_CHECK_THROW(defaulted->getInt(0) , std::out_of_range); } BOOST_AUTO_TEST_CASE(InitializeIntItem_setDescription_canReadBack) { @@ -389,6 +390,14 @@ BOOST_AUTO_TEST_CASE(Scan_All_CorrectIntSetInDeckItem) { BOOST_CHECK_EQUAL(25, deckIntItem->getInt(22)); } +BOOST_AUTO_TEST_CASE(Scan_All_WithDefaults) { + ParserItemSizeEnum sizeType = ALL; + ParserIntItem itemInt("ITEM", sizeType); + + RawRecordPtr rawRecord(new RawRecord("100 10* 10*1 25/")); + BOOST_CHECK_THROW(itemInt.scan(rawRecord), std::invalid_argument); +} + BOOST_AUTO_TEST_CASE(Scan_SINGLE_CorrectIntSetInDeckItem) { ParserIntItem itemInt(std::string("ITEM2")); diff --git a/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp b/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp index 6721c40f9..41ffba867 100644 --- a/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParserRecordTests.cpp @@ -215,9 +215,13 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) { DeckItemConstPtr deckIntItem = itemInt->scan(rawRecord); DeckItemConstPtr deckDoubleItem = itemDouble->scan(rawRecord); - BOOST_CHECK(!deckStringItem->wasSetInDeck(0)); - BOOST_CHECK(!deckIntItem->wasSetInDeck(0)); - BOOST_CHECK(!deckDoubleItem->wasSetInDeck(0)); + BOOST_CHECK(deckStringItem->size() == 1); + BOOST_CHECK(deckIntItem->size() == 1); + BOOST_CHECK(deckDoubleItem->size() == 1); + + BOOST_CHECK(deckStringItem->defaultApplied(0)); + BOOST_CHECK(deckIntItem->defaultApplied(0)); + BOOST_CHECK(deckDoubleItem->defaultApplied(0)); } @@ -227,21 +231,32 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) { DeckItemConstPtr deckIntItem = itemInt->scan(rawRecord); DeckItemConstPtr deckDoubleItem = itemDouble->scan(rawRecord); - BOOST_CHECK(!deckStringItem->wasSetInDeck(0)); - BOOST_CHECK(!deckIntItem->wasSetInDeck(0)); - BOOST_CHECK(!deckDoubleItem->wasSetInDeck(0)); + BOOST_CHECK(deckStringItem->size() == 1); + BOOST_CHECK(deckIntItem->size() == 1); + BOOST_CHECK(deckDoubleItem->size() == 1); + + BOOST_CHECK(deckStringItem->defaultApplied(0)); + BOOST_CHECK(deckIntItem->defaultApplied(0)); + BOOST_CHECK(deckDoubleItem->defaultApplied(0)); } { RawRecordPtr rawRecord(new RawRecord("TRYGVE 10 2.9 /")); + + // let the raw record be "consumed" by the items. Note that the scan() method + // modifies the rawRecord object! DeckItemConstPtr deckStringItem = itemString->scan(rawRecord); DeckItemConstPtr deckIntItem = itemInt->scan(rawRecord); DeckItemConstPtr deckDoubleItem = itemDouble->scan(rawRecord); - BOOST_CHECK(deckStringItem->wasSetInDeck(0)); - BOOST_CHECK(deckIntItem->wasSetInDeck(0)); - BOOST_CHECK(deckDoubleItem->wasSetInDeck(0)); + BOOST_CHECK(deckStringItem->size() == 1); + BOOST_CHECK(deckIntItem->size() == 1); + BOOST_CHECK(deckDoubleItem->size() == 1); + + BOOST_CHECK(!deckStringItem->defaultApplied(0)); + BOOST_CHECK(!deckIntItem->defaultApplied(0)); + BOOST_CHECK(!deckDoubleItem->defaultApplied(0)); } @@ -251,9 +266,13 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) { DeckItemConstPtr deckIntItem = itemInt->scan(rawRecord); DeckItemConstPtr deckDoubleItem = itemDouble->scan(rawRecord); - BOOST_CHECK(!deckStringItem->wasSetInDeck(0)); - BOOST_CHECK(!deckIntItem->wasSetInDeck(0)); - BOOST_CHECK(!deckDoubleItem->wasSetInDeck(0)); + BOOST_CHECK(deckStringItem->size() == 1); + BOOST_CHECK(deckIntItem->size() == 1); + BOOST_CHECK(deckDoubleItem->size() == 1); + + BOOST_CHECK(deckStringItem->defaultApplied(0)); + BOOST_CHECK(deckIntItem->defaultApplied(0)); + BOOST_CHECK(deckDoubleItem->defaultApplied(0)); } { @@ -262,9 +281,13 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) { DeckItemConstPtr deckIntItem = itemInt->scan(rawRecord); DeckItemConstPtr deckDoubleItem = itemDouble->scan(rawRecord); - BOOST_CHECK(!deckStringItem->wasSetInDeck(0)); - BOOST_CHECK(!deckIntItem->wasSetInDeck(0)); - BOOST_CHECK(!deckDoubleItem->wasSetInDeck(0)); + BOOST_CHECK(deckStringItem->size() == 1); + BOOST_CHECK(deckIntItem->size() == 1); + BOOST_CHECK(deckDoubleItem->size() == 1); + + BOOST_CHECK(deckStringItem->defaultApplied(0)); + BOOST_CHECK(deckIntItem->defaultApplied(0)); + BOOST_CHECK(deckDoubleItem->defaultApplied(0)); } }