972 lines
36 KiB
C++
972 lines
36 KiB
C++
/*
|
|
Copyright 2014 Statoil IT
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "config.h"
|
|
|
|
#include <cstdlib>
|
|
|
|
#define BOOST_TEST_MODULE EclipseIO
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
#include <opm/output/eclipse/EclipseIO.hpp>
|
|
#include <opm/output/eclipse/RestartIO.hpp>
|
|
#include <opm/output/eclipse/RestartValue.hpp>
|
|
#include <opm/output/data/Cells.hpp>
|
|
#include <opm/output/data/Wells.hpp>
|
|
|
|
#include <opm/parser/eclipse/EclipseState/Tables/Eqldims.hpp>
|
|
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
|
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
|
#include <opm/parser/eclipse/Utility/Functional.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
|
|
|
|
|
// ERT stuff
|
|
#include <ert/ecl/ecl_kw.h>
|
|
#include <ert/ecl/ecl_file.h>
|
|
#include <ert/ecl/ecl_util.h>
|
|
#include <ert/ecl/ecl_kw_magic.h>
|
|
#include <ert/ecl_well/well_info.h>
|
|
#include <ert/ecl_well/well_state.h>
|
|
#include <ert/util/test_work_area.h>
|
|
|
|
using namespace Opm;
|
|
|
|
inline std::string input( const std::string& rst_name = "FIRST_SIM" ) {
|
|
return std::string(
|
|
"RUNSPEC\n"
|
|
"OIL\n"
|
|
"GAS\n"
|
|
"WATER\n"
|
|
"DISGAS\n"
|
|
"VAPOIL\n"
|
|
"UNIFOUT\n"
|
|
"UNIFIN\n"
|
|
"DIMENS\n"
|
|
" 10 10 10 /\n"
|
|
|
|
"GRID\n"
|
|
"DXV\n"
|
|
"10*0.25 /\n"
|
|
"DYV\n"
|
|
"10*0.25 /\n"
|
|
"DZV\n"
|
|
"10*0.25 /\n"
|
|
"TOPS\n"
|
|
"100*0.25 /\n"
|
|
"\n"
|
|
|
|
"SOLUTION\n"
|
|
"RESTART\n"
|
|
) + rst_name + std::string(
|
|
" 1/\n"
|
|
"\n"
|
|
|
|
"START -- 0 \n"
|
|
"1 NOV 1979 / \n"
|
|
|
|
"SCHEDULE\n"
|
|
"SKIPREST\n"
|
|
"RPTRST\n"
|
|
"BASIC=1\n"
|
|
"/\n"
|
|
"DATES -- 1\n"
|
|
" 10 OKT 2008 / \n"
|
|
"/\n"
|
|
"WELSPECS\n"
|
|
" 'OP_1' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
|
" 'OP_2' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
|
"/\n"
|
|
"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 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"
|
|
"/\n"
|
|
"WCONINJE\n"
|
|
"'OP_2' 'GAS' 'OPEN' 'RATE' 100 200 400 /\n"
|
|
"/\n"
|
|
|
|
"DATES -- 2\n"
|
|
" 20 JAN 2011 / \n"
|
|
"/\n"
|
|
"WELSPECS\n"
|
|
" 'OP_3' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
|
"/\n"
|
|
"COMPDAT\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"
|
|
"/\n"
|
|
|
|
"DATES -- 3\n"
|
|
" 15 JUN 2013 / \n"
|
|
"/\n"
|
|
"COMPDAT\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"
|
|
" 22 APR 2014 / \n"
|
|
"/\n"
|
|
"WELSPECS\n"
|
|
" 'OP_4' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
|
"/\n"
|
|
"COMPDAT\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"
|
|
"/\n"
|
|
|
|
"DATES -- 5\n"
|
|
" 30 AUG 2014 / \n"
|
|
"/\n"
|
|
"WELSPECS\n"
|
|
" 'OP_5' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
|
"/\n"
|
|
"COMPDAT\n"
|
|
" 'OP_5' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
|
"/\n"
|
|
"WCONPROD\n"
|
|
"'OP_5' 'OPEN' 'ORAT' 20000 4* 1000 /\n"
|
|
"/\n"
|
|
|
|
"DATES -- 6\n"
|
|
" 15 SEP 2014 / \n"
|
|
"/\n"
|
|
"WCONPROD\n"
|
|
"'OP_3' 'SHUT' 'ORAT' 20000 4* 1000 /\n"
|
|
"/\n"
|
|
|
|
"DATES -- 7\n"
|
|
" 9 OCT 2014 / \n"
|
|
"/\n"
|
|
"WELSPECS\n"
|
|
" 'OP_6' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
|
"/\n"
|
|
"COMPDAT\n"
|
|
" 'OP_6' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
|
"/\n"
|
|
"WCONPROD\n"
|
|
"'OP_6' 'OPEN' 'ORAT' 20000 4* 1000 /\n"
|
|
"/\n"
|
|
"TSTEP -- 8\n"
|
|
"10 /"
|
|
"/\n"
|
|
);
|
|
}
|
|
|
|
namespace Opm {
|
|
namespace data {
|
|
|
|
/*
|
|
* Some test specific equivalence definitions and pretty-printing. Not fit as a
|
|
* general purpose implementation, but does its job for testing and
|
|
* pretty-pringing for debugging purposes.
|
|
*/
|
|
|
|
std::ostream& operator<<( std::ostream& stream, const Rates& r ) {
|
|
return stream << "{ "
|
|
<< "wat: " << r.get( Rates::opt::wat, 0.0 ) << ", "
|
|
<< "oil: " << r.get( Rates::opt::oil, 0.0 ) << ", "
|
|
<< "gas: " << r.get( Rates::opt::gas, 0.0 ) << " "
|
|
<< "}";
|
|
}
|
|
|
|
std::ostream& operator<<( std::ostream& stream, const Connection& c ) {
|
|
return stream << "{ index: "
|
|
<< c.index << ", "
|
|
<< c.rates << ", "
|
|
<< c.pressure << " }";
|
|
}
|
|
|
|
std::ostream& operator<<( std::ostream& stream,
|
|
const std::map< std::string, Well >& m ) {
|
|
stream << "\n";
|
|
|
|
for( const auto& p : m ) {
|
|
stream << p.first << ": \n"
|
|
<< "\t" << "bhp: " << p.second.bhp << "\n"
|
|
<< "\t" << "temp: " << p.second.temperature << "\n"
|
|
<< "\t" << "rates: " << p.second.rates << "\n"
|
|
<< "\t" << "connections: [\n";
|
|
|
|
for( const auto& c : p.second.connections )
|
|
stream << c << " ";
|
|
|
|
stream << "]\n";
|
|
}
|
|
|
|
return stream;
|
|
}
|
|
|
|
bool operator==( const Rates& lhs, const Rates& rhs ) {
|
|
using rt = Rates::opt;
|
|
|
|
BOOST_CHECK_EQUAL( lhs.has( rt::wat ), rhs.has( rt::wat ) );
|
|
BOOST_CHECK_EQUAL( lhs.has( rt::oil ), rhs.has( rt::oil ) );
|
|
BOOST_CHECK_EQUAL( lhs.has( rt::gas ), rhs.has( rt::gas ) );
|
|
BOOST_CHECK_EQUAL( lhs.has( rt::polymer ), rhs.has( rt::polymer ) );
|
|
BOOST_CHECK_EQUAL( lhs.get( rt::wat, 0.0 ), rhs.get( rt::wat, 0.0 ) );
|
|
BOOST_CHECK_EQUAL( lhs.get( rt::oil, 0.0 ), rhs.get( rt::oil, 0.0 ) );
|
|
BOOST_CHECK_EQUAL( lhs.get( rt::gas, 0.0 ), rhs.get( rt::gas, 0.0 ) );
|
|
BOOST_CHECK_EQUAL( lhs.get( rt::polymer, 0.0 ), rhs.get( rt::polymer, 0.0 ) );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool operator==( const Connection& lhs, const Connection& rhs ) {
|
|
BOOST_CHECK_EQUAL( lhs.index, rhs.index );
|
|
BOOST_CHECK_EQUAL( lhs.rates, rhs.rates );
|
|
BOOST_CHECK_EQUAL( lhs.pressure, rhs.pressure );
|
|
BOOST_CHECK_EQUAL( lhs.reservoir_rate, rhs.reservoir_rate );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool operator!=( const Connection& lhs, const Connection& rhs ) {
|
|
return !( lhs == rhs );
|
|
}
|
|
|
|
bool operator==( const Well& lhs, const Well& rhs ) {
|
|
BOOST_CHECK_EQUAL( lhs.rates, rhs.rates );
|
|
BOOST_CHECK_EQUAL( lhs.bhp, rhs.bhp );
|
|
BOOST_CHECK_EQUAL( lhs.temperature, rhs.temperature );
|
|
BOOST_CHECK_EQUAL( lhs.control, rhs.control );
|
|
|
|
BOOST_CHECK_EQUAL_COLLECTIONS(
|
|
lhs.connections.begin(), lhs.connections.end(),
|
|
rhs.connections.begin(), rhs.connections.end() );
|
|
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
data::Wells mkWells() {
|
|
data::Rates r1, r2, rc1, rc2, rc3;
|
|
r1.set( data::Rates::opt::wat, 5.67 );
|
|
r1.set( data::Rates::opt::oil, 6.78 );
|
|
r1.set( data::Rates::opt::gas, 7.89 );
|
|
|
|
r2.set( data::Rates::opt::wat, 8.90 );
|
|
r2.set( data::Rates::opt::oil, 9.01 );
|
|
r2.set( data::Rates::opt::gas, 10.12 );
|
|
|
|
rc1.set( data::Rates::opt::wat, 20.41 );
|
|
rc1.set( data::Rates::opt::oil, 21.19 );
|
|
rc1.set( data::Rates::opt::gas, 22.41 );
|
|
|
|
rc2.set( data::Rates::opt::wat, 23.19 );
|
|
rc2.set( data::Rates::opt::oil, 24.41 );
|
|
rc2.set( data::Rates::opt::gas, 25.19 );
|
|
|
|
rc3.set( data::Rates::opt::wat, 26.41 );
|
|
rc3.set( data::Rates::opt::oil, 27.19 );
|
|
rc3.set( data::Rates::opt::gas, 28.41 );
|
|
|
|
data::Well w1, w2;
|
|
w1.rates = r1;
|
|
w1.bhp = 1.23;
|
|
w1.temperature = 3.45;
|
|
w1.control = 1;
|
|
|
|
/*
|
|
* the completion keys (active indices) and well names correspond to the
|
|
* input deck. All other entries in the well structures are arbitrary.
|
|
*/
|
|
w1.connections.push_back( { 88, rc1, 30.45, 123.4, 543.21, 0.62, 0.15, 1.0e3 } );
|
|
w1.connections.push_back( { 288, rc2, 33.19, 123.4, 432.1, 0.26, 0.45, 2.56 } );
|
|
|
|
w2.rates = r2;
|
|
w2.bhp = 2.34;
|
|
w2.temperature = 4.56;
|
|
w2.control = 2;
|
|
w2.connections.push_back( { 188, rc3, 36.22, 123.4, 256.1, 0.55, 0.0125, 314.15 } );
|
|
|
|
{
|
|
data::Wells wellRates;
|
|
|
|
wellRates["OP_1"] = w1;
|
|
wellRates["OP_2"] = w2;
|
|
|
|
return wellRates;
|
|
}
|
|
}
|
|
|
|
data::Solution mkSolution( int numCells ) {
|
|
|
|
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 );
|
|
sol.data("TEMP").assign( numCells, 7.0 );
|
|
sol.data("SWAT").assign( numCells, 8.0 );
|
|
sol.data("SGAS").assign( numCells, 9.0 );
|
|
|
|
fun::iota rsi( 300, 300 + numCells );
|
|
fun::iota rvi( 400, 400 + numCells );
|
|
|
|
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;
|
|
}
|
|
|
|
Opm::SummaryState sim_state()
|
|
{
|
|
auto state = Opm::SummaryState{};
|
|
|
|
state.add("WOPR:OP_1" , 1.0);
|
|
state.add("WWPR:OP_1" , 2.0);
|
|
state.add("WGPR:OP_1" , 3.0);
|
|
state.add("WVPR:OP_1" , 4.0);
|
|
state.add("WOPT:OP_1" , 10.0);
|
|
state.add("WWPT:OP_1" , 20.0);
|
|
state.add("WGPT:OP_1" , 30.0);
|
|
state.add("WVPT:OP_1" , 40.0);
|
|
state.add("WWIR:OP_1" , 0.0);
|
|
state.add("WGIR:OP_1" , 0.0);
|
|
state.add("WWIT:OP_1" , 0.0);
|
|
state.add("WGIT:OP_1" , 0.0);
|
|
state.add("WWCT:OP_1" , 0.625);
|
|
state.add("WGOR:OP_1" , 234.5);
|
|
state.add("WBHP:OP_1" , 314.15);
|
|
state.add("WOPTH:OP_1", 345.6);
|
|
state.add("WWPTH:OP_1", 456.7);
|
|
state.add("WGPTH:OP_1", 567.8);
|
|
state.add("WWITH:OP_1", 0.0);
|
|
state.add("WGITH:OP_1", 0.0);
|
|
state.add("WGVIR:OP_1", 0.0);
|
|
state.add("WWVIR:OP_1", 0.0);
|
|
|
|
state.add("WOPR:OP_2" , 0.0);
|
|
state.add("WWPR:OP_2" , 0.0);
|
|
state.add("WGPR:OP_2" , 0.0);
|
|
state.add("WVPR:OP_2" , 0.0);
|
|
state.add("WOPT:OP_2" , 0.0);
|
|
state.add("WWPT:OP_2" , 0.0);
|
|
state.add("WGPT:OP_2" , 0.0);
|
|
state.add("WVPT:OP_2" , 0.0);
|
|
state.add("WWIR:OP_2" , 100.0);
|
|
state.add("WGIR:OP_2" , 200.0);
|
|
state.add("WWIT:OP_2" , 1000.0);
|
|
state.add("WGIT:OP_2" , 2000.0);
|
|
state.add("WWCT:OP_2" , 0.0);
|
|
state.add("WGOR:OP_2" , 0.0);
|
|
state.add("WBHP:OP_2" , 400.6);
|
|
state.add("WOPTH:OP_2", 0.0);
|
|
state.add("WWPTH:OP_2", 0.0);
|
|
state.add("WGPTH:OP_2", 0.0);
|
|
state.add("WWITH:OP_2", 1515.0);
|
|
state.add("WGITH:OP_2", 3030.0);
|
|
state.add("WGVIR:OP_2", 1234.0);
|
|
state.add("WWVIR:OP_2", 4321.0);
|
|
|
|
state.add("WOPR:OP_3" , 11.0);
|
|
state.add("WWPR:OP_3" , 12.0);
|
|
state.add("WGPR:OP_3" , 13.0);
|
|
state.add("WVPR:OP_3" , 14.0);
|
|
state.add("WOPT:OP_3" , 110.0);
|
|
state.add("WWPT:OP_3" , 120.0);
|
|
state.add("WGPT:OP_3" , 130.0);
|
|
state.add("WVPT:OP_3" , 140.0);
|
|
state.add("WWIR:OP_3" , 0.0);
|
|
state.add("WGIR:OP_3" , 0.0);
|
|
state.add("WWIT:OP_3" , 0.0);
|
|
state.add("WGIT:OP_3" , 0.0);
|
|
state.add("WWCT:OP_3" , 0.0625);
|
|
state.add("WGOR:OP_3" , 1234.5);
|
|
state.add("WBHP:OP_3" , 314.15);
|
|
state.add("WOPTH:OP_3", 2345.6);
|
|
state.add("WWPTH:OP_3", 3456.7);
|
|
state.add("WGPTH:OP_3", 4567.8);
|
|
state.add("WWITH:OP_3", 0.0);
|
|
state.add("WGITH:OP_3", 0.0);
|
|
state.add("WGVIR:OP_3", 0.0);
|
|
state.add("WWVIR:OP_3", 43.21);
|
|
|
|
state.add("GOPR:OP" , 110.0);
|
|
state.add("GWPR:OP" , 120.0);
|
|
state.add("GGPR:OP" , 130.0);
|
|
state.add("GVPR:OP" , 140.0);
|
|
state.add("GOPT:OP" , 1100.0);
|
|
state.add("GWPT:OP" , 1200.0);
|
|
state.add("GGPT:OP" , 1300.0);
|
|
state.add("GVPT:OP" , 1400.0);
|
|
state.add("GWIR:OP" , - 256.0);
|
|
state.add("GGIR:OP" , - 65536.0);
|
|
state.add("GWIT:OP" , 31415.9);
|
|
state.add("GGIT:OP" , 27182.8);
|
|
state.add("GWCT:OP" , 0.625);
|
|
state.add("GGOR:OP" , 1234.5);
|
|
state.add("GGVIR:OP", 123.45);
|
|
state.add("GWVIR:OP", 1234.56);
|
|
state.add("GOPTH:OP", 5678.90);
|
|
state.add("GWPTH:OP", 6789.01);
|
|
state.add("GGPTH:OP", 7890.12);
|
|
state.add("GWITH:OP", 8901.23);
|
|
state.add("GGITH:OP", 9012.34);
|
|
|
|
state.add("FOPR" , 1100.0);
|
|
state.add("FWPR" , 1200.0);
|
|
state.add("FGPR" , 1300.0);
|
|
state.add("FVPR" , 1400.0);
|
|
state.add("FOPT" , 11000.0);
|
|
state.add("FWPT" , 12000.0);
|
|
state.add("FGPT" , 13000.0);
|
|
state.add("FVPT" , 14000.0);
|
|
state.add("FWIR" , - 2560.0);
|
|
state.add("FGIR" , - 655360.0);
|
|
state.add("FWIT" , 314159.2);
|
|
state.add("FGIT" , 271828.1);
|
|
state.add("FWCT" , 0.625);
|
|
state.add("FGOR" , 1234.5);
|
|
state.add("FOPTH", 56789.01);
|
|
state.add("FWPTH", 67890.12);
|
|
state.add("FGPTH", 78901.23);
|
|
state.add("FWITH", 89012.34);
|
|
state.add("FGITH", 90123.45);
|
|
state.add("FGVIR", 1234.56);
|
|
state.add("FWVIR", 12345.67);
|
|
|
|
return state;
|
|
}
|
|
|
|
RestartValue first_sim(const EclipseState& es, EclipseIO& eclWriter, bool write_double) {
|
|
const auto& grid = es.getInputGrid();
|
|
auto num_cells = grid.getNumActive( );
|
|
|
|
auto start_time = ecl_util_make_date( 1, 11, 1979 );
|
|
auto first_step = ecl_util_make_date( 1, 2, 2011 ); // Must be after 2011-01-20
|
|
|
|
auto sol = mkSolution( num_cells );
|
|
auto wells = mkWells();
|
|
RestartValue restart_value(sol, wells);
|
|
|
|
eclWriter.writeTimeStep( 1,
|
|
false,
|
|
first_step - start_time,
|
|
restart_value,
|
|
{}, {}, {}, write_double);
|
|
|
|
return restart_value;
|
|
}
|
|
|
|
RestartValue second_sim(const EclipseIO& writer, const std::vector<RestartKey>& solution_keys) {
|
|
return writer.loadRestart( solution_keys );
|
|
}
|
|
|
|
|
|
void compare( const RestartValue& fst,
|
|
const RestartValue& snd,
|
|
const std::vector<RestartKey>& solution_keys) {
|
|
|
|
for (const auto& value : solution_keys) {
|
|
double tol = 0.00001;
|
|
const std::string& key = value.key;
|
|
auto first = fst.solution.data( key ).begin();
|
|
auto second = snd.solution.data( key ).begin();
|
|
|
|
if (key == "TEMP")
|
|
tol *= 10;
|
|
|
|
for( ; first != fst.solution.data( key).end(); ++first, ++second )
|
|
BOOST_CHECK_CLOSE( *first, *second, tol );
|
|
}
|
|
|
|
BOOST_CHECK_EQUAL( fst.wells, snd.wells );
|
|
}
|
|
|
|
|
|
struct Setup {
|
|
Deck deck;
|
|
EclipseState es;
|
|
const EclipseGrid& grid;
|
|
Schedule schedule;
|
|
SummaryConfig summary_config;
|
|
|
|
Setup( const char* path) :
|
|
deck( Parser().parseFile( path) ),
|
|
es( deck),
|
|
grid( es.getInputGrid( ) ),
|
|
schedule( deck, grid, es.get3DProperties(), es.runspec()),
|
|
summary_config( deck, schedule, es.getTableManager( ))
|
|
{
|
|
auto& io_config = es.getIOConfig();
|
|
io_config.setEclCompatibleRST(false);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData) {
|
|
std::vector<RestartKey> keys {{"PRESSURE" , UnitSystem::measure::pressure},
|
|
{"SWAT" , UnitSystem::measure::identity},
|
|
{"SGAS" , UnitSystem::measure::identity},
|
|
{"TEMP" , UnitSystem::measure::temperature}};
|
|
test_work_area_type * test_area = test_work_area_alloc("test_restart");
|
|
test_work_area_copy_file( test_area, "FIRST_SIM.DATA");
|
|
|
|
Setup setup("FIRST_SIM.DATA");
|
|
EclipseIO eclWriter( setup.es, setup.grid, setup.schedule, setup.summary_config);
|
|
auto state1 = first_sim( setup.es , eclWriter , false );
|
|
auto state2 = second_sim( eclWriter , keys );
|
|
compare(state1, state2 , keys);
|
|
|
|
BOOST_CHECK_THROW( second_sim( eclWriter, {{"SOIL", UnitSystem::measure::pressure}} ) , std::runtime_error );
|
|
BOOST_CHECK_THROW( second_sim( eclWriter, {{"SOIL", UnitSystem::measure::pressure, true}}) , std::runtime_error );
|
|
test_work_area_free( test_area );
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(ECL_FORMATTED) {
|
|
Setup setup("FIRST_SIM.DATA");
|
|
test_work_area_type * test_area = test_work_area_alloc("test_Restart");
|
|
auto& io_config = setup.es.getIOConfig();
|
|
{
|
|
auto num_cells = setup.grid.getNumActive( );
|
|
auto cells = mkSolution( num_cells );
|
|
auto wells = mkWells();
|
|
auto sumState = sim_state();
|
|
{
|
|
RestartValue restart_value(cells, wells);
|
|
|
|
io_config.setEclCompatibleRST( false );
|
|
restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3});
|
|
RestartIO::save("OPM_FILE.UNRST", 1 ,
|
|
100,
|
|
restart_value,
|
|
setup.es,
|
|
setup.grid,
|
|
setup.schedule,
|
|
sumState,
|
|
true);
|
|
|
|
{
|
|
ecl_file_type * rst_file = ecl_file_open( "OPM_FILE.UNRST" , 0 );
|
|
ecl_kw_type * swat = ecl_file_iget_named_kw(rst_file, "SWAT", 0);
|
|
|
|
BOOST_CHECK_EQUAL( ECL_DOUBLE_TYPE, ecl_kw_get_type(swat));
|
|
BOOST_CHECK( ecl_file_has_kw(rst_file, "EXTRA"));
|
|
ecl_file_close(rst_file);
|
|
}
|
|
|
|
io_config.setEclCompatibleRST( true );
|
|
RestartIO::save("ECL_FILE.UNRST", 1 ,
|
|
100,
|
|
restart_value,
|
|
setup.es,
|
|
setup.grid,
|
|
setup.schedule,
|
|
sumState,
|
|
true);
|
|
{
|
|
ecl_file_type * rst_file = ecl_file_open( "ECL_FILE.UNRST" , 0 );
|
|
ecl_kw_type * swat = ecl_file_iget_named_kw(rst_file, "SWAT", 0);
|
|
|
|
BOOST_CHECK_EQUAL( ECL_FLOAT_TYPE, ecl_kw_get_type(swat));
|
|
BOOST_CHECK( !ecl_file_has_kw(rst_file, "EXTRA"));
|
|
BOOST_CHECK( !ecl_file_has_kw(rst_file, "OPM_XWEL"));
|
|
BOOST_CHECK( !ecl_file_has_kw(rst_file, "OPM_IWEL"));
|
|
ecl_file_close(rst_file);
|
|
}
|
|
}
|
|
}
|
|
test_work_area_free(test_area);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void compare_equal( const RestartValue& fst,
|
|
const RestartValue& snd ,
|
|
const std::vector<RestartKey>& keys) {
|
|
|
|
for (const auto& value : keys) {
|
|
const std::string& key = value.key;
|
|
auto first = fst.solution.data( key ).begin();
|
|
auto second = snd.solution.data( key ).begin();
|
|
|
|
for( ; first != fst.solution.data( key ).end(); ++first, ++second )
|
|
BOOST_CHECK_EQUAL( *first, *second);
|
|
}
|
|
|
|
BOOST_CHECK_EQUAL( fst.wells, snd.wells );
|
|
//BOOST_CHECK_EQUAL( fst.extra, snd.extra );
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData_double) {
|
|
/*
|
|
Observe that the purpose of this test is to verify that with
|
|
write_double == true we can load solution fields which are
|
|
bitwise equal to those we stored. Unfortunately the scaling back
|
|
and forth between SI units and output units is enough to break
|
|
this equality for the pressure. For this test we therefor only
|
|
consider the saturations which have identity unit.
|
|
*/
|
|
std::vector<RestartKey> solution_keys {RestartKey("SWAT", UnitSystem::measure::identity),
|
|
RestartKey("SGAS", UnitSystem::measure::identity)};
|
|
|
|
test_work_area_type * test_area = test_work_area_alloc("test_Restart");
|
|
test_work_area_copy_file( test_area, "FIRST_SIM.DATA");
|
|
Setup setup("FIRST_SIM.DATA");
|
|
EclipseIO eclWriter( setup.es, setup.grid, setup.schedule, setup.summary_config);
|
|
|
|
auto state1 = first_sim( setup.es , eclWriter , true);
|
|
auto state2 = second_sim( eclWriter , solution_keys );
|
|
compare_equal( state1 , state2 , solution_keys);
|
|
test_work_area_free( test_area );
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) {
|
|
Setup setup("FIRST_SIM.DATA");
|
|
test_work_area_type * test_area = test_work_area_alloc("test_Restart");
|
|
{
|
|
auto num_cells = setup.grid.getNumActive( ) + 1;
|
|
auto cells = mkSolution( num_cells );
|
|
auto wells = mkWells();
|
|
Opm::SummaryState sumState;
|
|
|
|
BOOST_CHECK_THROW( RestartIO::save("FILE.UNRST", 1 ,
|
|
100,
|
|
RestartValue(cells, wells),
|
|
setup.es,
|
|
setup.grid ,
|
|
setup.schedule,
|
|
sumState),
|
|
std::runtime_error);
|
|
}
|
|
test_work_area_free(test_area);
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(ExtraData_KEYS) {
|
|
Setup setup("FIRST_SIM.DATA");
|
|
auto num_cells = setup.grid.getNumActive( );
|
|
auto cells = mkSolution( num_cells );
|
|
auto wells = mkWells();
|
|
RestartValue restart_value(cells, wells);
|
|
|
|
BOOST_CHECK_THROW( restart_value.addExtra("TOO-LONG-KEY", {0,1,2}), std::runtime_error);
|
|
|
|
// Keys must be unique
|
|
restart_value.addExtra("KEY", {0,1,1});
|
|
BOOST_CHECK_THROW( restart_value.addExtra("KEY", {0,1,1}), std::runtime_error);
|
|
|
|
/* The keys must be unique across solution and extra_data */
|
|
BOOST_CHECK_THROW( restart_value.addExtra("PRESSURE", {0,1}), std::runtime_error);
|
|
|
|
/* Must avoid using reserved keys like 'LOGIHEAD' */
|
|
BOOST_CHECK_THROW( restart_value.addExtra("LOGIHEAD", {0,1}), std::runtime_error);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(ExtraData_content) {
|
|
Setup setup("FIRST_SIM.DATA");
|
|
test_work_area_type * test_area = test_work_area_alloc("test_Restart");
|
|
{
|
|
auto num_cells = setup.grid.getNumActive( );
|
|
auto cells = mkSolution( num_cells );
|
|
auto wells = mkWells();
|
|
const auto& units = setup.es.getUnits();
|
|
{
|
|
RestartValue restart_value(cells, wells);
|
|
const auto sumState = sim_state();
|
|
|
|
restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3});
|
|
|
|
RestartIO::save("FILE.UNRST", 1 ,
|
|
100,
|
|
restart_value,
|
|
setup.es,
|
|
setup.grid,
|
|
setup.schedule,
|
|
sumState);
|
|
|
|
{
|
|
ecl_file_type * f = ecl_file_open( "FILE.UNRST" , 0 );
|
|
BOOST_CHECK( ecl_file_has_kw( f , "EXTRA"));
|
|
{
|
|
ecl_kw_type * ex = ecl_file_iget_named_kw( f , "EXTRA" , 0 );
|
|
BOOST_CHECK_EQUAL( ecl_kw_get_header( ex) , "EXTRA" );
|
|
BOOST_CHECK_EQUAL( 4 , ecl_kw_get_size( ex ));
|
|
|
|
BOOST_CHECK_CLOSE( 10 , units.to_si( UnitSystem::measure::pressure, ecl_kw_iget_double( ex, 0 )), 0.00001);
|
|
BOOST_CHECK_CLOSE( units.from_si( UnitSystem::measure::pressure, 3), ecl_kw_iget_double( ex, 3 ), 0.00001);
|
|
}
|
|
ecl_file_close( f );
|
|
}
|
|
|
|
BOOST_CHECK_THROW( RestartIO::load( "FILE.UNRST" , 1 , {}, setup.es, setup.grid , setup.schedule,
|
|
{{"NOT-THIS", UnitSystem::measure::identity, true}}) , std::runtime_error );
|
|
{
|
|
const auto rst_value = RestartIO::load(
|
|
"FILE.UNRST" , 1 ,
|
|
/* solution_keys = */ {
|
|
RestartKey("SWAT", UnitSystem::measure::identity),
|
|
RestartKey("NO" , UnitSystem::measure::identity, false)
|
|
},
|
|
setup.es, setup.grid , setup.schedule,
|
|
/* extra_keys = */ {
|
|
{"EXTRA" , UnitSystem::measure::pressure, true} ,
|
|
{"EXTRA2", UnitSystem::measure::identity, false}
|
|
}).first;
|
|
|
|
BOOST_CHECK(!rst_value.hasExtra("EXTRA2"));
|
|
BOOST_CHECK( rst_value.hasExtra("EXTRA"));
|
|
BOOST_CHECK_THROW(rst_value.getExtra("EXTRA2"), std::invalid_argument);
|
|
const auto& extraval = rst_value.getExtra("EXTRA");
|
|
const std::vector<double> expected = {10,1,2,3};
|
|
|
|
BOOST_CHECK_EQUAL( rst_value.solution.has("NO") , false );
|
|
for (size_t i=0; i < expected.size(); i++)
|
|
BOOST_CHECK_CLOSE(extraval[i], expected[i], 1e-5);
|
|
}
|
|
}
|
|
}
|
|
test_work_area_free(test_area);
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(STORE_THPRES) {
|
|
Setup setup("FIRST_SIM_THPRES.DATA");
|
|
test_work_area_type * test_area = test_work_area_alloc("test_Restart_THPRES");
|
|
{
|
|
auto num_cells = setup.grid.getNumActive( );
|
|
auto cells = mkSolution( num_cells );
|
|
auto wells = mkWells();
|
|
{
|
|
RestartValue restart_value(cells, wells);
|
|
RestartValue restart_value2(cells, wells);
|
|
|
|
/* Missing THPRES data in extra container. */
|
|
/* Because it proved to difficult to update the legacy simulators
|
|
to pass THPRES values when writing restart files this BOOST_CHECK_THROW
|
|
had to be disabled. The RestartIO::save() function will just log a warning.
|
|
|
|
BOOST_CHECK_THROW( RestartIO::save("FILE.UNRST", 1 ,
|
|
100,
|
|
restart_value,
|
|
setup.es,
|
|
setup.grid,
|
|
setup.schedule), std::runtime_error);
|
|
*/
|
|
|
|
restart_value.addExtra("THRESHPR", UnitSystem::measure::pressure, {0,1});
|
|
const auto sumState = sim_state();
|
|
|
|
/* THPRES data has wrong size in extra container. */
|
|
BOOST_CHECK_THROW( RestartIO::save("FILE.UNRST", 1 ,
|
|
100,
|
|
restart_value,
|
|
setup.es,
|
|
setup.grid,
|
|
setup.schedule,
|
|
sumState), std::runtime_error);
|
|
|
|
int num_regions = setup.es.getTableManager().getEqldims().getNumEquilRegions();
|
|
std::vector<double> thpres(num_regions * num_regions, 78);
|
|
restart_value2.addExtra("THRESHPR", UnitSystem::measure::pressure, thpres);
|
|
restart_value2.addExtra("EXTRA", UnitSystem::measure::pressure, thpres);
|
|
|
|
RestartIO::save("FILE2.UNRST", 1,
|
|
100,
|
|
restart_value2,
|
|
setup.es,
|
|
setup.grid,
|
|
setup.schedule, sumState);
|
|
|
|
{
|
|
ecl_file_type * rst_file = ecl_file_open("FILE2.UNRST", 0);
|
|
std::map<std::string,int> kw_pos;
|
|
for (int i=0; i < ecl_file_get_size(rst_file); i++)
|
|
kw_pos[ ecl_file_iget_header(rst_file, i ) ] = i;
|
|
|
|
BOOST_CHECK( kw_pos["STARTSOL"] < kw_pos["THRESHPR"] );
|
|
BOOST_CHECK( kw_pos["THRESHPR"] < kw_pos["ENDSOL"] );
|
|
BOOST_CHECK( kw_pos["ENDSOL"] < kw_pos["EXTRA"] );
|
|
|
|
BOOST_CHECK_EQUAL( ecl_file_get_num_named_kw(rst_file, "THRESHPR"), 1);
|
|
BOOST_CHECK_EQUAL( ecl_file_get_num_named_kw(rst_file, "EXTRA"), 1);
|
|
BOOST_CHECK_EQUAL( ecl_kw_get_type(ecl_file_iget_named_kw(rst_file, "THRESHPR", 0)), ECL_DOUBLE_TYPE);
|
|
ecl_file_close(rst_file);
|
|
}
|
|
|
|
}
|
|
}
|
|
test_work_area_free(test_area);
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Restore_Cumulatives)
|
|
{
|
|
Setup setup("FIRST_SIM.DATA");
|
|
|
|
// Write fully ECLIPSE compatible output. This also saves cumulatives.
|
|
setup.es.getIOConfig().setEclCompatibleRST(true);
|
|
|
|
const auto restart_value = RestartValue {
|
|
mkSolution(setup.grid.getNumActive()),
|
|
mkWells()
|
|
};
|
|
const auto sumState = sim_state();
|
|
|
|
RestartIO::save("FILE.UNRST", 1, 100, restart_value,
|
|
setup.es, setup.grid, setup.schedule, sumState);
|
|
|
|
const auto rst_value = RestartIO::load("FILE.UNRST", 1,
|
|
/* solution_keys = */ {
|
|
RestartKey("SWAT", UnitSystem::measure::identity),
|
|
},
|
|
setup.es, setup.grid, setup.schedule,
|
|
/* extra_keys = */ {});
|
|
|
|
const auto& rstSumState = rst_value.second;
|
|
|
|
// Verify that the restored summary state has all of its requisite
|
|
// cumulative summary vectors.
|
|
|
|
// Producer => W*IT{,H} saved/restored as zero (0.0)
|
|
BOOST_CHECK(rstSumState.has("WOPT:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WGPT:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WWPT:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WVPT:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WWIT:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WGIT:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WOPTH:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WGPTH:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WWPTH:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WWITH:OP_1"));
|
|
BOOST_CHECK(rstSumState.has("WGITH:OP_1"));
|
|
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WOPT:OP_1"), 10.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WGPT:OP_1"), 30.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WWPT:OP_1"), 20.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WVPT:OP_1"), 40.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WWIT:OP_1"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WGIT:OP_1"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WOPTH:OP_1"), 345.6, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WWPTH:OP_1"), 456.7, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WGPTH:OP_1"), 567.8, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WWITH:OP_1"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WGITH:OP_1"), 0.0, 1.0e-10);
|
|
|
|
// Gas injector => W*PT{,H} saved/restored as zero (0.0)
|
|
BOOST_CHECK(rstSumState.has("WOPT:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WGPT:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WWPT:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WVPT:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WWIT:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WGIT:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WOPTH:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WGPTH:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WWPTH:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WWITH:OP_2"));
|
|
BOOST_CHECK(rstSumState.has("WGITH:OP_2"));
|
|
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WOPT:OP_2"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WGPT:OP_2"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WWPT:OP_2"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WVPT:OP_2"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WWIT:OP_2"), 1000.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WGIT:OP_2"), 2000.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WOPTH:OP_2"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WGPTH:OP_2"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WWPTH:OP_2"), 0.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WWITH:OP_2"), 1515.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("WGITH:OP_2"), 3030.0, 1.0e-10);
|
|
|
|
// Group cumulatives saved/restored for all phases
|
|
BOOST_CHECK(rstSumState.has("GOPT:OP"));
|
|
BOOST_CHECK(rstSumState.has("GGPT:OP"));
|
|
BOOST_CHECK(rstSumState.has("GWPT:OP"));
|
|
BOOST_CHECK(rstSumState.has("GVPT:OP"));
|
|
BOOST_CHECK(rstSumState.has("GWIT:OP"));
|
|
BOOST_CHECK(rstSumState.has("GGIT:OP"));
|
|
BOOST_CHECK(rstSumState.has("GOPTH:OP"));
|
|
BOOST_CHECK(rstSumState.has("GGPTH:OP"));
|
|
BOOST_CHECK(rstSumState.has("GWPTH:OP"));
|
|
BOOST_CHECK(rstSumState.has("GWITH:OP"));
|
|
BOOST_CHECK(rstSumState.has("GGITH:OP"));
|
|
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GOPT:OP"), 1100.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GWPT:OP"), 1200.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GGPT:OP"), 1300.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GVPT:OP"), 1400.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GWIT:OP"), 31415.9, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GGIT:OP"), 27182.8, 1.0e-10);
|
|
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GOPTH:OP"), 5678.90, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GGPTH:OP"), 7890.12, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GWPTH:OP"), 6789.01, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GWITH:OP"), 8901.23, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("GGITH:OP"), 9012.34, 1.0e-10);
|
|
|
|
// Field cumulatives saved/restored for all phases
|
|
BOOST_CHECK(rstSumState.has("FOPT"));
|
|
BOOST_CHECK(rstSumState.has("FGPT"));
|
|
BOOST_CHECK(rstSumState.has("FWPT"));
|
|
BOOST_CHECK(rstSumState.has("FVPT"));
|
|
BOOST_CHECK(rstSumState.has("FWIT"));
|
|
BOOST_CHECK(rstSumState.has("FGIT"));
|
|
BOOST_CHECK(rstSumState.has("FOPTH"));
|
|
BOOST_CHECK(rstSumState.has("FGPTH"));
|
|
BOOST_CHECK(rstSumState.has("FWPTH"));
|
|
BOOST_CHECK(rstSumState.has("FWITH"));
|
|
BOOST_CHECK(rstSumState.has("FGITH"));
|
|
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FOPT"), 11000.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FWPT"), 12000.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FGPT"), 13000.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FVPT"), 14000.0, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FWIT"), 314159.2, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FGIT"), 271828.1, 1.0e-10);
|
|
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FOPTH"), 56789.01, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FGPTH"), 78901.23, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FWPTH"), 67890.12, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FWITH"), 89012.34, 1.0e-10);
|
|
BOOST_CHECK_CLOSE(rstSumState.get("FGITH"), 90123.45, 1.0e-10);
|
|
}
|
|
|
|
|
|
}
|