Polymer output

Change polymer production output from volume -> mass
Polymer injection rates are read from the simulator and not computed based on the water rate and the polymer injection concentration given in the schedule
This commit is contained in:
Tor Harald Sandve 2020-06-25 10:57:11 +02:00
parent 27e6e0735f
commit 13f07fdfef
4 changed files with 73 additions and 51 deletions

View File

@ -265,7 +265,6 @@ using rt = Opm::data::Rates::opt;
using measure = Opm::UnitSystem::measure; using measure = Opm::UnitSystem::measure;
constexpr const bool injector = true; constexpr const bool injector = true;
constexpr const bool producer = false; constexpr const bool producer = false;
constexpr const bool polymer = true;
/* Some numerical value with its unit tag embedded to enable caller to apply /* Some numerical value with its unit tag embedded to enable caller to apply
* unit conversion. This removes a lot of boilerplate. ad-hoc solution to poor * unit conversion. This removes a lot of boilerplate. ad-hoc solution to poor
@ -436,7 +435,7 @@ double efac( const std::vector<std::pair<std::string,double>>& eff_factors, cons
return (it != eff_factors.end()) ? it->second : 1; return (it != eff_factors.end()) ? it->second : 1;
} }
template< rt phase, bool injection = true, bool polymer = false > template< rt phase, bool injection = true >
inline quantity rate( const fn_args& args ) { inline quantity rate( const fn_args& args ) {
double sum = 0.0; double sum = 0.0;
@ -446,11 +445,7 @@ inline quantity rate( const fn_args& args ) {
double eff_fac = efac( args.eff_factors, name ); double eff_fac = efac( args.eff_factors, name );
double concentration = polymer const auto v = args.wells.at(name).rates.get(phase, 0.0) * eff_fac;
? sched_well.getPolymerProperties().m_polymerConcentration
: 1;
const auto v = args.wells.at(name).rates.get(phase, 0.0) * eff_fac * concentration;
if( ( v > 0 ) == injection ) if( ( v > 0 ) == injection )
sum += v; sum += v;
@ -458,7 +453,7 @@ inline quantity rate( const fn_args& args ) {
if( !injection ) sum *= -1; if( !injection ) sum *= -1;
if( polymer ) return { sum, measure::mass_rate }; if (phase == rt::polymer) return { sum, measure::mass_rate };
return { sum, rate_unit< phase >() }; return { sum, rate_unit< phase >() };
} }
@ -478,7 +473,7 @@ inline quantity flowing( const fn_args& args ) {
measure::identity }; measure::identity };
} }
template< rt phase, bool injection = true, bool polymer = false > template< rt phase, bool injection = true>
inline quantity crate( const fn_args& args ) { inline quantity crate( const fn_args& args ) {
const quantity zero = { 0, rate_unit< phase >() }; const quantity zero = { 0, rate_unit< phase >() };
// The args.num value is the literal value which will go to the // The args.num value is the literal value which will go to the
@ -502,19 +497,15 @@ inline quantity crate( const fn_args& args ) {
if( completion == well_data.connections.end() ) return zero; if( completion == well_data.connections.end() ) return zero;
double eff_fac = efac( args.eff_factors, name ); double eff_fac = efac( args.eff_factors, name );
double concentration = polymer auto v = completion->rates.get( phase, 0.0 ) * eff_fac;
? well.getPolymerProperties().m_polymerConcentration
: 1;
auto v = completion->rates.get( phase, 0.0 ) * eff_fac * concentration;
if( ( v > 0 ) != injection ) return zero; if( ( v > 0 ) != injection ) return zero;
if( !injection ) v *= -1; if( !injection ) v *= -1;
if( polymer ) return { v, measure::mass_rate }; if( phase == rt::polymer ) return { v, measure::mass_rate };
return { v, rate_unit< phase >() }; return { v, rate_unit< phase >() };
} }
template< rt phase, bool polymer = false > template< rt phase>
inline quantity srate( const fn_args& args ) { inline quantity srate( const fn_args& args ) {
const quantity zero = { 0, rate_unit< phase >() }; const quantity zero = { 0, rate_unit< phase >() };
// The args.num value is the literal value which will go to the // The args.num value is the literal value which will go to the
@ -535,15 +526,11 @@ inline quantity srate( const fn_args& args ) {
if( segment == well_data.segments.end() ) return zero; if( segment == well_data.segments.end() ) return zero;
double eff_fac = efac( args.eff_factors, name ); double eff_fac = efac( args.eff_factors, name );
double concentration = polymer auto v = segment->second.rates.get( phase, 0.0 ) * eff_fac;
? well.getPolymerProperties().m_polymerConcentration
: 1;
auto v = segment->second.rates.get( phase, 0.0 ) * eff_fac * concentration;
//switch sign of rate - opposite convention in flow vs eclipse //switch sign of rate - opposite convention in flow vs eclipse
v *= -1; v *= -1;
if( polymer ) return { v, measure::mass_rate }; if( phase == rt::polymer ) return { v, measure::mass_rate };
return { v, rate_unit< phase >() }; return { v, rate_unit< phase >() };
} }
@ -891,7 +878,7 @@ static const std::unordered_map< std::string, ofun > funs = {
{ "WOIR", rate< rt::oil, injector > }, { "WOIR", rate< rt::oil, injector > },
{ "WGIR", rate< rt::gas, injector > }, { "WGIR", rate< rt::gas, injector > },
{ "WNIR", rate< rt::solvent, injector > }, { "WNIR", rate< rt::solvent, injector > },
{ "WCIR", rate< rt::wat, injector, polymer > }, { "WCIR", rate< rt::polymer, injector > },
{ "WVIR", sum( sum( rate< rt::reservoir_water, injector >, rate< rt::reservoir_oil, injector > ), { "WVIR", sum( sum( rate< rt::reservoir_water, injector >, rate< rt::reservoir_oil, injector > ),
rate< rt::reservoir_gas, injector > ) }, rate< rt::reservoir_gas, injector > ) },
@ -899,7 +886,7 @@ static const std::unordered_map< std::string, ofun > funs = {
{ "WOIT", mul( rate< rt::oil, injector >, duration ) }, { "WOIT", mul( rate< rt::oil, injector >, duration ) },
{ "WGIT", mul( rate< rt::gas, injector >, duration ) }, { "WGIT", mul( rate< rt::gas, injector >, duration ) },
{ "WNIT", mul( rate< rt::solvent, injector >, duration ) }, { "WNIT", mul( rate< rt::solvent, injector >, duration ) },
{ "WCIT", mul( rate< rt::wat, injector, polymer >, duration ) }, { "WCIT", mul( rate< rt::polymer, injector >, duration ) },
{ "WVIT", mul( sum( sum( rate< rt::reservoir_water, injector >, rate< rt::reservoir_oil, injector > ), { "WVIT", mul( sum( sum( rate< rt::reservoir_water, injector >, rate< rt::reservoir_oil, injector > ),
rate< rt::reservoir_gas, injector > ), duration ) }, rate< rt::reservoir_gas, injector > ), duration ) },
@ -957,14 +944,14 @@ static const std::unordered_map< std::string, ofun > funs = {
{ "GOIR", rate< rt::oil, injector > }, { "GOIR", rate< rt::oil, injector > },
{ "GGIR", rate< rt::gas, injector > }, { "GGIR", rate< rt::gas, injector > },
{ "GNIR", rate< rt::solvent, injector > }, { "GNIR", rate< rt::solvent, injector > },
{ "GCIR", rate< rt::wat, injector, polymer > }, { "GCIR", rate< rt::polymer, injector > },
{ "GVIR", sum( sum( rate< rt::reservoir_water, injector >, rate< rt::reservoir_oil, injector > ), { "GVIR", sum( sum( rate< rt::reservoir_water, injector >, rate< rt::reservoir_oil, injector > ),
rate< rt::reservoir_gas, injector > ) }, rate< rt::reservoir_gas, injector > ) },
{ "GWIT", mul( rate< rt::wat, injector >, duration ) }, { "GWIT", mul( rate< rt::wat, injector >, duration ) },
{ "GOIT", mul( rate< rt::oil, injector >, duration ) }, { "GOIT", mul( rate< rt::oil, injector >, duration ) },
{ "GGIT", mul( rate< rt::gas, injector >, duration ) }, { "GGIT", mul( rate< rt::gas, injector >, duration ) },
{ "GNIT", mul( rate< rt::solvent, injector >, duration ) }, { "GNIT", mul( rate< rt::solvent, injector >, duration ) },
{ "GCIT", mul( rate< rt::wat, injector, polymer >, duration ) }, { "GCIT", mul( rate< rt::polymer, injector >, duration ) },
{ "GVIT", mul( sum( sum( rate< rt::reservoir_water, injector >, rate< rt::reservoir_oil, injector > ), { "GVIT", mul( sum( sum( rate< rt::reservoir_water, injector >, rate< rt::reservoir_oil, injector > ),
rate< rt::reservoir_gas, injector > ), duration ) }, rate< rt::reservoir_gas, injector > ), duration ) },
@ -1083,7 +1070,7 @@ static const std::unordered_map< std::string, ofun > funs = {
{ "CWIR", crate< rt::wat, injector > }, { "CWIR", crate< rt::wat, injector > },
{ "CGIR", crate< rt::gas, injector > }, { "CGIR", crate< rt::gas, injector > },
{ "CCIR", crate< rt::wat, injector, polymer > }, { "CCIR", crate< rt::polymer, injector > },
{ "CWIT", mul( crate< rt::wat, injector >, duration ) }, { "CWIT", mul( crate< rt::wat, injector >, duration ) },
{ "CGIT", mul( crate< rt::gas, injector >, duration ) }, { "CGIT", mul( crate< rt::gas, injector >, duration ) },
{ "CNIT", mul( crate< rt::solvent, injector >, duration ) }, { "CNIT", mul( crate< rt::solvent, injector >, duration ) },
@ -1103,8 +1090,8 @@ static const std::unordered_map< std::string, ofun > funs = {
{ "COPT", mul( crate< rt::oil, producer >, duration ) }, { "COPT", mul( crate< rt::oil, producer >, duration ) },
{ "CGPT", mul( crate< rt::gas, producer >, duration ) }, { "CGPT", mul( crate< rt::gas, producer >, duration ) },
{ "CNPT", mul( crate< rt::solvent, producer >, duration ) }, { "CNPT", mul( crate< rt::solvent, producer >, duration ) },
{ "CCIT", mul( crate< rt::wat, injector, polymer >, duration ) }, { "CCIT", mul( crate< rt::polymer, injector >, duration ) },
{ "CCPT", mul( crate< rt::wat, producer, polymer >, duration ) }, { "CCPT", mul( crate< rt::polymer, producer >, duration ) },
{ "CTFAC", trans_factors }, { "CTFAC", trans_factors },
{ "FWPR", rate< rt::wat, producer > }, { "FWPR", rate< rt::wat, producer > },
@ -1141,8 +1128,8 @@ static const std::unordered_map< std::string, ofun > funs = {
{ "FOIR", rate< rt::oil, injector > }, { "FOIR", rate< rt::oil, injector > },
{ "FGIR", rate< rt::gas, injector > }, { "FGIR", rate< rt::gas, injector > },
{ "FNIR", rate< rt::solvent, injector > }, { "FNIR", rate< rt::solvent, injector > },
{ "FCIR", rate< rt::wat, injector, polymer > }, { "FCIR", rate< rt::polymer, injector > },
{ "FCPR", rate< rt::wat, producer, polymer > }, { "FCPR", rate< rt::polymer, producer > },
{ "FVIR", sum( sum( rate< rt::reservoir_water, injector>, rate< rt::reservoir_oil, injector >), { "FVIR", sum( sum( rate< rt::reservoir_water, injector>, rate< rt::reservoir_oil, injector >),
rate< rt::reservoir_gas, injector>)}, rate< rt::reservoir_gas, injector>)},
@ -1151,8 +1138,8 @@ static const std::unordered_map< std::string, ofun > funs = {
{ "FOIT", mul( rate< rt::oil, injector >, duration ) }, { "FOIT", mul( rate< rt::oil, injector >, duration ) },
{ "FGIT", mul( rate< rt::gas, injector >, duration ) }, { "FGIT", mul( rate< rt::gas, injector >, duration ) },
{ "FNIT", mul( rate< rt::solvent, injector >, duration ) }, { "FNIT", mul( rate< rt::solvent, injector >, duration ) },
{ "FCIT", mul( rate< rt::wat, injector, polymer >, duration ) }, { "FCIT", mul( rate< rt::polymer, injector >, duration ) },
{ "FCPT", mul( rate< rt::wat, producer, polymer >, duration ) }, { "FCPT", mul( rate< rt::polymer, producer >, duration ) },
{ "FLIT", mul( sum( rate< rt::wat, injector >, rate< rt::oil, injector > ), { "FLIT", mul( sum( rate< rt::wat, injector >, rate< rt::oil, injector > ),
duration ) }, duration ) },
{ "FVIT", mul( sum( sum( rate< rt::reservoir_water, injector>, rate< rt::reservoir_oil, injector >), { "FVIT", mul( sum( sum( rate< rt::reservoir_water, injector>, rate< rt::reservoir_oil, injector >),

View File

@ -84,6 +84,7 @@ FLPRH
FGSR FGSR
FGCR FGCR
FNPR -- solvent FNPR -- solvent
FCPR
--FTPRSEA --FTPRSEA
-- Injection Rates -- Injection Rates
FVIR FVIR
@ -105,6 +106,7 @@ FGPTH
FWPTH FWPTH
FGST FGST
FGCT FGCT
FCPT
-- Injection Cummulatives -- Injection Cummulatives
FVIT FVIT
FWIT FWIT
@ -320,6 +322,12 @@ GMWPR
/ /
GMWIN GMWIN
/ /
GVPR
/
GVPT
/
-- Well Data -- Well Data
-- Production Rates -- Production Rates
WWPR WWPR
@ -347,6 +355,8 @@ WLPT
WLPTH WLPTH
/ /
WCPR
/
-- Production Cummulatives -- Production Cummulatives
WWPT WWPT
@ -364,6 +374,9 @@ WGPTH
WNPT WNPT
/ /
WCPT
/
-- Tracers -- Tracers
--WTPRSEA --WTPRSEA
--/ --/

View File

@ -97,6 +97,7 @@ FGPRF
FGPRS FGPRS
FOPRF FOPRF
FOPRS FOPRS
FCPR
--FTPRSEA --FTPRSEA
-- Injection Rates -- Injection Rates
FVIR FVIR
@ -124,6 +125,7 @@ FGPTF
FOPTF FOPTF
FOPTS FOPTS
FVPRT FVPRT
FCPT
-- Injection Cummulatives -- Injection Cummulatives
FVIT FVIT
FWIT FWIT
@ -423,6 +425,11 @@ GMWPR
/ /
GMWIN GMWIN
/ /
GCPR
/
GCPT
/
-- Well Data -- Well Data
-- Production Rates -- Production Rates
WWPR WWPR
@ -611,6 +618,12 @@ WVIT
WMCTL WMCTL
/ /
WCPR
/
WCPT
/
-- Water injection per connection -- Water injection per connection
CWIR CWIR
* / * /

View File

@ -122,6 +122,7 @@ static data::Wells result_wells(const bool w3_injector = true) {
rates1.set( rt::well_potential_water, -10.13 / day ); rates1.set( rt::well_potential_water, -10.13 / day );
rates1.set( rt::well_potential_oil, -10.14 / day ); rates1.set( rt::well_potential_oil, -10.14 / day );
rates1.set( rt::well_potential_gas, -10.15 / day ); rates1.set( rt::well_potential_gas, -10.15 / day );
rates1.set( rt::polymer, -10.16 / day );
data::Rates rates2; data::Rates rates2;
rates2.set( rt::wat, -20.0 / day ); rates2.set( rt::wat, -20.0 / day );
@ -139,6 +140,7 @@ static data::Wells result_wells(const bool w3_injector = true) {
rates2.set( rt::well_potential_water, -20.13 / day ); rates2.set( rt::well_potential_water, -20.13 / day );
rates2.set( rt::well_potential_oil, -20.14 / day ); rates2.set( rt::well_potential_oil, -20.14 / day );
rates2.set( rt::well_potential_gas, -20.15 / day ); rates2.set( rt::well_potential_gas, -20.15 / day );
rates2.set( rt::polymer, -20.16 / day );
data::Rates rates3; data::Rates rates3;
rates3.set( rt::wat, 30.0 / day ); rates3.set( rt::wat, 30.0 / day );
@ -156,6 +158,7 @@ static data::Wells result_wells(const bool w3_injector = true) {
rates3.set( rt::well_potential_water, 30.13 / day ); rates3.set( rt::well_potential_water, 30.13 / day );
rates3.set( rt::well_potential_oil, 30.14 / day ); rates3.set( rt::well_potential_oil, 30.14 / day );
rates3.set( rt::well_potential_gas, 30.15 / day ); rates3.set( rt::well_potential_gas, 30.15 / day );
rates3.set( rt::polymer, 30.16 / day );
data::Rates rates6; data::Rates rates6;
@ -174,6 +177,7 @@ static data::Wells result_wells(const bool w3_injector = true) {
rates6.set( rt::well_potential_water, 60.13 / day ); rates6.set( rt::well_potential_water, 60.13 / day );
rates6.set( rt::well_potential_oil, 60.14 / day ); rates6.set( rt::well_potential_oil, 60.14 / day );
rates6.set( rt::well_potential_gas, 60.15 / day ); rates6.set( rt::well_potential_gas, 60.15 / day );
rates6.set( rt::polymer, 60.16 / day );
/* completion rates */ /* completion rates */
data::Rates crates1; data::Rates crates1;
crates1.set( rt::wat, -100.0 / day ); crates1.set( rt::wat, -100.0 / day );
@ -207,6 +211,7 @@ static data::Wells result_wells(const bool w3_injector = true) {
crates3.set( rt::reservoir_water, 300.6 / day ); crates3.set( rt::reservoir_water, 300.6 / day );
crates3.set( rt::reservoir_oil, 300.7 / day ); crates3.set( rt::reservoir_oil, 300.7 / day );
crates3.set( rt::reservoir_gas, 300.8 / day ); crates3.set( rt::reservoir_gas, 300.8 / day );
crates3.set( rt::polymer, 300.16 / day );
data::Rates crates6; data::Rates crates6;
crates6.set( rt::wat, 600.0 / day ); crates6.set( rt::wat, 600.0 / day );
@ -454,7 +459,7 @@ BOOST_AUTO_TEST_CASE(well_keywords) {
BOOST_CHECK_CLOSE( 20.0 + 20.1, ecl_sum_get_well_var( resp, 1, "W_2", "WLPR" ), 1e-5 ); BOOST_CHECK_CLOSE( 20.0 + 20.1, ecl_sum_get_well_var( resp, 1, "W_2", "WLPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.3, ecl_sum_get_well_var( resp, 1, "W_1", "WNPR" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.3, ecl_sum_get_well_var( resp, 1, "W_1", "WNPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 20.3, ecl_sum_get_well_var( resp, 1, "W_2", "WNPR" ), 1e-5 ); BOOST_CHECK_CLOSE( 20.3, ecl_sum_get_well_var( resp, 1, "W_2", "WNPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.16, ecl_sum_get_well_var( resp, 1, "W_1", "WCPR" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.4, ecl_sum_get_well_var( resp, 1, "W_1", "WGPRS" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.4, ecl_sum_get_well_var( resp, 1, "W_1", "WGPRS" ), 1e-5 );
BOOST_CHECK_CLOSE( 20.4, ecl_sum_get_well_var( resp, 1, "W_2", "WGPRS" ), 1e-5 ); BOOST_CHECK_CLOSE( 20.4, ecl_sum_get_well_var( resp, 1, "W_2", "WGPRS" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.2 - 10.4, ecl_sum_get_well_var( resp, 1, "W_1", "WGPRF" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.2 - 10.4, ecl_sum_get_well_var( resp, 1, "W_1", "WGPRF" ), 1e-5 );
@ -522,6 +527,7 @@ BOOST_AUTO_TEST_CASE(well_keywords) {
ecl_sum_get_well_var( resp, 2, "W_1", "WVPT" ), 1e-5 ); ecl_sum_get_well_var( resp, 2, "W_1", "WVPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (20.6 + 20.7 + 20.8), BOOST_CHECK_CLOSE( 2 * (20.6 + 20.7 + 20.8),
ecl_sum_get_well_var( resp, 2, "W_2", "WVPT" ), 1e-5 ); ecl_sum_get_well_var( resp, 2, "W_2", "WVPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * 10.16, ecl_sum_get_well_var( resp, 2, "W_1", "WCPT" ), 1e-5 );
/* Production rates (history) */ /* Production rates (history) */
BOOST_CHECK_CLOSE( 10, ecl_sum_get_well_var( resp, 1, "W_1", "WWPRH" ), 1e-5 ); BOOST_CHECK_CLOSE( 10, ecl_sum_get_well_var( resp, 1, "W_1", "WWPRH" ), 1e-5 );
@ -545,20 +551,19 @@ BOOST_AUTO_TEST_CASE(well_keywords) {
BOOST_CHECK_CLOSE( 30.8, ecl_sum_get_well_var( resp, 1, "W_3", "WGVIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.8, ecl_sum_get_well_var( resp, 1, "W_3", "WGVIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.2, ecl_sum_get_well_var( resp, 1, "W_3", "WGIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.2, ecl_sum_get_well_var( resp, 1, "W_3", "WGIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.3, ecl_sum_get_well_var( resp, 1, "W_3", "WNIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.3, ecl_sum_get_well_var( resp, 1, "W_3", "WNIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5, ecl_sum_get_well_var( resp, 1, "W_3", "WCIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.16, ecl_sum_get_well_var( resp, 1, "W_3", "WCIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 2.5, ecl_sum_get_well_var( resp, 2, "W_3", "WCIR" ), 1e-5 );
/* Injection totals */ /* Injection totals */
BOOST_CHECK_CLOSE( 30.0, ecl_sum_get_well_var( resp, 1, "W_3", "WWIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.0, ecl_sum_get_well_var( resp, 1, "W_3", "WWIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.2, ecl_sum_get_well_var( resp, 1, "W_3", "WGIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.2, ecl_sum_get_well_var( resp, 1, "W_3", "WGIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.3, ecl_sum_get_well_var( resp, 1, "W_3", "WNIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.3, ecl_sum_get_well_var( resp, 1, "W_3", "WNIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5, ecl_sum_get_well_var( resp, 1, "W_3", "WCIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.16, ecl_sum_get_well_var( resp, 1, "W_3", "WCIT" ), 1e-5 );
BOOST_CHECK_CLOSE( (30.6 + 30.7 + 30.8), BOOST_CHECK_CLOSE( (30.6 + 30.7 + 30.8),
ecl_sum_get_well_var( resp, 1, "W_3", "WVIT" ), 1e-5 ); ecl_sum_get_well_var( resp, 1, "W_3", "WVIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * 30.0, ecl_sum_get_well_var( resp, 2, "W_3", "WWIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * 30.0, ecl_sum_get_well_var( resp, 2, "W_3", "WWIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * 30.2, ecl_sum_get_well_var( resp, 2, "W_3", "WGIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * 30.2, ecl_sum_get_well_var( resp, 2, "W_3", "WGIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * 30.3, ecl_sum_get_well_var( resp, 2, "W_3", "WNIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * 30.3, ecl_sum_get_well_var( resp, 2, "W_3", "WNIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5 + 30.0 * 2.5, ecl_sum_get_well_var( resp, 2, "W_3", "WCIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * 30.16, ecl_sum_get_well_var( resp, 2, "W_3", "WCIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2* (30.6 + 30.7 + 30.8), BOOST_CHECK_CLOSE( 2* (30.6 + 30.7 + 30.8),
ecl_sum_get_well_var( resp, 2, "W_3", "WVIT" ), 1e-5 ); ecl_sum_get_well_var( resp, 2, "W_3", "WVIT" ), 1e-5 );
@ -695,6 +700,8 @@ BOOST_AUTO_TEST_CASE(group_keywords) {
BOOST_CHECK_CLOSE( 30.13 + 60.13, ecl_sum_get_group_var( resp, 1, "G_2", "GWPI" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.13 + 60.13, ecl_sum_get_group_var( resp, 1, "G_2", "GWPI" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.15 + 60.15, ecl_sum_get_group_var( resp, 1, "G_2", "GGPI" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.15 + 60.15, ecl_sum_get_group_var( resp, 1, "G_2", "GGPI" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.16 + 20.16, ecl_sum_get_group_var( resp, 1, "G_1", "GCPR" ), 1e-5 );
/* Production totals */ /* Production totals */
BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_group_var( resp, 1, "G_1", "GWPT" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_group_var( resp, 1, "G_1", "GWPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_group_var( resp, 1, "G_1", "GOPT" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_group_var( resp, 1, "G_1", "GOPT" ), 1e-5 );
@ -706,6 +713,7 @@ BOOST_AUTO_TEST_CASE(group_keywords) {
BOOST_CHECK_CLOSE( (10.2 - 10.4) + (20.2 - 20.4), ecl_sum_get_group_var( resp, 1, "G_1", "GGPTF" ), 1e-5 ); BOOST_CHECK_CLOSE( (10.2 - 10.4) + (20.2 - 20.4), ecl_sum_get_group_var( resp, 1, "G_1", "GGPTF" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.6 + 10.7 + 10.8 + 20.6 + 20.7 + 20.8, BOOST_CHECK_CLOSE( 10.6 + 10.7 + 10.8 + 20.6 + 20.7 + 20.8,
ecl_sum_get_group_var( resp, 1, "G_1", "GVPT" ), 1e-5 ); ecl_sum_get_group_var( resp, 1, "G_1", "GVPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.16 + 20.16, ecl_sum_get_group_var( resp, 1, "G_1", "GCPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (10.0 + 20.0), ecl_sum_get_group_var( resp, 2, "G_1", "GWPT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (10.0 + 20.0), ecl_sum_get_group_var( resp, 2, "G_1", "GWPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (10.1 + 20.1), ecl_sum_get_group_var( resp, 2, "G_1", "GOPT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (10.1 + 20.1), ecl_sum_get_group_var( resp, 2, "G_1", "GOPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (10.2 + 20.2), ecl_sum_get_group_var( resp, 2, "G_1", "GGPT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (10.2 + 20.2), ecl_sum_get_group_var( resp, 2, "G_1", "GGPT" ), 1e-5 );
@ -716,7 +724,7 @@ BOOST_AUTO_TEST_CASE(group_keywords) {
BOOST_CHECK_CLOSE( 2 * ((10.1 - 10.5) + (20.1 - 20.5)), ecl_sum_get_group_var( resp, 2, "G_1", "GOPTF" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * ((10.1 - 10.5) + (20.1 - 20.5)), ecl_sum_get_group_var( resp, 2, "G_1", "GOPTF" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (10.6 + 10.7 + 10.8 + 20.6 + 20.7 + 20.8), BOOST_CHECK_CLOSE( 2 * (10.6 + 10.7 + 10.8 + 20.6 + 20.7 + 20.8),
ecl_sum_get_group_var( resp, 2, "G_1", "GVPT" ), 1e-5 ); ecl_sum_get_group_var( resp, 2, "G_1", "GVPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (10.16 + 20.16), ecl_sum_get_group_var( resp, 2, "G_1", "GCPT" ), 1e-5 );
/* Production rates (history) */ /* Production rates (history) */
BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_group_var( resp, 1, "G_1", "GWPRH" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_group_var( resp, 1, "G_1", "GWPRH" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_group_var( resp, 1, "G_1", "GOPRH" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_group_var( resp, 1, "G_1", "GOPRH" ), 1e-5 );
@ -742,8 +750,7 @@ BOOST_AUTO_TEST_CASE(group_keywords) {
BOOST_CHECK_CLOSE( 30.0 + 60.0, ecl_sum_get_group_var( resp, 1, "G_2", "GWIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.0 + 60.0, ecl_sum_get_group_var( resp, 1, "G_2", "GWIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.2 + 60.2, ecl_sum_get_group_var( resp, 1, "G_2", "GGIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.2 + 60.2, ecl_sum_get_group_var( resp, 1, "G_2", "GGIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.3 + 60.3, ecl_sum_get_group_var( resp, 1, "G_2", "GNIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.3 + 60.3, ecl_sum_get_group_var( resp, 1, "G_2", "GNIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5, ecl_sum_get_group_var( resp, 1, "G_2", "GCIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.16 + 60.16, ecl_sum_get_group_var( resp, 1, "G_2", "GCIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 2.5, ecl_sum_get_group_var( resp, 2, "G_2", "GCIR" ), 1e-5 );
BOOST_CHECK_CLOSE( (30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8), BOOST_CHECK_CLOSE( (30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8),
ecl_sum_get_group_var( resp, 1, "G_2", "GVIR" ), 1e-5 ); ecl_sum_get_group_var( resp, 1, "G_2", "GVIR" ), 1e-5 );
@ -751,13 +758,13 @@ BOOST_AUTO_TEST_CASE(group_keywords) {
BOOST_CHECK_CLOSE( 30.0 + 60.0, ecl_sum_get_group_var( resp, 1, "G_2", "GWIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.0 + 60.0, ecl_sum_get_group_var( resp, 1, "G_2", "GWIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.2 + 60.2, ecl_sum_get_group_var( resp, 1, "G_2", "GGIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.2 + 60.2, ecl_sum_get_group_var( resp, 1, "G_2", "GGIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.3 + 60.3, ecl_sum_get_group_var( resp, 1, "G_2", "GNIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.3 + 60.3, ecl_sum_get_group_var( resp, 1, "G_2", "GNIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5, ecl_sum_get_group_var( resp, 1, "G_2", "GCIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.16 + 60.16, ecl_sum_get_group_var( resp, 1, "G_2", "GCIT" ), 1e-5 );
BOOST_CHECK_CLOSE( (30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8), BOOST_CHECK_CLOSE( (30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8),
ecl_sum_get_group_var( resp, 1, "G_2", "GVIT" ), 1e-5 ); ecl_sum_get_group_var( resp, 1, "G_2", "GVIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (30.0 + 60.0), ecl_sum_get_group_var( resp, 2, "G_2", "GWIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (30.0 + 60.0), ecl_sum_get_group_var( resp, 2, "G_2", "GWIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (30.2 + 60.2), ecl_sum_get_group_var( resp, 2, "G_2", "GGIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (30.2 + 60.2), ecl_sum_get_group_var( resp, 2, "G_2", "GGIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (30.3 + 60.3), ecl_sum_get_group_var( resp, 2, "G_2", "GNIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (30.3 + 60.3), ecl_sum_get_group_var( resp, 2, "G_2", "GNIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5 + 30.0 * 2.5, ecl_sum_get_group_var( resp, 2, "G_2", "GCIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (30.16 + 60.16), ecl_sum_get_group_var( resp, 2, "G_2", "GCIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8), BOOST_CHECK_CLOSE( 2 * (30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8),
ecl_sum_get_group_var( resp, 2, "G_2", "GVIT" ), 1e-5 ); ecl_sum_get_group_var( resp, 2, "G_2", "GVIT" ), 1e-5 );
@ -898,18 +905,17 @@ BOOST_AUTO_TEST_CASE(completion_kewords) {
/* Injection rates */ /* Injection rates */
BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIR", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIR", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGIR", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGIR", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 300.0 * 1.5, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CCIR", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 300.16, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CCIR", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 300.0 * 2.5, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CCIR", 3, 1, 1 ), 1e-5 );
/* Injection totals */ /* Injection totals */
BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIT", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIT", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGIT", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGIT", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 300.3, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CNIT", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 300.3, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CNIT", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 300.0 * 1.5, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CCIT", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 300.16, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CCIT", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * 300.0, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CWIT", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * 300.0, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CWIT", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * 300.2, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CGIT", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * 300.2, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CGIT", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * 300.3, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CNIT", 3, 1, 1 ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * 300.3, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CNIT", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 300.0 * 1.5 + 300.0 * 2.5, BOOST_CHECK_CLOSE( 2 * 300.16,
ecl_sum_get_well_completion_var( resp, 2, "W_3", "CCIT", 3, 1, 1 ), 1e-5 ); ecl_sum_get_well_completion_var( resp, 2, "W_3", "CCIT", 3, 1, 1 ), 1e-5 );
/* Solvent flow rate + or - Note OPM uses negative values for producers, while CNFR outputs positive /* Solvent flow rate + or - Note OPM uses negative values for producers, while CNFR outputs positive
@ -994,6 +1000,8 @@ BOOST_AUTO_TEST_CASE(field_keywords) {
BOOST_CHECK_CLOSE( 30.15 + 60.15, ecl_sum_get_field_var( resp, 1, "FGPI" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.15 + 60.15, ecl_sum_get_field_var( resp, 1, "FGPI" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.13 + 60.13, ecl_sum_get_field_var( resp, 1, "FWPI" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.13 + 60.13, ecl_sum_get_field_var( resp, 1, "FWPI" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.16 + 20.16, ecl_sum_get_field_var( resp, 1, "FCPR" ), 1e-5 );
/* Production totals */ /* Production totals */
BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_field_var( resp, 1, "FWPT" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_field_var( resp, 1, "FWPT" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_field_var( resp, 1, "FOPT" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_field_var( resp, 1, "FOPT" ), 1e-5 );
@ -1027,6 +1035,8 @@ BOOST_AUTO_TEST_CASE(field_keywords) {
BOOST_CHECK_CLOSE( 2 * (10.1 - 10.5 + 20.1 - 20.5), BOOST_CHECK_CLOSE( 2 * (10.1 - 10.5 + 20.1 - 20.5),
ecl_sum_get_field_var( resp, 2, "FOPTF" ), 1e-5 ); ecl_sum_get_field_var( resp, 2, "FOPTF" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (10.16 + 20.16), ecl_sum_get_field_var( resp, 2, "FCPT" ), 1e-5 );
/* Production rates (history) */ /* Production rates (history) */
BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_field_var( resp, 1, "FWPRH" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.0 + 20.0, ecl_sum_get_field_var( resp, 1, "FWPRH" ), 1e-5 );
BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_field_var( resp, 1, "FOPRH" ), 1e-5 ); BOOST_CHECK_CLOSE( 10.1 + 20.1, ecl_sum_get_field_var( resp, 1, "FOPRH" ), 1e-5 );
@ -1051,19 +1061,18 @@ BOOST_AUTO_TEST_CASE(field_keywords) {
BOOST_CHECK_CLOSE( 30.0 + 60., ecl_sum_get_field_var( resp, 1, "FWIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.0 + 60., ecl_sum_get_field_var( resp, 1, "FWIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.2 + 60.2, ecl_sum_get_field_var( resp, 1, "FGIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.2 + 60.2, ecl_sum_get_field_var( resp, 1, "FGIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8, ecl_sum_get_field_var( resp, 1, "FVIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8, ecl_sum_get_field_var( resp, 1, "FVIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5, ecl_sum_get_field_var( resp, 1, "FCIR" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.16 + 60.16, ecl_sum_get_field_var( resp, 1, "FCIR" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 2.5, ecl_sum_get_field_var( resp, 2, "FCIR" ), 1e-5 );
/* Injection totals */ /* Injection totals */
BOOST_CHECK_CLOSE( 30.0 + 60., ecl_sum_get_field_var( resp, 1, "FWIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.0 + 60., ecl_sum_get_field_var( resp, 1, "FWIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.2 + 60.2, ecl_sum_get_field_var( resp, 1, "FGIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.2 + 60.2, ecl_sum_get_field_var( resp, 1, "FGIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8, ecl_sum_get_field_var( resp, 1, "FVIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8, ecl_sum_get_field_var( resp, 1, "FVIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5, ecl_sum_get_field_var( resp, 1, "FCIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.16 + 60.16, ecl_sum_get_field_var( resp, 1, "FCIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (30.0 + 60.0), ecl_sum_get_field_var( resp, 2, "FWIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (30.0 + 60.0), ecl_sum_get_field_var( resp, 2, "FWIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (30.2 + 60.2), ecl_sum_get_field_var( resp, 2, "FGIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (30.2 + 60.2), ecl_sum_get_field_var( resp, 2, "FGIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 2 * (30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8), ecl_sum_get_field_var( resp, 2, "FVIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (30.6 + 30.7 + 30.8 + 60.6 + 60.7 + 60.8), ecl_sum_get_field_var( resp, 2, "FVIT" ), 1e-5 );
BOOST_CHECK_CLOSE( 30.0 * 1.5 + 30.0 * 2.5, ecl_sum_get_field_var( resp, 2, "FCIT" ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * (30.16 + 60.16), ecl_sum_get_field_var( resp, 2, "FCIT" ), 1e-5 );
/* Injection totals (history) */ /* Injection totals (history) */
BOOST_CHECK_CLOSE( 30.0, ecl_sum_get_field_var( resp, 1, "FWITH" ), 1e-5 ); BOOST_CHECK_CLOSE( 30.0, ecl_sum_get_field_var( resp, 1, "FWITH" ), 1e-5 );