Use dimensions from ParserKeyword

This commit is contained in:
Joakim Hove 2019-09-16 08:12:13 +02:00
parent 233f55c4e2
commit 697545cf54
18 changed files with 342 additions and 253 deletions

View File

@ -154,10 +154,11 @@ namespace Opm {
std::vector< DeckKeyword > keywordList;
UnitSystem defaultUnits;
UnitSystem activeUnits;
std::unique_ptr<UnitSystem> activeUnits;
std::string m_dataFile;
std::string input_path;
mutable std::size_t unit_system_access_count = 0;
};
}
#endif /* DECK_HPP */

View File

@ -36,9 +36,11 @@ namespace Opm {
public:
DeckItem() = default;
DeckItem( const std::string&, int);
DeckItem( const std::string&, double);
DeckItem( const std::string&, std::string);
DeckItem( const std::string&, UDAValue);
DeckItem( const std::string&, double) = delete;
DeckItem( const std::string&, UDAValue) = delete;
DeckItem( const std::string&, UDAValue, const std::vector<Dimension>& active_dim, const std::vector<Dimension>& default_dim);
DeckItem( const std::string&, double, const std::vector<Dimension>& active_dim, const std::vector<Dimension>& default_dim);
const std::string& name() const;
@ -58,8 +60,10 @@ namespace Opm {
size_t size() const;
size_t out_size() const;
//template< typename T > T& get( size_t ) ;
template< typename T > T get( size_t ) const;
template<typename T>
T get( size_t index ) const;
double getSIDouble( size_t ) const;
std::string getTrimmedString( size_t ) const;
@ -81,9 +85,6 @@ namespace Opm {
// trying to access the data of a "dummy default item" will raise an exception
void push_backDummyDefault();
void push_backDimension( const Dimension& /* activeDimension */,
const Dimension& /* defaultDimension */);
type_tag getType() const;
void write(DeckOutput& writer) const;
@ -97,7 +98,6 @@ namespace Opm {
account, i.e. two items will compare differently if one is
defaulted and the other has the default value explicitly
set. The default behaviour is cmp_default == false -
i.e. only the actual values in the items will be compared,
itrespective of whether they have been set explicitly or
have been defaulted.
*/
@ -120,13 +120,15 @@ namespace Opm {
std::string item_name;
std::vector< bool > defaulted;
std::vector< Dimension > dimensions;
/*
To save space we mutate the dval object in place when asking for SI
data; the current state of of the dval member is tracked with the
raw_data bool member.
*/
mutable bool raw_data = true;
std::vector< Dimension > active_dimensions;
std::vector< Dimension > default_dimensions;
template< typename T > std::vector< T >& value_ref();
template< typename T > const std::vector< T >& value_ref() const;
template< typename T > void push( T );

View File

@ -34,6 +34,7 @@ public:
UDAValue();
explicit UDAValue(double);
explicit UDAValue(const std::string&);
UDAValue(const UDAValue& src, const Dimension& dim);
template<typename T>
T get() const;
@ -46,7 +47,6 @@ public:
void assert_numeric() const;
void assert_numeric(const std::string& error_msg) const;
void set_dim(const Dimension& dim) const;
const Dimension& get_dim() const;
bool operator==(const UDAValue& other) const;
@ -58,7 +58,7 @@ private:
/* This 'mutable' modifier is a hack to avoid tampering with the overall
const-ness of the data in a deck item. */
mutable Dimension dim;
Dimension dim;
};
std::ostream& operator<<( std::ostream& stream, const UDAValue& uda_value );

View File

@ -33,6 +33,7 @@ namespace Json {
namespace Opm {
class UnitSystem;
class RawRecord;
@ -92,7 +93,7 @@ namespace Opm {
bool operator==( const ParserItem& ) const;
bool operator!=( const ParserItem& ) const;
DeckItem scan( RawRecord& rawRecord ) const;
DeckItem scan( RawRecord& rawRecord, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem) const;
std::string size_literal() const;
const std::string className() const;

View File

@ -124,7 +124,7 @@ namespace Opm {
SectionNameSet::const_iterator validSectionNamesBegin() const;
SectionNameSet::const_iterator validSectionNamesEnd() const;
DeckKeyword parse(const ParseContext& parseContext, ErrorGuard& errors, RawKeyword& rawKeyword, const std::string& filename) const;
DeckKeyword parse(const ParseContext& parseContext, ErrorGuard& errors, RawKeyword& rawKeyword, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& filename) const;
enum ParserKeywordSizeEnum getSizeType() const;
const KeywordSize& getKeywordSize() const;
bool isDataKeyword() const;
@ -134,7 +134,6 @@ namespace Opm {
std::string createDeclaration(const std::string& indent) const;
std::string createDecl() const;
std::string createCode() const;
void applyUnitsToDeck( Deck& deck, DeckKeyword& deckKeyword) const;
bool operator==( const ParserKeyword& ) const;
bool operator!=( const ParserKeyword& ) const;

View File

@ -34,6 +34,7 @@ namespace Opm {
class ParserItem;
class RawRecord;
class ErrorGuard;
class UnitSystem;
class ParserRecord {
public:
@ -43,12 +44,11 @@ namespace Opm {
void addDataItem( ParserItem item );
const ParserItem& get(size_t index) const;
const ParserItem& get(const std::string& itemName) const;
DeckRecord parse( const ParseContext&, ErrorGuard&, RawRecord&, const std::string& keyword, const std::string& filename) const;
DeckRecord parse( const ParseContext&, ErrorGuard&, RawRecord&, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& keyword, const std::string& filename) const;
bool isDataRecord() const;
bool equal(const ParserRecord& other) const;
bool hasDimension() const;
bool hasItem(const std::string& itemName) const;
void applyUnitsToDeck( Deck& deck, DeckRecord& deckRecord) const;
std::vector< ParserItem >::const_iterator begin() const;
std::vector< ParserItem >::const_iterator end() const;

View File

@ -97,6 +97,7 @@ namespace Opm {
void to_si( measure, std::vector<double>& ) const;
const char* name( measure ) const;
std::string deck_name() const;
std::size_t use_count() const;
static bool valid_name(const std::string& deck_name);
static UnitSystem newMETRIC();
@ -119,6 +120,21 @@ namespace Opm {
const double* measure_table_from_si;
const double* measure_table_to_si;
const char* const* unit_name_table;
/*
The active unit system is determined runtime, to be certain that we do
not end up in a situation where we first use the default unit system,
and then subsequently change it.
The Deck::selectActiveUnitSystem() method has this code:
const auto& current = this->getActiveUnitSystem();
if (current.use_count() > 0)
throw std::logic_error("Sorry - can not change unit system halways");
*/
mutable std::size_t m_use_count = 0;
};
}

View File

@ -143,8 +143,7 @@ namespace Opm {
Deck::Deck( std::vector<DeckKeyword>&& x) :
DeckView(x.begin(), x.end()),
keywordList(std::move(x)),
defaultUnits( UnitSystem::newMETRIC() ),
activeUnits( UnitSystem::newMETRIC() )
defaultUnits( UnitSystem::newMETRIC() )
{
}
@ -152,19 +151,28 @@ namespace Opm {
DeckView(d.begin(), d.end()),
keywordList( d.keywordList ),
defaultUnits( d.defaultUnits ),
activeUnits( d.activeUnits ),
m_dataFile( d.m_dataFile ),
input_path( d.input_path )
{
this->init(this->keywordList.begin(), this->keywordList.end());
if (d.activeUnits)
this->activeUnits.reset( new UnitSystem(*d.activeUnits.get()));
}
void Deck::addKeyword( DeckKeyword&& keyword ) {
this->keywordList.push_back( std::move( keyword ) );
void Deck::addKeyword( DeckKeyword&& keyword ) {
if (keyword.name() == "FIELD")
this->selectActiveUnitSystem( UnitSystem::UnitType::UNIT_TYPE_FIELD );
else if (keyword.name() == "METRIC")
this->selectActiveUnitSystem( UnitSystem::UnitType::UNIT_TYPE_METRIC );
else if (keyword.name() == "LAB")
this->selectActiveUnitSystem( UnitSystem::UnitType::UNIT_TYPE_LAB );
else if (keyword.name() == "PVT-M")
this->selectActiveUnitSystem( UnitSystem::UnitType::UNIT_TYPE_PVT_M );
this->keywordList.push_back( std::move( keyword ) );
auto fst = this->keywordList.begin();
auto lst = this->keywordList.end();
this->add( &this->keywordList.back(), fst, lst );
}
@ -187,16 +195,29 @@ namespace Opm {
}
UnitSystem& Deck::getActiveUnitSystem() {
return this->activeUnits;
this->unit_system_access_count++;
if (this->activeUnits)
return *this->activeUnits;
else
return this->defaultUnits;
}
void Deck::selectActiveUnitSystem(UnitSystem::UnitType unit_type) {
this->activeUnits = UnitSystem(unit_type);
const auto& current = this->getActiveUnitSystem();
if (current.use_count() > 0 && (current.getType() != unit_type))
throw std::invalid_argument("Sorry - can not change unit system after dimensionfull features have been entered");
if (current.getType() != unit_type)
this->activeUnits.reset( new UnitSystem(unit_type) );
}
const UnitSystem& Deck::getActiveUnitSystem() const {
return this->activeUnits;
this->unit_system_access_count++;
if (this->activeUnits)
return *this->activeUnits;
else
return this->defaultUnits;
}
const std::string& Deck::getDataFile() const {

View File

@ -77,24 +77,29 @@ DeckItem::DeckItem( const std::string& nm, int) :
{
}
DeckItem::DeckItem( const std::string& nm, double) :
type( get_type< double >() ),
item_name( nm )
{
}
DeckItem::DeckItem( const std::string& nm, UDAValue) :
type( get_type< UDAValue >() ),
item_name( nm )
{
}
DeckItem::DeckItem( const std::string& nm, std::string) :
type( get_type< std::string >() ),
item_name( nm )
{
}
DeckItem::DeckItem( const std::string& nm, double, const std::vector<Dimension>& active_dim, const std::vector<Dimension>& default_dim) :
type( get_type< double >() ),
item_name( nm ),
active_dimensions(active_dim),
default_dimensions(default_dim)
{
}
DeckItem::DeckItem( const std::string& nm, UDAValue, const std::vector<Dimension>& active_dim, const std::vector<Dimension>& default_dim) :
type( get_type< UDAValue >() ),
item_name( nm ),
active_dimensions(active_dim),
default_dimensions(default_dim)
{
}
const std::string& DeckItem::name() const {
return this->item_name;
}
@ -128,26 +133,32 @@ size_t DeckItem::out_size() const {
return std::max( data_size , this->defaulted.size() );
}
/*
The non const overload is only used for the UDAValue type because we need to
mutate the UDAValue object and add dimension to it retroactively.
*/
/*template<>
UDAValue& DeckItem::get( size_t index ) {
return this->uval[index];
}
*/
template< typename T >
T DeckItem::get( size_t index ) const {
return this->value_ref< T >().at( index );
}
template<>
UDAValue DeckItem::get( size_t index ) const {
auto value = this->value_ref<UDAValue>().at(index);
if (this->active_dimensions.empty())
return value;
std::size_t dim_index = index % this->active_dimensions.size();
if (this->defaulted[index])
return UDAValue( value, this->default_dimensions[dim_index]);
else
return UDAValue( value, this->active_dimensions[dim_index]);
}
template< typename T >
const std::vector< T >& DeckItem::getData() const {
return this->value_ref< T >();
}
template< typename T >
void DeckItem::push( T x ) {
auto& val = this->value_ref< T >();
@ -169,7 +180,7 @@ void DeckItem::push_back( std::string x ) {
}
void DeckItem::push_back( UDAValue x ) {
this->push( std::move( x ) );
this->push( std::move( x ) );
}
template< typename T >
@ -193,7 +204,7 @@ void DeckItem::push_back( std::string x, size_t n ) {
}
void DeckItem::push_back( UDAValue x, size_t n ) {
this->push( std::move( x ), n );
this->push( std::move( x ), n );
}
template< typename T >
@ -220,7 +231,7 @@ void DeckItem::push_backDefault( std::string x ) {
}
void DeckItem::push_backDefault( UDAValue x ) {
this->push_default( std::move( x ) );
this->push_default( std::move( x ) );
}
@ -262,7 +273,7 @@ const std::vector< double >& DeckItem::getSIDoubleData() const {
return data;
if( this->dimensions.empty() )
if( this->active_dimensions.empty() )
throw std::invalid_argument("No dimension has been set for item'"
+ this->name()
+ "'; can not ask for SI data");
@ -271,73 +282,21 @@ const std::vector< double >& DeckItem::getSIDoubleData() const {
* This is an unobservable state change - SIData is lazily converted to
* SI units, so externally the object still behaves as const
*/
const auto dim_size = dimensions.size();
for( size_t index = 0; index < data.size(); index++ ) {
const auto dim_size = this->active_dimensions.size();
const auto sz = raw.size();
this->SIdata.resize( sz );
for( size_t index = 0; index < sz; index++ ) {
const auto dimIndex = index % dim_size;
data[ index ] = this->dimensions[ dimIndex ].convertRawToSi( data[ index ] );
const auto& dim = this->defaulted[index] ? this->default_dimensions[dimIndex] : this->active_dimensions[dimIndex];
this->SIdata[ index ] = dim.convertRawToSi( raw[ index ] );
}
this->raw_data = false;
return data;
}
void DeckItem::push_backDimension( const Dimension& active,
const Dimension& def ) {
if (this->type == type_tag::fdouble) {
const auto& ds = this->value_ref< double >();
const bool dim_inactive = ds.empty()
|| this->defaultApplied( ds.size() - 1 );
this->dimensions.push_back( dim_inactive ? def : active );
return;
}
if (this->type == type_tag::uda) {
auto& du = this->value_ref< UDAValue >();
const bool dim_inactive = du.empty()
|| this->defaultApplied( du.size() - 1 );
// The data model when it comes to UDA values, dimensions for vectors
// and so on is stretched beyond the breaking point. It is a *really*
// hard assumption here that UDA values only apply to scalar values.
if (du.size() > 1)
throw std::logic_error("Internal program meltdown - we do not handle non-scalar UDA values");
/*
The interaction between UDA values and dimensions is not really clean,
and treated differently for items with UDAValue and 'normal' items
with double data. The points of difference include:
- The double data do not have a dimension property; that is solely
carried by the DeckItem which will apply unit conversion and return
naked double values with the correct transformations applied. The
UDAvalues will hold on to a Dimension object, which is not used
before the UDAValue is eventually converted to a numerical value at
simulation time.
- For double data like PORO the conversion is one dimension object
which is applied to all elements in the container, whereas for
UDAValues one would need to assign an individual Dimension object to
each UDAValue instance - this is "solved" by requiring that in the
case of UDAValues only scalar values are allowed; that is not really
a practical limitation.
Finally the use of set() method to mutate the DeckItem in the case of
UDAValues is unfortunate.
*/
if (du.size() == 1)
du[0].set_dim( dim_inactive ? def : active );
this->dimensions.push_back( dim_inactive ? def : active );
return;
}
throw std::logic_error("Tried to push dimensions to an item which can not hold dimension. ");
}
type_tag DeckItem::getType() const {
return this->type;
}

View File

@ -40,6 +40,13 @@ UDAValue::UDAValue(const std::string& value):
{
}
UDAValue::UDAValue(const UDAValue& src, const Dimension& new_dim):
UDAValue(src)
{
this->dim = new_dim;
}
void UDAValue::assert_numeric() const {
std::string msg = "Internal error: The support for use of UDQ/UDA is not complete in opm/flow. The string: '" + this->string_value + "' must be numeric";
this->assert_numeric(msg);
@ -90,9 +97,6 @@ std::string UDAValue::get() const {
}
void UDAValue::set_dim(const Dimension& dim_arg) const {
this->dim = dim_arg;
}
const Dimension& UDAValue::get_dim() const {
return this->dim;

View File

@ -836,7 +836,12 @@ bool parseState( ParserState& parserState, const Parser& parser ) {
OpmLog::info(ss.str());
}
try {
parserState.deck.addKeyword( parserKeyword.parse( parserState.parseContext, parserState.errors, *rawKeyword, filename ) );
parserState.deck.addKeyword( parserKeyword.parse( parserState.parseContext,
parserState.errors,
*rawKeyword,
parserState.deck.getActiveUnitSystem(),
parserState.deck.getDefaultUnitSystem(),
filename ) );
} catch (const std::exception& exc) {
/*
This catch-all of parsing errors is to be able to write a good
@ -931,7 +936,6 @@ bool parseState( ParserState& parserState, const Parser& parser ) {
Deck Parser::parseFile(const std::string &dataFileName, const ParseContext& parseContext, ErrorGuard& errors) const {
ParserState parserState( this->codeKeywords(), parseContext, errors, dataFileName );
parseState( parserState, *this );
applyUnitsToDeck( parserState.deck );
return std::move( parserState.deck );
}
@ -953,10 +957,7 @@ bool parseState( ParserState& parserState, const Parser& parser ) {
Deck Parser::parseString(const std::string &data, const ParseContext& parseContext, ErrorGuard& errors) const {
ParserState parserState( this->codeKeywords(), parseContext, errors );
parserState.loadString( data );
parseState( parserState, *this );
applyUnitsToDeck( parserState.deck );
return std::move( parserState.deck );
}
@ -1118,18 +1119,8 @@ std::vector<std::string> Parser::getAllDeckNames () const {
}
#if 0
void Parser::applyUnitsToDeck(Deck& deck) const {
/*
* If multiple unit systems are requested, metric is preferred over
* lab, and field over metric, for as long as we have no easy way of
* figuring out which was requested last.
*/
if( deck.hasKeyword( "LAB" ) )
deck.selectActiveUnitSystem( UnitSystem::UnitType::UNIT_TYPE_LAB );
if( deck.hasKeyword( "FIELD" ) )
deck.selectActiveUnitSystem( UnitSystem::UnitType::UNIT_TYPE_FIELD );
if( deck.hasKeyword( "METRIC" ) )
deck.selectActiveUnitSystem( UnitSystem::UnitType::UNIT_TYPE_METRIC );
for( auto& deckKeyword : deck ) {
@ -1141,6 +1132,8 @@ std::vector<std::string> Parser::getAllDeckNames () const {
parserKeyword.applyUnitsToDeck(deck , deckKeyword);
}
}
#endif
static bool isSectionDelimiter( const DeckKeyword& keyword ) {
const auto& name = keyword.name();

View File

@ -29,11 +29,13 @@
#include <opm/parser/eclipse/Parser/ParserItem.hpp>
#include <opm/parser/eclipse/Parser/ParserEnums.hpp>
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include "raw/RawRecord.hpp"
#include "raw/StarToken.hpp"
namespace Opm {
class UnitSystem;
namespace {
@ -465,8 +467,7 @@ std::string ParserItem::createCode(const std::string& indent) const {
namespace {
template< typename T >
DeckItem scan_item( const ParserItem& p, RawRecord& record ) {
DeckItem item( p.name(), T());
void scan_item( DeckItem& item, const ParserItem& p, RawRecord& record ) {
bool parse_raw = p.parseRaw();
if( p.sizeType() == ParserItem::item_size::ALL ) {
@ -475,7 +476,7 @@ DeckItem scan_item( const ParserItem& p, RawRecord& record ) {
auto token = record.pop_front();
item.push_back( token.string() );
}
return item;
return;
}
while( record.size() > 0 ) {
@ -501,7 +502,7 @@ DeckItem scan_item( const ParserItem& p, RawRecord& record ) {
item.push_backDefault( value );
}
return item;
return;
}
if( record.size() == 0 ) {
@ -515,12 +516,12 @@ DeckItem scan_item( const ParserItem& p, RawRecord& record ) {
item.push_backDummyDefault();
}
return item;
return;
}
if (parse_raw) {
item.push_back( record.pop_front().string());
return item;
return;
}
// The '*' should be interpreted as a repetition indicator, but it must
@ -530,7 +531,7 @@ DeckItem scan_item( const ParserItem& p, RawRecord& record ) {
std::string valueString;
if( !isStarToken(token, countString, valueString) ) {
item.push_back( readValueToken<T>( token) );
return item;
return;
}
StarToken st(token, countString, valueString);
@ -554,7 +555,7 @@ DeckItem scan_item( const ParserItem& p, RawRecord& record ) {
: string_view{ token.begin() + value_start, token.end() };
record.prepend( st.count() - 1, rep );
return item;
return;
}
}
@ -563,18 +564,52 @@ DeckItem scan_item( const ParserItem& p, RawRecord& record ) {
/// Scans the records data according to the ParserItems definition.
/// returns a DeckItem object.
/// NOTE: data are popped from the records deque!
DeckItem ParserItem::scan( RawRecord& record ) const {
DeckItem ParserItem::scan( RawRecord& record, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem) const {
switch( this->data_type ) {
case type_tag::integer:
return scan_item< int >( *this, record );
case type_tag::fdouble:
return scan_item< double >( *this, record );
case type_tag::string:
return scan_item< std::string >( *this, record );
case type_tag::uda:
return scan_item<UDAValue>(*this, record);
default:
throw std::logic_error( "ParserItem::scan: Fatal error; should not be reachable" );
case type_tag::integer:
{
DeckItem item( this->name(), int());
scan_item< int >( item, *this, record );
return item;
}
break;
case type_tag::fdouble:
{
std::vector<Dimension> active_dimensions;
std::vector<Dimension> default_dimensions;
for (const auto& dim_string : this->m_dimensions) {
active_dimensions.push_back( active_unitsystem.getNewDimension(dim_string) );
default_dimensions.push_back( default_unitsystem.getNewDimension(dim_string) );
}
DeckItem item(this->name(), double(), active_dimensions, default_dimensions);
scan_item< double >( item, *this, record );
return item;
}
break;
case type_tag::string:
{
DeckItem item(this->name(), std::string());
scan_item< std::string >( item, *this, record );
return item;
}
break;
case type_tag::uda:
{
std::vector<Dimension> active_dimensions;
std::vector<Dimension> default_dimensions;
for (const auto& dim_string : this->m_dimensions) {
active_dimensions.push_back( active_unitsystem.getNewDimension(dim_string) );
default_dimensions.push_back( default_unitsystem.getNewDimension(dim_string) );
}
DeckItem item(this->name(), UDAValue(), active_dimensions, default_dimensions);
scan_item<UDAValue>(item, *this, record);
return item;
}
break;
default:
throw std::logic_error( "ParserItem::scan: Fatal error; should not be reachable" );
}
}

View File

@ -502,6 +502,8 @@ void set_dimensions( ParserItem& item,
DeckKeyword ParserKeyword::parse(const ParseContext& parseContext,
ErrorGuard& errors,
RawKeyword& rawKeyword,
UnitSystem& active_unitsystem,
UnitSystem& default_unitsystem,
const std::string& filename) const {
if( !rawKeyword.isFinished() )
throw std::invalid_argument("Tried to create a deck keyword from an incomplete raw keyword " + rawKeyword.getKeywordName());
@ -515,7 +517,7 @@ void set_dimensions( ParserItem& item,
if( m_records.size() == 0 && rawRecord.size() > 0 )
throw std::invalid_argument("Missing item information " + rawKeyword.getKeywordName());
keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, rawKeyword.getKeywordName(), filename ) );
keyword.addRecord( this->getRecord( record_nr ).parse( parseContext, errors, rawRecord, active_unitsystem, default_unitsystem, rawKeyword.getKeywordName(), filename ) );
record_nr++;
}
@ -718,6 +720,7 @@ void set_dimensions( ParserItem& item,
}
#if 0
void ParserKeyword::applyUnitsToDeck( Deck& deck, DeckKeyword& deckKeyword) const {
for (size_t index = 0; index < deckKeyword.size(); index++) {
const auto& parserRecord = this->getRecord( index );
@ -725,6 +728,7 @@ void set_dimensions( ParserItem& item,
parserRecord.applyUnitsToDeck( deck, deckRecord );
}
}
#endif
bool ParserKeyword::operator==( const ParserKeyword& rhs ) const {
// compare the deck names. we don't care about the ordering of the strings.

View File

@ -94,7 +94,7 @@ namespace {
}
#if 0
void ParserRecord::applyUnitsToDeck( Deck& deck, DeckRecord& deckRecord ) const {
for( const auto& parser_item : *this ) {
if( parser_item.dimensions().empty() ) continue;
@ -122,6 +122,7 @@ namespace {
}
}
}
#endif
const ParserItem& ParserRecord::get(size_t index) const {
@ -145,11 +146,12 @@ namespace {
return *itr;
}
DeckRecord ParserRecord::parse(const ParseContext& parseContext , ErrorGuard& errors , RawRecord& rawRecord, const std::string& keyword, const std::string& filename) const {
DeckRecord ParserRecord::parse(const ParseContext& parseContext , ErrorGuard& errors , RawRecord& rawRecord, UnitSystem& active_unitsystem, UnitSystem& default_unitsystem, const std::string& keyword, const std::string& filename) const {
std::vector< DeckItem > items;
items.reserve( this->size() + 20 );
for( const auto& parserItem : *this )
items.emplace_back( parserItem.scan( rawRecord ) );
items.emplace_back( parserItem.scan( rawRecord, active_unitsystem, default_unitsystem ) );
if (rawRecord.size() > 0) {
std::string msg = "The RawRecord for keyword \"" + keyword + "\" in file\"" + filename + "\" contained " +

View File

@ -1024,10 +1024,16 @@ namespace {
auto iter = this->m_dimensions.find(dimension);
if (iter == this->m_dimensions.end())
throw std::out_of_range("The dimension: '" + dimension + "' was not recognized");
this->m_use_count++;
return iter->second;
}
std::size_t UnitSystem::use_count() const {
return this->m_use_count;
}
void UnitSystem::addDimension( Dimension dimension ) {
this->m_dimensions[ dimension.getName() ] = std::move( dimension );
}

View File

@ -25,6 +25,7 @@
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Deck/DeckOutput.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
@ -44,6 +45,11 @@ BOOST_AUTO_TEST_CASE(hasKeyword_empty_returnFalse) {
BOOST_CHECK_THROW( deck.getKeyword("Bjarne") , std::invalid_argument);
}
std::pair<std::vector<Dimension>, std::vector<Dimension>> make_dims() {
UnitSystem metric(UnitSystem::UnitType::UNIT_TYPE_METRIC);
return std::make_pair<std::vector<Dimension>, std::vector<Dimension>>({metric.getDimension("Length")}, {metric.getDimension("Length")});
}
BOOST_AUTO_TEST_CASE(getKeywordList_empty_list) {
@ -215,7 +221,10 @@ BOOST_AUTO_TEST_CASE(PushBackMultipleString) {
}
BOOST_AUTO_TEST_CASE(GetDoubleAtIndex_NoData_ExceptionThrown) {
DeckItem deckDoubleItem( "TEST", double() );
auto dims = make_dims();
DeckItem deckDoubleItem( "TEST", double(), dims.first, dims.second );
printf("Current type: %s \n",tag_name(deckDoubleItem.getType()).c_str());
BOOST_CHECK(deckDoubleItem.getType() == type_tag::fdouble);
BOOST_CHECK_THROW(deckDoubleItem.get< double >(0), std::out_of_range);
deckDoubleItem.push_back(1.89);
@ -224,7 +233,8 @@ BOOST_AUTO_TEST_CASE(GetDoubleAtIndex_NoData_ExceptionThrown) {
BOOST_AUTO_TEST_CASE(sizeDouble_correct) {
DeckItem deckDoubleItem( "TEST", double() );
auto dims = make_dims();
DeckItem deckDoubleItem( "TEST", double(), dims.first, dims.second);
BOOST_CHECK_EQUAL( 0U , deckDoubleItem.size());
deckDoubleItem.push_back( 100.0 );
@ -238,7 +248,8 @@ BOOST_AUTO_TEST_CASE(sizeDouble_correct) {
BOOST_AUTO_TEST_CASE(SetInDeck) {
DeckItem deckDoubleItem( "TEST", double() );
auto dims = make_dims();
DeckItem deckDoubleItem( "TEST", double(), dims.first, dims.second);
BOOST_CHECK( deckDoubleItem.size() == 0 );
deckDoubleItem.push_backDefault( 1.0 );
@ -255,7 +266,8 @@ BOOST_AUTO_TEST_CASE(SetInDeck) {
}
BOOST_AUTO_TEST_CASE(DummyDefaultsDouble) {
DeckItem deckDoubleItem( "TEST", double() );
auto dims = make_dims();
DeckItem deckDoubleItem( "TEST", double(), dims.first, dims.second);
BOOST_CHECK_EQUAL(deckDoubleItem.size(), 0);
deckDoubleItem.push_backDummyDefault();
@ -265,33 +277,17 @@ BOOST_AUTO_TEST_CASE(DummyDefaultsDouble) {
}
BOOST_AUTO_TEST_CASE(PushBackMultipleDouble) {
DeckItem item( "HEI", double() );
auto dims = make_dims();
DeckItem item( "HEI", double() , dims.first, dims.second);
item.push_back(10.22 , 100 );
BOOST_CHECK_EQUAL( 100U , item.size() );
for (size_t i=0; i < 100; i++)
BOOST_CHECK_EQUAL(10.22 , item.get< double >(i));
}
BOOST_AUTO_TEST_CASE(PushBackDimension) {
DeckItem item( "HEI", double() );
Dimension activeDimension{ "Length" , 100 };
Dimension defaultDimension{ "Length" , 10 };
item.push_back(1.234);
item.push_backDimension( activeDimension , defaultDimension);
item.push_backDefault(5.678);
item.push_backDimension( activeDimension , defaultDimension);
}
BOOST_AUTO_TEST_CASE(PushBackDimensionInvalidType) {
DeckItem item( "HEI", int() );
Dimension dim{ "Length" , 100 };
BOOST_CHECK_THROW( item.push_backDimension( dim , dim ) , std::logic_error );
}
BOOST_AUTO_TEST_CASE(GetSIWithoutDimensionThrows) {
DeckItem item( "HEI", double() );
DeckItem item( "HEI", double() , {},{});
item.push_back(10.22 , 100 );
BOOST_CHECK_THROW( item.getSIDouble(0) , std::invalid_argument );
@ -299,41 +295,34 @@ BOOST_AUTO_TEST_CASE(GetSIWithoutDimensionThrows) {
}
BOOST_AUTO_TEST_CASE(GetSISingleDimensionCorrect) {
DeckItem item( "HEI", double() );
Dimension dim{ "Length" , 100 };
DeckItem item( "HEI", double(), { dim }, { dim } );
item.push_back(1.0 , 100 );
item.push_backDimension( dim , dim );
BOOST_CHECK_EQUAL( 1.0 , item.get< double >(0) );
BOOST_CHECK_EQUAL( 100 , item.getSIDouble(0) );
}
BOOST_AUTO_TEST_CASE(GetSISingleDefault) {
DeckItem item( "HEI", double() );
Dimension dim{ "Length" , 1 };
Dimension defaultDim{ "Length" , 100 };
DeckItem item( "HEI", double() , {dim}, {defaultDim});
item.push_backDefault( 1.0 );
item.push_backDimension( dim , defaultDim );
BOOST_CHECK_EQUAL( 1 , item.get< double >(0) );
BOOST_CHECK_EQUAL( 100 , item.getSIDouble(0) );
}
BOOST_AUTO_TEST_CASE(GetSIMultipleDim) {
DeckItem item( "HEI", double() );
Dimension dim1{ "Length" , 2 };
Dimension dim2{ "Length" , 4 };
Dimension dim3{ "Length" , 8 };
Dimension dim4{ "Length" ,16 };
Dimension defaultDim{ "Length" , 100 };
DeckItem item( "HEI", double(), {dim1, dim2, dim3, dim4}, {defaultDim, defaultDim, defaultDim, defaultDim} );
item.push_back( 1.0, 16 );
item.push_backDimension( dim1 , defaultDim );
item.push_backDimension( dim2 , defaultDim );
item.push_backDimension( dim3 , defaultDim );
item.push_backDimension( dim4 , defaultDim );
for (size_t i=0; i < 16; i+= 4) {
BOOST_CHECK_EQUAL( 2 , item.getSIDouble(i) );
@ -495,10 +484,11 @@ BOOST_AUTO_TEST_CASE(StringsWithSpaceOK) {
RawRecord rawRecord( " ' VALUE ' " );
ParseContext parseContext;
ErrorGuard errors;
UnitSystem active_unitsystem(UnitSystem::UnitType::UNIT_TYPE_LAB);
record1.addItem( itemString );
const auto deckRecord = record1.parse( parseContext, errors , rawRecord, "KEYWORD", "filename" );
const auto deckRecord = record1.parse( parseContext, errors , rawRecord, active_unitsystem, active_unitsystem, "KEYWORD", "filename" );
BOOST_CHECK_EQUAL(" VALUE " , deckRecord.getItem(0).get< std::string >(0));
}
@ -625,10 +615,10 @@ BOOST_AUTO_TEST_CASE(DeckItemWriteString) {
BOOST_AUTO_TEST_CASE(RecordWrite) {
auto dims = make_dims();
DeckRecord deckRecord;
DeckItem item1("TEST1", int());
DeckItem item2("TEST2", double());
DeckItem item2("TEST2", double(), dims.first, dims.second);
DeckItem item3("TEST3", std::string());
item1.push_back( 123 );
@ -647,11 +637,12 @@ BOOST_AUTO_TEST_CASE(RecordWrite) {
BOOST_AUTO_TEST_CASE(DeckItemEqual) {
auto dims = make_dims();
DeckItem item1("TEST1" , int());
DeckItem item2("TEST2" , int());
DeckItem item3("TEST1" , double());
DeckItem item3("TEST1" , double(), dims.first, dims.second);
DeckItem item4("TEST1" , int());
DeckItem item5("TEST1" , double());
DeckItem item5("TEST1" , double(), dims.first, dims.second);
BOOST_CHECK( item1 != item2 );
BOOST_CHECK( item1 != item3 );

View File

@ -22,6 +22,7 @@
#include <opm/json/JsonObject.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
@ -434,7 +435,8 @@ BOOST_AUTO_TEST_CASE(scan_PreMatureTerminator_defaultUsed) {
itemInt.setDefault(123);
RawRecord rawRecord1( "" );
const auto defaulted = itemInt.scan(rawRecord1);
UnitSystem unit_system;
const auto defaulted = itemInt.scan(rawRecord1, unit_system, unit_system);
BOOST_CHECK(defaulted.defaultApplied(0));
BOOST_CHECK_EQUAL(defaulted.get< int >(0), 123);
@ -644,7 +646,8 @@ BOOST_AUTO_TEST_CASE(Scan_All_CorrectIntSetInDeckItem) {
ParserItem itemInt("ITEM", INT); itemInt.setSizeType(sizeType);
RawRecord rawRecord( "100 443 10*77 10*1 25" );
const auto deckIntItem = itemInt.scan(rawRecord);
UnitSystem unit_system;
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(23U, deckIntItem.size());
BOOST_CHECK_EQUAL(77, deckIntItem.get< int >(3));
BOOST_CHECK_EQUAL(1, deckIntItem.get< int >(21));
@ -657,7 +660,8 @@ BOOST_AUTO_TEST_CASE(Scan_All_WithDefaults) {
itemInt.setInputType( ParserItem::itype::INT );
RawRecord rawRecord( "100 10* 10*1 25" );
const auto deckIntItem = itemInt.scan(rawRecord);
UnitSystem unit_system;
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(22U, deckIntItem.size());
BOOST_CHECK(!deckIntItem.defaultApplied(0));
BOOST_CHECK( deckIntItem.defaultApplied(1));
@ -671,7 +675,8 @@ BOOST_AUTO_TEST_CASE(Scan_SINGLE_CorrectIntSetInDeckItem) {
ParserItem itemInt(std::string("ITEM2"), INT);
RawRecord rawRecord("100 44.3 'Heisann'" );
const auto deckIntItem = itemInt.scan(rawRecord);
UnitSystem unit_system;
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(100, deckIntItem.get< int >(0));
}
@ -681,13 +686,14 @@ BOOST_AUTO_TEST_CASE(Scan_SeveralInts_CorrectIntsSetInDeckItem) {
ParserItem itemInt3(std::string("ITEM3"), INT);
RawRecord rawRecord( "100 443 338932 222.33 'Heisann' " );
const auto deckIntItem1 = itemInt1.scan(rawRecord);
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(100, deckIntItem1.get< int >(0));
const auto deckIntItem2 = itemInt2.scan(rawRecord);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(443, deckIntItem2.get< int >(0));
const auto deckIntItem3 = itemInt3.scan(rawRecord);
const auto deckIntItem3 = itemInt3.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(338932, deckIntItem3.get< int >(0));
}
@ -699,8 +705,9 @@ BOOST_AUTO_TEST_CASE(Scan_Multiplier_CorrectIntsSetInDeckItem) {
ParserItem itemInt("ITEM2", INT);
RawRecord rawRecord( "3*4 " );
UnitSystem unit_system;
itemInt.setSizeType(ParserItem::item_size::ALL);
const auto deckIntItem = itemInt.scan(rawRecord);
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(4, deckIntItem.get< int >(0));
BOOST_CHECK_EQUAL(4, deckIntItem.get< int >(1));
BOOST_CHECK_EQUAL(4, deckIntItem.get< int >(2));
@ -709,8 +716,9 @@ BOOST_AUTO_TEST_CASE(Scan_Multiplier_CorrectIntsSetInDeckItem) {
BOOST_AUTO_TEST_CASE(Scan_StarNoMultiplier_ExceptionThrown) {
ParserItem itemInt("ITEM2", INT);
UnitSystem unit_system;
RawRecord rawRecord( "*45 " );
BOOST_CHECK_THROW(itemInt.scan(rawRecord), std::invalid_argument);
BOOST_CHECK_THROW(itemInt.scan(rawRecord, unit_system, unit_system), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(Scan_MultipleItems_CorrectIntsSetInDeckItem) {
@ -718,8 +726,9 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleItems_CorrectIntsSetInDeckItem) {
ParserItem itemInt2(std::string("ITEM2"), INT);
RawRecord rawRecord( "10 20" );
const auto deckIntItem1 = itemInt1.scan(rawRecord);
const auto deckIntItem2 = itemInt2.scan(rawRecord);
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(10, deckIntItem1.get< int >(0));
BOOST_CHECK_EQUAL(20, deckIntItem2.get< int >(0));
@ -730,8 +739,9 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleDefault_CorrectIntsSetInDeckItem) {
ParserItem itemInt2("ITEM2", INT); itemInt2.setDefault(20);
RawRecord rawRecord( "* * " );
const auto deckIntItem1 = itemInt1.scan(rawRecord);
const auto deckIntItem2 = itemInt2.scan(rawRecord);
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(10, deckIntItem1.get< int >(0));
BOOST_CHECK_EQUAL(20, deckIntItem2.get< int >(0));
@ -742,8 +752,9 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleWithMultiplier_CorrectIntsSetInDeckItem) {
ParserItem itemInt2("ITEM2", INT);
RawRecord rawRecord( "2*30" );
const auto deckIntItem1 = itemInt1.scan(rawRecord);
const auto deckIntItem2 = itemInt2.scan(rawRecord);
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(30, deckIntItem1.get< int >(0));
BOOST_CHECK_EQUAL(30, deckIntItem2.get< int >(0));
@ -752,15 +763,17 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleWithMultiplier_CorrectIntsSetInDeckItem) {
BOOST_AUTO_TEST_CASE(Scan_MalformedMultiplier_Throw) {
ParserItem itemInt1("ITEM1", INT);
UnitSystem unit_system;
RawRecord rawRecord( "2.10*30" );
BOOST_CHECK_THROW(itemInt1.scan(rawRecord), std::invalid_argument);
BOOST_CHECK_THROW(itemInt1.scan(rawRecord, unit_system, unit_system), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(Scan_MalformedMultiplierChar_Throw) {
ParserItem itemInt1("ITEM1", INT);
RawRecord rawRecord( "210X30" );
BOOST_CHECK_THROW(itemInt1.scan(rawRecord), std::invalid_argument);
UnitSystem unit_system;
BOOST_CHECK_THROW(itemInt1.scan(rawRecord, unit_system, unit_system), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(Scan_MultipleWithMultiplierDefault_CorrectIntsSetInDeckItem) {
@ -768,8 +781,9 @@ BOOST_AUTO_TEST_CASE(Scan_MultipleWithMultiplierDefault_CorrectIntsSetInDeckItem
ParserItem itemInt2("ITEM2", INT); itemInt2.setDefault(20);
RawRecord rawRecord( "2*" );
const auto deckIntItem1 = itemInt1.scan(rawRecord);
const auto deckIntItem2 = itemInt2.scan(rawRecord);
UnitSystem unit_system;
const auto deckIntItem1 = itemInt1.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem2 = itemInt2.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(10, deckIntItem1.get< int >(0));
BOOST_CHECK_EQUAL(20, deckIntItem2.get< int >(0));
@ -780,15 +794,16 @@ BOOST_AUTO_TEST_CASE(Scan_RawRecordErrorInRawData_ExceptionThrown) {
// Wrong type
RawRecord rawRecord2( "333.2 /" );
BOOST_CHECK_THROW(itemInt.scan(rawRecord2), std::invalid_argument);
UnitSystem unit_system;
BOOST_CHECK_THROW(itemInt.scan(rawRecord2, unit_system, unit_system), std::invalid_argument);
// Wrong type
RawRecord rawRecord3( "100X /" );
BOOST_CHECK_THROW(itemInt.scan(rawRecord3), std::invalid_argument);
BOOST_CHECK_THROW(itemInt.scan(rawRecord3, unit_system, unit_system), std::invalid_argument);
// Wrong type
RawRecord rawRecord5( "astring /" );
BOOST_CHECK_THROW(itemInt.scan(rawRecord5), std::invalid_argument);
BOOST_CHECK_THROW(itemInt.scan(rawRecord5, unit_system, unit_system), std::invalid_argument);
}
/*********************String************************'*/
@ -816,21 +831,23 @@ BOOST_AUTO_TEST_CASE(InitializeStringItem_FromJsonObject_withDefaultInvalid_thro
BOOST_AUTO_TEST_CASE(init_defaultvalue_defaultset) {
ParserItem itemString(std::string("ITEM1"), STRING);
RawRecord rawRecord0( "'1*'" );
UnitSystem unit_system;
itemString.setDefault(std::string("DEFAULT"));
BOOST_CHECK_EQUAL("1*", itemString.scan( rawRecord0 ).get< std::string >(0) );
BOOST_CHECK_EQUAL("1*", itemString.scan( rawRecord0, unit_system, unit_system ).get< std::string >(0) );
RawRecord rawRecord1( "13*" );
BOOST_CHECK_EQUAL("DEFAULT" , itemString.scan( rawRecord1 ).get< std::string >(0) );
BOOST_CHECK_EQUAL("DEFAULT" , itemString.scan( rawRecord1, unit_system, unit_system ).get< std::string >(0) );
RawRecord rawRecord2( "*" );
BOOST_CHECK_EQUAL("DEFAULT", itemString.scan( rawRecord2 ).get< std::string >(0) );
BOOST_CHECK_EQUAL("DEFAULT", itemString.scan( rawRecord2, unit_system, unit_system ).get< std::string >(0) );
}
BOOST_AUTO_TEST_CASE(scan_all_valuesCorrect) {
ParserItem itemString("ITEMWITHMANY", STRING);
RawRecord rawRecord( "'WELL1' FISK BANAN 3*X OPPLEGG_FOR_DATAANALYSE 'Foo$*!% BAR' " );
UnitSystem unit_system;
itemString.setSizeType( ParserItem::item_size::ALL );
const auto deckItem = itemString.scan(rawRecord);
const auto deckItem = itemString.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(8U, deckItem.size());
BOOST_CHECK_EQUAL("WELL1", deckItem.get< std::string >(0));
@ -846,9 +863,10 @@ BOOST_AUTO_TEST_CASE(scan_all_valuesCorrect) {
BOOST_AUTO_TEST_CASE(scan_all_withdefaults) {
ParserItem itemString("ITEMWITHMANY", INT);
RawRecord rawRecord( "10*1 10* 10*2 " );
UnitSystem unit_system;
itemString.setDefault(0);
itemString.setSizeType( ParserItem::item_size::ALL );
const auto deckItem = itemString.scan(rawRecord);
const auto deckItem = itemString.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(30U, deckItem.size());
@ -871,7 +889,8 @@ BOOST_AUTO_TEST_CASE(scan_all_withdefaults) {
BOOST_AUTO_TEST_CASE(scan_single_dataCorrect) {
ParserItem itemString( "ITEM1", STRING);
RawRecord rawRecord( "'WELL1' 'WELL2'" );
const auto deckItem = itemString.scan(rawRecord);
UnitSystem unit_system;
const auto deckItem = itemString.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(1U, deckItem.size());
BOOST_CHECK_EQUAL("WELL1", deckItem.get< std::string >(0));
}
@ -879,24 +898,24 @@ BOOST_AUTO_TEST_CASE(scan_single_dataCorrect) {
BOOST_AUTO_TEST_CASE(scan_singleWithMixedRecord_dataCorrect) {
ParserItem itemString("ITEM1", STRING);
ParserItem itemInt("ITEM1", INT);
UnitSystem unit_system;
RawRecord rawRecord( "2 'WELL1' /" );
itemInt.scan(rawRecord);
const auto deckItem = itemString.scan(rawRecord);
itemInt.scan(rawRecord, unit_system, unit_system);
const auto deckItem = itemString.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL("WELL1", deckItem.get< std::string >(0));
}
/******************String and int**********************/
BOOST_AUTO_TEST_CASE(scan_intsAndStrings_dataCorrect) {
RawRecord rawRecord( "'WELL1' 2 2 2*3" );
UnitSystem unit_system;
ParserItem itemSingleString(std::string("ITEM1"), STRING);
const auto deckItemWell1 = itemSingleString.scan(rawRecord);
const auto deckItemWell1 = itemSingleString.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL("WELL1", deckItemWell1.get< std::string >(0));
ParserItem itemSomeInts("SOMEINTS", INT);
itemSomeInts.setSizeType( ParserItem::item_size::ALL );
const auto deckItemInts = itemSomeInts.scan(rawRecord);
const auto deckItemInts = itemSomeInts.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(2, deckItemInts.get< int >(0));
BOOST_CHECK_EQUAL(2, deckItemInts.get< int >(1));
BOOST_CHECK_EQUAL(3, deckItemInts.get< int >(2));
@ -1031,7 +1050,8 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_noThrow) {
ParseContext parseContext;
ErrorGuard errors;
RawRecord raw( string_view( "100 443" ) );
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, raw , "KEYWORD", "filename") );
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, raw , unit_system, unit_system, "KEYWORD", "filename") );
}
BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
@ -1039,7 +1059,8 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
RawRecord rawRecord( string_view( "100 443" ) );
ParseContext parseContext;
ErrorGuard errors;
const auto deckRecord = record.parse(parseContext , errors, rawRecord, "KEYWORD", "filename");
UnitSystem unit_system;
const auto deckRecord = record.parse(parseContext , errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename");
BOOST_CHECK_EQUAL(2U, deckRecord.size());
}
@ -1070,7 +1091,8 @@ BOOST_AUTO_TEST_CASE(parse_validMixedRecord_noThrow) {
RawRecord rawRecord( string_view( "1 2 10.0 20.0 4 90.0") );
ParseContext parseContext;
ErrorGuard errors;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, rawRecord, "KEYWORD", "filename"));
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename"));
}
BOOST_AUTO_TEST_CASE(Equal_Equal_ReturnsTrue) {
@ -1117,9 +1139,10 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
// but it seems to appear in the wild. Thus, we interpret this as "1*"...
{
RawRecord rawRecord( "* " );
const auto& deckStringItem = itemString.scan(rawRecord);
const auto& deckIntItem = itemInt.scan(rawRecord);
const auto& deckDoubleItem = itemDouble.scan(rawRecord);
UnitSystem unit_system;
const auto& deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto& deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
const auto& deckDoubleItem = itemDouble.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK(deckStringItem.size() == 1);
BOOST_CHECK(deckIntItem.size() == 1);
@ -1132,9 +1155,10 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
{
RawRecord rawRecord( "" );
const auto deckStringItem = itemString.scan(rawRecord);
const auto deckIntItem = itemInt.scan(rawRecord);
const auto deckDoubleItem = itemDouble.scan(rawRecord);
UnitSystem unit_system;
const auto deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
const auto deckDoubleItem = itemDouble.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(deckStringItem.size(), 1);
BOOST_CHECK_EQUAL(deckIntItem.size(), 1);
@ -1151,9 +1175,10 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
// let the raw record be "consumed" by the items. Note that the scan() method
// modifies the rawRecord object!
const auto& deckStringItem = itemString.scan(rawRecord);
const auto& deckIntItem = itemInt.scan(rawRecord);
const auto& deckDoubleItem = itemDouble.scan(rawRecord);
UnitSystem unit_system;
const auto& deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto& deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
const auto& deckDoubleItem = itemDouble.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(deckStringItem.size(), 1);
BOOST_CHECK_EQUAL(deckIntItem.size(), 1);
@ -1167,9 +1192,10 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
// again this is invalid according to the RM, but it is used anyway in the wild...
{
RawRecord rawRecord( "* * *" );
const auto deckStringItem = itemString.scan(rawRecord);
const auto deckIntItem = itemInt.scan(rawRecord);
const auto deckDoubleItem = itemDouble.scan(rawRecord);
UnitSystem unit_system;
const auto deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
const auto deckDoubleItem = itemDouble.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(deckStringItem.size(), 1);
BOOST_CHECK_EQUAL(deckIntItem.size(), 1);
@ -1182,9 +1208,10 @@ BOOST_AUTO_TEST_CASE(ParseWithDefault_defaultAppliedCorrectInDeck) {
{
RawRecord rawRecord( "3*" );
const auto deckStringItem = itemString.scan(rawRecord);
const auto deckIntItem = itemInt.scan(rawRecord);
const auto deckDoubleItem = itemDouble.scan(rawRecord);
UnitSystem unit_system;
const auto deckStringItem = itemString.scan(rawRecord, unit_system, unit_system);
const auto deckIntItem = itemInt.scan(rawRecord, unit_system, unit_system);
const auto deckDoubleItem = itemDouble.scan(rawRecord, unit_system, unit_system);
BOOST_CHECK_EQUAL(deckStringItem.size(), 1);
BOOST_CHECK_EQUAL(deckIntItem.size(), 1);
@ -1210,14 +1237,14 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooManyItems_Throws) {
RawRecord rawRecord( "3 3 3 " );
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, "KEYWORD", "filename"));
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEYWORD", "filename"));
RawRecord rawRecordOneExtra( "3 3 3 4 " );
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordOneExtra, "KEYWORD", "filename"), std::invalid_argument);
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordOneExtra, unit_system, unit_system, "KEYWORD", "filename"), std::invalid_argument);
RawRecord rawRecordForgotRecordTerminator( "3 3 3 \n 4 4 4 " );
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordForgotRecordTerminator, "KEYWORD", "filename"), std::invalid_argument);
BOOST_CHECK_THROW(parserRecord.parse(parseContext, errors, rawRecordForgotRecordTerminator, unit_system, unit_system, "KEYWORD", "filename"), std::invalid_argument);
}
@ -1235,10 +1262,11 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems) {
ParseContext parseContext;
ErrorGuard errors;
RawRecord rawRecord( "3 3 " );
UnitSystem unit_system;
// no default specified for the third item, record can be parsed just fine but trying
// to access the data will raise an exception...;
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, "KEWYORD", "filename"));
auto record = parserRecord.parse(parseContext, errors , rawRecord, "KEYWORD", "filename");
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEWYORD", "filename"));
auto record = parserRecord.parse(parseContext, errors , rawRecord, unit_system, unit_system, "KEYWORD", "filename");
BOOST_CHECK_NO_THROW(record.getItem(2));
BOOST_CHECK_THROW(record.getItem(2).get< int >(0), std::out_of_range);
}
@ -1613,13 +1641,14 @@ BOOST_AUTO_TEST_CASE(ParseEmptyRecord) {
RawKeyword rawkeyword( tabdimsKeyword.getName() , "FILE" , 10U , false, Raw::FIXED, 1);
ParseContext parseContext;
ErrorGuard errors;
UnitSystem unit_system;
BOOST_CHECK_EQUAL( Raw::FIXED , rawkeyword.getSizeType());
rawkeyword.addRecord( RawRecord("") );
record.addItem(item);
tabdimsKeyword.addRecord( record );
const auto deckKeyword = tabdimsKeyword.parse( parseContext, errors, rawkeyword , "filename");
const auto deckKeyword = tabdimsKeyword.parse( parseContext, errors, rawkeyword , unit_system, unit_system, "filename");
BOOST_REQUIRE_EQUAL( 1U , deckKeyword.size());
const auto& deckRecord = deckKeyword.getRecord(0);
@ -1639,13 +1668,15 @@ BOOST_AUTO_TEST_CASE(ParseKeywordHasDimensionCorrect) {
ParserRecord record;
BOOST_CHECK( !parserKeyword.hasDimension());
BOOST_CHECK_EQUAL( 0U , item1.dimensions().size() );
item2.push_backDimension("Length");
BOOST_CHECK_EQUAL( 1U , item2.dimensions().size() );
record.addItem( item1 );
parserKeyword.addRecord( record );
BOOST_CHECK( !parserKeyword.hasDimension() );
BOOST_CHECK_EQUAL( 0U , item1.dimensions().size() );
item2.push_backDimension("Length");
record.addItem( item2 );
auto parserKeyword2 = createDynamicSized("JA");
@ -1990,6 +2021,29 @@ RSCONSTT
const auto deck = Parser{}.parseString( deck_string );
}
BOOST_AUTO_TEST_CASE(InvalidLateUnits) {
const auto deck_string = std::string { R"(RUNSPEC
DX
100*100/
FIELD
)" };
/*
The opm-parser will fail hard if you change unit system with one of the
FIELD, METRIC, LAB or PVT-M keywords after you have loaded a keyword with
a dimension. This test verifies that you indeed get an exception in this
case.
The faulty situation should be "impossible" because the unit system
keywords should be in the RUNSPEC section, and all the other keywords in
the RUNSPEC section are integer keywords without dimension. Hence the deck
used in this test has incorrectly put the DX keyword in the RUNSPEC
section in order to provoke the exception; if at some stage the opm parser
treats section stricter this test might fail due to that reason instead.
*/
BOOST_CHECK_THROW( Parser{}.parseString(deck_string), std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(ParseRSConstT) {
// Check that parsing RSCONSTT does not bleed into next keyword.

View File

@ -1114,9 +1114,10 @@ BOOST_AUTO_TEST_CASE(UDA_VALUE) {
BOOST_AUTO_TEST_CASE(UDA_VALUE_DIM) {
UDAValue value0(1);
Dimension dim("DUMMY", 10);
UDAValue value1(value0, dim);
BOOST_CHECK_EQUAL( value0.get<double>(), 1);
value0.set_dim( dim );
BOOST_CHECK_EQUAL( value0.get<double>(), 10);
BOOST_CHECK_EQUAL( value1.get<double>(), 10);
}