Merge pull request #116 from jokva/exchange-completions-as-vector
data::Well::Completion is vector, not map
This commit is contained in:
@@ -81,6 +81,8 @@ namespace Opm {
|
||||
|
||||
struct Completion {
|
||||
using active_index = size_t;
|
||||
static const constexpr int restart_size = 2;
|
||||
|
||||
active_index index;
|
||||
Rates rates;
|
||||
double pressure;
|
||||
@@ -93,7 +95,7 @@ namespace Opm {
|
||||
double thp;
|
||||
double temperature;
|
||||
int control;
|
||||
std::map< Completion::active_index, Completion > completions;
|
||||
std::vector< Completion > completions;
|
||||
};
|
||||
|
||||
using Wells = std::map< std::string, Well >;
|
||||
|
||||
@@ -130,10 +130,12 @@ data::Wells restore_wells( const double* xwel_data,
|
||||
const std::vector< rt >& phases,
|
||||
const EclipseGrid& grid ) {
|
||||
|
||||
|
||||
const auto well_size = [&]( size_t acc, const Well* w ) {
|
||||
return acc
|
||||
+ 2 + phases.size()
|
||||
+ (w->getCompletions( restart_step ).size() * (phases.size() + 2));
|
||||
+ ( w->getCompletions( restart_step ).size()
|
||||
* (phases.size() + data::Completion::restart_size) );
|
||||
};
|
||||
|
||||
const auto expected_xwel_size = std::accumulate( sched_wells.begin(),
|
||||
@@ -165,17 +167,17 @@ data::Wells restore_wells( const double* xwel_data,
|
||||
for( auto phase : phases )
|
||||
well.rates.set( phase, *xwel_data++ );
|
||||
|
||||
const auto& completions = sched_well->getCompletions( restart_step );
|
||||
for( const auto& sc : completions ) {
|
||||
for( const auto& sc : sched_well->getCompletions( restart_step ) ) {
|
||||
const auto i = sc.getI(), j = sc.getJ(), k = sc.getK();
|
||||
if( !grid.cellActive( i, j, k ) ) {
|
||||
xwel_data += 2 + phases.size();
|
||||
if( !grid.cellActive( i, j, k ) || sc.getState() == WellCompletion::SHUT ) {
|
||||
xwel_data += data::Completion::restart_size + phases.size();
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto active_index = grid.activeIndex( i, j, k );
|
||||
|
||||
auto& completion = well.completions[ active_index ];
|
||||
well.completions.emplace_back();
|
||||
auto& completion = well.completions.back();
|
||||
completion.index = active_index;
|
||||
completion.pressure = *xwel_data++;
|
||||
completion.reservoir_rate = *xwel_data++;
|
||||
|
||||
@@ -593,8 +593,8 @@ std::vector< double > serialize_XWEL( const data::Wells& wells,
|
||||
for( const auto* sched_well : sched_wells ) {
|
||||
|
||||
if( wells.count( sched_well->name() ) == 0 ) {
|
||||
const auto elems =
|
||||
sched_well->getCompletions( report_step ).size() * (phases.size() + 2)
|
||||
const auto elems = (sched_well->getCompletions( report_step ).size()
|
||||
* (phases.size() + data::Completion::restart_size))
|
||||
+ 2 /* bhp, temperature */
|
||||
+ phases.size();
|
||||
|
||||
@@ -613,24 +613,29 @@ std::vector< double > serialize_XWEL( const data::Wells& wells,
|
||||
for( const auto& sc : sched_well->getCompletions( report_step ) ) {
|
||||
const auto i = sc.getI(), j = sc.getJ(), k = sc.getK();
|
||||
|
||||
if( !grid.cellActive( i, j, k ) ) {
|
||||
xwel.insert( xwel.end(), phases.size() + 2, 0.0 );
|
||||
const auto rs_size = phases.size() + data::Completion::restart_size;
|
||||
if( !grid.cellActive( i, j, k ) || sc.getState() == WellCompletion::SHUT ) {
|
||||
xwel.insert( xwel.end(), rs_size, 0.0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto active_index = grid.activeIndex( i, j, k );
|
||||
const auto at_index = [=]( const data::Completion& c ) {
|
||||
return c.index == active_index;
|
||||
};
|
||||
const auto& completion = std::find_if( well.completions.begin(),
|
||||
well.completions.end(),
|
||||
at_index );
|
||||
|
||||
if( well.completions.count( active_index ) == 0 ) {
|
||||
xwel.insert( xwel.end(), phases.size() + 2, 0.0 );
|
||||
if( completion == well.completions.end() ) {
|
||||
xwel.insert( xwel.end(), rs_size, 0.0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& completion = well.completions.at( active_index );
|
||||
|
||||
xwel.push_back( completion.pressure );
|
||||
xwel.push_back( completion.reservoir_rate );
|
||||
xwel.push_back( completion->pressure );
|
||||
xwel.push_back( completion->reservoir_rate );
|
||||
for( auto phase : phases )
|
||||
xwel.push_back( completion.rates.get( phase ) );
|
||||
xwel.push_back( completion->rates.get( phase ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -174,9 +174,15 @@ inline quantity crate( const fn_args& args ) {
|
||||
if( args.wells.count( name ) == 0 ) return zero;
|
||||
|
||||
const auto& well = args.wells.at( name );
|
||||
if( well.completions.count( index ) == 0 ) return zero;
|
||||
|
||||
const auto v = well.completions.at( index ).rates.get( phase, 0.0 );
|
||||
const auto& completion = std::find_if( well.completions.begin(),
|
||||
well.completions.end(),
|
||||
[=]( const data::Completion& c ) {
|
||||
return c.index == index;
|
||||
} );
|
||||
|
||||
if( completion == well.completions.end() ) return zero;
|
||||
const auto v = completion->rates.get( phase, 0.0 );
|
||||
if( ( v > 0 ) != injection ) return zero;
|
||||
|
||||
if( !injection ) return { -v, rate_unit< phase >() };
|
||||
|
||||
@@ -43,7 +43,7 @@ WELSPECS
|
||||
COMPDAT
|
||||
'OP_1' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 /
|
||||
'OP_2' 9 9 2 2 'OPEN' 1* 46.825 0.311 4332.346 1* 1* 'X' 22.123 /
|
||||
'OP_1' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 /
|
||||
'OP_1' 9 9 3 3 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 /
|
||||
/
|
||||
WCONPROD
|
||||
'OP_1' 'OPEN' 'ORAT' 20000 4* 1000 /
|
||||
|
||||
@@ -97,7 +97,7 @@ inline std::string input( const std::string& rst_name = "FIRST_SIM" ) {
|
||||
"COMPDAT\n"
|
||||
" 'OP_1' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_2' 9 9 2 2 'OPEN' 1* 46.825 0.311 4332.346 1* 1* 'X' 22.123 / \n"
|
||||
" 'OP_1' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_1' 9 9 3 3 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
"/\n"
|
||||
"WCONPROD\n"
|
||||
"'OP_1' 'OPEN' 'ORAT' 20000 4* 1000 /\n"
|
||||
@@ -113,7 +113,7 @@ inline std::string input( const std::string& rst_name = "FIRST_SIM" ) {
|
||||
" 'OP_3' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
||||
"/\n"
|
||||
"COMPDAT\n"
|
||||
" 'OP_3' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_3' 9 9 1 1 'SHUT' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
"/\n"
|
||||
"WCONPROD\n"
|
||||
"'OP_3' 'OPEN' 'ORAT' 20000 4* 1000 /\n"
|
||||
@@ -123,8 +123,8 @@ inline std::string input( const std::string& rst_name = "FIRST_SIM" ) {
|
||||
" 15 JUN 2013 / \n"
|
||||
"/\n"
|
||||
"COMPDAT\n"
|
||||
" 'OP_2' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_1' 9 9 7 7 'SHUT' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_2' 9 9 3 9 SHUT 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_1' 9 9 7 7 OPEN 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
"/\n"
|
||||
|
||||
"DATES -- 4\n"
|
||||
@@ -134,8 +134,8 @@ inline std::string input( const std::string& rst_name = "FIRST_SIM" ) {
|
||||
" 'OP_4' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
||||
"/\n"
|
||||
"COMPDAT\n"
|
||||
" 'OP_4' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_3' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_4' 9 9 3 9 'SHUT' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_3' 9 9 3 9 'SHUT' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
"/\n"
|
||||
"WCONPROD\n"
|
||||
"'OP_4' 'OPEN' 'ORAT' 20000 4* 1000 /\n"
|
||||
@@ -215,7 +215,7 @@ std::ostream& operator<<( std::ostream& stream,
|
||||
<< "\t" << "completions: [\n";
|
||||
|
||||
for( const auto& c : p.second.completions )
|
||||
stream << c.second << " ";
|
||||
stream << c << " ";
|
||||
|
||||
stream << "]\n";
|
||||
}
|
||||
@@ -247,6 +247,9 @@ bool operator==( const Completion& lhs, const Completion& rhs ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=( const Completion& lhs, const Completion& rhs ) {
|
||||
return !( lhs == rhs );
|
||||
}
|
||||
|
||||
bool operator==( const Well& lhs, const Well& rhs ) {
|
||||
BOOST_CHECK_EQUAL( lhs.rates, rhs.rates );
|
||||
@@ -254,8 +257,9 @@ bool operator==( const Well& lhs, const Well& rhs ) {
|
||||
BOOST_CHECK_EQUAL( lhs.temperature, rhs.temperature );
|
||||
BOOST_CHECK_EQUAL( lhs.control, rhs.control );
|
||||
|
||||
for( const auto& p : lhs.completions )
|
||||
BOOST_CHECK_EQUAL( p.second, rhs.completions.at( p.first ) );
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
lhs.completions.begin(), lhs.completions.end(),
|
||||
rhs.completions.begin(), rhs.completions.end() );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -317,14 +321,14 @@ data::Wells mkWells() {
|
||||
* the completion keys (active indices) and well names correspond to the
|
||||
* input deck. All other entries in the well structures are arbitrary.
|
||||
*/
|
||||
w1.completions[ 88 ] = { 88, rc1, 30.45 };
|
||||
w1.completions[ 288 ] = { 288, rc2, 33.19 };
|
||||
w1.completions.push_back( { 88, rc1, 30.45 } );
|
||||
w1.completions.push_back( { 288, rc2, 33.19 } );
|
||||
|
||||
w2.rates = r2;
|
||||
w2.bhp = 2.34;
|
||||
w2.temperature = 4.56;
|
||||
w2.control = 2;
|
||||
w2.completions[ 188 ] = { 188, rc3, 36.22 };
|
||||
w2.completions.push_back( { 188, rc3, 36.22 } );
|
||||
|
||||
return { { "OP_1", w1 },
|
||||
{ "OP_2", w2 } };
|
||||
|
||||
@@ -143,9 +143,9 @@ static data::Wells result_wells() {
|
||||
data::Completion comp2 { 1, crates2, 1.10 };
|
||||
data::Completion comp3 { 3, crates3, 1.11 };
|
||||
|
||||
data::Well well1 { rates1, 0.1 * ps, 0.2 * ps, 0.3 * ps, 1, { {1, comp1} } };
|
||||
data::Well well2 { rates2, 1.1 * ps, 1.2 * ps, 1.3 * ps, 2, { {1, comp2} } };
|
||||
data::Well well3 { rates3, 2.1 * ps, 2.2 * ps, 2.3 * ps, 3, { {3, comp3} } };
|
||||
data::Well well1 { rates1, 0.1 * ps, 0.2 * ps, 0.3 * ps, 1, { comp1 } };
|
||||
data::Well well2 { rates2, 1.1 * ps, 1.2 * ps, 1.3 * ps, 2, { comp2 } };
|
||||
data::Well well3 { rates3, 2.1 * ps, 2.2 * ps, 2.3 * ps, 3, { comp3 } };
|
||||
|
||||
return { { "W_1", well1 }, { "W_2", well2 }, { "W_3", well3 } };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user