diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 74ea0ef..251ed4c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -26,17 +26,11 @@ foreach (plt ${plts}) configure_file(${plt} test-data/${fl} COPYONLY) endforeach () -foreach (name nexus_plot_load - nexus_plot_spe1 - nexus_unit) - add_executable(${name} tests/${name}.cpp) - target_link_libraries(${name} nex) - target_include_directories(${name} PRIVATE src/include) - target_compile_options(${name} PRIVATE ${CPP_STANDARD}) - add_test(NAME ${name} COMMAND ${name}) -endforeach () - -add_executable(testsuite tests/testsuite.cpp) -target_link_libraries(testsuite catch2) +add_executable(testsuite tests/testsuite.cpp tests/load.cpp tests/spe1.cpp + tests/units.cpp) +target_link_libraries(testsuite catch2 nex) target_include_directories(testsuite PRIVATE src/include) target_compile_options(testsuite PRIVATE ${CPP_STANDARD}) +add_test(NAME load COMMAND testsuite [load]) +add_test(NAME spe1 COMMAND testsuite [spe1]) +add_test(NAME units COMMAND testsuite [units]) diff --git a/lib/tests/load.cpp b/lib/tests/load.cpp new file mode 100644 index 0000000..13b00f6 --- /dev/null +++ b/lib/tests/load.cpp @@ -0,0 +1,37 @@ +/* + Copyright (C) 2017 Statoil ASA, Norway. + + The file 'load.cpp' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 at + for more details. +*/ + +#include + +#include +#include + +TEST_CASE( "load", "[load]") { + + GIVEN( "an invalid header" ) { + std::stringstream stream( "xxxxINVALID_HEADER" ); + CHECK_THROWS_AS( nex::load(stream), nex::bad_header ); + stream.str( "xxx" ); + CHECK_THROWS_AS( nex::load(stream), nex::bad_header ); + } + + GIVEN( "a valid header" ) { + std::stringstream stream( "xxxxPLOT BIN " ); + CHECK_THROWS_AS( nex::load(stream), nex::unexpected_eof ); + } +} diff --git a/lib/tests/nexus_plot_load.cpp b/lib/tests/nexus_plot_load.cpp deleted file mode 100644 index 5bec369..0000000 --- a/lib/tests/nexus_plot_load.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2017 Statoil ASA, Norway. - - The file 'nexus_plot_load.cpp' is part of ERT - Ensemble based Reservoir Tool. - - ERT 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. - - ERT 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 at - for more details. -*/ - -#include -#include -#include -#include -#include -#include - - -#include -#include - - -void test_invalid_header1() { - std::stringstream stream( "xxxxINVALID_HEADER" ); - test_assert_throw(nex::load(stream), nex::bad_header); -} - -void test_invalid_header2() { - std::stringstream stream( "xxx" ); - test_assert_throw(nex::load(stream), nex::bad_header); -} - -void test_valid_header() { - std::stringstream stream( "xxxxPLOT BIN " ); - test_assert_throw(nex::load(stream), nex::unexpected_eof); -} - -int main(int argc, char* argv[]) { - test_invalid_header1(); - test_invalid_header2(); - test_valid_header(); - return 0; -} diff --git a/lib/tests/nexus_plot_spe1.cpp b/lib/tests/nexus_plot_spe1.cpp deleted file mode 100644 index a9f70c1..0000000 --- a/lib/tests/nexus_plot_spe1.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - Copyright (C) 2017 Statoil ASA, Norway. - - The file 'nexus_plot_load.cpp' is part of ERT - Ensemble based Reservoir Tool. - - ERT 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. - - ERT 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 at - for more details. -*/ - -#include -#include -#include -#include -#include - - -#include -#include - -using namespace nex; - - -namespace { - const std::vector< std::string > spe1_classnames {{ - "WELL", "NODE", "CONN", "REGION", "FIELD", "CONNLIST" - }}; - const std::array< int, 9 > spe1_vars_in_class {{ - 56, 52, 4, 43, 69, 58, 20, 25, 25 - }}; - const std::array< int, 10 > spe1_timesteps {{ - 33, 46, 59, 72, 85, 89, 91, 92, 94, 97 - }}; - const std::array< std::vector< std::string >, 9 > spe1_varnames {{ - std::vector< std::string > {{ - "COP" , "CGP" , "CWP" , "CGI" , "CWI" , "QOP" , "QGP" , "QWP" , - "QGI" , "QWI" , "BHP" , "WPH" , "WKH" , "WPAV", "THP" , "COWP", - "QOWP", "GOR" , "WCUT", "WOR" , "QGLG", "CGLG", "DRDN", "DRMX", - "CROP", "CRGP", "CRWP", "CROI", "CRGI", "CRWI", "ROP" , "RGP" , - "RWP" , "ROI" , "RGI" , "RWI" , "ONTM", "ALQ" , "API" , "QCDP", - "CCDP", "YCDP", "ACTV", "STAT", "Q1P" , "Q1I" , "C1P" , "C1I" , - "X1P" , "Y1P" , "Q2P" , "Q2I" , "C2P" , "C2I" , "X2P" , "Y2P" - }}, - std::vector< std::string > {{ - "PNOD", "PDAT", "TNOD", "ACTV" - }}, - std::vector< std::string > {{ - "QGAS", "QOIL", "QWTR", "CGAS", "COIL", "CWTR", "CBFG", "CBFO", - "CBFW", "QGIS", "QOIS", "QWIS", "P_IN", "POUT", "T_IN", "TOUT", - "ACTV", "STAT", "CSTR", "ITRG", "ONTM", "ALQ" , "SETM", "SETA", - "POWM", "POWA", "SPDM", "SPDA", "API" , "DELP", "QTOT", "GVF" , - "EFF" , "POSN", "WCUT", "GOR" , "WOR" , "Q1" , "Q2" , "X1" , - "X2" , "Y1" , "Y2" - }}, - std::vector< std::string > {{ - "COP" , "CGP" , "CWP" , "COI" , "CGI" , "CWI" , "PAVT", "PAVH", - "OIP" , "GIP" , "WIP" , "QOP" , "QGP" , "QWP" , "QOI" , "QGI" , - "QWI" , "OIN" , "GIN" , "WIN" , "SO" , "SG" , "SW" , "OREC", - "FGIP", "CIP" , "PAVE", "PAVD", "ROIP", "RGIP", "RWIP", "MRO" , - "MRG" , "MRW" , "NFLX", "PV" , "HCPV", "TAVT", "TAVH", "CROP", - "CRGP", "CRWP", "CROI", "CRGI", "CRWI", "ROP" , "RGP" , "RWP" , - "ROI" , "RGI" , "RWI" , "QCDP", "CCDP", "YCDP", "API" , "GOR" , - "WCUT", "WOR" , "Z1" , "Z2" , "MC1" , "MC2" , "MC3" , "C1P" , - "C2P" , "C3P" , "C1I" , "C2I" , "C3I" - }}, - std::vector< std::string > {{ - "COP" , "CGP" , "CWP" , "CGI" , "CWI" , "QOP" , "QGP" , "QWP" , - "QGI" , "QWI" , "COWP", "QOWP", "GOR" , "OREC", "GREC", "PAVT", - "PAVH", "QGLG", "CGLG", "WCUT", "NFLX", "CROP", "CRGP", "CRWP", - "CROI", "CRGI", "CRWI", "ROP" , "RGP" , "RWP" , "ROI" , "RGI" , - "RWI" , "OIP" , "GIP" , "WIP" , "QCDP", "CCDP", "YCDP", "WLLS", - "PRDW", "GLFW", "WINJ", "GINJ", "ACTW", "API" , "Q1P" , "Q1I" , - "C1P" , "C1I" , "X1P" , "Y1P" , "Q2P" , "Q2I" , "C2P" , "C2I" , - "X2P" , "Y2P" - }}, - std::vector< std::string > {{ - "QOP", "QGP", "QWP", "QOI", "QGI", "QWI" , "COP", "CGP", - "CWP", "COI", "CGI", "CWI", "API", "WCUT", "GOR", "WOR", - "Q1P", "Q1I", "Q2P", "Q2I" - }} - }}; -} - -void test_spe1_header(const NexusPlot& spe1) { - test_assert_int_equal(spe1.header.num_classes, 9); - test_assert_int_equal(spe1.header.day, 1); - test_assert_int_equal(spe1.header.month, 1); - test_assert_int_equal(spe1.header.year, 1980); - test_assert_int_equal(spe1.header.nx, 1); - test_assert_int_equal(spe1.header.ny, 1); - test_assert_int_equal(spe1.header.nz, 1); - test_assert_int_equal(spe1.header.ncomp, 2); -} - -void test_spe1_classes(const NexusPlot& spe1) { - auto classes = unique( spe1, get::classname_str ); - for (const auto& c : classes) { - auto f = std::find( spe1_classnames.begin(), spe1_classnames.end(), c ); - test_assert_true( f != spe1_classnames.end() ); - } -} - -void test_spe1_timesteps(const NexusPlot& spe1) { - auto data = spe1.data; - std::vector< int32_t > timesteps; - std::transform(data.begin(), data.end(), std::back_inserter( timesteps ), - get::timestep); - std::sort( timesteps.begin(), timesteps.end() ); - timesteps.erase( std::unique( timesteps.begin(), timesteps.end() ), - timesteps.end() ); - - for (size_t i = 0; i < timesteps.size(); i++) { - test_assert_int_equal( timesteps[i], spe1_timesteps[i] ); - } -} - -void test_spe1_well_comulative_gas_injected(const NexusPlot& spe1) { - std::vector< float > cgi_all_timesteps {{ - 6.222797E+08, 6.291119E+08, 6.291336E+08, 6.291336E+08, 6.291336E+08, - 6.291336E+08, 6.291336E+08, 6.291336E+08, 6.291336E+08, 6.291336E+08 - }}; - - auto data = spe1.data; - auto pred_well_1_cgi = [](const NexusData& d) { - return is::classname("WELL")(d) - && is::instancename("1")(d) - && is::varname("CGI")(d); - }; - std::vector< NexusData > well_1_cgi; - std::copy_if( data.begin(), data.end(), std::back_inserter( well_1_cgi ), - pred_well_1_cgi ); - - test_assert_int_equal( well_1_cgi.size(), cgi_all_timesteps.size() ); - for (size_t i = 0; i < cgi_all_timesteps.size(); i++) { - test_assert_string_equal( get::varname_str(well_1_cgi[i]).c_str(), - "CGI" ); - test_assert_float_equal( well_1_cgi[i].value, cgi_all_timesteps[i] ); - } -} - -void test_spe1_region_rgs00002_ts97_all_variables(const NexusPlot& spe1) { - std::vector< float > rgs00002_ts97_values {{ - 4.011786E+06, 1.171299E+09, 2.301113E-01, 0.000000E+00, 6.291336E+08, 0.000000E+00, - 3.071745E+02, 3.076096E+02, 4.116595E+04, 9.679420E+06, 1.007316E+04, 7.339244E+02, - 3.030684E+05, 6.215015E-05, 0.000000E+00, 0.000000E+00, 0.000000E+00, 0.000000E+00, - 3.354057E-08, 0.000000E+00, 7.575931E-01, 1.221395E-01, 1.202674E-01, 8.951913E+00, - 1.980881E+06, 1.869358E+02, 3.075959E+02, 3.080320E+02, 6.521049E+04, 1.051327E+04, - 1.035212E+04, 5.231004E+04, 9.115127E+03, 8.709983E+01, 0.000000E+00, 8.607588E+04, - 7.572375E+04, 0.000000E+00, 0.000000E+00, 6.233132E+06, 3.475308E+06, 2.375755E-01, - 0.000000E+00, 1.436540E+06, 0.000000E+00, 1.103374E+03, 1.443378E+03, 6.422060E-05, - 0.000000E+00, 0.000000E+00, 0.000000E+00, 1.428432E-02, 4.753889E+01, 7.038322E-05, - 3.776984E+01, 4.129422E+02, 8.468194E-08, 8.468194E-08, 7.952135E-01, 2.047865E-01, - 3.483044E+10, 8.969672E+09, 1.003638E+10, 3.405106E+09, 1.084520E+09, 2.292876E+02, - 0.000000E+00, 5.836104E+08, 0.000000E+00 - }}; - - auto data = spe1.data; - - auto pred_rgs00002_ts97 = [](const NexusData& d){ - return is::instancename( "RGS00002" )(d) - && is::timestep( 97 )(d); - }; - std::vector< NexusData > rgs00002_ts97; - std::copy_if( data.begin(), data.end(), std::back_inserter( rgs00002_ts97 ), - pred_rgs00002_ts97 ); - - // Test the test - test_assert_int_equal( rgs00002_ts97_values.size(), - spe1_varnames[3].size() ); - test_assert_int_equal( rgs00002_ts97_values.size(), - rgs00002_ts97.size() ); - for (size_t i = 0; i < rgs00002_ts97.size(); i++) { - auto cn = get::classname_str(rgs00002_ts97[i]); - auto vn = get::varname_str(rgs00002_ts97[i]); - test_assert_string_equal( cn.c_str(), spe1_classnames[3].c_str() ); - test_assert_string_equal( vn.c_str(), spe1_varnames[3][i].c_str() ); - test_assert_float_equal( rgs00002_ts97[i].value, - rgs00002_ts97_values[i] ); - - } -} - -void test_spe1_class_varnames(const NexusPlot& plt) { - auto data = plt.data; - - for (size_t i = 0; i < spe1_classnames.size(); i++) { - auto vn = varnames( plt, spe1_classnames[i] ); - auto spe1_varnames_sorted = spe1_varnames[i]; - std::sort( spe1_varnames_sorted.begin(), spe1_varnames_sorted.end() ); - - test_assert_int_equal( vn.size(), - spe1_varnames_sorted.size() ); - for (size_t k = 0; k < vn.size(); k++) { - test_assert_string_equal( vn[k].c_str(), - spe1_varnames_sorted[k].c_str() ); - } - } -} - - -int main(int argc, char* argv[]) { - const auto spe1 = load("test-data/SPE1.plt"); - - test_spe1_header(spe1); - test_spe1_classes(spe1); - test_spe1_timesteps(spe1); - test_spe1_well_comulative_gas_injected(spe1); - test_spe1_region_rgs00002_ts97_all_variables(spe1); - test_spe1_class_varnames(spe1); - return 0; -} diff --git a/lib/tests/nexus_unit.cpp b/lib/tests/nexus_unit.cpp deleted file mode 100644 index 99fbd94..0000000 --- a/lib/tests/nexus_unit.cpp +++ /dev/null @@ -1,109 +0,0 @@ - -#include -#include - -#include - -#include - - -void test_metric_bars_units() { - const nex::UnitSystem u( nex::UnitSystem::UnitType::metric_bars ); - - auto compressibility = u.unit_str(nex::UnitSystem::Measure::compressibility); - auto concentration = u.unit_str(nex::UnitSystem::Measure::concentration); - auto density = u.unit_str(nex::UnitSystem::Measure::density); - auto formation_volume_factor_gas = u.unit_str(nex::UnitSystem::Measure::formation_volume_factor_gas); - auto formation_volume_factor_oil = u.unit_str(nex::UnitSystem::Measure::formation_volume_factor_oil); - auto fraction = u.unit_str(nex::UnitSystem::Measure::fraction); - auto gas_liquid_ratio = u.unit_str(nex::UnitSystem::Measure::gas_liquid_ratio); - auto identity = u.unit_str(nex::UnitSystem::Measure::identity); - auto length = u.unit_str(nex::UnitSystem::Measure::length); - auto moles = u.unit_str(nex::UnitSystem::Measure::moles); - auto permeability = u.unit_str(nex::UnitSystem::Measure::permeability); - auto pressure = u.unit_str(nex::UnitSystem::Measure::pressure); - auto pressure_absolute = u.unit_str(nex::UnitSystem::Measure::pressure_absolute); - auto reservoir_rates = u.unit_str(nex::UnitSystem::Measure::reservoir_rates); - auto reservoir_volumes = u.unit_str(nex::UnitSystem::Measure::reservoir_volumes); - auto surface_rates_gas = u.unit_str(nex::UnitSystem::Measure::surface_rates_gas); - auto surface_rates_liquid = u.unit_str(nex::UnitSystem::Measure::surface_rates_liquid); - auto surface_volumes_gas = u.unit_str(nex::UnitSystem::Measure::surface_volumes_gas); - auto surface_volumes_liquid = u.unit_str(nex::UnitSystem::Measure::surface_volumes_liquid); - auto temperature = u.unit_str(nex::UnitSystem::Measure::temperature); - auto time = u.unit_str(nex::UnitSystem::Measure::time); - auto viscosity = u.unit_str(nex::UnitSystem::Measure::viscosity); - auto volume = u.unit_str(nex::UnitSystem::Measure::volume); - auto water_cut = u.unit_str(nex::UnitSystem::Measure::water_cut); - - test_assert_string_equal( compressibility.c_str(), "BARS-1"); - test_assert_string_equal( concentration.c_str(), "KG/SM3"); - test_assert_string_equal( density.c_str(), "KG/M3"); - test_assert_string_equal( formation_volume_factor_gas.c_str(), "RM3/SM3"); - test_assert_string_equal( formation_volume_factor_oil.c_str(), "RM3/SM3"); - test_assert_string_equal( fraction.c_str(), ""); - test_assert_string_equal( gas_liquid_ratio.c_str(), "SM3/SM3"); - test_assert_string_equal( identity.c_str(), ""); - test_assert_string_equal( length.c_str(), "M"); - test_assert_string_equal( moles.c_str(), "KG-M"); - test_assert_string_equal( permeability.c_str(), "MD"); - test_assert_string_equal( pressure.c_str(), "BARS"); - test_assert_string_equal( pressure_absolute.c_str(), "BARSA"); - test_assert_string_equal( reservoir_rates.c_str(), "RM3/DAY"); - test_assert_string_equal( reservoir_volumes.c_str(), "RM3"); - test_assert_string_equal( surface_rates_gas.c_str(), "SM3/DAY"); - test_assert_string_equal( surface_rates_liquid.c_str(), "SM3/DAY"); - test_assert_string_equal( surface_volumes_gas.c_str(), "SM3"); - test_assert_string_equal( surface_volumes_liquid.c_str(), "SM3"); - test_assert_string_equal( temperature.c_str(), "C"); - test_assert_string_equal( time.c_str(), "DAY"); - test_assert_string_equal( viscosity.c_str(), "CP"); - test_assert_string_equal( volume.c_str(), "M3"); - test_assert_string_equal( water_cut.c_str(), "SM3/SM3"); -} - - -namespace { - void test_single_conversion( const nex::UnitSystem& u, - nex::UnitSystem::Measure measure, - float n, - float expected_conversion ) { - float c = n * u.conversion( measure ); - test_assert_float_equal( n, c / expected_conversion ); - } -} - -void test_metric_conversions() { - const nex::UnitSystem u( nex::UnitSystem::UnitType::metric_bars ); - std::default_random_engine gen; - std::uniform_real_distribution dist( -1e20, 1e20 ); - - test_single_conversion( u, nex::UnitSystem::Measure::compressibility, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::density, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::formation_volume_factor_gas, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::formation_volume_factor_oil, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::fraction, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::gas_liquid_ratio, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::identity, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::length, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::moles, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::permeability, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::pressure, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::pressure_absolute, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::reservoir_rates, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::reservoir_volumes, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::surface_rates_gas, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::surface_rates_liquid, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::surface_volumes_gas, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::surface_volumes_liquid, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::temperature, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::time, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::viscosity, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::volume, dist(gen), 1.0f ); - test_single_conversion( u, nex::UnitSystem::Measure::water_cut, dist(gen), 1.0f ); -} - -int main(int argc, char **argv) { - test_metric_bars_units(); - test_metric_conversions(); - exit(0); -} diff --git a/lib/tests/spe1.cpp b/lib/tests/spe1.cpp new file mode 100644 index 0000000..a9aa167 --- /dev/null +++ b/lib/tests/spe1.cpp @@ -0,0 +1,197 @@ +/* + Copyright (C) 2017 Statoil ASA, Norway. + + The file 'spe1.cpp' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 at + for more details. +*/ +#include + +#include + +#include + +using namespace nex; + +namespace { + const std::vector< std::string > spe1_classnames {{ + "WELL", "NODE", "CONN", "REGION", "FIELD", "CONNLIST" + }}; + const std::array< int, 9 > spe1_vars_in_class {{ + 56, 52, 4, 43, 69, 58, 20, 25, 25 + }}; + const std::array< int, 10 > spe1_timesteps {{ + 33, 46, 59, 72, 85, 89, 91, 92, 94, 97 + }}; + const std::array< std::vector< std::string >, 9 > spe1_varnames {{ + std::vector< std::string > {{ + "COP" , "CGP" , "CWP" , "CGI" , "CWI" , "QOP" , "QGP" , "QWP" , + "QGI" , "QWI" , "BHP" , "WPH" , "WKH" , "WPAV", "THP" , "COWP", + "QOWP", "GOR" , "WCUT", "WOR" , "QGLG", "CGLG", "DRDN", "DRMX", + "CROP", "CRGP", "CRWP", "CROI", "CRGI", "CRWI", "ROP" , "RGP" , + "RWP" , "ROI" , "RGI" , "RWI" , "ONTM", "ALQ" , "API" , "QCDP", + "CCDP", "YCDP", "ACTV", "STAT", "Q1P" , "Q1I" , "C1P" , "C1I" , + "X1P" , "Y1P" , "Q2P" , "Q2I" , "C2P" , "C2I" , "X2P" , "Y2P" + }}, + std::vector< std::string > {{ + "PNOD", "PDAT", "TNOD", "ACTV" + }}, + std::vector< std::string > {{ + "QGAS", "QOIL", "QWTR", "CGAS", "COIL", "CWTR", "CBFG", "CBFO", + "CBFW", "QGIS", "QOIS", "QWIS", "P_IN", "POUT", "T_IN", "TOUT", + "ACTV", "STAT", "CSTR", "ITRG", "ONTM", "ALQ" , "SETM", "SETA", + "POWM", "POWA", "SPDM", "SPDA", "API" , "DELP", "QTOT", "GVF" , + "EFF" , "POSN", "WCUT", "GOR" , "WOR" , "Q1" , "Q2" , "X1" , + "X2" , "Y1" , "Y2" + }}, + std::vector< std::string > {{ + "COP" , "CGP" , "CWP" , "COI" , "CGI" , "CWI" , "PAVT", "PAVH", + "OIP" , "GIP" , "WIP" , "QOP" , "QGP" , "QWP" , "QOI" , "QGI" , + "QWI" , "OIN" , "GIN" , "WIN" , "SO" , "SG" , "SW" , "OREC", + "FGIP", "CIP" , "PAVE", "PAVD", "ROIP", "RGIP", "RWIP", "MRO" , + "MRG" , "MRW" , "NFLX", "PV" , "HCPV", "TAVT", "TAVH", "CROP", + "CRGP", "CRWP", "CROI", "CRGI", "CRWI", "ROP" , "RGP" , "RWP" , + "ROI" , "RGI" , "RWI" , "QCDP", "CCDP", "YCDP", "API" , "GOR" , + "WCUT", "WOR" , "Z1" , "Z2" , "MC1" , "MC2" , "MC3" , "C1P" , + "C2P" , "C3P" , "C1I" , "C2I" , "C3I" + }}, + std::vector< std::string > {{ + "COP" , "CGP" , "CWP" , "CGI" , "CWI" , "QOP" , "QGP" , "QWP" , + "QGI" , "QWI" , "COWP", "QOWP", "GOR" , "OREC", "GREC", "PAVT", + "PAVH", "QGLG", "CGLG", "WCUT", "NFLX", "CROP", "CRGP", "CRWP", + "CROI", "CRGI", "CRWI", "ROP" , "RGP" , "RWP" , "ROI" , "RGI" , + "RWI" , "OIP" , "GIP" , "WIP" , "QCDP", "CCDP", "YCDP", "WLLS", + "PRDW", "GLFW", "WINJ", "GINJ", "ACTW", "API" , "Q1P" , "Q1I" , + "C1P" , "C1I" , "X1P" , "Y1P" , "Q2P" , "Q2I" , "C2P" , "C2I" , + "X2P" , "Y2P" + }}, + std::vector< std::string > {{ + "QOP", "QGP", "QWP", "QOI", "QGI", "QWI" , "COP", "CGP", + "CWP", "COI", "CGI", "CWI", "API", "WCUT", "GOR", "WOR", + "Q1P", "Q1I", "Q2P", "Q2I" + }} + }}; + + const auto spe1 = load("test-data/SPE1.plt"); +} + +SCENARIO( "spe1", "[spe1]") { WHEN( "loading nexus plot file" ) { + + THEN( "header is correct" ) { + CHECK( spe1.header.num_classes == 9 ); + CHECK( spe1.header.day == 1 ); + CHECK( spe1.header.month == 1 ); + CHECK( spe1.header.year == 1980 ); + CHECK( spe1.header.nx == 1 ); + CHECK( spe1.header.ny == 1 ); + CHECK( spe1.header.nz == 1 ); + CHECK( spe1.header.ncomp == 2 ); + } + + THEN( "classes are correct" ) { + auto classes = unique( spe1, get::classname_str ); + for (const auto& c : classes) { + auto f = std::find( spe1_classnames.begin(), spe1_classnames.end(), c ); + CHECK( f != spe1_classnames.end() ); + } + } + + THEN( "timesteps are correct" ) { + auto data = spe1.data; + std::vector< int32_t > timesteps; + std::transform( data.begin(), data.end(), std::back_inserter( timesteps ), + get::timestep ); + std::sort( timesteps.begin(), timesteps.end() ); + timesteps.erase( std::unique( timesteps.begin(), timesteps.end() ), + timesteps.end() ); + + for (size_t i = 0; i < timesteps.size(); i++) { + CHECK( timesteps[i] == spe1_timesteps[i] ); + } + } + + THEN( "well comulative gas injected is correct" ) { + std::vector< float > cgi_all_timesteps {{ + 6.222797E+08, 6.291119E+08, 6.291336E+08, 6.291336E+08, 6.291336E+08, + 6.291336E+08, 6.291336E+08, 6.291336E+08, 6.291336E+08, 6.291336E+08 + }}; + + auto data = spe1.data; + auto pred_well_1_cgi = [](const NexusData& d) { + return is::classname("WELL")(d) + && is::instancename("1")(d) + && is::varname("CGI")(d); + }; + std::vector< NexusData > well_1_cgi; + std::copy_if( data.begin(), data.end(), std::back_inserter( well_1_cgi ), + pred_well_1_cgi ); + + CHECK( well_1_cgi.size() == cgi_all_timesteps.size() ); + for (size_t i = 0; i < cgi_all_timesteps.size(); i++) { + CHECK( get::varname_str(well_1_cgi[i]) == std::string { "CGI" } ); + CHECK( well_1_cgi[i].value == Approx(cgi_all_timesteps[i]) ); + } + } + + THEN( "all region rgs00002 ts97 variables are correct" ) { + std::vector< float > rgs00002_ts97_values {{ + 4.011786E+06, 1.171299E+09, 2.301113E-01, 0.000000E+00, 6.291336E+08, 0.000000E+00, + 3.071745E+02, 3.076096E+02, 4.116595E+04, 9.679420E+06, 1.007316E+04, 7.339244E+02, + 3.030684E+05, 6.215015E-05, 0.000000E+00, 0.000000E+00, 0.000000E+00, 0.000000E+00, + 3.354057E-08, 0.000000E+00, 7.575931E-01, 1.221395E-01, 1.202674E-01, 8.951913E+00, + 1.980881E+06, 1.869358E+02, 3.075959E+02, 3.080320E+02, 6.521049E+04, 1.051327E+04, + 1.035212E+04, 5.231004E+04, 9.115127E+03, 8.709983E+01, 0.000000E+00, 8.607588E+04, + 7.572375E+04, 0.000000E+00, 0.000000E+00, 6.233132E+06, 3.475308E+06, 2.375755E-01, + 0.000000E+00, 1.436540E+06, 0.000000E+00, 1.103374E+03, 1.443378E+03, 6.422060E-05, + 0.000000E+00, 0.000000E+00, 0.000000E+00, 1.428432E-02, 4.753889E+01, 7.038322E-05, + 3.776984E+01, 4.129422E+02, 8.468194E-08, 8.468194E-08, 7.952135E-01, 2.047865E-01, + 3.483044E+10, 8.969672E+09, 1.003638E+10, 3.405106E+09, 1.084520E+09, 2.292876E+02, + 0.000000E+00, 5.836104E+08, 0.000000E+00 + }}; + + auto data = spe1.data; + + auto pred_rgs00002_ts97 = [](const NexusData& d){ + return is::instancename( "RGS00002" )(d) + && is::timestep( 97 )(d); + }; + std::vector< NexusData > rgs00002_ts97; + std::copy_if( data.begin(), data.end(), std::back_inserter( rgs00002_ts97 ), + pred_rgs00002_ts97 ); + + // Test the test + CHECK( rgs00002_ts97_values.size() == spe1_varnames[3].size() ); + CHECK( rgs00002_ts97_values.size() == rgs00002_ts97.size() ); + + for (size_t i = 0; i < rgs00002_ts97.size(); i++) { + CHECK( get::classname_str(rgs00002_ts97[i]) == std::string { "REGION" } ); + CHECK( get::varname_str(rgs00002_ts97[i]) == spe1_varnames[3][i] ); + CHECK( rgs00002_ts97[i].value == Approx(rgs00002_ts97_values[i]) ); + } + } + + THEN( "test spe1 class varnames are correct" ) { + auto data = spe1.data; + + for (size_t i = 0; i < spe1_classnames.size(); i++) { + auto vn = varnames( spe1, spe1_classnames[i] ); + auto spe1_varnames_sorted = spe1_varnames[i]; + std::sort( spe1_varnames_sorted.begin(), spe1_varnames_sorted.end() ); + + CHECK( vn.size() == spe1_varnames_sorted.size() ); + for (size_t k = 0; k < vn.size(); k++) { + CHECK( vn[k] == spe1_varnames_sorted[k] ); + } + } + } +}} diff --git a/lib/tests/units.cpp b/lib/tests/units.cpp new file mode 100644 index 0000000..d55082a --- /dev/null +++ b/lib/tests/units.cpp @@ -0,0 +1,121 @@ +/* + Copyright (C) 2017 Statoil ASA, Norway. + + The file 'units.cpp' is part of ERT - Ensemble based Reservoir Tool. + + ERT 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. + + ERT 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 at + for more details. +*/ +#include +#include + +#include + +#include + +namespace { + +void test_single_conversion( const nex::UnitSystem& u, + nex::UnitSystem::Measure measure, + float n, + float expected_conversion ) { + float c = n * u.conversion( measure ); + CHECK( n == Approx(c / expected_conversion) ); +} + +} + +TEST_CASE( "unit conversions", "[units]") { + const nex::UnitSystem u( nex::UnitSystem::UnitType::metric_bars ); + + SECTION( "metric bars units" ) { + auto compressibility = u.unit_str(nex::UnitSystem::Measure::compressibility); + auto concentration = u.unit_str(nex::UnitSystem::Measure::concentration); + auto density = u.unit_str(nex::UnitSystem::Measure::density); + auto formation_volume_factor_gas = u.unit_str(nex::UnitSystem::Measure::formation_volume_factor_gas); + auto formation_volume_factor_oil = u.unit_str(nex::UnitSystem::Measure::formation_volume_factor_oil); + auto fraction = u.unit_str(nex::UnitSystem::Measure::fraction); + auto gas_liquid_ratio = u.unit_str(nex::UnitSystem::Measure::gas_liquid_ratio); + auto identity = u.unit_str(nex::UnitSystem::Measure::identity); + auto length = u.unit_str(nex::UnitSystem::Measure::length); + auto moles = u.unit_str(nex::UnitSystem::Measure::moles); + auto permeability = u.unit_str(nex::UnitSystem::Measure::permeability); + auto pressure = u.unit_str(nex::UnitSystem::Measure::pressure); + auto pressure_absolute = u.unit_str(nex::UnitSystem::Measure::pressure_absolute); + auto reservoir_rates = u.unit_str(nex::UnitSystem::Measure::reservoir_rates); + auto reservoir_volumes = u.unit_str(nex::UnitSystem::Measure::reservoir_volumes); + auto surface_rates_gas = u.unit_str(nex::UnitSystem::Measure::surface_rates_gas); + auto surface_rates_liquid = u.unit_str(nex::UnitSystem::Measure::surface_rates_liquid); + auto surface_volumes_gas = u.unit_str(nex::UnitSystem::Measure::surface_volumes_gas); + auto surface_volumes_liquid = u.unit_str(nex::UnitSystem::Measure::surface_volumes_liquid); + auto temperature = u.unit_str(nex::UnitSystem::Measure::temperature); + auto time = u.unit_str(nex::UnitSystem::Measure::time); + auto viscosity = u.unit_str(nex::UnitSystem::Measure::viscosity); + auto volume = u.unit_str(nex::UnitSystem::Measure::volume); + auto water_cut = u.unit_str(nex::UnitSystem::Measure::water_cut); + + CHECK( compressibility == "BARS-1"); + CHECK( concentration == "KG/SM3"); + CHECK( density == "KG/M3"); + CHECK( formation_volume_factor_gas == "RM3/SM3"); + CHECK( formation_volume_factor_oil == "RM3/SM3"); + CHECK( fraction == ""); + CHECK( gas_liquid_ratio == "SM3/SM3"); + CHECK( identity == ""); + CHECK( length == "M"); + CHECK( moles == "KG-M"); + CHECK( permeability == "MD"); + CHECK( pressure == "BARS"); + CHECK( pressure_absolute == "BARSA"); + CHECK( reservoir_rates == "RM3/DAY"); + CHECK( reservoir_volumes == "RM3"); + CHECK( surface_rates_gas == "SM3/DAY"); + CHECK( surface_rates_liquid == "SM3/DAY"); + CHECK( surface_volumes_gas == "SM3"); + CHECK( surface_volumes_liquid == "SM3"); + CHECK( temperature == "C"); + CHECK( time == "DAY"); + CHECK( viscosity == "CP"); + CHECK( volume == "M3"); + CHECK( water_cut == "SM3/SM3"); + } + + SECTION( "metric conversions" ) { + std::default_random_engine gen; + std::uniform_real_distribution dist( -1e20, 1e20 ); + + test_single_conversion( u, nex::UnitSystem::Measure::compressibility, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::density, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::formation_volume_factor_gas, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::formation_volume_factor_oil, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::fraction, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::gas_liquid_ratio, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::identity, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::length, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::moles, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::permeability, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::pressure, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::pressure_absolute, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::reservoir_rates, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::reservoir_volumes, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::surface_rates_gas, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::surface_rates_liquid, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::surface_volumes_gas, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::surface_volumes_liquid, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::temperature, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::time, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::viscosity, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::volume, dist(gen), 1.0f ); + test_single_conversion( u, nex::UnitSystem::Measure::water_cut, dist(gen), 1.0f ); + + } +}