Use only one double vector in DeckItem

This commit is contained in:
Joakim Hove
2019-09-24 11:59:39 +02:00
parent 25f8ec6641
commit 6c34aee00e
3 changed files with 33 additions and 16 deletions

View File

@@ -121,8 +121,12 @@ namespace Opm {
std::string item_name;
std::vector< bool > defaulted;
std::vector< Dimension > dimensions;
mutable std::vector< double > SIdata;
/*
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;
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

@@ -241,10 +241,26 @@ double DeckItem::getSIDouble( size_t index ) const {
return this->getSIDoubleData().at( index );
}
template<>
const std::vector<double>& DeckItem::getData() const {
auto& data = (const_cast<DeckItem*>(this))->value_ref< double >();
if (this->raw_data)
return data;
const auto dim_size = dimensions.size();
for( size_t index = 0; index < data.size(); index++ ) {
const auto dimIndex = index % dim_size;
data[ index ] = this->dimensions[ dimIndex ].convertSiToRaw( data[ index ] );
}
this->raw_data = true;
return data;
}
const std::vector< double >& DeckItem::getSIDoubleData() const {
const auto& raw = this->value_ref< double >();
// we already converted this item to SI?
if( !this->SIdata.empty() ) return this->SIdata;
auto& data = (const_cast<DeckItem*>(this))->value_ref< double >();
if (!this->raw_data)
return data;
if( this->dimensions.empty() )
throw std::invalid_argument("No dimension has been set for item'"
@@ -256,18 +272,17 @@ const std::vector< double >& DeckItem::getSIDoubleData() const {
* SI units, so externally the object still behaves as const
*/
const auto dim_size = dimensions.size();
const auto sz = raw.size();
this->SIdata.resize( sz );
for( size_t index = 0; index < sz; index++ ) {
for( size_t index = 0; index < data.size(); index++ ) {
const auto dimIndex = index % dim_size;
this->SIdata[ index ] = this->dimensions[ dimIndex ]
.convertRawToSi( raw[ index ] );
data[ index ] = this->dimensions[ dimIndex ].convertRawToSi( data[ index ] );
}
return this->SIdata;
this->raw_data = false;
return data;
}
void DeckItem::push_backDimension( const Dimension& active,
const Dimension& def ) {
if (this->type == type_tag::fdouble) {

View File

@@ -697,10 +697,8 @@ BOOST_AUTO_TEST_CASE( PORO_PERMX ) {
BOOST_CHECK_EQUAL( 0.251224369 , poro[1]);
BOOST_CHECK_EQUAL( 0.155628711 , poro[439]);
const std::vector<double>& permx = kw2.getSIDoubleData();
const std::vector<double>& permxRAW = kw2.getRawDoubleData();
const auto& permx = kw2.getSIDoubleData();
BOOST_CHECK_EQUAL( 1000U , permx.size() );
BOOST_CHECK_EQUAL( 1000U , permxRAW.size() );
BOOST_CHECK_CLOSE( Metric::Permeability * 1 , permx[0] , 0.001);
BOOST_CHECK_CLOSE( Metric::Permeability * 2 , permx[1] , 0.001);