Implement Solution via std::map

This commit is contained in:
Jørgen Kvalsvik
2016-10-06 16:31:41 +02:00
committed by Joakim Hove
parent 79e7ce643d
commit 8ac5dc553f
10 changed files with 106 additions and 188 deletions

View File

@@ -42,7 +42,6 @@ namespace data {
* Small struct that keeps track of data for output to restart/summary files.
*/
struct CellData {
std::string name; //< Name of the output field (will end up "verbatim" in output)
UnitSystem::measure dim; //< Dimension of the data to write
std::vector<double> data; //< The actual data itself
TargetType target;

View File

@@ -21,82 +21,47 @@
#define OPM_OUTPUT_DATA_SOLUTION_HPP
#include <string>
#include <vector>
#include <initializer_list>
#include <map>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/output/data/Cells.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
namespace Opm {
namespace data {
/*
The Solution class is a small class whose only purpose
is to transport cell data, i.e. pressure, saturations and
auxillary properties like fluid in place from the simulator to
output layer.
The container consist of instances of struct data::Cells.
*/
class Solution : public std::map< std::string, data::CellData > {
using Base = std::map< std::string, data::CellData >;
class Solution {
public:
/*
The initializer_list based constructor can be used as:
Solution cd = {{ "PRESSURE" , UnitSystem::measure::pressure , pressure_data , true},
{ "SWAT" , UnitSystem::measure::unity , swat_data , true}};
*/
Solution( std::initializer_list<data::CellData> init_list );
Solution( std::vector<data::CellData> init_list );
Solution() = default;
Solution( bool si );
using Base::map;
using Base::insert;
bool has( const std::string& ) const;
/*
Default constructor - create a valid empty container.
*/
Solution( ) = default;
* Get the data field of the struct matching the requested key. Will
* throw std::out_of_range if they key does not exist.
*/
std::vector< double >& data(const std::string& );
const std::vector< double >& data(const std::string& ) const;
size_t size() const;
bool has(const std::string& keyword) const;
std::pair< iterator, bool > insert( std::string name,
UnitSystem::measure,
std::vector< double >,
TargetType );
const data::CellData& get(const std::string& keyword) const;
data::CellData& get(const std::string& keyword);
void convertToSI( const UnitSystem& );
void convertFromSI( const UnitSystem& );
std::vector<double>& data(const std::string& keyword);
const std::vector<double>& data(const std::string& keyword) const;
/*
Construct a struct data::CellData instance based on the
input arguments and insert it in the container.
*/
void insert(const std::string& keyword, UnitSystem::measure dim, const std::vector<double>& data , TargetType target);
void insert(data::CellData cell_data);
/*
Will inplace convert all the data vectors back and forth
between SI and the unit system given units. The internal
member variable si will keep track of whether we are in SI
units or not.
*/
void convertToSI( const UnitSystem& units );
void convertFromSI( const UnitSystem& units );
/*
Iterate over the struct data::CellData instances in the container.
*/
std::vector<data::CellData>::const_iterator begin() const ;
std::vector<data::CellData>::const_iterator end() const;
/* hack to keep matlab/vtk output support */
const SimulationDataContainer* sdc = nullptr;
// Retained for compile-time compatibility with the vtk and matlab output targets.
const SimulationDataContainer * sdc = nullptr;
private:
bool si = true;
std::vector<data::CellData> storage;
};
};
}
}
#endif

View File

@@ -26,102 +26,51 @@
namespace Opm {
namespace data {
Solution::Solution( std::initializer_list<data::CellData> init_list )
: storage( init_list )
{ }
Solution::Solution( bool init_si ) : si( init_si ) {}
bool Solution::has(const std::string& keyword) const {
return this->count( keyword ) > 0;
}
Solution::Solution( std::vector<data::CellData> init_list )
: storage(std::move(init_list))
{ }
std::vector<double>& Solution::data(const std::string& keyword) {
return this->at( keyword ).data;
}
const std::vector<double>& Solution::data(const std::string& keyword) const {
return this->at( keyword ).data;
}
Solution::Solution( bool init_si )
: si( init_si )
{ }
std::pair< Solution::iterator, bool > Solution::insert( std::string name,
UnitSystem::measure m,
std::vector< double > xs,
TargetType type ) {
size_t Solution::size() const {
return this->storage.size();
return this->emplace( name, CellData{ m, std::move( xs ), type } );
}
void data::Solution::convertToSI( const UnitSystem& units ) {
if (this->si) return;
for( auto& elm : *this ) {
UnitSystem::measure dim = elm.second.dim;
if (dim != UnitSystem::measure::identity)
units.to_si( dim , elm.second.data );
}
this->si = true;
}
bool Solution::has(const std::string& keyword) const {
const auto iter = std::find_if( this->storage.begin() , this->storage.end() , [&keyword](const data::CellData& cd) { return cd.name == keyword; });
return (iter != this->storage.end());
void data::Solution::convertFromSI( const UnitSystem& units ) {
if (!this->si) return;
for (auto& elm : *this ) {
UnitSystem::measure dim = elm.second.dim;
if (dim != UnitSystem::measure::identity)
units.from_si( dim , elm.second.data );
}
void Solution::insert(const std::string& keyword, UnitSystem::measure dim, const std::vector<double>& data , TargetType target) {
data::CellData cd { keyword, dim , data , target };
this->insert( cd );
}
void Solution::insert(data::CellData cell_data) {
this->storage.push_back( std::move(cell_data) );
}
const data::CellData& Solution::get(const std::string& keyword) const {
const auto iter = std::find_if( this->storage.begin() , this->storage.end() , [&keyword](const data::CellData& cd) { return cd.name == keyword; });
if (iter == this->storage.end())
throw std::invalid_argument("No such keyword in container: " + keyword);
else
return *iter;
}
data::CellData& Solution::get(const std::string& keyword) {
auto iter = std::find_if( this->storage.begin() , this->storage.end() , [&keyword](const data::CellData& cd) { return cd.name == keyword; });
if (iter == this->storage.end())
throw std::invalid_argument("No such keyword in container: " + keyword);
else
return *iter;
}
std::vector<double>& Solution::data(const std::string& keyword) {
auto& elm = this->get( keyword );
return elm.data;
}
const std::vector<double>& Solution::data(const std::string& keyword) const {
const auto& elm = this->get( keyword );
return elm.data;
}
void data::Solution::convertToSI( const UnitSystem& units ) {
if (this->si)
return;
for (auto& elm : this->storage) {
UnitSystem::measure dim = elm.dim;
if (dim != UnitSystem::measure::identity)
units.to_si( dim , elm.data );
}
this->si = true;
}
void data::Solution::convertFromSI( const UnitSystem& units ) {
if (!this->si)
return;
for (auto& elm : this->storage) {
UnitSystem::measure dim = elm.dim;
if (dim != UnitSystem::measure::identity)
units.from_si( dim , elm.data );
}
this->si = false;
}
std::vector<data::CellData>::const_iterator Solution::begin() const {
return this->storage.begin();
}
std::vector<data::CellData>::const_iterator Solution::end() const {
return this->storage.end();
}
this->si = false;
}
}
}

View File

@@ -282,8 +282,8 @@ public:
template<typename T>
void addFromCells(const data::Solution& solution) {
for (const auto& elm: solution) {
if (elm.target == data::TargetType::RESTART_SOLUTION)
this->add( ERT::EclKW<T>(elm.name , elm.data ));
if (elm.second.target == data::TargetType::RESTART_SOLUTION)
this->add( ERT::EclKW<T>(elm.first, elm.second.data ));
}
}
@@ -345,9 +345,9 @@ void RFT::writeTimeStep( std::vector< const Well* > wells,
const data::Solution& cells) {
using rft = ERT::ert_unique_ptr< ecl_rft_node_type, ecl_rft_node_free >;
const std::vector<double>& pressure = cells.get("PRESSURE").data;
const std::vector<double>& swat = cells.get("SWAT").data;
const std::vector<double>& sgas = cells.get("SGAS").data;
const std::vector<double>& pressure = cells.data("PRESSURE");
const std::vector<double>& swat = cells.data("SWAT");
const std::vector<double>& sgas = cells.data("SGAS");
for( const auto& well : wells ) {
if( !( well->getRFTActive( report_step )
@@ -515,8 +515,8 @@ void EclipseWriter::Impl::writeINITFile( const data::Solution& simProps, const N
// Write properties which have been initialized by the simulator.
{
for (const auto& prop : simProps) {
auto ecl_data = grid.compressedVector( prop.data );
writeKeyword( fortio, prop.name, ecl_data );
auto ecl_data = grid.compressedVector( prop.second.data );
writeKeyword( fortio, prop.first, ecl_data );
}
}
@@ -721,9 +721,9 @@ void EclipseWriter::writeTimeStep(int report_step,
auto ecl_data = grid.compressedVector( prop.second.data );
if (write_float)
sol.add( ERT::EclKW<float>(prop.name , ecl_data));
sol.add( ERT::EclKW<float>(prop.first, ecl_data));
else
sol.add( ERT::EclKW<double>(prop.name , ecl_data));
sol.add( ERT::EclKW<double>(prop.first, ecl_data));
}
}
}

View File

@@ -283,7 +283,7 @@ quantity rpr(const fn_args& args) {
double RPR = 0;
const std::vector<double>& pressure = args.state.get( "PRESSURE" ).data;
const std::vector<double>& pressure = args.state.data( "PRESSURE" );
const auto& cells = pair->second;
for (auto cell_index : cells)

View File

@@ -112,11 +112,11 @@ namespace Opm {
using eclkw = ERT::ert_unique_ptr< ecl_kw_type, ecl_kw_free >;
for (const auto& elm : data) {
if (elm.target == data::TargetType::RESTART_SOLUTION) {
eclkw kw( ecl_kw_alloc( elm.name.c_str() , nactive, ECL_FLOAT_TYPE ) );
if (elm.second.target == data::TargetType::RESTART_SOLUTION) {
eclkw kw( ecl_kw_alloc( elm.first.c_str() , nactive, ECL_FLOAT_TYPE ) );
for( int i = 0; i < nactive; i++ )
ecl_kw_iset_float( kw.get(), i, elm.data[ i ] );
ecl_kw_iset_float( kw.get(), i, elm.second.data[ i ] );
ecl_rst_file_add_kw( rst_file, kw.get() );
}

View File

@@ -176,7 +176,7 @@ void checkInitFile( const Deck& deck, const data::Solution& simProps) {
BOOST_CHECK( ecl_file_has_kw( initFile.get() , "SATNUM" ));
for (const auto& prop : simProps) {
BOOST_CHECK( ecl_file_has_kw( initFile.get() , prop.name.c_str()) );
BOOST_CHECK( ecl_file_has_kw( initFile.get() , prop.first.c_str()) );
}
}
@@ -279,14 +279,16 @@ BOOST_AUTO_TEST_CASE(EclipseWriterIntegration) {
EclipseWriter eclWriter( es, eclGrid );
using measure = UnitSystem::measure;
using TargetType = data::TargetType;
auto start_time = ecl_util_make_date( 10, 10, 2008 );
std::vector<double> tranx(3*3*3);
std::vector<double> trany(3*3*3);
std::vector<double> tranz(3*3*3);
data::Solution eGridProps{
{"TRANX" , UnitSystem::measure::transmissibility, tranx, data::TargetType::INIT},
{"TRANY" , UnitSystem::measure::transmissibility, trany, data::TargetType::INIT},
{"TRANZ" , UnitSystem::measure::transmissibility, tranz, data::TargetType::INIT}
data::Solution eGridProps {
{ "TRANX", { measure::transmissibility, tranx, TargetType::INIT } },
{ "TRANY", { measure::transmissibility, trany, TargetType::INIT } },
{ "TRANZ", { measure::transmissibility, tranz, TargetType::INIT } },
};
@@ -297,8 +299,8 @@ BOOST_AUTO_TEST_CASE(EclipseWriterIntegration) {
for( int i = first; i < last; ++i ) {
data::Solution sol = createBlackoilState( i, 3 * 3 * 3 );
sol.insert({"KRO" , UnitSystem::measure::identity , std::vector<double>(3*3*3 , i), data::TargetType::RESTART_AUXILLARY});
sol.insert({"KRG" , UnitSystem::measure::identity , std::vector<double>(3*3*3 , i*10), data::TargetType::RESTART_AUXILLARY});
sol.insert("KRO", measure::identity , std::vector<double>(3*3*3 , i), TargetType::RESTART_AUXILLARY);
sol.insert("KRG", measure::identity , std::vector<double>(3*3*3 , i*10), TargetType::RESTART_AUXILLARY);
auto first_step = ecl_util_make_date( 10 + i, 11, 2008 );

View File

@@ -197,10 +197,16 @@ data::Wells mkWells() {
}
data::Solution mkSolution( int numCells ) {
data::Solution sol = {{"PRESSURE" , UnitSystem::measure::pressure , std::vector<double>( numCells ) , data::TargetType::RESTART_SOLUTION},
{"TEMP" , UnitSystem::measure::temperature , std::vector<double>( numCells ) , data::TargetType::RESTART_SOLUTION},
{"SWAT" , UnitSystem::measure::identity , std::vector<double>( numCells ) , data::TargetType::RESTART_SOLUTION},
{"SGAS" , UnitSystem::measure::identity , std::vector<double>( numCells ) , data::TargetType::RESTART_SOLUTION}};
using measure = UnitSystem::measure;
using namespace data;
data::Solution sol = {
{ "PRESSURE", { measure::pressure, std::vector<double>( numCells ), TargetType::RESTART_SOLUTION } },
{ "TEMP", { measure::temperature, std::vector<double>( numCells ), TargetType::RESTART_SOLUTION } },
{ "SWAT", { measure::identity, std::vector<double>( numCells ), TargetType::RESTART_SOLUTION } },
{ "SGAS", { measure::identity, std::vector<double>( numCells ), TargetType::RESTART_SOLUTION } }
};
sol.data("PRESSURE").assign( numCells, 6.0 );
@@ -211,8 +217,8 @@ data::Solution mkSolution( int numCells ) {
fun::iota rsi( 300, 300 + numCells );
fun::iota rvi( 400, 400 + numCells );
sol.insert( "RS", UnitSystem::measure::identity, { rsi.begin(), rsi.end() } , data::TargetType::RESTART_SOLUTION );
sol.insert( "RV", UnitSystem::measure::identity, { rvi.begin(), rvi.end() } , data::TargetType::RESTART_SOLUTION );
sol.insert( "RS", measure::identity, { rsi.begin(), rsi.end() } , TargetType::RESTART_SOLUTION );
sol.insert( "RV", measure::identity, { rvi.begin(), rvi.end() } , TargetType::RESTART_SOLUTION );
return sol;
}

View File

@@ -45,10 +45,9 @@ BOOST_AUTO_TEST_CASE(Create)
BOOST_CHECK_EQUAL( c.size() , 1U );
BOOST_CHECK_EQUAL( c.has("NAME") , true);
const auto& prop = c.get( "NAME" );
BOOST_CHECK_EQUAL( prop.name , "NAME");
BOOST_CHECK_EQUAL( c.find("NAME")->first, "NAME");
BOOST_CHECK_THROW( c.get("NO_NOT_THIS") , std::invalid_argument );
BOOST_CHECK_THROW( c.at("NotLikeThis") , std::out_of_range );
c.insert( "NAME2" , UnitSystem::measure::identity, data , data::TargetType::RESTART_SOLUTION );
@@ -60,7 +59,7 @@ BOOST_AUTO_TEST_CASE(Create)
for (const auto& prop : c)
actual.push_back( prop.name );
actual.push_back( prop.first );
BOOST_CHECK_EQUAL_COLLECTIONS( expected.begin() , expected.end() , actual.begin() , actual.end() );
}
@@ -71,18 +70,15 @@ BOOST_AUTO_TEST_CASE(Create2)
{
std::vector<double> data(100);
data::Solution c = {{"TRANX" , UnitSystem::measure::transmissibility, data, data::TargetType::RESTART_SOLUTION},
{"TRANY" , UnitSystem::measure::transmissibility, data, data::TargetType::RESTART_SOLUTION},
{"TRANZ" , UnitSystem::measure::transmissibility, data, data::TargetType::RESTART_SOLUTION}};
data::Solution c = {
{ "TRANX", { UnitSystem::measure::transmissibility, data, data::TargetType::RESTART_SOLUTION } },
{ "TRANY", { UnitSystem::measure::transmissibility, data, data::TargetType::RESTART_SOLUTION } },
{ "TRANZ", { UnitSystem::measure::transmissibility, data, data::TargetType::RESTART_SOLUTION } }
};
std::vector<data::CellData> vec;
for (const auto& elm : c)
vec.push_back( elm );
data::Solution c2(vec);
auto c2 = c;
BOOST_CHECK_EQUAL( c2.size() , 3U );
BOOST_CHECK( c2.has("TRANX"));
BOOST_CHECK( c2.has("TRANX") );
}

View File

@@ -58,9 +58,10 @@ static const int day = 24 * 60 * 60;
static data::Solution make_solution( const EclipseGrid& grid ) {
int numCells = grid.getCartesianSize();
data::Solution sol = {{"TEMP" , UnitSystem::measure::temperature , std::vector<double>( numCells ) , data::TargetType::RESTART_SOLUTION},
{"SWAT" , UnitSystem::measure::identity , std::vector<double>( numCells ) , data::TargetType::RESTART_SOLUTION},
{"SGAS" , UnitSystem::measure::identity , std::vector<double>( numCells ) , data::TargetType::RESTART_SOLUTION}};
data::Solution sol = {
{"TEMP" , { UnitSystem::measure::temperature, std::vector<double>( numCells ), data::TargetType::RESTART_SOLUTION} },
{"SWAT" , { UnitSystem::measure::identity, std::vector<double>( numCells ), data::TargetType::RESTART_SOLUTION} },
{"SGAS" , { UnitSystem::measure::identity, std::vector<double>( numCells ), data::TargetType::RESTART_SOLUTION} }};
sol.data("TEMP").assign( numCells, 7.0 );