Implement Solution via std::map
This commit is contained in:
committed by
Joakim Hove
parent
79e7ce643d
commit
8ac5dc553f
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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() );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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") );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user