Merge pull request #2788 from joakim-hove/deck-view
Refactor Deck and DeckView class hierarchy
This commit is contained in:
commit
01a7149b36
@ -46,6 +46,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/io/eclipse/SummaryNode.cpp
|
||||
src/opm/json/JsonObject.cpp
|
||||
src/opm/parser/eclipse/Deck/Deck.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckView.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckTree.cpp
|
||||
src/opm/parser/eclipse/Deck/FileDeck.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckItem.cpp
|
||||
@ -871,6 +872,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp
|
||||
opm/parser/eclipse/Deck/DeckItem.hpp
|
||||
opm/parser/eclipse/Deck/Deck.hpp
|
||||
opm/parser/eclipse/Deck/DeckView.hpp
|
||||
opm/parser/eclipse/Deck/FileDeck.hpp
|
||||
opm/parser/eclipse/Deck/DeckSection.hpp
|
||||
opm/parser/eclipse/Deck/DeckTree.hpp
|
||||
|
@ -4,6 +4,7 @@ set(genkw_SOURCES src/opm/json/JsonObject.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckTree.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckValue.cpp
|
||||
src/opm/parser/eclipse/Deck/Deck.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckView.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckItem.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckKeyword.cpp
|
||||
src/opm/parser/eclipse/Deck/DeckRecord.cpp
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef DECK_HPP
|
||||
#define DECK_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
@ -27,6 +28,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/DeckView.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckTree.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
@ -56,80 +58,14 @@ namespace Opm {
|
||||
*/
|
||||
class DeckOutput;
|
||||
|
||||
class DeckViewInternal {
|
||||
|
||||
|
||||
class Deck {
|
||||
public:
|
||||
typedef std::vector< DeckKeyword >::const_iterator const_iterator;
|
||||
|
||||
bool hasKeyword( const std::string& keyword ) const;
|
||||
template< class Keyword >
|
||||
bool hasKeyword() const {
|
||||
return hasKeyword( Keyword::keywordName );
|
||||
}
|
||||
|
||||
const DeckKeyword& getKeyword( const std::string& keyword, size_t index ) const;
|
||||
const DeckKeyword& getKeyword( const std::string& keyword ) const;
|
||||
const DeckKeyword& getKeyword( size_t index ) const;
|
||||
|
||||
const DeckKeyword& operator[](std::size_t index) const;
|
||||
DeckKeyword& getKeyword( size_t index );
|
||||
template< class Keyword >
|
||||
const DeckKeyword& getKeyword() const {
|
||||
return getKeyword( Keyword::keywordName );
|
||||
}
|
||||
template< class Keyword >
|
||||
const DeckKeyword& getKeyword( size_t index ) const {
|
||||
return getKeyword( Keyword::keywordName, index );
|
||||
}
|
||||
template< class Keyword >
|
||||
std::size_t count() const {
|
||||
return count( Keyword::keywordName );
|
||||
}
|
||||
|
||||
const std::vector< const DeckKeyword* > getKeywordList( const std::string& keyword ) const;
|
||||
template< class Keyword >
|
||||
const std::vector< const DeckKeyword* > getKeywordList() const {
|
||||
return getKeywordList( Keyword::keywordName );
|
||||
}
|
||||
|
||||
size_t count(const std::string& keyword) const;
|
||||
size_t size() const;
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
|
||||
protected:
|
||||
void add( const DeckKeyword*, const_iterator, const_iterator );
|
||||
|
||||
const std::vector< size_t >& offsets( const std::string& ) const;
|
||||
|
||||
DeckViewInternal( const_iterator first, const_iterator last );
|
||||
explicit DeckViewInternal( std::pair< const_iterator, const_iterator > );
|
||||
DeckViewInternal() = default;
|
||||
void init( const_iterator, const_iterator );
|
||||
|
||||
private:
|
||||
const_iterator first;
|
||||
const_iterator last;
|
||||
std::map< std::string, std::vector< size_t > > keywordMap;
|
||||
|
||||
};
|
||||
|
||||
class Deck : private DeckViewInternal {
|
||||
public:
|
||||
using DeckViewInternal::const_iterator;
|
||||
using DeckViewInternal::hasKeyword;
|
||||
using DeckViewInternal::getKeyword;
|
||||
using DeckViewInternal::getKeywordList;
|
||||
using DeckViewInternal::count;
|
||||
using DeckViewInternal::size;
|
||||
using DeckViewInternal::begin;
|
||||
using DeckViewInternal::end;
|
||||
using DeckViewInternal::operator[];
|
||||
|
||||
using iterator = std::vector< DeckKeyword >::iterator;
|
||||
using const_iterator = std::vector< DeckKeyword >::const_iterator;
|
||||
|
||||
Deck();
|
||||
Deck() = default;
|
||||
Deck( const Deck& );
|
||||
Deck( Deck&& );
|
||||
|
||||
@ -141,8 +77,6 @@ namespace Opm {
|
||||
void addKeyword( DeckKeyword&& keyword );
|
||||
void addKeyword( const DeckKeyword& keyword );
|
||||
|
||||
DeckKeyword& getKeyword( size_t );
|
||||
|
||||
const UnitSystem& getDefaultUnitSystem() const;
|
||||
const UnitSystem& getActiveUnitSystem() const;
|
||||
UnitSystem& getActiveUnitSystem();
|
||||
@ -162,6 +96,30 @@ namespace Opm {
|
||||
iterator end();
|
||||
void write( DeckOutput& output ) const ;
|
||||
friend std::ostream& operator<<(std::ostream& os, const Deck& deck);
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
const DeckKeyword& getKeyword( const std::string& keyword, size_t index ) const;
|
||||
const DeckKeyword& getKeyword( const std::string& keyword ) const;
|
||||
const DeckKeyword& getKeyword( size_t index ) const;
|
||||
DeckKeyword& getKeyword( size_t index );
|
||||
|
||||
const DeckKeyword& operator[](std::size_t index) const;
|
||||
|
||||
template< class Keyword >
|
||||
const DeckKeyword& getKeyword() const {
|
||||
return getKeyword( Keyword::keywordName );
|
||||
}
|
||||
template< class Keyword >
|
||||
const DeckKeyword& getKeyword( size_t index ) const {
|
||||
return getKeyword( Keyword::keywordName, index );
|
||||
}
|
||||
|
||||
std::vector< const DeckKeyword* > getKeywordList( const std::string& keyword ) const;
|
||||
template< class Keyword >
|
||||
std::vector< const DeckKeyword* > getKeywordList() const {
|
||||
return getKeywordList( Keyword::keywordName );
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
@ -172,12 +130,30 @@ namespace Opm {
|
||||
serializer(m_dataFile);
|
||||
serializer(input_path);
|
||||
serializer(unit_system_access_count);
|
||||
if (!serializer.isSerializing())
|
||||
this->init(this->keywordList.begin(), this->keywordList.end());
|
||||
}
|
||||
|
||||
bool hasKeyword( const std::string& keyword ) const;
|
||||
|
||||
template< class Keyword >
|
||||
bool hasKeyword() const {
|
||||
return this->hasKeyword( Keyword::keywordName );
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::vector<std::size_t> index(const std::string& keyword) const {
|
||||
return this->global_view().index(keyword);
|
||||
}
|
||||
|
||||
template< class Keyword >
|
||||
std::size_t count() const {
|
||||
return count( Keyword::keywordName );
|
||||
}
|
||||
size_t count(const std::string& keyword) const;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Deck(std::vector<DeckKeyword>&& keywordList);
|
||||
|
||||
std::vector< DeckKeyword > keywordList;
|
||||
UnitSystem defaultUnits;
|
||||
@ -187,6 +163,9 @@ namespace Opm {
|
||||
std::string input_path;
|
||||
DeckTree file_tree;
|
||||
mutable std::size_t unit_system_access_count = 0;
|
||||
|
||||
const DeckView& global_view() const;
|
||||
mutable std::unique_ptr<DeckView> m_global_view{nullptr};
|
||||
};
|
||||
}
|
||||
#endif /* DECK_HPP */
|
||||
|
@ -41,9 +41,8 @@ enum class Section {
|
||||
class Parser;
|
||||
|
||||
|
||||
class DeckSection : public DeckViewInternal {
|
||||
class DeckSection : public DeckView {
|
||||
public:
|
||||
using DeckViewInternal::const_iterator;
|
||||
|
||||
DeckSection( const Deck& deck, const std::string& startKeyword );
|
||||
const std::string& name() const;
|
||||
@ -64,6 +63,53 @@ class DeckSection : public DeckViewInternal {
|
||||
const Parser&,
|
||||
bool ensureKeywordSectionAffiliation = false);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// Highly deprecated shims
|
||||
const DeckKeyword& getKeyword(const std::string& keyword, std::size_t index) const {
|
||||
auto view = this->operator[](keyword);
|
||||
return view[index];
|
||||
}
|
||||
|
||||
const DeckKeyword& getKeyword(const std::string& keyword) const {
|
||||
auto view = this->operator[](keyword);
|
||||
return view.back();
|
||||
}
|
||||
|
||||
template<class Keyword>
|
||||
const DeckKeyword& getKeyword() const {
|
||||
auto view = this->operator[](Keyword::keywordName);
|
||||
return view.back();
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<const DeckKeyword*> getKeywordList(const std::string& keyword) const {
|
||||
std::vector<const DeckKeyword*> kw_list;
|
||||
auto view = this->operator[](keyword);
|
||||
for (const auto& kw : view)
|
||||
kw_list.push_back(&kw);
|
||||
return kw_list;
|
||||
}
|
||||
|
||||
template <class Keyword>
|
||||
std::vector<const DeckKeyword*> getKeywordList() const {
|
||||
return this->getKeywordList(Keyword::keywordName);
|
||||
}
|
||||
|
||||
|
||||
bool hasKeyword(const std::string& keyword) const {
|
||||
return this->has_keyword(keyword);
|
||||
}
|
||||
|
||||
template <class Keyword>
|
||||
bool hasKeyword() const {
|
||||
return this->has_keyword(Keyword::keywordName);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
private:
|
||||
std::string section_name;
|
||||
const UnitSystem& units;
|
||||
@ -72,49 +118,41 @@ class DeckSection : public DeckViewInternal {
|
||||
|
||||
class RUNSPECSection : public DeckSection {
|
||||
public:
|
||||
using DeckSection::const_iterator;
|
||||
explicit RUNSPECSection(const Deck& deck) : DeckSection(deck, "RUNSPEC") {}
|
||||
};
|
||||
|
||||
class GRIDSection : public DeckSection {
|
||||
public:
|
||||
using DeckSection::const_iterator;
|
||||
explicit GRIDSection(const Deck& deck) : DeckSection(deck, "GRID") {}
|
||||
};
|
||||
|
||||
class EDITSection : public DeckSection {
|
||||
public:
|
||||
using DeckSection::const_iterator;
|
||||
explicit EDITSection(const Deck& deck) : DeckSection(deck, "EDIT") {}
|
||||
};
|
||||
|
||||
class PROPSSection : public DeckSection {
|
||||
public:
|
||||
using DeckSection::const_iterator;
|
||||
explicit PROPSSection(const Deck& deck) : DeckSection(deck, "PROPS") {}
|
||||
};
|
||||
|
||||
class REGIONSSection : public DeckSection {
|
||||
public:
|
||||
using DeckSection::const_iterator;
|
||||
explicit REGIONSSection(const Deck& deck) : DeckSection(deck, "REGIONS") {}
|
||||
};
|
||||
|
||||
class SOLUTIONSection : public DeckSection {
|
||||
public:
|
||||
using DeckSection::const_iterator;
|
||||
explicit SOLUTIONSection(const Deck& deck) : DeckSection(deck, "SOLUTION") {}
|
||||
};
|
||||
|
||||
class SUMMARYSection : public DeckSection {
|
||||
public:
|
||||
using DeckSection::const_iterator;
|
||||
explicit SUMMARYSection(const Deck& deck) : DeckSection(deck, "SUMMARY") {}
|
||||
};
|
||||
|
||||
class SCHEDULESection : public DeckSection {
|
||||
public:
|
||||
using DeckSection::const_iterator;
|
||||
explicit SCHEDULESection(const Deck& deck) : DeckSection(deck, "SCHEDULE") {}
|
||||
};
|
||||
}
|
||||
|
84
opm/parser/eclipse/Deck/DeckView.hpp
Normal file
84
opm/parser/eclipse/Deck/DeckView.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright 2021 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DECKVIEW_HPP
|
||||
#define DECKVIEW_HPP
|
||||
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
|
||||
class DeckView {
|
||||
public:
|
||||
typedef std::vector<std::reference_wrapper<const DeckKeyword>> storage_type;
|
||||
|
||||
|
||||
struct Iterator : public storage_type::iterator {
|
||||
Iterator(storage_type::const_iterator inner_iter) :
|
||||
inner(inner_iter)
|
||||
{}
|
||||
|
||||
const DeckKeyword& operator*() { return this->inner->get(); }
|
||||
const DeckKeyword* operator->() { return &this->inner->get(); }
|
||||
|
||||
Iterator& operator++() { ++this->inner; return *this; }
|
||||
Iterator operator++(int) { auto tmp = *this; ++this->inner; return tmp; }
|
||||
|
||||
|
||||
Iterator& operator--() { --this->inner; return *this; }
|
||||
Iterator operator--(int) { auto tmp = *this; --this->inner; return tmp; }
|
||||
|
||||
Iterator::difference_type operator-(const Iterator &other) { return this->inner - other.inner; }
|
||||
Iterator operator+(Iterator::difference_type shift) { Iterator tmp = *this; tmp.inner += shift; return tmp;}
|
||||
|
||||
friend bool operator== (const Iterator& a, const Iterator& b) { return a.inner == b.inner; };
|
||||
friend bool operator!= (const Iterator& a, const Iterator& b) { return a.inner != b.inner; };
|
||||
private:
|
||||
storage_type::const_iterator inner;
|
||||
};
|
||||
|
||||
Iterator begin() const { return Iterator(this->keywords.begin()); }
|
||||
Iterator end() const { return Iterator(this->keywords.end()); }
|
||||
|
||||
const DeckKeyword& operator[](std::size_t index) const;
|
||||
DeckView operator[](const std::string& keyword) const;
|
||||
std::vector<std::size_t> index(const std::string& keyword) const;
|
||||
std::size_t count(const std::string& keyword) const;
|
||||
const DeckKeyword& front() const;
|
||||
const DeckKeyword& back() const;
|
||||
|
||||
DeckView() = default;
|
||||
void add_keyword(const DeckKeyword& kw);
|
||||
bool has_keyword(const std::string& kw) const;
|
||||
bool empty() const;
|
||||
std::size_t size() const;
|
||||
|
||||
template<class Keyword>
|
||||
bool has_keyword() const {
|
||||
return this->has_keyword( Keyword::keywordName );
|
||||
}
|
||||
|
||||
private:
|
||||
storage_type keywords;
|
||||
std::unordered_map<std::string, std::vector<std::size_t>> keyword_index;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -30,122 +30,58 @@ namespace fs = std::filesystem;
|
||||
|
||||
namespace Opm {
|
||||
|
||||
bool DeckViewInternal::hasKeyword( const std::string& keyword ) const {
|
||||
return this->keywordMap.find( keyword ) != this->keywordMap.end();
|
||||
std::vector< const DeckKeyword* > Deck::getKeywordList( const std::string& keyword ) const {
|
||||
std::vector<const DeckKeyword *> pointers;
|
||||
auto view = this->global_view().operator[](keyword);
|
||||
for (const auto& kw : view)
|
||||
pointers.push_back(&kw);
|
||||
return pointers;
|
||||
}
|
||||
|
||||
const DeckKeyword& DeckViewInternal::getKeyword( const std::string& keyword, size_t index ) const {
|
||||
if( !this->hasKeyword( keyword ) )
|
||||
throw std::invalid_argument("Keyword " + keyword + " not in deck.");
|
||||
|
||||
return this->getKeyword( this->offsets( keyword ).at( index ) );
|
||||
Deck::const_iterator Deck::begin() const {
|
||||
return this->keywordList.begin();
|
||||
}
|
||||
|
||||
const DeckKeyword& DeckViewInternal::getKeyword( const std::string& keyword ) const {
|
||||
if( !this->hasKeyword( keyword ) )
|
||||
throw std::invalid_argument("Keyword " + keyword + " not in deck.");
|
||||
|
||||
return this->getKeyword( this->offsets( keyword ).back() );
|
||||
}
|
||||
|
||||
const DeckKeyword& DeckViewInternal::getKeyword( size_t index ) const {
|
||||
if( index >= this->size() )
|
||||
throw std::out_of_range("Keyword index " + std::to_string( index ) + " is out of range.");
|
||||
|
||||
return *( this->begin() + index );
|
||||
}
|
||||
|
||||
const DeckKeyword& DeckViewInternal::operator[](std::size_t index) const {
|
||||
return this->getKeyword(index);
|
||||
Deck::const_iterator Deck::end() const {
|
||||
return this->keywordList.end();
|
||||
}
|
||||
|
||||
|
||||
size_t DeckViewInternal::count( const std::string& keyword ) const {
|
||||
if( !this->hasKeyword( keyword ) ) return 0;
|
||||
std::size_t Deck::count(const std::string& keyword) const {
|
||||
return this->global_view().count(keyword);
|
||||
}
|
||||
|
||||
return this->offsets( keyword ).size();
|
||||
const DeckView& Deck::global_view() const {
|
||||
if (!this->m_global_view) {
|
||||
this->m_global_view = std::make_unique<DeckView>();
|
||||
for (const auto& kw : this->keywordList)
|
||||
this->m_global_view->add_keyword(kw);
|
||||
}
|
||||
return *this->m_global_view;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const DeckKeyword& Deck::getKeyword( const std::string& keyword, size_t index ) const {
|
||||
return this->global_view().operator[](keyword)[index];
|
||||
}
|
||||
|
||||
const std::vector< const DeckKeyword* > DeckViewInternal::getKeywordList( const std::string& keyword ) const {
|
||||
if( !hasKeyword( keyword ) ) return {};
|
||||
|
||||
const auto& indices = this->offsets( keyword );
|
||||
|
||||
std::vector< const DeckKeyword* > ret;
|
||||
ret.reserve( indices.size() );
|
||||
|
||||
for( size_t i : indices )
|
||||
ret.push_back( &this->getKeyword( i ) );
|
||||
|
||||
return ret;
|
||||
const DeckKeyword& Deck::getKeyword( const std::string& keyword ) const {
|
||||
return this->global_view().operator[](keyword).back();
|
||||
}
|
||||
|
||||
size_t DeckViewInternal::size() const {
|
||||
return std::distance( this->begin(), this->end() );
|
||||
const DeckKeyword& Deck::getKeyword( size_t index ) const {
|
||||
return this->operator[](index);
|
||||
}
|
||||
|
||||
DeckViewInternal::const_iterator DeckViewInternal::begin() const {
|
||||
return this->first;
|
||||
const DeckKeyword& Deck::operator[](std::size_t index) const {
|
||||
return this->keywordList.at(index);
|
||||
}
|
||||
|
||||
DeckViewInternal::const_iterator DeckViewInternal::end() const {
|
||||
return this->last;
|
||||
}
|
||||
|
||||
void DeckViewInternal::add( const DeckKeyword* kw, const_iterator f, const_iterator l ) {
|
||||
this->keywordMap[ kw->name() ].push_back( std::distance( f, l ) - 1 );
|
||||
this->first = f;
|
||||
this->last = l;
|
||||
}
|
||||
|
||||
static const std::vector< size_t > empty_indices = {};
|
||||
const std::vector< size_t >& DeckViewInternal::offsets( const std::string& keyword ) const {
|
||||
if( !hasKeyword( keyword ) ) return empty_indices;
|
||||
|
||||
return this->keywordMap.find( keyword )->second;
|
||||
}
|
||||
|
||||
DeckViewInternal::DeckViewInternal( const_iterator first_arg, const_iterator last_arg)
|
||||
{
|
||||
this->init(first_arg, last_arg);
|
||||
}
|
||||
|
||||
void DeckViewInternal::init( const_iterator first_arg, const_iterator last_arg ) {
|
||||
this->first = first_arg;
|
||||
this->last = last_arg;
|
||||
|
||||
this->keywordMap.clear();
|
||||
|
||||
size_t index = 0;
|
||||
for( const auto& kw : *this )
|
||||
this->keywordMap[ kw.name() ].push_back( index++ );
|
||||
}
|
||||
|
||||
DeckViewInternal::DeckViewInternal( std::pair< const_iterator, const_iterator > limits ) :
|
||||
DeckViewInternal( limits.first, limits.second )
|
||||
{}
|
||||
|
||||
Deck::Deck() :
|
||||
Deck( std::vector<DeckKeyword>() )
|
||||
{}
|
||||
|
||||
/*
|
||||
This constructor should be ssen as a technical implemtation detail of the
|
||||
default constructor, and not something which should be invoked directly.
|
||||
The point is that the derived class DeckViewInternal contains iterators to the
|
||||
keywordList member in the base class - this represents some ordering
|
||||
challenges in the construction phase.
|
||||
*/
|
||||
Deck::Deck( std::vector<DeckKeyword>&& x) :
|
||||
DeckViewInternal(x.begin(), x.end()),
|
||||
keywordList(std::move(x)),
|
||||
defaultUnits( UnitSystem::newMETRIC() )
|
||||
{
|
||||
}
|
||||
|
||||
Deck::Deck( const Deck& d )
|
||||
: DeckViewInternal(d.begin(), d.end())
|
||||
, keywordList( d.keywordList )
|
||||
: keywordList( d.keywordList )
|
||||
, defaultUnits( d.defaultUnits )
|
||||
, activeUnits( d.activeUnits )
|
||||
, m_dataFile( d.m_dataFile )
|
||||
@ -153,12 +89,10 @@ namespace Opm {
|
||||
, file_tree( d.file_tree )
|
||||
, unit_system_access_count(d.unit_system_access_count)
|
||||
{
|
||||
this->init(this->keywordList.begin(), this->keywordList.end());
|
||||
}
|
||||
|
||||
Deck::Deck( Deck&& d )
|
||||
: DeckViewInternal(d.begin(), d.end())
|
||||
, keywordList( std::move(d.keywordList) )
|
||||
: keywordList( std::move(d.keywordList) )
|
||||
, defaultUnits( d.defaultUnits )
|
||||
, activeUnits( d.activeUnits )
|
||||
, m_dataFile( d.m_dataFile )
|
||||
@ -166,7 +100,6 @@ namespace Opm {
|
||||
, file_tree( std::move(d.file_tree) )
|
||||
, unit_system_access_count(d.unit_system_access_count)
|
||||
{
|
||||
this->init(this->keywordList.begin(), this->keywordList.end());
|
||||
}
|
||||
|
||||
Deck Deck::serializeObject()
|
||||
@ -193,9 +126,7 @@ namespace Opm {
|
||||
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 );
|
||||
this->m_global_view = nullptr;
|
||||
}
|
||||
|
||||
void Deck::addKeyword( const DeckKeyword& keyword ) {
|
||||
@ -311,7 +242,6 @@ namespace Opm {
|
||||
m_dataFile = data.m_dataFile;
|
||||
input_path = data.input_path;
|
||||
unit_system_access_count = data.unit_system_access_count;
|
||||
this->init(this->keywordList.begin(), this->keywordList.end());
|
||||
activeUnits = data.activeUnits;
|
||||
|
||||
return *this;
|
||||
@ -344,4 +274,9 @@ namespace Opm {
|
||||
bool Deck::empty() const {
|
||||
return this->keywordList.size() == 0;
|
||||
}
|
||||
|
||||
bool Deck::hasKeyword(const std::string& keyword) const {
|
||||
return this->global_view().has_keyword(keyword);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,53 +17,80 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/E.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/G.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/P.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/R.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/S.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
static bool isSectionDelimiter( const DeckKeyword& keyword ) {
|
||||
const auto& name = keyword.name();
|
||||
for( const auto& x : { "RUNSPEC", "GRID", "EDIT", "PROPS",
|
||||
"REGIONS", "SOLUTION", "SUMMARY", "SCHEDULE" } )
|
||||
if( name == x ) return true;
|
||||
|
||||
return false;
|
||||
const std::unordered_map<std::string, std::size_t> section_index = {
|
||||
{"RUNSPEC", 0},
|
||||
{"GRID", 1},
|
||||
{"EDIT", 2},
|
||||
{"PROPS", 3},
|
||||
{"REGIONS", 4},
|
||||
{"SOLUTION", 5},
|
||||
{"SUMMARY", 6},
|
||||
{"SCHEDULE", 7}
|
||||
};
|
||||
|
||||
std::pair<std::size_t, std::size_t> index_pair(const Deck& deck, const std::string& section) {
|
||||
if (!deck.hasKeyword(section))
|
||||
return {0,0};
|
||||
|
||||
auto start_index = deck.index(section).front();
|
||||
std::unordered_set<std::string> end_set;
|
||||
{
|
||||
auto this_section_index = section_index.at(section);
|
||||
|
||||
for (const auto& [section_name, index] : section_index) {
|
||||
if (index > this_section_index)
|
||||
end_set.insert(section_name);
|
||||
}
|
||||
}
|
||||
|
||||
static std::pair< DeckViewInternal::const_iterator, DeckViewInternal::const_iterator >
|
||||
find_section( const Deck& deck, const std::string& keyword ) {
|
||||
if (end_set.empty())
|
||||
return {start_index, deck.size()};
|
||||
|
||||
const auto fn = [&keyword]( const DeckKeyword& kw ) {
|
||||
return kw.name() == keyword;
|
||||
};
|
||||
std::size_t deck_index = start_index;
|
||||
while (true) {
|
||||
const auto& kw = deck[deck_index];
|
||||
if (end_set.count(kw.name()) == 1)
|
||||
break;
|
||||
|
||||
auto first = std::find_if( deck.begin(), deck.end(), fn );
|
||||
deck_index++;
|
||||
|
||||
if( first == deck.end() )
|
||||
return { first, first };
|
||||
|
||||
auto last = std::find_if( first + 1, deck.end(), isSectionDelimiter );
|
||||
|
||||
if( last != deck.end() && last->name() == keyword )
|
||||
throw std::invalid_argument( std::string( "Deck contains the '" ) + keyword + "' section multiple times" );
|
||||
|
||||
return { first, last };
|
||||
if (deck_index == deck.size())
|
||||
break;
|
||||
}
|
||||
return {start_index, deck_index};
|
||||
}
|
||||
|
||||
|
||||
DeckSection::DeckSection( const Deck& deck, const std::string& section )
|
||||
: DeckViewInternal( find_section( deck, section ) ),
|
||||
section_name( section ),
|
||||
units( deck.getActiveUnitSystem() )
|
||||
{}
|
||||
: section_name( section )
|
||||
, units( deck.getActiveUnitSystem() )
|
||||
{
|
||||
auto [start_index, end_index] = index_pair(deck, section);
|
||||
for (std::size_t index = start_index; index < end_index; index++)
|
||||
this->add_keyword(deck.getKeyword(index));
|
||||
}
|
||||
|
||||
|
||||
const std::string& DeckSection::name() const {
|
||||
return this->section_name;
|
||||
@ -73,13 +100,13 @@ namespace Opm {
|
||||
return this->units;
|
||||
}
|
||||
|
||||
bool DeckSection::hasRUNSPEC(const Deck& deck) { return deck.hasKeyword( "RUNSPEC" ); }
|
||||
bool DeckSection::hasGRID(const Deck& deck) { return deck.hasKeyword( "GRID" ); }
|
||||
bool DeckSection::hasEDIT(const Deck& deck) { return deck.hasKeyword( "EDIT" ); }
|
||||
bool DeckSection::hasPROPS(const Deck& deck) { return deck.hasKeyword( "PROPS" ); }
|
||||
bool DeckSection::hasREGIONS(const Deck& deck) { return deck.hasKeyword( "REGIONS" ); }
|
||||
bool DeckSection::hasSOLUTION(const Deck& deck) { return deck.hasKeyword( "SOLUTION" ); }
|
||||
bool DeckSection::hasSUMMARY(const Deck& deck) { return deck.hasKeyword( "SUMMARY" ); }
|
||||
bool DeckSection::hasSCHEDULE(const Deck& deck) { return deck.hasKeyword( "SCHEDULE" ); }
|
||||
bool DeckSection::hasRUNSPEC(const Deck& deck) { return deck.hasKeyword<ParserKeywords::RUNSPEC>(); }
|
||||
bool DeckSection::hasGRID(const Deck& deck) { return deck.hasKeyword<ParserKeywords::GRID>(); }
|
||||
bool DeckSection::hasEDIT(const Deck& deck) { return deck.hasKeyword<ParserKeywords::EDIT>(); }
|
||||
bool DeckSection::hasPROPS(const Deck& deck) { return deck.hasKeyword<ParserKeywords::PROPS>(); }
|
||||
bool DeckSection::hasREGIONS(const Deck& deck) { return deck.hasKeyword<ParserKeywords::REGIONS>(); }
|
||||
bool DeckSection::hasSOLUTION(const Deck& deck) { return deck.hasKeyword<ParserKeywords::SOLUTION>(); }
|
||||
bool DeckSection::hasSUMMARY(const Deck& deck) { return deck.hasKeyword<ParserKeywords::SUMMARY>(); }
|
||||
bool DeckSection::hasSCHEDULE(const Deck& deck) { return deck.hasKeyword<ParserKeywords::SCHEDULE>(); }
|
||||
|
||||
}
|
||||
|
85
src/opm/parser/eclipse/Deck/DeckView.cpp
Normal file
85
src/opm/parser/eclipse/Deck/DeckView.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright 2021 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/DeckView.hpp>
|
||||
|
||||
|
||||
void Opm::DeckView::add_keyword(const Opm::DeckKeyword& kw) {
|
||||
this->keyword_index[kw.name()].push_back(this->keywords.size());
|
||||
this->keywords.push_back(std::cref(kw));
|
||||
}
|
||||
|
||||
bool Opm::DeckView::has_keyword(const std::string& kw) const {
|
||||
return this->keyword_index.find(kw) != this->keyword_index.end();
|
||||
}
|
||||
|
||||
bool Opm::DeckView::empty() const {
|
||||
return this->keywords.empty();
|
||||
}
|
||||
|
||||
std::size_t Opm::DeckView::size() const {
|
||||
return this->keywords.size();
|
||||
}
|
||||
|
||||
const Opm::DeckKeyword& Opm::DeckView::operator[](std::size_t kw_index) const {
|
||||
return this->keywords.at(kw_index).get();
|
||||
}
|
||||
|
||||
Opm::DeckView Opm::DeckView::operator[](const std::string& kw_name) const {
|
||||
DeckView dw;
|
||||
auto iter = this->keyword_index.find(kw_name);
|
||||
if (iter != this->keyword_index.end()) {
|
||||
for (const auto& kw_index : iter->second) {
|
||||
const auto& kw = this->keywords[kw_index].get();
|
||||
dw.add_keyword(kw);
|
||||
}
|
||||
}
|
||||
return dw;
|
||||
}
|
||||
|
||||
const Opm::DeckKeyword& Opm::DeckView::front() const {
|
||||
if (this->empty())
|
||||
throw std::logic_error("Tried to get front() from empty DeckView");
|
||||
|
||||
return this->keywords.front().get();
|
||||
}
|
||||
|
||||
const Opm::DeckKeyword& Opm::DeckView::back() const {
|
||||
if (this->empty())
|
||||
throw std::logic_error("Tried to get back() from empty DeckView");
|
||||
|
||||
return this->keywords.back().get();
|
||||
}
|
||||
|
||||
std::vector<std::size_t> Opm::DeckView::index(const std::string& keyword) const {
|
||||
auto iter = this->keyword_index.find(keyword);
|
||||
if (iter != this->keyword_index.end())
|
||||
return iter->second;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::size_t Opm::DeckView::count(const std::string& keyword) const {
|
||||
auto iter = this->keyword_index.find(keyword);
|
||||
if (iter == this->keyword_index.end())
|
||||
return 0;
|
||||
|
||||
return iter->second.size();
|
||||
}
|
@ -29,10 +29,12 @@
|
||||
#include <opm/parser/eclipse/Deck/DeckTree.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckOutput.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckView.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/D.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserItem.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserRecord.hpp>
|
||||
#include <opm/common/OpmLog/KeywordLocation.hpp>
|
||||
@ -44,7 +46,7 @@ using namespace Opm;
|
||||
BOOST_AUTO_TEST_CASE(hasKeyword_empty_returnFalse) {
|
||||
Deck deck;
|
||||
BOOST_CHECK_EQUAL(false, deck.hasKeyword("Bjarne"));
|
||||
BOOST_CHECK_THROW( deck.getKeyword("Bjarne") , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( deck.getKeyword("Bjarne") , std::exception);
|
||||
}
|
||||
|
||||
std::pair<std::vector<Dimension>, std::vector<Dimension>> make_dims() {
|
||||
@ -64,7 +66,7 @@ BOOST_AUTO_TEST_CASE(getKeyword_singlekeyword_outRange_throws) {
|
||||
Deck deck;
|
||||
Parser parser;
|
||||
deck.addKeyword( DeckKeyword( parser.getKeyword("GRID")));
|
||||
BOOST_CHECK_THROW(deck.getKeyword("GRID" , 10) , std::out_of_range);
|
||||
BOOST_CHECK_THROW(deck.getKeyword("GRID" , 10) , std::exception);
|
||||
}
|
||||
|
||||
|
||||
@ -108,7 +110,8 @@ BOOST_AUTO_TEST_CASE(size_twokeyword_return2) {
|
||||
deck.addKeyword(keyword);
|
||||
deck.addKeyword(keyword);
|
||||
BOOST_CHECK_EQUAL(2U , deck.size());
|
||||
BOOST_CHECK_THROW( deck.getKeyword("GRID" , 3) , std::out_of_range);
|
||||
|
||||
BOOST_CHECK_THROW( deck.getKeyword("GRID" , 3) , std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(getKeywordList_OK) {
|
||||
@ -126,12 +129,12 @@ BOOST_AUTO_TEST_CASE(getKeywordList_OK) {
|
||||
BOOST_AUTO_TEST_CASE(keywordList_getbyindexoutofbounds_exceptionthrown) {
|
||||
Parser parser;
|
||||
Deck deck;
|
||||
BOOST_CHECK_THROW(deck.getKeyword(0), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deck.getKeyword(0), std::exception);
|
||||
deck.addKeyword( DeckKeyword( parser.getKeyword("GRID")));
|
||||
deck.addKeyword( DeckKeyword( parser.getKeyword("GRID")));
|
||||
deck.addKeyword( DeckKeyword( parser.getKeyword("INIT")));
|
||||
BOOST_CHECK_NO_THROW(deck.getKeyword(2));
|
||||
BOOST_CHECK_THROW(deck.getKeyword(3), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deck.getKeyword(3), std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(keywordList_getbyindex_correctkeywordreturned) {
|
||||
@ -159,14 +162,14 @@ BOOST_AUTO_TEST_CASE(DummyDefaultsString) {
|
||||
deckStringItem.push_backDummyDefault<std::string>();
|
||||
BOOST_CHECK_EQUAL(deckStringItem.data_size(), 1U);
|
||||
BOOST_CHECK_EQUAL(true, deckStringItem.defaultApplied(0));
|
||||
BOOST_CHECK_THROW(deckStringItem.get< std::string >(0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(deckStringItem.get< std::string >(0), std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetStringAtIndex_NoData_ExceptionThrown) {
|
||||
DeckItem deckStringItem( "TEST", std::string() );
|
||||
BOOST_CHECK_THROW(deckStringItem.get< std::string >(0), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckStringItem.get< std::string >(0), std::exception);
|
||||
deckStringItem.push_back("SA");
|
||||
BOOST_CHECK_THROW(deckStringItem.get< std::string >(1), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckStringItem.get< std::string >(1), std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(size_variouspushes_sizecorrect) {
|
||||
@ -216,9 +219,9 @@ BOOST_AUTO_TEST_CASE(GetDoubleAtIndex_NoData_ExceptionThrown) {
|
||||
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);
|
||||
BOOST_CHECK_THROW(deckDoubleItem.get< double >(0), std::exception);
|
||||
deckDoubleItem.push_back(1.89);
|
||||
BOOST_CHECK_THROW(deckDoubleItem.get< double >(1), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckDoubleItem.get< double >(1), std::exception);
|
||||
}
|
||||
|
||||
|
||||
@ -263,7 +266,7 @@ BOOST_AUTO_TEST_CASE(DummyDefaultsDouble) {
|
||||
deckDoubleItem.push_backDummyDefault<double>();
|
||||
BOOST_CHECK_EQUAL(deckDoubleItem.data_size(), 1U);
|
||||
BOOST_CHECK_EQUAL(true, deckDoubleItem.defaultApplied(0));
|
||||
BOOST_CHECK_THROW(deckDoubleItem.get< double >(0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(deckDoubleItem.get< double >(0), std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PushBackMultipleDouble) {
|
||||
@ -280,8 +283,8 @@ BOOST_AUTO_TEST_CASE(GetSIWithoutDimensionThrows) {
|
||||
DeckItem item( "HEI", double() , {},{});
|
||||
item.push_back(10.22 , 100 );
|
||||
|
||||
BOOST_CHECK_THROW( item.getSIDouble(0) , std::invalid_argument );
|
||||
BOOST_CHECK_THROW( item.getSIDoubleData() , std::invalid_argument );
|
||||
BOOST_CHECK_THROW( item.getSIDouble(0) , std::exception );
|
||||
BOOST_CHECK_THROW( item.getSIDoubleData() , std::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetSISingleDimensionCorrect) {
|
||||
@ -339,14 +342,14 @@ BOOST_AUTO_TEST_CASE(DummyDefaultsInt) {
|
||||
BOOST_CHECK_EQUAL(true, deckIntItem.defaultApplied(0));
|
||||
BOOST_CHECK_EQUAL( false , deckIntItem.hasValue(0));
|
||||
BOOST_CHECK_EQUAL( false , deckIntItem.hasValue(1));
|
||||
BOOST_CHECK_THROW(deckIntItem.get< int >(0), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(deckIntItem.get< int >(0), std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetIntAtIndex_NoData_ExceptionThrown) {
|
||||
DeckItem deckIntItem( "TEST", int() );
|
||||
deckIntItem.push_back(100);
|
||||
BOOST_CHECK(deckIntItem.get< int >(0) == 100);
|
||||
BOOST_CHECK_THROW(deckIntItem.get< int >(1), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckIntItem.get< int >(1), std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(InitializeDefaultApplied) {
|
||||
@ -375,8 +378,8 @@ BOOST_AUTO_TEST_CASE(DefaultNotAppliedInt) {
|
||||
BOOST_CHECK( deckIntItem.get< int >(0) == 100 );
|
||||
BOOST_CHECK( !deckIntItem.defaultApplied(0) );
|
||||
|
||||
BOOST_CHECK_THROW( deckIntItem.defaultApplied(1), std::out_of_range );
|
||||
BOOST_CHECK_THROW( deckIntItem.get< int >(1), std::out_of_range );
|
||||
BOOST_CHECK_THROW( deckIntItem.defaultApplied(1), std::exception );
|
||||
BOOST_CHECK_THROW( deckIntItem.get< int >(1), std::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UseDefault) {
|
||||
@ -387,8 +390,8 @@ BOOST_AUTO_TEST_CASE(UseDefault) {
|
||||
BOOST_CHECK( deckIntItem.defaultApplied(0) );
|
||||
BOOST_CHECK( deckIntItem.get< int >(0) == 100 );
|
||||
|
||||
BOOST_CHECK_THROW( deckIntItem.defaultApplied(1), std::out_of_range );
|
||||
BOOST_CHECK_THROW( deckIntItem.get< int >(1), std::out_of_range );
|
||||
BOOST_CHECK_THROW( deckIntItem.defaultApplied(1), std::exception );
|
||||
BOOST_CHECK_THROW( deckIntItem.get< int >(1), std::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DefaultAppliedInt) {
|
||||
@ -439,9 +442,9 @@ BOOST_AUTO_TEST_CASE(addItem_multipleItems_sizecorrect) {
|
||||
BOOST_AUTO_TEST_CASE(addItem_differentItemsSameName_throws) {
|
||||
DeckRecord deckRecord;
|
||||
deckRecord.addItem( DeckItem { "TEST", int() } );
|
||||
BOOST_CHECK_THROW( deckRecord.addItem( DeckItem { "TEST", int() } ), std::invalid_argument );
|
||||
BOOST_CHECK_THROW( deckRecord.addItem( DeckItem { "TEST", int() } ), std::exception );
|
||||
std::vector< DeckItem > items = { DeckItem { "TEST", int() }, DeckItem { "TEST" , int() } };
|
||||
BOOST_CHECK_THROW( DeckRecord( std::move( items ) ), std::invalid_argument );
|
||||
BOOST_CHECK_THROW( DeckRecord( std::move( items ) ), std::exception );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(get_byIndex_returnsItem) {
|
||||
@ -453,7 +456,7 @@ BOOST_AUTO_TEST_CASE(get_byIndex_returnsItem) {
|
||||
BOOST_AUTO_TEST_CASE(get_indexoutofbounds_throws) {
|
||||
DeckRecord deckRecord;
|
||||
deckRecord.addItem( DeckItem { "TEST", int() } );
|
||||
BOOST_CHECK_THROW(deckRecord.getItem(1), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckRecord.getItem(1), std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(get_byName_returnsItem) {
|
||||
@ -465,7 +468,7 @@ BOOST_AUTO_TEST_CASE(get_byName_returnsItem) {
|
||||
BOOST_AUTO_TEST_CASE(get_byNameNonExisting_throws) {
|
||||
DeckRecord deckRecord;
|
||||
deckRecord.addItem( DeckItem { "TEST", int() } );
|
||||
BOOST_CHECK_THROW(deckRecord.getItem("INVALID"), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(deckRecord.getItem("INVALID"), std::exception);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(StringsWithSpaceOK) {
|
||||
@ -507,7 +510,7 @@ BOOST_AUTO_TEST_CASE(size_noRecords_returnszero) {
|
||||
Parser parser;
|
||||
DeckKeyword deckKeyword( parser.getKeyword("GRID"));;
|
||||
BOOST_CHECK_EQUAL(0U, deckKeyword.size());
|
||||
BOOST_CHECK_THROW(deckKeyword.getRecord(0), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckKeyword.getRecord(0), std::exception);
|
||||
}
|
||||
|
||||
|
||||
@ -676,9 +679,170 @@ BOOST_AUTO_TEST_CASE(STRING_TO_BOOL) {
|
||||
BOOST_CHECK( !DeckItem::to_bool("N"));
|
||||
BOOST_CHECK( !DeckItem::to_bool("0") );
|
||||
//
|
||||
BOOST_CHECK_THROW(DeckItem::to_bool("NO - not valid"), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(DeckItem::to_bool("YE"), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(DeckItem::to_bool("YE"), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(DeckItem::to_bool("NO - not valid"), std::exception);
|
||||
BOOST_CHECK_THROW(DeckItem::to_bool("YE"), std::exception);
|
||||
BOOST_CHECK_THROW(DeckItem::to_bool("YE"), std::exception);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DeckView2Test) {
|
||||
std::string deck_string = R"(
|
||||
START
|
||||
7 OCT 2020 /
|
||||
|
||||
DIMENS
|
||||
10 10 3 /
|
||||
|
||||
GRID
|
||||
DXV
|
||||
10*100.0 /
|
||||
DYV
|
||||
10*100.0 /
|
||||
DZV
|
||||
3*10.0 /
|
||||
|
||||
DEPTHZ
|
||||
121*2000.0 /
|
||||
|
||||
PORO
|
||||
300*0.3 /
|
||||
|
||||
SCHEDULE
|
||||
|
||||
VFPPROD
|
||||
-- table_num, datum_depth, flo, wfr, gfr, pressure, alq, unit, table_vals
|
||||
42 7.0E+03 LIQ WCT GOR THP ' ' METRIC BHP /
|
||||
1.0 / flo axis
|
||||
0.0 1.0 / THP axis
|
||||
0.0 / WFR axis
|
||||
0.0 / GFR axis
|
||||
0.0 / ALQ axis
|
||||
-- Table itself: thp_idx wfr_idx gfr_idx alq_idx <vals>
|
||||
1 1 1 1 0.0 /
|
||||
2 1 1 1 1.0 /
|
||||
|
||||
VFPPROD
|
||||
-- table_num, datum_depth, flo, wfr, gfr, pressure, alq, unit, table_vals
|
||||
43 7.0E+03 LIQ WCT GOR THP 'GRAT' METRIC BHP /
|
||||
1.0 / flo axis
|
||||
0.0 1.0 / THP axis
|
||||
0.0 / WFR axis
|
||||
0.0 / GFR axis
|
||||
0.0 / ALQ axis
|
||||
-- Table itself: thp_idx wfr_idx gfr_idx alq_idx <vals>
|
||||
1 1 1 1 0.0 /
|
||||
2 1 1 1 1.0 /
|
||||
|
||||
WELSPECS -- 0
|
||||
'P1' 'G' 10 10 2005 'LIQ' /
|
||||
'P2' 'G' 10 10 2005 'LIQ' /
|
||||
/
|
||||
|
||||
COMPDAT
|
||||
'P1' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 /
|
||||
'P2' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 /
|
||||
/
|
||||
|
||||
WCONPROD
|
||||
'P1' 'OPEN' 'ORAT' 123.4 0.0 0.0 0.0 0.0 100 100 42 'UDA' /
|
||||
'P2' 'OPEN' 'ORAT' 123.4 0.0 0.0 0.0 0.0 100 100 43 'UDA' /
|
||||
/
|
||||
|
||||
DATES
|
||||
10 'JAN' 2000 /
|
||||
/
|
||||
|
||||
DATES
|
||||
20 'JAN' 2000 /
|
||||
/
|
||||
|
||||
DATES
|
||||
30 'JAN' 2000 /
|
||||
/
|
||||
|
||||
)";
|
||||
|
||||
Parser parser;
|
||||
auto deck = parser.parseString(deck_string);
|
||||
DeckView dw;
|
||||
for (const auto& kw : deck)
|
||||
dw.add_keyword(kw);
|
||||
|
||||
BOOST_CHECK(dw.has_keyword("DATES"));
|
||||
BOOST_CHECK(!dw.has_keyword("RADIAL"));
|
||||
BOOST_CHECK(!dw.empty());
|
||||
BOOST_CHECK_EQUAL(dw.size(), 17);
|
||||
|
||||
BOOST_CHECK_THROW(dw[100], std::exception);
|
||||
const auto& start = dw[0];
|
||||
BOOST_CHECK_EQUAL(start.name(), "START");
|
||||
BOOST_CHECK_EQUAL(dw.front().name(), "START");
|
||||
BOOST_CHECK(dw.back() == dw[16]);
|
||||
{
|
||||
DeckView dw2;
|
||||
BOOST_CHECK_THROW(dw2.back(), std::exception);
|
||||
BOOST_CHECK_THROW(dw2.front(), std::exception);
|
||||
}
|
||||
const auto& radial_kw = dw["RADIAL"];
|
||||
BOOST_CHECK(radial_kw.empty());
|
||||
|
||||
|
||||
const auto& dates_view = dw["DATES"];
|
||||
BOOST_CHECK_EQUAL(dates_view.size(), 3);
|
||||
const auto& first_dates = dates_view.front();
|
||||
const auto& rec0 = first_dates[0];
|
||||
const auto& month = rec0.getItem(1).get<std::string>(0);
|
||||
BOOST_CHECK_EQUAL(month, "JAN");
|
||||
|
||||
const auto& last_dates = dates_view.back();
|
||||
const auto& rec1 = last_dates[0];
|
||||
const auto& day = rec1.getItem(0).get<int>(0);
|
||||
BOOST_CHECK_EQUAL(day, 30);
|
||||
|
||||
|
||||
BOOST_CHECK(dw.has_keyword<ParserKeywords::DATES>());
|
||||
std::vector<std::string> expected = {"START", "DIMENS", "GRID", "DXV", "DYV", "DZV", "DEPTHZ", "PORO",
|
||||
"SCHEDULE", "VFPPROD", "VFPPROD", "WELSPECS", "COMPDAT", "WCONPROD",
|
||||
"DATES", "DATES", "DATES"};
|
||||
std::vector<std::string> actual;
|
||||
for (const auto& kw : dw)
|
||||
actual.push_back(kw.name());
|
||||
|
||||
BOOST_CHECK( actual == expected );
|
||||
|
||||
const auto& radial_index = dw.index("RADIAL");
|
||||
BOOST_CHECK( radial_index.empty() );
|
||||
|
||||
auto dates_index = dw.index("DATES");
|
||||
std::vector<std::size_t> dates_expected = {14, 15, 16};
|
||||
BOOST_CHECK(dates_index == dates_expected);
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(dw.count("RADIAL"), 0);
|
||||
BOOST_CHECK_EQUAL(dw.count("VFPPROD"), 2);
|
||||
BOOST_CHECK_EQUAL(dw.count("SCHEDULE"), 1);
|
||||
|
||||
|
||||
bool have_grid0 = std::any_of(dw.begin(), dw.end(), [](const DeckKeyword& kw) {
|
||||
return kw.name() == "GRID";
|
||||
});
|
||||
BOOST_CHECK( have_grid0 );
|
||||
|
||||
bool have_grid1 = std::any_of(dw.begin() + 3, dw.end(), [](const DeckKeyword& kw) {
|
||||
return kw.name() == "GRID";
|
||||
});
|
||||
BOOST_CHECK( !have_grid1 );
|
||||
|
||||
auto is_vfpprod = [](const DeckKeyword& kw) { return kw.name() == "VFPPROD"; };
|
||||
auto iter = std::find_if(dw.begin(), dw.end(), is_vfpprod);
|
||||
BOOST_CHECK( iter != dw.end() );
|
||||
|
||||
auto iter2 = std::find_if(iter + 1, dw.end(), is_vfpprod);
|
||||
BOOST_CHECK( iter2 != dw.end() );
|
||||
|
||||
auto iter3 = std::find_if(iter2 + 1, dw.end(), is_vfpprod);
|
||||
BOOST_CHECK( iter3 == dw.end() );
|
||||
|
||||
auto count = std::count_if(dw.begin(), dw.end(), is_vfpprod);
|
||||
BOOST_CHECK_EQUAL(count, 2);
|
||||
}
|
||||
|
@ -854,8 +854,8 @@ BOOST_AUTO_TEST_CASE(WCONPROD_BHP_CMode)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BHP_CMODE)
|
||||
{
|
||||
BOOST_CHECK_THROW( WCONHIST::properties(WCONHIST::all_specified_CMODE_THP()) , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( WCONPROD::properties(WCONPROD::all_specified_CMODE_BHP()) , std::invalid_argument);
|
||||
BOOST_CHECK_THROW( WCONHIST::properties(WCONHIST::all_specified_CMODE_THP()) , std::exception);
|
||||
BOOST_CHECK_THROW( WCONPROD::properties(WCONPROD::all_specified_CMODE_BHP()) , std::exception);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user