diff --git a/opm/parser/eclipse/EclipseState/EclipseState.cpp b/opm/parser/eclipse/EclipseState/EclipseState.cpp index 9d9064630..ee116d0a4 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->size() > 0 && !I1Item->defaultApplied(0)) + if (!I1Item->defaultApplied(0)) setCount++; - if (I2Item->size() > 0 && !I2Item->defaultApplied(0)) + if (!I2Item->defaultApplied(0)) setCount++; - if (J1Item->size() > 0 && !J1Item->defaultApplied(0)) + if (!J1Item->defaultApplied(0)) setCount++; - if (J2Item->size() > 0 && !J2Item->defaultApplied(0)) + if (!J2Item->defaultApplied(0)) setCount++; - if (K1Item->size() > 0 && !K1Item->defaultApplied(0)) + if (!K1Item->defaultApplied(0)) setCount++; - if (K2Item->size() > 0 && !K2Item->defaultApplied(0)) + if (!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 10fd5c4ed..08249155c 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Completion.cpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Completion.cpp @@ -71,14 +71,11 @@ namespace Opm { DeckItemConstPtr diameterItem = compdatRecord->getItem("DIAMETER"); DeckItemConstPtr skinFactorItem = compdatRecord->getItem("SKIN"); - if (connectionTransmissibilityFactorItem->size() > 0 && !connectionTransmissibilityFactorItem->defaultApplied(0)) - connectionTransmissibilityFactor.setValue( connectionTransmissibilityFactorItem->getSIDouble(0)); - - if (diameterItem->size() > 0 && !diameterItem->defaultApplied(0)) - diameter.setValue( diameterItem->getSIDouble(0)); + if (!connectionTransmissibilityFactorItem->defaultApplied(0)) + connectionTransmissibilityFactor.setValue(connectionTransmissibilityFactorItem->getSIDouble(0)); - if (skinFactorItem->size() > 0 && !skinFactorItem->defaultApplied(0)) - skinFactor.setValue( skinFactorItem->getRawDouble(0)); + diameter.setValue( diameterItem->getSIDouble(0)); + skinFactor.setValue( skinFactorItem->getRawDouble(0)); } const CompletionDirection::DirectionEnum& direction = CompletionDirection::DirectionEnumFromString(compdatRecord->getItem("DIR")->getTrimmedString(0)); diff --git a/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp b/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp index ab225c7fb..f057b372f 100644 --- a/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp +++ b/opm/parser/eclipse/IntegrationTests/IntegrationTests.cpp @@ -235,14 +235,16 @@ 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::out_of_range); + BOOST_CHECK_NO_THROW(radfin4_2_nodata->getRecord(0)->getItem(0)->getString(0)); + BOOST_CHECK( radfin4_2_nodata->getRecord(0)->getItem(0)->defaultApplied(0)); // 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::out_of_range); + BOOST_CHECK_NO_THROW( radfin4_2_nodata->getRecord(0)->getItem(1)->getInt(0)); + BOOST_CHECK( radfin4_2_nodata->getRecord(0)->getItem(1)->defaultApplied(0)); ParserKeywordConstPtr parserKeyword = parser->getParserKeywordFromDeckName("RADFIN4"); diff --git a/opm/parser/eclipse/IntegrationTests/ParsePVTO.cpp b/opm/parser/eclipse/IntegrationTests/ParsePVTO.cpp index a86a9ecb5..2c977e849 100644 --- a/opm/parser/eclipse/IntegrationTests/ParsePVTO.cpp +++ b/opm/parser/eclipse/IntegrationTests/ParsePVTO.cpp @@ -86,6 +86,7 @@ static void check_parser(ParserPtr parser) { DeckItemConstPtr item2_0 = record2->getItem("RS"); DeckItemConstPtr item2_1 = record2->getItem("DATA"); + BOOST_CHECK(item2_0->defaultApplied(0)); BOOST_CHECK_EQUAL(0U , item2_1->size()); BOOST_CHECK_EQUAL(2U , record2->size()); diff --git a/opm/parser/eclipse/Parser/ParserDoubleItem.cpp b/opm/parser/eclipse/Parser/ParserDoubleItem.cpp index c4774389c..2719b4f2d 100644 --- a/opm/parser/eclipse/Parser/ParserDoubleItem.cpp +++ b/opm/parser/eclipse/Parser/ParserDoubleItem.cpp @@ -34,10 +34,14 @@ namespace Opm ParserItemSizeEnum sizeType_) : ParserItem(itemName, sizeType_) { + // use NaN as 'default default'. (Keep in mind that in the deck it can be queried + // using deckItem->defaultApplied(idx) if an item was defaulted or not... + m_default = std::numeric_limits::quiet_NaN(); } ParserDoubleItem::ParserDoubleItem(const std::string& itemName) : ParserItem(itemName) { + m_default = std::numeric_limits::quiet_NaN(); } @@ -54,10 +58,7 @@ namespace Opm double ParserDoubleItem::getDefault() const { - if (m_defaultSet) - return m_default; - else - throw std::invalid_argument("Tried get default from parser item " + name() + " No default has been configured"); + return m_default; } @@ -71,6 +72,7 @@ namespace Opm ParserDoubleItem::ParserDoubleItem(const Json::JsonObject& jsonConfig) : ParserItem(jsonConfig) { + m_default = std::numeric_limits::quiet_NaN(); if (jsonConfig.has_item("default")) setDefault( jsonConfig.get_double("default") ); } diff --git a/opm/parser/eclipse/Parser/ParserFloatItem.cpp b/opm/parser/eclipse/Parser/ParserFloatItem.cpp index 5ae8b1db2..b03d34585 100644 --- a/opm/parser/eclipse/Parser/ParserFloatItem.cpp +++ b/opm/parser/eclipse/Parser/ParserFloatItem.cpp @@ -34,10 +34,14 @@ namespace Opm ParserItemSizeEnum sizeType_) : ParserItem(itemName, sizeType_) { + // use NaN as 'default default'. (Keep in mind that in the deck it can be queried + // using deckItem->defaultApplied(idx) if an item was defaulted or not... + m_default = std::numeric_limits::quiet_NaN(); } ParserFloatItem::ParserFloatItem(const std::string& itemName) : ParserItem(itemName) { + m_default = std::numeric_limits::quiet_NaN(); } @@ -54,10 +58,7 @@ namespace Opm float ParserFloatItem::getDefault() const { - if (m_defaultSet) - return m_default; - else - throw std::invalid_argument("Tried get default from parser item " + name() + " No default has been configured"); + return m_default; } @@ -73,6 +74,7 @@ namespace Opm ParserFloatItem::ParserFloatItem(const Json::JsonObject& jsonConfig) : ParserItem(jsonConfig) { + m_default = std::numeric_limits::quiet_NaN(); if (jsonConfig.has_item("default")) setDefault( jsonConfig.get_double("default")); } diff --git a/opm/parser/eclipse/Parser/ParserIntItem.cpp b/opm/parser/eclipse/Parser/ParserIntItem.cpp index 7ff300214..dfebf1347 100644 --- a/opm/parser/eclipse/Parser/ParserIntItem.cpp +++ b/opm/parser/eclipse/Parser/ParserIntItem.cpp @@ -30,10 +30,15 @@ namespace Opm { ParserIntItem::ParserIntItem(const std::string& itemName) : ParserItem(itemName) { + // integers do not have a representation for NaN. Let's use a negative value as + // this is usually meaningless. (Keep in mind that in the deck it can be queried + // using deckItem->defaultApplied(idx) if an item was defaulted or not... + m_default = -1; } ParserIntItem::ParserIntItem(const std::string& itemName, ParserItemSizeEnum sizeType_) : ParserItem(itemName, sizeType_) { + m_default = -1; } ParserIntItem::ParserIntItem(const std::string& itemName, int defaultValue) : ParserItem(itemName) @@ -49,6 +54,7 @@ namespace Opm { ParserIntItem::ParserIntItem(const Json::JsonObject& jsonConfig) : ParserItem(jsonConfig) { + m_default = -1; if (jsonConfig.has_item("default")) setDefault( jsonConfig.get_int("default") ); } @@ -62,10 +68,7 @@ namespace Opm { } int ParserIntItem::getDefault() const { - if (m_defaultSet) - return m_default; - else - throw std::invalid_argument("Tried get default from parser item " + name() + " No default has been configured"); + return m_default; } DeckItemPtr ParserIntItem::scan(RawRecordPtr rawRecord) const { diff --git a/opm/parser/eclipse/Parser/ParserItem.hpp b/opm/parser/eclipse/Parser/ParserItem.hpp index 7d48c077d..e1f9358af 100644 --- a/opm/parser/eclipse/Parser/ParserItem.hpp +++ b/opm/parser/eclipse/Parser/ParserItem.hpp @@ -104,13 +104,9 @@ namespace Opm { value = st.value(); deckItem->push_backMultiple( value , st.multiplier()); } else { - 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"); + value = self->getDefault(); + for (size_t i=0; i < st.multiplier(); i++) + deckItem->push_backDefault( value ); } } else { ValueType value = readValueToken(token); @@ -118,22 +114,19 @@ namespace Opm { } } } else { - if (rawRecord->size() == 0) { + 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 { + 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() ); - } + if (!st.hasValue()) + deckItem->push_backDefault( self->getDefault() ); else deckItem->push_back(st.value()); diff --git a/opm/parser/eclipse/Parser/ParserStringItem.cpp b/opm/parser/eclipse/Parser/ParserStringItem.cpp index e99831e8d..ac278965d 100644 --- a/opm/parser/eclipse/Parser/ParserStringItem.cpp +++ b/opm/parser/eclipse/Parser/ParserStringItem.cpp @@ -26,11 +26,13 @@ namespace Opm { ParserStringItem::ParserStringItem(const std::string& itemName) : ParserItem(itemName) { + m_default = ""; } ParserStringItem::ParserStringItem(const std::string& itemName, ParserItemSizeEnum sizeType_) : ParserItem(itemName, sizeType_) { + m_default = ""; } ParserStringItem::ParserStringItem(const std::string& itemName, ParserItemSizeEnum sizeType_, const std::string& defaultValue) : ParserItem(itemName, sizeType_) { @@ -44,6 +46,7 @@ namespace Opm { ParserStringItem::ParserStringItem(const Json::JsonObject& jsonConfig) : ParserItem(jsonConfig) { + m_default = ""; if (jsonConfig.has_item("default")) setDefault( jsonConfig.get_string("default") ); } @@ -59,10 +62,7 @@ namespace Opm { } std::string ParserStringItem::getDefault() const { - if (m_defaultSet) - return m_default; - else - throw std::invalid_argument("Tried get default from parser item " + name() + " No default has been configured"); + return m_default; } diff --git a/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp b/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp index 3cb35ae90..af1be54ba 100644 --- a/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp +++ b/opm/parser/eclipse/Parser/tests/ParserItemTests.cpp @@ -34,6 +34,8 @@ #include +#include + using namespace Opm; BOOST_AUTO_TEST_CASE(Initialize) { @@ -69,7 +71,7 @@ BOOST_AUTO_TEST_CASE(Initialize_DefaultSizeType) { BOOST_AUTO_TEST_CASE(Initialize_Default) { ParserIntItem item1(std::string("ITEM1")); ParserIntItem item2(std::string("ITEM1"), 88); - BOOST_CHECK_THROW(item1.getDefault(), std::invalid_argument); + BOOST_CHECK(item1.getDefault() < 0); BOOST_CHECK_EQUAL(item2.getDefault(), 88); } @@ -77,21 +79,21 @@ BOOST_AUTO_TEST_CASE(Initialize_Default) { BOOST_AUTO_TEST_CASE(Initialize_Default_Double) { ParserDoubleItem item1(std::string("ITEM1")); ParserDoubleItem item2("ITEM1", 88.91); - BOOST_CHECK_THROW(item1.getDefault(), std::invalid_argument); + BOOST_CHECK(!std::isfinite(item1.getDefault())); BOOST_CHECK_EQUAL( 88.91 , item2.getDefault()); } BOOST_AUTO_TEST_CASE(Initialize_Default_Float) { ParserFloatItem item1(std::string("ITEM1")); ParserFloatItem item2("ITEM1", 88.91F); - BOOST_CHECK_THROW(item1.getDefault(), std::invalid_argument); + BOOST_CHECK(!std::isfinite(item1.getDefault())); BOOST_CHECK_EQUAL( 88.91F , item2.getDefault()); } BOOST_AUTO_TEST_CASE(Initialize_Default_String) { ParserStringItem item1(std::string("ITEM1")); - BOOST_CHECK_THROW( item1.getDefault(), std::invalid_argument); + BOOST_CHECK(item1.getDefault() == ""); ParserStringItem item2("ITEM1", "String"); BOOST_CHECK_EQUAL( "String" , item2.getDefault()); @@ -102,8 +104,12 @@ BOOST_AUTO_TEST_CASE(scan_PreMatureTerminator_defaultUsed) { RawRecordPtr rawRecord1(new RawRecord("/")); DeckItemConstPtr defaulted = itemInt.scan(rawRecord1); - BOOST_CHECK_THROW(defaulted->defaultApplied(0), std::out_of_range); - BOOST_CHECK_THROW(defaulted->getInt(0) , std::out_of_range); + // an item is always present even if the record was ended. If the deck specified no + // data and the item does not have a meaningful default, the item gets assigned a NaN + // (for float and double items), -1 (for integer items) and "" (for string items) + // whit the defaultApplied(0) method returning true... + BOOST_CHECK(defaulted->defaultApplied(0)); + BOOST_CHECK(defaulted->getInt(0) < 0); } BOOST_AUTO_TEST_CASE(InitializeIntItem_setDescription_canReadBack) { @@ -136,7 +142,7 @@ BOOST_AUTO_TEST_CASE(InitializeIntItem_FromJsonObject) { ParserIntItem item1( jsonConfig ); BOOST_CHECK_EQUAL( "ITEM1" , item1.name() ); BOOST_CHECK_EQUAL( ALL , item1.sizeType() ); - BOOST_CHECK_THROW( item1.getDefault(), std::invalid_argument); + BOOST_CHECK(item1.getDefault() < 0); } @@ -395,7 +401,14 @@ BOOST_AUTO_TEST_CASE(Scan_All_WithDefaults) { ParserIntItem itemInt("ITEM", sizeType); RawRecordPtr rawRecord(new RawRecord("100 10* 10*1 25/")); - BOOST_CHECK_THROW(itemInt.scan(rawRecord), std::invalid_argument); + DeckItemConstPtr deckIntItem = itemInt.scan(rawRecord); + BOOST_CHECK_EQUAL(22U, deckIntItem->size()); + BOOST_CHECK(!deckIntItem->defaultApplied(0)); + BOOST_CHECK(deckIntItem->defaultApplied(1)); + BOOST_CHECK(!deckIntItem->defaultApplied(11)); + BOOST_CHECK(!deckIntItem->defaultApplied(21)); + BOOST_CHECK_EQUAL(1, deckIntItem->getInt(20)); + BOOST_CHECK_EQUAL(25, deckIntItem->getInt(21)); } BOOST_AUTO_TEST_CASE(Scan_SINGLE_CorrectIntSetInDeckItem) { @@ -540,7 +553,7 @@ BOOST_AUTO_TEST_CASE(InitializeStringItem_FromJsonObject) { ParserStringItem item1( jsonConfig ); BOOST_CHECK_EQUAL( "ITEM1" , item1.name() ); BOOST_CHECK_EQUAL( ALL , item1.sizeType() ); - BOOST_CHECK_THROW( item1.getDefault() , std::invalid_argument ); + BOOST_CHECK(item1.getDefault() == ""); } diff --git a/opm/parser/eclipse/Utility/MultiRecordTable.cpp b/opm/parser/eclipse/Utility/MultiRecordTable.cpp index 9e0a0d9e2..18c0e2ad3 100644 --- a/opm/parser/eclipse/Utility/MultiRecordTable.cpp +++ b/opm/parser/eclipse/Utility/MultiRecordTable.cpp @@ -99,7 +99,7 @@ size_t MultiRecordTable::getNumFlatItems_(Opm::DeckRecordConstPtr deckRecord) int result = 0; for (unsigned i = 0; i < deckRecord->size(); ++ i) { Opm::DeckItemConstPtr item(deckRecord->getItem(i)); - if (i == 0 && !item->wasSetInDeck(0)) + if (item->size() == 0 || item->defaultApplied(0)) return result; result += item->size(); }