Added operator<< suppport for Deckxxx
This commit is contained in:
parent
1f646711d4
commit
1050b8cba9
@ -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 >&& );
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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 ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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") );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user