Added operator<< suppport for Deckxxx

This commit is contained in:
Joakim Hove 2017-08-30 16:25:06 +02:00
parent 1f646711d4
commit 1050b8cba9
12 changed files with 274 additions and 16 deletions

View File

@ -22,6 +22,7 @@
#include <map>
#include <memory>
#include <ostream>
#include <vector>
#include <string>
@ -54,6 +55,7 @@ namespace Opm {
* alive as long as DeckItem (and friends) are needed, to avoid
* use-after-free.
*/
class DeckOutput;
class DeckView {
public:
@ -91,6 +93,7 @@ namespace Opm {
const_iterator begin() const;
const_iterator end() const;
protected:
void add( const DeckKeyword*, const_iterator, const_iterator );
@ -140,7 +143,8 @@ namespace Opm {
iterator begin();
iterator end();
void write( DeckOutput& output ) const ;
friend std::ostream& operator<<(std::ostream& os, const Deck& deck);
private:
Deck( std::vector< DeckKeyword >&& );

View File

@ -23,11 +23,13 @@
#include <string>
#include <vector>
#include <memory>
#include <ostream>
#include <opm/parser/eclipse/Units/Dimension.hpp>
#include <opm/parser/eclipse/Utility/Typetools.hpp>
namespace Opm {
class DeckOutput;
class DeckItem {
public:
@ -54,6 +56,7 @@ namespace Opm {
// creates the defaulted items if all their sizes are fully specified by the
// keyword, though...
size_t size() const;
size_t out_size() const;
template< typename T > const T& get( size_t ) const;
double getSIDouble( size_t ) const;
@ -79,6 +82,10 @@ namespace Opm {
type_tag getType() const;
void write(DeckOutput& writer) const;
friend std::ostream& operator<<(std::ostream& os, const DeckItem& item);
/*
The comparison can be adjusted with the cmp_default and
cmp_numeric flags. If cmp_default is set to true the
@ -98,6 +105,7 @@ namespace Opm {
*/
bool operator==(const DeckItem& other) const;
bool operator!=(const DeckItem& other) const;
private:
std::vector< double > dval;
std::vector< int > ival;
@ -115,6 +123,7 @@ namespace Opm {
template< typename T > void push( T );
template< typename T > void push( T, size_t );
template< typename T > void push_default( T );
template< typename T > void write_vector(DeckOutput& writer, const std::vector<T>& data) const;
};
}
#endif /* DECKITEM_HPP */

View File

@ -28,6 +28,7 @@
namespace Opm {
class ParserKeyword;
class DeckOutput;
class DeckKeyword {
public:
@ -37,6 +38,7 @@ namespace Opm {
DeckKeyword(const std::string& keywordName, bool knownKeyword);
const std::string& name() const;
void setFixedSize();
void setLocation(const std::string& fileName, int lineNumber);
const std::string& getFileName() const;
int getLineNumber() const;
@ -55,6 +57,9 @@ namespace Opm {
const std::vector<double>& getSIDoubleData() const;
const std::vector<std::string>& getStringData() const;
size_t getDataSize() const;
void write( DeckOutput& output ) const;
void write_data( DeckOutput& output ) const;
void write_TITLE( DeckOutput& output ) const;
template <class Keyword>
bool isKeyword() const {
@ -71,6 +76,7 @@ namespace Opm {
bool operator==(const DeckKeyword& other) const;
bool operator!=(const DeckKeyword& other) const;
friend std::ostream& operator<<(std::ostream& os, const DeckKeyword& keyword);
private:
std::string m_keywordName;
std::string m_fileName;
@ -79,6 +85,7 @@ namespace Opm {
std::vector< DeckRecord > m_recordList;
bool m_knownKeyword;
bool m_isDataKeyword;
bool m_slashTerminated;
};
}

View File

@ -23,6 +23,7 @@
#include <string>
#include <vector>
#include <memory>
#include <ostream>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
@ -61,6 +62,10 @@ namespace Opm {
const_iterator begin() const;
const_iterator end() const;
void write(DeckOutput& writer) const;
void write_data(DeckOutput& writer) const;
friend std::ostream& operator<<(std::ostream& os, const DeckRecord& record);
bool equal(const DeckRecord& other, bool cmp_default, bool cmp_numeric) const;
bool operator==(const DeckRecord& other) const;
bool operator!=(const DeckRecord& other) const;

View File

@ -21,6 +21,7 @@
#include <vector>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckOutput.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/Section.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
@ -205,4 +206,20 @@ namespace Opm {
return this->keywordList.end();
}
void Deck::write( DeckOutput& output ) const {
size_t kw_index = 1;
for (const auto& keyword: *this) {
keyword.write( output );
kw_index++;
if (kw_index < size())
output.write_string( output.keyword_sep );
}
}
std::ostream& operator<<(std::ostream& os, const Deck& deck) {
DeckOutput out( os );
deck.write( out );
return os;
}
}

View File

@ -15,13 +15,15 @@
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include <opm/parser/eclipse/Deck/DeckOutput.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Units/Dimension.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <stdexcept>
namespace Opm {
@ -109,6 +111,11 @@ size_t DeckItem::size() const {
}
}
size_t DeckItem::out_size() const {
size_t data_size = this->size();
return std::max( data_size , this->defaulted.size() );
}
template< typename T >
const T& DeckItem::get( size_t index ) const {
return this->value_ref< T >().at( index );
@ -240,6 +247,41 @@ type_tag DeckItem::getType() const {
return this->type;
}
template< typename T >
void DeckItem::write_vector(DeckOutput& stream, const std::vector<T>& data) const {
for (size_t index = 0; index < this->out_size(); index++) {
if (this->defaultApplied(index))
stream.stash_default( );
else
stream.write( data[index] );
}
}
void DeckItem::write(DeckOutput& stream) const {
switch( this->type ) {
case type_tag::integer:
this->write_vector( stream, this->ival );
break;
case type_tag::fdouble:
this->write_vector( stream, this->dval );
break;
case type_tag::string:
this->write_vector( stream, this->sval );
break;
default:
throw std::logic_error( "Type not set." );
}
}
std::ostream& operator<<(std::ostream& os, const DeckItem& item) {
DeckOutput stream(os);
item.write( stream );
return os;
}
namespace {
bool double_equal(double value1, double value2, double abs_eps , double rel_eps) {
@ -312,6 +354,9 @@ bool DeckItem::operator==(const DeckItem& other) const {
bool DeckItem::operator!=(const DeckItem& other) const {
return !(*this == other);
}
/*
* Explicit template instantiations. These must be manually maintained and
* updated with changes in DeckItem so that code is emitted.
@ -324,5 +369,4 @@ template const std::string& DeckItem::get< std::string >( size_t ) const;
template const std::vector< int >& DeckItem::getData< int >() const;
template const std::vector< double >& DeckItem::getData< double >() const;
template const std::vector< std::string >& DeckItem::getData< std::string >() const;
}

View File

@ -17,6 +17,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <opm/parser/eclipse/Deck/DeckOutput.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
@ -24,17 +25,28 @@
namespace Opm {
DeckKeyword::DeckKeyword(const std::string& keywordName) :
m_keywordName(keywordName), m_lineNumber(-1),
m_knownKeyword(true), m_isDataKeyword(false)
m_keywordName(keywordName),
m_lineNumber(-1),
m_knownKeyword(true),
m_isDataKeyword(false),
m_slashTerminated(true)
{
}
DeckKeyword::DeckKeyword(const std::string& keywordName, bool knownKeyword) :
m_keywordName(keywordName), m_lineNumber(-1),
m_knownKeyword(knownKeyword), m_isDataKeyword(false)
m_keywordName(keywordName),
m_lineNumber(-1),
m_knownKeyword(knownKeyword),
m_isDataKeyword(false),
m_slashTerminated(true)
{
}
void DeckKeyword::setFixedSize() {
m_slashTerminated = false;
}
void DeckKeyword::setLocation(const std::string& fileName, int lineNumber) {
m_fileName = fileName;
m_lineNumber = lineNumber;
@ -120,6 +132,36 @@ namespace Opm {
return this->getDataRecord().getDataItem().getSIDoubleData();
}
void DeckKeyword::write_data( DeckOutput& output ) const {
for (const auto& record: *this)
record.write( output );
}
void DeckKeyword::write_TITLE( DeckOutput& output ) const {
output.start_keyword( this->name( ) );
{
const auto& record = this->getRecord(0);
output.write_string(" ");
record.write_data( output );
}
}
void DeckKeyword::write( DeckOutput& output ) const {
if (this->name() == "TITLE")
this->write_TITLE( output );
else {
output.start_keyword( this->name( ) );
this->write_data( output );
output.end_keyword( this->m_slashTerminated );
}
}
std::ostream& operator<<(std::ostream& os, const DeckKeyword& keyword) {
DeckOutput out( os );
keyword.write( out );
return os;
}
bool DeckKeyword::equal_data(const DeckKeyword& other, bool cmp_default, bool cmp_numeric) const {
if (this->size() != other.size())
return false;

View File

@ -23,6 +23,7 @@
#include <string>
#include <algorithm>
#include <opm/parser/eclipse/Deck/DeckOutput.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
@ -130,6 +131,25 @@ namespace Opm {
return this->m_items.end();
}
void DeckRecord::write_data(DeckOutput& writer) const {
for (const auto& item : *this)
item.write( writer );
}
void DeckRecord::write(DeckOutput& writer) const {
writer.start_record( );
this->write_data( writer );
writer.end_record( );
}
std::ostream& operator<<(std::ostream& os, const DeckRecord& record) {
DeckOutput output(os);
record.write( output );
return os;
}
bool DeckRecord::equal(const DeckRecord& other, bool cmp_default, bool cmp_numeric) const {
if (this->size() != other.size())
return false;

View File

@ -490,6 +490,17 @@ void set_dimensions( ParserItem& item,
record_nr++;
}
if (this->hasFixedSize( ))
keyword.setFixedSize( );
if (this->m_keywordSizeType == OTHER_KEYWORD_IN_DECK) {
if (!m_isTableCollection)
keyword.setFixedSize( );
}
if (this->m_keywordSizeType == UNKNOWN)
keyword.setFixedSize( );
return keyword;
}

View File

@ -561,6 +561,31 @@ BOOST_AUTO_TEST_CASE(setUnknown_wasknown_nowunknown) {
DeckKeyword deckKeyword( "KW", false );
BOOST_CHECK(!deckKeyword.isKnown());
}
BOOST_AUTO_TEST_CASE(DeckItemWrite) {
DeckItem item("TEST", int());
std::stringstream s;
DeckOutput w(s);
item.push_back(1);
item.push_back(2);
item.push_back(3);
item.write(w);
{
int v1,v2,v3;
s >> v1;
s >> v2;
s >> v3;
BOOST_CHECK_EQUAL( v1 , 1 );
BOOST_CHECK_EQUAL( v2 , 2 );
BOOST_CHECK_EQUAL( v3 , 3 );
}
}
BOOST_AUTO_TEST_CASE(DeckOutputTest) {
std::string expected = "KEYWORD\n\
==1-2\n\
@ -597,6 +622,61 @@ ABC";
BOOST_CHECK_EQUAL( expected, s.str());
}
BOOST_AUTO_TEST_CASE(DeckItemWriteDefault) {
DeckItem item("TEST", int());
item.push_backDefault(1);
item.push_backDefault(1);
item.push_backDefault(1);
{
std::stringstream s;
DeckOutput w(s);
item.write( w );
BOOST_CHECK_EQUAL( s.str() , "");
}
item.push_back(13);
{
std::stringstream s;
DeckOutput w(s);
item.write( w );
BOOST_CHECK_EQUAL( s.str() , "3* 13");
}
}
BOOST_AUTO_TEST_CASE(DeckItemWriteString) {
DeckItem item("TEST", std::string());
item.push_back("NO");
item.push_back("YES");
std::stringstream s;
DeckOutput w(s);
item.write( w );
BOOST_CHECK_EQUAL( s.str() , "'NO' 'YES'");
}
BOOST_AUTO_TEST_CASE(RecordWrite) {
DeckRecord deckRecord;
DeckItem item1("TEST1", int());
DeckItem item2("TEST2", double());
DeckItem item3("TEST3", std::string());
item1.push_back( 123 );
item2.push_backDefault( 100.0 );
item3.push_back("VALUE");
deckRecord.addItem( item1 );
deckRecord.addItem( item2 );
deckRecord.addItem( item3 );
std::stringstream s;
DeckOutput w(s);
deckRecord.write_data( w );
BOOST_CHECK_EQUAL( s.str() , "123 1* 'VALUE'");
}
BOOST_AUTO_TEST_CASE(DeckItemEqual) {
DeckItem item1("TEST1" , int());

View File

@ -226,6 +226,11 @@ PERMR
2100*100.0D0
/
PERMXY
2100*100.0D0
/
PORO
2100*0.3D0
/
@ -455,6 +460,14 @@ BOOST_AUTO_TEST_CASE(RadialPermeabilityTensor) {
BOOST_CHECK_CLOSE(permtht.iget(49, 10, 9), permr.iget(49, 10, 9), check_tol);
BOOST_CHECK_CLOSE(permz.iget(49, 10, 9), 0.1 * permr.iget(49, 10, 9), check_tol);
BOOST_CHECK_CLOSE(0.3, poro.iget(49, 10, 9), check_tol);
{
const auto& d1 = s.deck.getKeyword("PERMR");
const auto& d2 = s.deck.getKeyword("PERMXY");
BOOST_CHECK( !d1.equal( d2 ));
BOOST_CHECK( d1.equal_data( d2 ));
}
}

View File

@ -48,16 +48,22 @@ inline std::string pathprefix() {
BOOST_AUTO_TEST_CASE(CreateSchedule) {
ParseContext parseContext;
Parser parser;
std::string scheduleFile(pathprefix() + "SCHEDULE/SCHEDULE1");
auto deck = parser.parseFile(scheduleFile, parseContext);
EclipseGrid grid(10,10,10);
TableManager table ( deck );
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Schedule sched(parseContext , grid , eclipseProperties, deck, Phases(true, true, true) );
const auto& timeMap = sched.getTimeMap();
BOOST_CHECK_EQUAL(TimeMap::mkdate(2007 , 5 , 10), sched.getStartTime());
BOOST_CHECK_EQUAL(9U, timeMap.size());
BOOST_CHECK( deck.hasKeyword("NETBALAN") );
std::string scheduleFile(pathprefix() + "SCHEDULE/SCHEDULE1");
auto deck1 = parser.parseFile(scheduleFile, parseContext);
std::stringstream ss;
ss << deck1;
auto deck2 = parser.parseString( ss.str(), parseContext );
for (const auto& deck : {deck1 , deck2}) {
TableManager table ( deck );
Eclipse3DProperties eclipseProperties ( deck , table, grid);
Schedule sched(parseContext , grid , eclipseProperties, deck, Phases(true, true, true) );
const auto& timeMap = sched.getTimeMap();
BOOST_CHECK_EQUAL(TimeMap::mkdate(2007 , 5 , 10), sched.getStartTime());
BOOST_CHECK_EQUAL(9U, timeMap.size());
BOOST_CHECK( deck.hasKeyword("NETBALAN") );
}
}