From d84b7e19eea7d3de9c7f7a98945f819f2322dd3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 11 Oct 2019 01:04:23 -0500 Subject: [PATCH 1/6] ESmry: Add Way of Retrieving Ministep Index at Start of Report Step This commit introduces a new member function int ESmry::miniStepIdxAtReportStep(rptStep) which returns the zero-based ministep corresponding to the start of the given report step (one-based indexing). This will simplify decoupling a few unit tests from libecl. --- opm/io/eclipse/ESmry.hpp | 2 ++ src/opm/io/eclipse/ESmry.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/opm/io/eclipse/ESmry.hpp b/opm/io/eclipse/ESmry.hpp index a2424336c..da29b8b6d 100644 --- a/opm/io/eclipse/ESmry.hpp +++ b/opm/io/eclipse/ESmry.hpp @@ -39,6 +39,8 @@ public: const std::vector& keywordList() const { return keyword; } + int timestepIdxAtReportstepStart(const int reportStep) const; + private: int nVect, nI, nJ, nK; std::string path=""; diff --git a/src/opm/io/eclipse/ESmry.cpp b/src/opm/io/eclipse/ESmry.cpp index 3aea0491f..e11a5fbe6 100644 --- a/src/opm/io/eclipse/ESmry.cpp +++ b/src/opm/io/eclipse/ESmry.cpp @@ -18,6 +18,7 @@ #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include @@ -442,4 +444,18 @@ std::vector ESmry::get_at_rstep(const std::string& name) const return rstep_vector; } +int ESmry::timestepIdxAtReportstepStart(const int reportStep) const +{ + const auto nReport = static_cast(seqIndex.size()); + + if ((reportStep < 1) || (reportStep > nReport)) { + throw std::invalid_argument { + "Report step " + std::to_string(reportStep) + + " outside valid range 1 .. " + std::to_string(nReport) + }; + } + + return seqIndex[reportStep - 1]; +} + }} // namespace Opm::ecl From bcfe700461040983a819055f11cd7d1270ca6231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 11 Oct 2019 01:10:56 -0500 Subject: [PATCH 2/6] Decouple Most of OPM-Common From LibECL This commit takes a pass at the implementation files in opm-common and removes references to libecl functions where practical. In particular we switch to using types from C++'s standard library (and Boost.Filesystem) to achieve the effects of the interfaces being replaced. We also insert direct calls to Posix function fnmatch() to preserve existing pattern matching behaviour (well lists and well templates). --- .../EclipseState/IOConfig/IOConfig.hpp | 2 +- src/opm/output/eclipse/EclipseIO.cpp | 62 ++++++++++++------- .../eclipse/EclipseState/Grid/GridDims.cpp | 16 ++--- .../EclipseState/IOConfig/IOConfig.cpp | 29 +++++++-- .../EclipseState/IOConfig/RestartConfig.cpp | 29 ++++++--- .../parser/eclipse/EclipseState/Runspec.cpp | 12 ++-- .../EclipseState/Schedule/Well/Well2.cpp | 4 +- .../parser/eclipse/Parser/ParseContext.cpp | 5 +- .../parser/eclipse/Parser/raw/StarToken.cpp | 7 ++- .../parser/eclipse/Parser/raw/StarToken.hpp | 6 +- 10 files changed, 110 insertions(+), 62 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp b/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp index 73f7409bd..48e38e489 100644 --- a/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp +++ b/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp @@ -20,7 +20,7 @@ #ifndef OPM_IO_CONFIG_HPP #define OPM_IO_CONFIG_HPP -#include +#include namespace Opm { diff --git a/src/opm/output/eclipse/EclipseIO.cpp b/src/opm/output/eclipse/EclipseIO.cpp index acfada85e..6fadcf95d 100644 --- a/src/opm/output/eclipse/EclipseIO.cpp +++ b/src/opm/output/eclipse/EclipseIO.cpp @@ -49,15 +49,14 @@ #include #include #include // unique_ptr +#include +#include #include #include // move -#include -#include -#include +#include +#include -// namespace start here since we don't want the ERT headers in it -namespace Opm { namespace { inline std::string uppercase( std::string x ) { @@ -67,8 +66,34 @@ inline std::string uppercase( std::string x ) { return x; } +void ensure_directory_exists( const boost::filesystem::path& odir ) +{ + namespace fs = boost::filesystem; + + if (fs::exists( odir ) && !fs::is_directory( odir )) + throw std::runtime_error { + "Filesystem element '" + odir.generic_string() + + "' already exists but is not a directory" + }; + + boost::system::error_code ec{}; + if (! fs::exists( odir )) + fs::create_directories( odir, ec ); + + if (ec != boost::system::errc::success) { + std::ostringstream msg; + + msg << "Failed to create output directory '" + << odir.generic_string() + << "\nSystem reports: " << ec << '\n'; + + throw std::runtime_error { msg.str() }; + } } +} + +namespace Opm { class EclipseIO::Impl { public: Impl( const EclipseState&, EclipseGrid, const Schedule&, const SummaryConfig& ); @@ -113,14 +138,16 @@ void EclipseIO::Impl::writeINITFile(const data::Solution& simP void EclipseIO::Impl::writeEGRIDFile( const NNC& nnc ) { - const auto& ioConfig = this->es.getIOConfig(); + const auto formatted = this->es.cfg().io().getFMTOUT(); - std::string egridFile( ERT::EclFilename( this->outputDir, - this->baseName, - ECL_EGRID_FILE, - ioConfig.getFMTOUT() )); + const auto ext = '.' + + (formatted ? std::string{"F"} : std::string{}) + + "EGRID"; - this->grid.save( egridFile, ioConfig.getFMTOUT(), nnc, this->es.getDeckUnitSystem()); + const auto egridFile = (boost::filesystem::path{ this->outputDir } + / (this->baseName + ext)).generic_string(); + + this->grid.save( egridFile, formatted, nnc, this->es.getDeckUnitSystem()); } /* @@ -236,19 +263,8 @@ EclipseIO::EclipseIO( const EclipseState& es, { if( !this->impl->output_enabled ) return; - { - const auto& outputDir = this->impl->outputDir; - // make sure that the output directory exists, if not try to create it - if ( !util_entry_exists( outputDir.c_str() ) ) { - util_make_path( outputDir.c_str() ); - } - - if( !util_is_directory( outputDir.c_str() ) ) { - throw std::runtime_error( "The path specified as output directory '" - + outputDir + "' is not a directory"); - } - } + ensure_directory_exists( this->impl->outputDir ); } const out::Summary& EclipseIO::summary() { diff --git a/src/opm/parser/eclipse/EclipseState/Grid/GridDims.cpp b/src/opm/parser/eclipse/EclipseState/Grid/GridDims.cpp index 894d73e1d..db3d1ceb4 100644 --- a/src/opm/parser/eclipse/EclipseState/Grid/GridDims.cpp +++ b/src/opm/parser/eclipse/EclipseState/Grid/GridDims.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include @@ -140,15 +140,11 @@ namespace Opm { void GridDims::binary_init(const Deck& deck) { const DeckKeyword& gdfile_kw = deck.getKeyword("GDFILE"); const std::string& gdfile_arg = gdfile_kw.getRecord(0).getItem("filename").get(0); - std::string filename = deck.makeDeckPath(gdfile_arg); - ecl_grid_dims_type * grid_dims = ecl_grid_dims_alloc( filename.c_str(), nullptr ); - if (grid_dims) { - const auto& dims = ecl_grid_dims_iget_dims(grid_dims, 0); - m_nx = dims->nx; - m_ny = dims->ny; - m_nz = dims->nz; - } else - throw std::invalid_argument("Could not determine grid dimensions from: " + filename); + const EclIO::EGrid egrid( deck.makeDeckPath(gdfile_arg) ); + const auto& dimens = egrid.dimension(); + m_nx = dimens[0]; + m_ny = dimens[1]; + m_nz = dimens[2]; } } diff --git a/src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp b/src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp index 28a1eb48e..93cecf057 100644 --- a/src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp +++ b/src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp @@ -17,9 +17,10 @@ along with OPM. If not, see . */ -#include +#include #include #include +#include #include #include @@ -32,9 +33,6 @@ #include #include -#include - - namespace Opm { namespace { @@ -190,9 +188,28 @@ namespace Opm { std::string IOConfig::getRestartFileName(const std::string& restart_base, int report_step, bool output) const { bool unified = output ? getUNIFOUT() : getUNIFIN(); bool fmt_file = output ? getFMTOUT() : getFMTIN(); - ecl_file_enum file_type = (unified) ? ECL_UNIFIED_RESTART_FILE : ECL_RESTART_FILE; - return ERT::EclFilename( restart_base , file_type , report_step , fmt_file ); + auto ext = std::string{}; + if (unified) { + ext = fmt_file ? "FUNRST" : "UNRST"; + } + else { + std::ostringstream os; + + const char* fmt_prefix = "FGH"; + const char* unfmt_prefix = "XYZ"; + + const int cycle = 10 * 1000; + const int p_ix = report_step / cycle; + const int n = report_step % cycle; + + os << (fmt_file ? fmt_prefix[p_ix] : unfmt_prefix[p_ix]) + << std::setw(4) << std::setfill('0') << n; + + ext = os.str(); + } + + return restart_base + '.' + ext; } diff --git a/src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp b/src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp index 91ac22008..e86f176ff 100644 --- a/src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp +++ b/src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp @@ -20,13 +20,13 @@ #include #include #include +#include +#include #include #include -#include - #include #include #include @@ -708,12 +708,27 @@ void RestartConfig::handleScheduleSection(const SCHEDULESection& schedule, const std::string RestartConfig::getRestartFileName(const std::string& restart_base, int report_step, bool unified , bool fmt_file) { - ecl_file_enum file_type = (unified) ? ECL_UNIFIED_RESTART_FILE : ECL_RESTART_FILE; - char * c_str = ecl_util_alloc_filename( NULL , restart_base.c_str() , file_type, fmt_file , report_step); - std::string restart_filename = c_str; - free( c_str ); + auto ext = std::string{}; + if (unified) { + ext = fmt_file ? "FUNRST" : "UNRST"; + } + else { + std::ostringstream os; - return restart_filename; + const char* fmt_prefix = "FGH"; + const char* unfmt_prefix = "XYZ"; + + const int cycle = 10 * 1000; + const int p_ix = report_step / cycle; + const int n = report_step % cycle; + + os << (fmt_file ? fmt_prefix[p_ix] : unfmt_prefix[p_ix]) + << std::setw(4) << std::setfill('0') << n; + + ext = os.str(); + } + + return restart_base + '.' + ext; } diff --git a/src/opm/parser/eclipse/EclipseState/Runspec.cpp b/src/opm/parser/eclipse/EclipseState/Runspec.cpp index b86839c1f..cd91edd93 100644 --- a/src/opm/parser/eclipse/EclipseState/Runspec.cpp +++ b/src/opm/parser/eclipse/EclipseState/Runspec.cpp @@ -19,8 +19,6 @@ #include #include -#include - #include #include #include @@ -249,9 +247,13 @@ const EclHysterConfig& Runspec::hysterPar() const noexcept available phases in Eclipse restart and init files. */ int Runspec::eclPhaseMask( ) const noexcept { - return ( active_phases.active( Phase::WATER ) ? ECL_WATER_PHASE : 0 ) - | ( active_phases.active( Phase::OIL ) ? ECL_OIL_PHASE : 0 ) - | ( active_phases.active( Phase::GAS ) ? ECL_GAS_PHASE : 0 ); + const int water = 1 << 2; + const int oil = 1 << 0; + const int gas = 1 << 1; + + return ( active_phases.active( Phase::WATER ) ? water : 0 ) + | ( active_phases.active( Phase::OIL ) ? oil : 0 ) + | ( active_phases.active( Phase::GAS ) ? gas : 0 ); } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.cpp index 3a45afbf3..a45c3bbee 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include namespace Opm { @@ -728,7 +728,7 @@ double Well2::injection_rate(const SummaryState& st, Phase phase_arg) const { bool Well2::wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern) { bool wellNameInPattern = false; - if (util_fnmatch( wellNamePattern.c_str() , wellName.c_str()) == 0) { + if (fnmatch( wellNamePattern.c_str() , wellName.c_str() , 0 ) == 0) { wellNameInPattern = true; } return wellNameInPattern; diff --git a/src/opm/parser/eclipse/Parser/ParseContext.cpp b/src/opm/parser/eclipse/Parser/ParseContext.cpp index e15784619..42281a944 100644 --- a/src/opm/parser/eclipse/Parser/ParseContext.cpp +++ b/src/opm/parser/eclipse/Parser/ParseContext.cpp @@ -21,7 +21,8 @@ #include #include -#include + +#include #include #include @@ -266,7 +267,7 @@ namespace Opm { const char * c_pattern = pattern.c_str(); for (const auto& pair : m_errorContexts) { const std::string& key = pair.first; - if (util_fnmatch( c_pattern , key.c_str()) == 0) + if (fnmatch( c_pattern , key.c_str() , 0 ) == 0) updateKey( key , action ); } } diff --git a/src/opm/parser/eclipse/Parser/raw/StarToken.cpp b/src/opm/parser/eclipse/Parser/raw/StarToken.cpp index d4ee0e406..560072ab8 100644 --- a/src/opm/parser/eclipse/Parser/raw/StarToken.cpp +++ b/src/opm/parser/eclipse/Parser/raw/StarToken.cpp @@ -143,13 +143,14 @@ namespace Opm { m_count = 1; } else { - m_count = std::stoi( m_countString ); + const auto cnt = std::stoi( m_countString ); - if (m_count == 0) + if (cnt < 1) // TODO: decorate the deck with a warning instead? throw std::invalid_argument("Specifing zero repetitions is not allowed. Token: \'" + token + "\'."); + + m_count = static_cast(cnt); } } } - diff --git a/src/opm/parser/eclipse/Parser/raw/StarToken.hpp b/src/opm/parser/eclipse/Parser/raw/StarToken.hpp index ded2f2c0c..675fee567 100644 --- a/src/opm/parser/eclipse/Parser/raw/StarToken.hpp +++ b/src/opm/parser/eclipse/Parser/raw/StarToken.hpp @@ -20,10 +20,10 @@ #ifndef STAR_TOKEN_HPP #define STAR_TOKEN_HPP +#include #include #include -#include namespace Opm { bool isStarToken(const string_view& token, @@ -49,7 +49,7 @@ public: init_(token); } - size_t count() const { + std::size_t count() const { return m_count; } @@ -78,7 +78,7 @@ private: // must be set before calling this method. void init_(const string_view& token); - ssize_t m_count; + std::size_t m_count; std::string m_countString; std::string m_valueString; }; From c013639b51eb97c234fae28f3ab174dc2d9aceee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 11 Oct 2019 01:16:22 -0500 Subject: [PATCH 3/6] Make Most Unit Tests Independent of LibECL This commit switches a set of OPM-Common's unit tests away from using direct calls to libecl functions and into using base types from OPM-Common itself (along with Boost.Filesystem). In particular summary related queries are replaced by calls to ESmry member functions (wrapped in libecl-like interfaces to minimise code changes). We disable checks on unit strings since ESmry currently does not have a way of associating those with individual variables. --- tests/WorkArea.cpp | 66 +++++++++++++++++++++++++++ tests/msim/test_msim.cpp | 75 +++++++++++++++---------------- tests/msim/test_msim_ACTIONX.cpp | 74 ++++++++++++++++++------------ tests/parser/ACTIONX.cpp | 2 - tests/parser/EclipseGridTests.cpp | 2 - tests/parser/InitConfigTest.cpp | 14 +++--- tests/parser/RunspecTests.cpp | 6 ++- 7 files changed, 157 insertions(+), 82 deletions(-) create mode 100644 tests/WorkArea.cpp diff --git a/tests/WorkArea.cpp b/tests/WorkArea.cpp new file mode 100644 index 000000000..df36edc70 --- /dev/null +++ b/tests/WorkArea.cpp @@ -0,0 +1,66 @@ +/* + Copyright 2019 Equinor ASA. + + 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 . +*/ + +// NOTE: This file is inteded to be copy-pasted into user code +// through an #include statement. + +#include + +#include + +namespace { + class WorkArea + { + public: + explicit WorkArea(const std::string& subdir = "") + : root_(boost::filesystem::temp_directory_path() / + boost::filesystem::unique_path("wrk-%%%%")) + , area_(root_) + , orig_(boost::filesystem::current_path()) + { + if (! subdir.empty()) + this->area_ /= subdir; + + boost::filesystem::create_directories(this->area_); + boost::filesystem::current_path(this->area_); + } + + void copyIn(const std::string& filename) const + { + boost::filesystem::copy_file(this->orig_ / filename, + this->area_ / filename); + } + + void makeSubDir(const std::string& dirname) + { + boost::filesystem::create_directories(this->area_ / dirname); + } + + ~WorkArea() + { + boost::filesystem::current_path(this->orig_); + boost::filesystem::remove_all(this->root_); + } + + private: + boost::filesystem::path root_; + boost::filesystem::path area_; + boost::filesystem::path orig_; + }; +} // Anonymous diff --git a/tests/msim/test_msim.cpp b/tests/msim/test_msim.cpp index aa3c053e6..e1cc39708 100644 --- a/tests/msim/test_msim.cpp +++ b/tests/msim/test_msim.cpp @@ -17,22 +17,19 @@ along with OPM. If not, see . */ -#include -#include -#include - -#define BOOST_TEST_MODULE WTEST +#define BOOST_TEST_MODULE MSIM_BASIC #include -#include -#include -#include -#include -#include -#include - - #include + +#include +#include + +#include + +#include +#include + #include #include #include @@ -41,8 +38,11 @@ #include #include +#include + using namespace Opm; +namespace { double prod_opr(const EclipseState& es, const Schedule& /* sched */, const SummaryState&, const data::Solution& /* sol */, size_t /* report_step */, double seconds_elapsed) { const auto& units = es.getUnits(); @@ -59,6 +59,13 @@ void pressure(const EclipseState& es, const Schedule& /* sched */, data::Solutio std::fill(data.begin(), data.end(), units.to_si(UnitSystem::measure::pressure, seconds_elapsed)); } +bool is_file(const boost::filesystem::path& name) +{ + return boost::filesystem::exists(name) + && boost::filesystem::is_regular_file(name); +} + +} BOOST_AUTO_TEST_CASE(RUN) { Parser parser; @@ -71,45 +78,35 @@ BOOST_AUTO_TEST_CASE(RUN) { msim.well_rate("PROD", data::Rates::opt::oil, prod_opr); msim.solution("PRESSURE", pressure); { - test_work_area_type * work_area = test_work_area_alloc("test_msim"); + const WorkArea work_area("test_msim"); EclipseIO io(state, state.getInputGrid(), schedule, summary_config); msim.run(schedule, io, false); for (const auto& fname : {"SPE1CASE1.INIT", "SPE1CASE1.UNRST", "SPE1CASE1.EGRID", "SPE1CASE1.SMSPEC", "SPE1CASE1.UNSMRY"}) - BOOST_CHECK( util_is_file( fname )); + BOOST_CHECK( is_file( fname )); { - ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case("SPE1CASE1", ":"); - int param_index = ecl_sum_get_general_var_params_index(ecl_sum, "WOPR:PROD"); - for (int time_index=0; time_index < ecl_sum_get_data_length(ecl_sum); time_index++) { - double seconds_elapsed = ecl_sum_iget_sim_days(ecl_sum, time_index) * 86400; - double opr = ecl_sum_iget(ecl_sum, time_index, param_index); - BOOST_CHECK_CLOSE(seconds_elapsed, opr, 1e-3); + const auto smry = EclIO::ESmry("SPE1CASE1"); + const auto& time = smry.get("TIME"); + const auto& press = smry.get("WOPR:PROD"); + + for (auto nstep = time.size(), time_index=0*nstep; time_index < nstep; time_index++) { + double seconds_elapsed = time[time_index] * 86400; + BOOST_CHECK_CLOSE(seconds_elapsed, press[time_index], 1e-3); } - ecl_sum_free( ecl_sum ); } { - int report_step = 1; - ecl_file_type * rst_file = ecl_file_open("SPE1CASE1.UNRST", 0); - ecl_file_view_type * global_view = ecl_file_get_global_view( rst_file ); - while (true) { - ecl_file_view_type * rst_view = ecl_file_view_add_restart_view( global_view, -1, report_step, -1, -1); - if (!rst_view) - break; + auto rst = EclIO::ERst("SPE1CASE1.UNRST"); - { - ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_view, report_step); - const ecl_kw_type * p = ecl_file_view_iget_named_kw(rst_view, "PRESSURE", 0); - BOOST_CHECK_CLOSE( ecl_kw_iget_float(p, 0), rst_head->sim_days * 86400, 1e-3 ); - ecl_rsthead_free( rst_head ); - } - report_step++; + for (const auto& step : rst.listOfReportStepNumbers()) { + const auto& dh = rst.getRst("DOUBHEAD", step); + const auto& press = rst.getRst("PRESSURE", step); + + // DOUBHEAD[0] is elapsed time in days since start of simulation. + BOOST_CHECK_CLOSE( press[0], dh[0] * 86400, 1e-3 ); } - ecl_file_close(rst_file); } - - test_work_area_free( work_area ); } } diff --git a/tests/msim/test_msim_ACTIONX.cpp b/tests/msim/test_msim_ACTIONX.cpp index aa39e7cdb..f0cac7d77 100644 --- a/tests/msim/test_msim_ACTIONX.cpp +++ b/tests/msim/test_msim_ACTIONX.cpp @@ -17,16 +17,14 @@ along with OPM. If not, see . */ -#include -#include - #define BOOST_TEST_MODULE ACTIONX_SIM #include -#include -#include +#include +#include +#include #include #include @@ -40,13 +38,15 @@ #include #include +#include + #include -#include +#include using namespace Opm; - +namespace { struct test_data { Deck deck; @@ -118,6 +118,33 @@ double inj_wir_INJ(const EclipseState& , const Schedule& sched, const SummarySta return -99; } +bool ecl_sum_has_general_var(const EclIO::ESmry& smry, const std::string& var) +{ + return smry.hasKey(var); +} + +float ecl_sum_get_general_var(const EclIO::ESmry& smry, const int timeIdx, const std::string& var) +{ + return smry.get(var)[timeIdx]; +} + +int ecl_sum_get_data_length(const EclIO::ESmry& smry) +{ + return static_cast(smry.get("TIME").size()); +} + +int ecl_sum_get_last_report_step(const EclIO::ESmry& smry) +{ + return static_cast(smry.get_at_rstep("TIME").size()); +} + +int ecl_sum_iget_report_end(const EclIO::ESmry& smry, const int reportStep) +{ + return smry.timestepIdxAtReportstepStart(reportStep + 1) - 1; +} +} + + /* The deck tested here has a UDQ DEFINE statement which sorts the wells after oil production rate, and then subsequently closes the well with lowest OPR @@ -130,7 +157,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA_EXAMPLE) { test_data td( actionx ); msim sim(td.state); { - test_work_area_type * work_area = test_work_area_alloc("test_msim"); + WorkArea work_area("test_msim"); EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config); sim.well_rate("P1", data::Rates::opt::oil, prod_opr); @@ -151,8 +178,6 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA_EXAMPLE) { BOOST_CHECK(w1.getStatus() == Well2::Status::OPEN ); BOOST_CHECK(w4.getStatus() == Well2::Status::SHUT ); } - - test_work_area_free(work_area); } } @@ -163,7 +188,7 @@ BOOST_AUTO_TEST_CASE(WELL_CLOSE_EXAMPLE) { test_data td( actionx1 ); msim sim(td.state); { - test_work_area_type * work_area = test_work_area_alloc("test_msim"); + WorkArea work_area("test_msim"); EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config); sim.well_rate("P1", data::Rates::opt::oil, prod_opr); @@ -208,8 +233,6 @@ BOOST_AUTO_TEST_CASE(WELL_CLOSE_EXAMPLE) { BOOST_CHECK(w4_10.getStatus() == Well2::Status::OPEN ); BOOST_CHECK(w4_11.getStatus() == Well2::Status::SHUT ); } - - test_work_area_free(work_area); } } @@ -219,7 +242,7 @@ BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) { test_data td( actionx1 ); msim sim(td.state); { - test_work_area_type * work_area = test_work_area_alloc("test_msim"); + WorkArea work_area("test_msim"); EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config); sim.well_rate("P1", data::Rates::opt::oil, prod_opr); @@ -236,14 +259,16 @@ BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) { const auto& base_name = td.state.getIOConfig().getBaseName(); - ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( base_name.c_str(), ":"); + const EclIO::ESmry ecl_sum(base_name + ".SMSPEC"); BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUBHP:P1") ); BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUBHP:P2") ); BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUOPRL:P3") ); BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUOPRL:P4") ); +#if 0 BOOST_CHECK_EQUAL( ecl_sum_get_unit(ecl_sum, "WUBHP:P1"), "BARSA"); BOOST_CHECK_EQUAL( ecl_sum_get_unit(ecl_sum, "WUOPRL:P1"), "SM3/DAY"); +#endif BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUBHP:P1"), 11); BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUBHP:P2"), 12); @@ -254,9 +279,6 @@ BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) { BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUOPRL:P2"), 20); BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUOPRL:P3"), 20); BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUOPRL:P4"), 20); - ecl_sum_free( ecl_sum ); - - test_work_area_free(work_area); } } @@ -266,7 +288,7 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) { test_data td( actionx1 ); msim sim(td.state); { - test_work_area_type * work_area = test_work_area_alloc("test_msim"); + WorkArea work_area("test_msim"); EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config); sim.well_rate("P1", data::Rates::opt::oil, prod_opr); @@ -282,7 +304,7 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) { sim.run(td.schedule, io, false); const auto& base_name = td.state.getIOConfig().getBaseName(); - ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( base_name.c_str(), ":"); + const EclIO::ESmry ecl_sum(base_name + ".SMSPEC"); for (int step = 0; step < ecl_sum_get_data_length(ecl_sum); step++) { double wopr_sum = 0; @@ -300,9 +322,6 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) { ecl_sum_get_general_var(ecl_sum, step, "FUOPR")); BOOST_CHECK_EQUAL( wopr_sum, ecl_sum_get_general_var(ecl_sum, step, "FOPR")); } - - - test_work_area_free(work_area); } } @@ -319,15 +338,16 @@ BOOST_AUTO_TEST_CASE(UDA) { sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4); sim.well_rate("INJ", data::Rates::opt::wat, inj_wir_INJ); { - ecl::util::TestArea ta("uda_sim"); + WorkArea work_area("uda_sim"); sim.run(td.schedule, io, true); const auto& base_name = td.state.getIOConfig().getBaseName(); - ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( base_name.c_str(), ":"); + const EclIO::ESmry ecl_sum(base_name + ".SMSPEC"); // Should only get at report steps - for (int report_step = 2; report_step < ecl_sum_get_last_report_step(ecl_sum); report_step++) { + const auto last_report = ecl_sum_get_last_report_step(ecl_sum); + for (int report_step = 2; report_step < last_report; report_step++) { double wwpr_sum = 0; { int prev_tstep = ecl_sum_iget_report_end(ecl_sum, report_step - 1); @@ -338,7 +358,5 @@ BOOST_AUTO_TEST_CASE(UDA) { } BOOST_CHECK_CLOSE( 0.90 * wwpr_sum, ecl_sum_get_general_var(ecl_sum, ecl_sum_iget_report_end(ecl_sum, report_step), "WWIR:INJ"), 1e-3); } - - ecl_sum_free( ecl_sum ); } } diff --git a/tests/parser/ACTIONX.cpp b/tests/parser/ACTIONX.cpp index a435e7fa3..d400e1129 100644 --- a/tests/parser/ACTIONX.cpp +++ b/tests/parser/ACTIONX.cpp @@ -26,8 +26,6 @@ #include #include -#include - #include #include #include diff --git a/tests/parser/EclipseGridTests.cpp b/tests/parser/EclipseGridTests.cpp index 75c8785c1..f77efb6c9 100644 --- a/tests/parser/EclipseGridTests.cpp +++ b/tests/parser/EclipseGridTests.cpp @@ -30,8 +30,6 @@ #include #include -//#include - #include #include #include diff --git a/tests/parser/InitConfigTest.cpp b/tests/parser/InitConfigTest.cpp index 5f6b6fecd..93461244c 100644 --- a/tests/parser/InitConfigTest.cpp +++ b/tests/parser/InitConfigTest.cpp @@ -17,11 +17,7 @@ along with OPM. If not, see . */ - - #define BOOST_TEST_MODULE InitConfigTests -#include -#include #include @@ -31,7 +27,7 @@ #include #include -#include +#include using namespace Opm; @@ -188,8 +184,10 @@ BOOST_AUTO_TEST_CASE( EquilOperations ) { } BOOST_AUTO_TEST_CASE(RestartCWD) { - test_work_area_type * work_area = test_work_area_alloc("restart_cwd"); - mkdir("simulation", 0777); + WorkArea output_area; + + output_area.makeSubDir("simulation"); + { std::fstream fs; fs.open ("simulation/CASE.DATA", std::fstream::out); @@ -229,8 +227,6 @@ BOOST_AUTO_TEST_CASE(RestartCWD) { Opm::InitConfig init_config(deck); BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "/abs/path/BASE"); } - - test_work_area_free(work_area); } // -------------------------------------------------------------------- diff --git a/tests/parser/RunspecTests.cpp b/tests/parser/RunspecTests.cpp index ab2e3edd6..3b11c39c3 100644 --- a/tests/parser/RunspecTests.cpp +++ b/tests/parser/RunspecTests.cpp @@ -21,8 +21,6 @@ along with OPM. If not, see . #include -#include - #include #include #include @@ -60,6 +58,10 @@ BOOST_AUTO_TEST_CASE(TwoPhase) { BOOST_CHECK( !phases.active( Phase::GAS ) ); BOOST_CHECK( phases.active( Phase::WATER ) ); BOOST_CHECK( !phases.active( Phase::POLYMW ) ); + + const auto ECL_OIL_PHASE = 1 << 0; + const auto ECL_WATER_PHASE = 1 << 2; + BOOST_CHECK_EQUAL( ECL_OIL_PHASE + ECL_WATER_PHASE , runspec.eclPhaseMask( )); } From 3802b4574a0281092adfeb065c8c67a50a141d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Sun, 13 Oct 2019 22:53:25 -0500 Subject: [PATCH 4/6] Make 'test_Summary' Independent of LibeECL This commit switches the 'test_Summary' unit test to use class ESmry for inspecting the values output to disk by 'out::Summary'. As a consequence, we are not able to verify units of measure for the parameters, at least not for the time being. Moreover, class ESmry exclusively uses the "i,j,k" sub-key for block-related parameters so switch those to reference the IJK identifiers. Finally, as class ESmry currently does not support reading separate (multiple) summary files, switch the input decks to generate unified output. --- tests/SOFR_TEST.DATA | 3 + tests/SUMMARY_EFF_FAC.DATA | 3 + tests/group_group.DATA | 3 + tests/summary_deck.DATA | 3 + tests/test_Summary.cpp | 240 ++++++++++++++++++++++--------------- 5 files changed, 158 insertions(+), 94 deletions(-) diff --git a/tests/SOFR_TEST.DATA b/tests/SOFR_TEST.DATA index 3f56ba903..f98c7062b 100644 --- a/tests/SOFR_TEST.DATA +++ b/tests/SOFR_TEST.DATA @@ -18,6 +18,9 @@ WATER GAS METRIC +UNIFIN +UNIFOUT + WELLDIMS -- MAX CONN WELLS IN -- WELLS PR WELL GROUPS GROUP diff --git a/tests/SUMMARY_EFF_FAC.DATA b/tests/SUMMARY_EFF_FAC.DATA index 3b3f91dbf..6640dbc28 100644 --- a/tests/SUMMARY_EFF_FAC.DATA +++ b/tests/SUMMARY_EFF_FAC.DATA @@ -25,6 +25,9 @@ OIL GAS WATER +UNIFIN +UNIFOUT + GRID DX diff --git a/tests/group_group.DATA b/tests/group_group.DATA index 5cec18fa6..4ac989d63 100644 --- a/tests/group_group.DATA +++ b/tests/group_group.DATA @@ -21,6 +21,9 @@ OIL GAS WATER +UNIFIN +UNIFOUT + GRID DX diff --git a/tests/summary_deck.DATA b/tests/summary_deck.DATA index fdf252e9d..2e1dddde7 100644 --- a/tests/summary_deck.DATA +++ b/tests/summary_deck.DATA @@ -30,6 +30,9 @@ OIL GAS WATER +UNIFIN +UNIFOUT + GRID DX diff --git a/tests/test_Summary.cpp b/tests/test_Summary.cpp index 8826e962c..e5a092ffc 100644 --- a/tests/test_Summary.cpp +++ b/tests/test_Summary.cpp @@ -25,17 +25,12 @@ #include #include +#include #include #include #include #include -#include -#include -#include -#include -#include - #include #include @@ -50,6 +45,10 @@ #include +#include + +#include + using namespace Opm; using rt = data::Rates::opt; @@ -75,6 +74,7 @@ namespace SegmentResultHelpers { data::Well inje01_results(); } // SegmentResultHelpers +namespace { /* conversion factor for whenever 'day' is the unit of measure, whereas we * expect input in SI units (seconds) */ @@ -261,10 +261,75 @@ static data::Wells result_wells() { return wellrates; } -ERT::ert_unique_ptr< ecl_sum_type, ecl_sum_free > readsum( const std::string& base ) { - return ERT::ert_unique_ptr< ecl_sum_type, ecl_sum_free >( - ecl_sum_fread_alloc_case( base.c_str(), ":" ) - ); +std::unique_ptr< EclIO::ESmry > readsum( const std::string& base ) { + return std::make_unique(base); +} + +bool ecl_sum_has_key( const EclIO::ESmry* smry, + const std::string& key ) +{ + return smry->hasKey(key); +} + +bool ecl_sum_has_field_var( const EclIO::ESmry* smry, + const std::string& variable ) +{ + return smry->hasKey(variable); +} + +double ecl_sum_get_field_var(const EclIO::ESmry* smry, + const int timeIdx, + const std::string& var) +{ + return smry->get(var)[timeIdx]; +} + +bool ecl_sum_has_general_var( const EclIO::ESmry* smry, + const std::string& variable) +{ + return smry->hasKey(variable); +} + +double ecl_sum_get_general_var(const EclIO::ESmry* smry, + const int timeIdx, + const std::string& var) +{ + return smry->get(var)[timeIdx]; +} + +bool ecl_sum_has_well_var( const EclIO::ESmry* smry, + const std::string& wellname, + const std::string& variable ) +{ + return smry->hasKey(variable + ':' + wellname); +} + +double ecl_sum_get_well_var( const EclIO::ESmry* smry, + const int timeIdx, + const std::string& wellname, + const std::string& variable ) +{ + return smry->get(variable + ':' + wellname)[timeIdx]; +} + +double ecl_sum_get_group_var( const EclIO::ESmry* smry, + const int timeIdx, + const std::string& groupname, + const std::string& variable ) +{ + return smry->get(variable + ':' + groupname)[timeIdx]; +} + +double ecl_sum_get_well_completion_var( const EclIO::ESmry* smry, + const int timeIdx, + const std::string& wellname, + const std::string& variable, + const int i, + const int j, + const int k) +{ + const auto ijk = std::to_string(i) + ',' + std::to_string(j) + ',' + std::to_string(k); + return smry->get(variable + ':' + wellname + ':' + ijk)[timeIdx]; } struct setup { @@ -275,7 +340,7 @@ struct setup { SummaryConfig config; data::Wells wells; std::string name; - test_work_area_type * ta; + WorkArea ta; /*-----------------------------------------------------------------*/ @@ -287,29 +352,10 @@ struct setup { config( deck, schedule, es.getTableManager()), wells( result_wells() ), name( toupper(std::move(fname)) ), - ta( test_work_area_alloc("summary_test")) - { - } - - ~setup() { - test_work_area_free(this->ta); - } - + ta( "summary_test" ) + {} }; - - -void compare(const SummaryState& st, const ecl_sum_type * ecl_sum, int tstep) { - for (const auto& key_value : st) { - const std::string& key = key_value.first; - double value = key_value.second; - - if (ecl_sum_has_general_var(ecl_sum, key.c_str())) - // The ecl_sum value has been on disk where it has been stored as float - // - i.e. we must use BOOST_CHECK_CLOSE() - BOOST_CHECK_CLOSE(value, ecl_sum_get_general_var(ecl_sum, tstep, key.c_str()), 1e-5); - } -} - +} // Anonymous namespace BOOST_AUTO_TEST_SUITE(Summary) /* @@ -321,7 +367,7 @@ BOOST_AUTO_TEST_CASE(well_keywords) { // Force to run in a directory, to make sure the basename with // leading path works. - util_make_path( "PATH" ); + cfg.ta.makeSubDir( "PATH" ); cfg.name = "PATH/CASE"; SummaryState st(std::chrono::system_clock::now()); @@ -556,7 +602,10 @@ BOOST_AUTO_TEST_CASE(udq_keywords) { const auto& udq_params = cfg.es.runspec().udqParams(); BOOST_CHECK_CLOSE( ecl_sum_get_well_var(resp, 1, "W_1", "WUBHP"), udq_params.undefinedValue(), 1e-5 ); BOOST_CHECK_CLOSE( ecl_sum_get_well_var(resp, 1, "W_3", "WUBHP"), udq_params.undefinedValue(), 1e-5 ); + +#if 0 BOOST_CHECK_EQUAL( std::string(ecl_sum_get_unit(resp, "WUBHP:W_1")), "BARSA"); +#endif } BOOST_AUTO_TEST_CASE(group_keywords) { @@ -776,49 +825,49 @@ BOOST_AUTO_TEST_CASE(completion_kewords) { const auto* resp = res.get(); /* Production rates */ - BOOST_CHECK_CLOSE( 100.0, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CWPR", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 100.1, ecl_sum_get_well_completion_var( resp, 1, "W_1", "COPR", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPR", 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 100.0, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CWPR", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 100.1, ecl_sum_get_well_completion_var( resp, 1, "W_1", "COPR", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPR", 1, 1, 1 ), 1e-5 ); /* Production totals */ - BOOST_CHECK_CLOSE( 100.0, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CWPT", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 100.1, ecl_sum_get_well_completion_var( resp, 1, "W_1", "COPT", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPT", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 100.3, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CNPT", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 2 * 100.0, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CWPT", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 2 * 100.1, ecl_sum_get_well_completion_var( resp, 2, "W_1", "COPT", 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 100.0, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CWPT", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 100.1, ecl_sum_get_well_completion_var( resp, 1, "W_1", "COPT", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPT", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 100.3, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CNPT", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 2 * 100.0, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CWPT", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 2 * 100.1, ecl_sum_get_well_completion_var( resp, 2, "W_1", "COPT", 1, 1, 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 2 * 100.2, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CGPT", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 2 * 200.2, ecl_sum_get_well_completion_var( resp, 2, "W_2", "CGPT", 2 ), 1e-5 ); - BOOST_CHECK_CLOSE( 0 , ecl_sum_get_well_completion_var( resp, 2, "W_3", "CGPT", 3 ), 1e-5 ); + BOOST_CHECK_CLOSE( 2 * 100.2, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CGPT", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 2 * 200.2, ecl_sum_get_well_completion_var( resp, 2, "W_2", "CGPT", 2, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 0 , ecl_sum_get_well_completion_var( resp, 2, "W_3", "CGPT", 3, 1, 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 1 * 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPT", 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 1 * 200.2, ecl_sum_get_well_completion_var( resp, 1, "W_2", "CGPT", 2 ), 1e-5 ); - BOOST_CHECK_CLOSE( 0 , ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGPT", 3 ), 1e-5 ); + BOOST_CHECK_CLOSE( 1 * 100.2, ecl_sum_get_well_completion_var( resp, 1, "W_1", "CGPT", 1, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 1 * 200.2, ecl_sum_get_well_completion_var( resp, 1, "W_2", "CGPT", 2, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 0 , ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGPT", 3, 1, 1 ), 1e-5 ); - BOOST_CHECK_CLOSE( 2 * 100.3, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CNPT", 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 2 * 100.3, ecl_sum_get_well_completion_var( resp, 2, "W_1", "CNPT", 1, 1, 1 ), 1e-5 ); /* Injection rates */ - BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIR", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGIR", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 300.0 * 1.5, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CCIR", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 300.0 * 2.5, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CCIR", 3 ), 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.0 * 1.5, 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 */ - BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIT", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 300.2, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CGIT", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 300.3, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CNIT", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 300.0 * 1.5, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CCIT", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 2 * 300.0, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CWIT", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 2 * 300.2, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CGIT", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 2 * 300.3, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CNIT", 3 ), 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.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( 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.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, - ecl_sum_get_well_completion_var( resp, 2, "W_3", "CCIT", 3 ), 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 values for producers*/ - BOOST_CHECK_CLOSE( -300.3, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CNFR", 3 ), 1e-5 ); - BOOST_CHECK_CLOSE( 200.3, ecl_sum_get_well_completion_var( resp, 1, "W_2", "CNFR", 2 ), 1e-5 ); + BOOST_CHECK_CLOSE( -300.3, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CNFR", 3, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 200.3, ecl_sum_get_well_completion_var( resp, 1, "W_2", "CNFR", 2, 1, 1 ), 1e-5 ); } BOOST_AUTO_TEST_CASE(field_keywords) { @@ -950,6 +999,7 @@ BOOST_AUTO_TEST_CASE(field_keywords) { } +#if 0 BOOST_AUTO_TEST_CASE(report_steps_time) { setup cfg( "test_summary_report_steps_time" ); @@ -975,6 +1025,7 @@ BOOST_AUTO_TEST_CASE(report_steps_time) { BOOST_CHECK_EQUAL( ecl_sum_iget_sim_days( resp, 2 ), 10 ); BOOST_CHECK_EQUAL( ecl_sum_get_sim_length( resp ), 10 ); } +#endif BOOST_AUTO_TEST_CASE(skip_unknown_var) { setup cfg( "test_summary_skip_unknown_var" ); @@ -1157,17 +1208,17 @@ BOOST_AUTO_TEST_CASE(region_production) { BOOST_CHECK( ecl_sum_has_general_var( resp , "ROPR:1")); BOOST_CHECK_CLOSE(ecl_sum_get_general_var( resp , 1 , "ROPR:1" ) , - ecl_sum_get_general_var( resp , 1 , "COPR:W_1:1") + - ecl_sum_get_general_var( resp , 1 , "COPR:W_2:2") + - ecl_sum_get_general_var( resp , 1 , "COPR:W_3:3"), 1e-5); + ecl_sum_get_general_var( resp , 1 , "COPR:W_1:1,1,1") + + ecl_sum_get_general_var( resp , 1 , "COPR:W_2:2,1,1") + + ecl_sum_get_general_var( resp , 1 , "COPR:W_3:3,1,1"), 1e-5); BOOST_CHECK( ecl_sum_has_general_var( resp , "RGPT:1")); BOOST_CHECK_CLOSE(ecl_sum_get_general_var( resp , 2 , "RGPT:1" ) , - ecl_sum_get_general_var( resp , 2 , "CGPT:W_1:1") + - ecl_sum_get_general_var( resp , 2 , "CGPT:W_2:2") + - ecl_sum_get_general_var( resp , 2 , "CGPT:W_3:3"), 1e-5); + ecl_sum_get_general_var( resp , 2 , "CGPT:W_1:1,1,1") + + ecl_sum_get_general_var( resp , 2 , "CGPT:W_2:2,1,1") + + ecl_sum_get_general_var( resp , 2 , "CGPT:W_3:3,1,1"), 1e-5); } BOOST_AUTO_TEST_CASE(region_injection) { @@ -1188,17 +1239,17 @@ BOOST_AUTO_TEST_CASE(region_injection) { BOOST_CHECK( ecl_sum_has_general_var( resp , "RWIR:1")); BOOST_CHECK_CLOSE(ecl_sum_get_general_var( resp , 1 , "RWIR:1" ) , - ecl_sum_get_general_var( resp , 1 , "CWIR:W_1:1") + - ecl_sum_get_general_var( resp , 1 , "CWIR:W_2:2") + - ecl_sum_get_general_var( resp , 1 , "CWIR:W_3:3"), 1e-5); + ecl_sum_get_general_var( resp , 1 , "CWIR:W_1:1,1,1") + + ecl_sum_get_general_var( resp , 1 , "CWIR:W_2:2,1,1") + + ecl_sum_get_general_var( resp , 1 , "CWIR:W_3:3,1,1"), 1e-5); BOOST_CHECK( ecl_sum_has_general_var( resp , "RGIT:1")); BOOST_CHECK_CLOSE(ecl_sum_get_general_var( resp , 2 , "RGIT:1" ) , - ecl_sum_get_general_var( resp , 2 , "CGIT:W_1:1") + - ecl_sum_get_general_var( resp , 2 , "CGIT:W_2:2") + - ecl_sum_get_general_var( resp , 2 , "CGIT:W_3:3"), 1e-5); + ecl_sum_get_general_var( resp , 2 , "CGIT:W_1:1,1,1") + + ecl_sum_get_general_var( resp , 2 , "CGIT:W_2:2,1,1") + + ecl_sum_get_general_var( resp , 2 , "CGIT:W_3:3,1,1"), 1e-5); } @@ -1273,13 +1324,13 @@ BOOST_AUTO_TEST_CASE(BLOCK_VARIABLES) { BOOST_CHECK_CLOSE( 31.0 , units.to_si( UnitSystem::measure::viscosity , ecl_sum_get_general_var( resp, 1, "BVOIL:1,1,1")) , 1e-5); BOOST_CHECK_CLOSE( 33.0 , units.to_si( UnitSystem::measure::viscosity , ecl_sum_get_general_var( resp, 1, "BOVIS:1,1,1")) , 1e-5); - BOOST_CHECK_CLOSE( 100 , ecl_sum_get_well_completion_var( resp, 1, "W_1", "CTFAC", 1) , 1e-5); - BOOST_CHECK_CLOSE( 2.1430730819702148 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2) , 1e-5); - BOOST_CHECK_CLOSE( 2.6788413524627686 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 102) , 1e-5); - BOOST_CHECK_CLOSE( 2.7855057716369629 , ecl_sum_get_well_completion_var( resp, 1, "W_3", "CTFAC", 3) , 1e-5); + BOOST_CHECK_CLOSE( 100 , ecl_sum_get_well_completion_var( resp, 1, "W_1", "CTFAC", 1, 1, 1), 1e-5); + BOOST_CHECK_CLOSE( 2.1430730819702148 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2, 1, 1), 1e-5); + BOOST_CHECK_CLOSE( 2.6788413524627686 , ecl_sum_get_well_completion_var( resp, 1, "W_2", "CTFAC", 2, 1, 2), 1e-5); + BOOST_CHECK_CLOSE( 2.7855057716369629 , ecl_sum_get_well_completion_var( resp, 1, "W_3", "CTFAC", 3, 1, 1), 1e-5); - BOOST_CHECK_CLOSE( 50 , ecl_sum_get_well_completion_var( resp, 3, "W_1", "CTFAC", 1) , 1e-5); - BOOST_CHECK_CLOSE( 25 , ecl_sum_get_well_completion_var( resp, 4, "W_1", "CTFAC", 1) , 1e-5); + BOOST_CHECK_CLOSE( 50 , ecl_sum_get_well_completion_var( resp, 3, "W_1", "CTFAC", 1, 1, 1), 1e-5); + BOOST_CHECK_CLOSE( 25 , ecl_sum_get_well_completion_var( resp, 4, "W_1", "CTFAC", 1, 1, 1), 1e-5); // Cell is not active BOOST_CHECK( !ecl_sum_has_general_var( resp , "BPR:2,1,10")); @@ -1509,8 +1560,8 @@ BOOST_AUTO_TEST_CASE(efficiency_factor) { BOOST_CHECK_CLOSE( 300 * 0.2 * 0.01, ecl_sum_get_general_var( resp , 1 , "RWIR:1" ) , 1e-5); - BOOST_CHECK_CLOSE( 200.1, ecl_sum_get_well_completion_var( resp, 1, "W_2", "COPR", 2 ), 1e-5 ); - BOOST_CHECK_CLOSE( 200.1 * 0.2 * 0.01, ecl_sum_get_well_completion_var( resp, 1, "W_2", "COPT", 2 ), 1e-5 ); + BOOST_CHECK_CLOSE( 200.1, ecl_sum_get_well_completion_var( resp, 1, "W_2", "COPR", 2, 1, 1 ), 1e-5 ); + BOOST_CHECK_CLOSE( 200.1 * 0.2 * 0.01, ecl_sum_get_well_completion_var( resp, 1, "W_2", "COPT", 2, 1, 1 ), 1e-5 ); } @@ -2550,23 +2601,23 @@ BOOST_AUTO_TEST_CASE(WaterRate_Correct) // ==================================================================== namespace { - bool hasSegmentVariable_Prod01(const ecl_sum_type* ecl_sum, - const char* vector, - const int segID) + bool hasSegmentVariable_Prod01(const Opm::EclIO::ESmry* ecl_sum, + const char* vector, + const int segID) { const auto lookup_kw = genKeyPROD01(vector, segID); - return ecl_sum_has_general_var(ecl_sum, lookup_kw.c_str()); + return ecl_sum_has_general_var(ecl_sum, lookup_kw); } - double getSegmentVariable_Prod01(const ecl_sum_type* ecl_sum, - const int timeIdx, - const char* vector, - const int segID) + double getSegmentVariable_Prod01(const Opm::EclIO::ESmry* ecl_sum, + const int timeIdx, + const char* vector, + const int segID) { const auto lookup_kw = genKeyPROD01(vector, segID); - return ecl_sum_get_general_var(ecl_sum, timeIdx, lookup_kw.c_str()); + return ecl_sum_get_general_var(ecl_sum, timeIdx, lookup_kw); } } // Anonymous @@ -3134,6 +3185,7 @@ BOOST_AUTO_TEST_CASE(SummaryState_TOTAL) { BOOST_CHECK_EQUAL(st.get_elapsed(), 200); } +namespace { bool equal(const SummaryState& st1 , const SummaryState& st2) { if (st1.size() != st2.size()) return false; @@ -3185,7 +3237,7 @@ void test_serialize(const SummaryState& st) { st2.deserialize(serial); BOOST_CHECK( equal(st, st2)); } - +} // Anonymous namespace BOOST_AUTO_TEST_CASE(serialize_sumary_state) { SummaryState st(std::chrono::system_clock::now()); From 411da1d8a507f2d170aaf892b05d6c39e499b432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Mon, 14 Oct 2019 00:09:34 -0500 Subject: [PATCH 5/6] Make 'test_Restart' Mostly Independent of libecl In particular, swith to using class EclIO::ERst to read the files produced by RestartIO::save(). --- tests/WorkArea.cpp | 5 ++ tests/test_Restart.cpp | 145 +++++++++++++++++++++++------------------ 2 files changed, 87 insertions(+), 63 deletions(-) diff --git a/tests/WorkArea.cpp b/tests/WorkArea.cpp index df36edc70..9cf82327d 100644 --- a/tests/WorkArea.cpp +++ b/tests/WorkArea.cpp @@ -47,6 +47,11 @@ namespace { this->area_ / filename); } + std::string currentWorkingDirectory() const + { + return this->area_.generic_string(); + } + void makeSubDir(const std::string& dirname) { boost::filesystem::create_directories(this->area_ / dirname); diff --git a/tests/test_Restart.cpp b/tests/test_Restart.cpp index b4b989e74..3f8c7c7c8 100644 --- a/tests/test_Restart.cpp +++ b/tests/test_Restart.cpp @@ -39,18 +39,52 @@ #include #include +#include +#include + +#include // ERT stuff -#include -#include #include -#include -#include -#include -#include + +#include using namespace Opm; +namespace { + int ecl_file_get_num_named_kw(Opm::EclIO::ERst& rst, + const std::string& kw) + { + int count = 0; + for (const auto& step : rst.listOfReportStepNumbers()) { + for (const auto& vec : rst.listOfRstArrays(step)) { + count += std::get<0>(vec) == kw; + } + } + + return count; + } + + EclIO::EclFile::EclEntry + ecl_file_iget_named_kw(Opm::EclIO::ERst& rst, + const std::string& kw, + const int seqnum) + { + for (const auto& vec : rst.listOfRstArrays(seqnum)) { + if (std::get<0>(vec) == kw) { + return vec; + } + } + + return { "NoSuchKeyword", Opm::EclIO::eclArrType::MESS, 0 }; + } + + EclIO::eclArrType ecl_kw_get_type(const EclIO::EclFile::EclEntry& vec) + { + return std::get<1>(vec); + } +} + inline std::string input( const std::string& rst_name = "FIRST_SIM" ) { return std::string( "RUNSPEC\n" @@ -541,8 +575,8 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData) { {"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"); + WorkArea test_area("test_restart"); + test_area.copyIn("FIRST_SIM.DATA"); Setup setup("FIRST_SIM.DATA"); EclipseIO eclWriter( setup.es, setup.grid, setup.schedule, setup.summary_config); @@ -553,7 +587,6 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData) { BOOST_CHECK_THROW( second_sim( eclWriter, st, {{"SOIL", UnitSystem::measure::pressure}} ) , std::runtime_error ); BOOST_CHECK_THROW( second_sim( eclWriter, st, {{"SOIL", UnitSystem::measure::pressure, true}}) , std::runtime_error ); - test_work_area_free( test_area ); } @@ -561,7 +594,7 @@ BOOST_AUTO_TEST_CASE(ECL_FORMATTED) { namespace OS = ::Opm::EclIO::OutputStream; Setup setup("FIRST_SIM.DATA"); - test_work_area_type * test_area = test_work_area_alloc("test_Restart"); + WorkArea test_area("test_Restart"); auto& io_config = setup.es.getIOConfig(); { auto num_cells = setup.grid.getNumActive( ); @@ -574,9 +607,7 @@ BOOST_AUTO_TEST_CASE(ECL_FORMATTED) { io_config.setEclCompatibleRST( false ); restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3}); - const auto outputDir = std::string { - test_work_area_get_cwd(test_area) - }; + const auto outputDir = test_area.currentWorkingDirectory(); { const auto seqnum = 1; @@ -599,12 +630,10 @@ BOOST_AUTO_TEST_CASE(ECL_FORMATTED) { const auto rstFile = ::Opm::EclIO::OutputStream:: outputFileName({outputDir, "OPM_FILE"}, "UNRST"); - ecl_file_type * rst_file = ecl_file_open( rstFile.c_str() , 0 ); - ecl_kw_type * swat = ecl_file_iget_named_kw(rst_file, "SWAT", 0); + EclIO::ERst rst{ rstFile }; - 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); + BOOST_CHECK_MESSAGE(rst.hasKey("SWAT"), "Restart file must have SWAT vector"); + BOOST_CHECK_MESSAGE(rst.hasKey("EXTRA"), "Restart file must have EXTRA vector"); } io_config.setEclCompatibleRST( true ); @@ -629,18 +658,15 @@ BOOST_AUTO_TEST_CASE(ECL_FORMATTED) { const auto rstFile = ::Opm::EclIO::OutputStream:: outputFileName({outputDir, "ECL_FILE"}, "UNRST"); - ecl_file_type * rst_file = ecl_file_open( rstFile.c_str() , 0 ); - ecl_kw_type * swat = ecl_file_iget_named_kw(rst_file, "SWAT", 0); + EclIO::ERst rst{ rstFile }; - 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); + BOOST_CHECK_MESSAGE(rst.hasKey("SWAT"), "Restart file must have SWAT vector"); + BOOST_CHECK_MESSAGE(!rst.hasKey("EXTRA"), "Restart file must NOT have EXTRA vector"); + BOOST_CHECK_MESSAGE(!rst.hasKey("OPM_IWEL"), "Restart file must NOT have OPM_IWEL vector"); + BOOST_CHECK_MESSAGE(!rst.hasKey("OPM_XWEL"), "Restart file must NOT have OPM_XWEL vector"); } } } - test_work_area_free(test_area); } @@ -676,8 +702,8 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData_double) { std::vector 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"); + WorkArea test_area("test_Restart"); + test_area.copyIn("FIRST_SIM.DATA"); Setup setup("FIRST_SIM.DATA"); EclipseIO eclWriter( setup.es, setup.grid, setup.schedule, setup.summary_config); SummaryState st(std::chrono::system_clock::now()); @@ -685,15 +711,15 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData_double) { auto state1 = first_sim( setup.es , eclWriter , st, true); auto state2 = second_sim( eclWriter ,st, solution_keys ); compare_equal( state1 , state2 , solution_keys); - test_work_area_free( test_area ); } BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) { namespace OS = ::Opm::EclIO::OutputStream; + WorkArea test_area("test_Restart"); + test_area.copyIn("FIRST_SIM.DATA"); 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 ); @@ -702,7 +728,7 @@ BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) { const auto seqnum = 1; auto rstFile = OS::Restart { - OS::ResultSet { test_work_area_get_cwd(test_area), "FILE" }, seqnum, + OS::ResultSet { test_area.currentWorkingDirectory(), "FILE" }, seqnum, OS::Formatted { false }, OS::Unified { true } }; @@ -715,7 +741,6 @@ BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) { sumState), std::runtime_error); } - test_work_area_free(test_area); } @@ -742,8 +767,9 @@ BOOST_AUTO_TEST_CASE(ExtraData_KEYS) { BOOST_AUTO_TEST_CASE(ExtraData_content) { namespace OS = ::Opm::EclIO::OutputStream; + WorkArea test_area("test_Restart"); + test_area.copyIn("FIRST_SIM.DATA"); 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 ); @@ -756,9 +782,7 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) { restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3}); - const auto outputDir = std::string { - test_work_area_get_cwd(test_area) - }; + const auto outputDir = test_area.currentWorkingDirectory(); { const auto seqnum = 1; @@ -780,17 +804,12 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) { outputFileName({outputDir, "FILE"}, "UNRST"); { - ecl_file_type * f = ecl_file_open( rstFile.c_str() , 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 )); + EclIO::ERst rst{ rstFile }; + BOOST_CHECK_MESSAGE( rst.hasKey("EXTRA"), "Restart file is expexted to have EXTRA vector"); - 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 ); + const auto& ex = rst.getRst("EXTRA", 1); + BOOST_CHECK_CLOSE( 10 , units.to_si( UnitSystem::measure::pressure, ex[0] ), 0.00001); + BOOST_CHECK_CLOSE( units.from_si( UnitSystem::measure::pressure, 3), ex[3], 0.00001); } BOOST_CHECK_THROW( RestartIO::load( rstFile , 1 , st, {}, setup.es, setup.grid , setup.schedule, @@ -819,22 +838,20 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) { } } } - test_work_area_free(test_area); } BOOST_AUTO_TEST_CASE(STORE_THPRES) { namespace OS = ::Opm::EclIO::OutputStream; + WorkArea test_area("test_Restart_THPRES"); + test_area.copyIn("FIRST_SIM_THPRES.DATA"); 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(); - const auto outputDir = std::string { - test_work_area_get_cwd(test_area) - }; + const auto outputDir = test_area.currentWorkingDirectory(); { RestartValue restart_value(cells, wells); RestartValue restart_value2(cells, wells); @@ -897,34 +914,36 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) { const auto rstFile = ::Opm::EclIO::OutputStream:: outputFileName({outputDir, "FILE2"}, "UNRST"); - ecl_file_type * rst_file = ecl_file_open(rstFile.c_str(), 0); + EclIO::ERst rst(rstFile); std::map kw_pos; - for (int i=0; i < ecl_file_get_size(rst_file); i++) - kw_pos[ ecl_file_iget_header(rst_file, i ) ] = i; + + { + auto i = 0; + for (const auto& vec : rst.listOfRstArrays(1)) + kw_pos[ std::get<0>(vec) ] = 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); + BOOST_CHECK_EQUAL( ecl_file_get_num_named_kw(rst, "THRESHPR"), 1); + BOOST_CHECK_EQUAL( ecl_file_get_num_named_kw(rst, "EXTRA"), 1); + BOOST_CHECK_MESSAGE( ecl_kw_get_type(ecl_file_iget_named_kw(rst, "THRESHPR", 1)) == EclIO::eclArrType::DOUB, + R"("THRESHPR" vector must have type DOUB)"); } - } } - test_work_area_free(test_area); } BOOST_AUTO_TEST_CASE(Restore_Cumulatives) { + WorkArea wa{"test_Restart"}; + wa.copyIn("FIRST_SIM.DATA"); Setup setup("FIRST_SIM.DATA"); - const auto wa = ::ecl::util::TestArea{"test_Restart"}; - // Write fully ECLIPSE compatible output. This also saves cumulatives. setup.es.getIOConfig().setEclCompatibleRST(true); @@ -936,7 +955,7 @@ BOOST_AUTO_TEST_CASE(Restore_Cumulatives) namespace OS = ::Opm::EclIO::OutputStream; - const auto rset = OS::ResultSet{ wa.test_cwd(), "FILE" }; + const auto rset = OS::ResultSet{ wa.currentWorkingDirectory(), "FILE" }; const auto seqnum = 1; { auto rstFile = OS::Restart { From 662e44683cbc0b2ff6ebf59b8c65382d9fec829a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Mon, 14 Oct 2019 00:10:38 -0500 Subject: [PATCH 6/6] INTEHEAD Test: Initialize Maximum Number of Wells in Field Fixes a warning about missing initializers. --- tests/test_InteHEAD.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_InteHEAD.cpp b/tests/test_InteHEAD.cpp index 81b59cbae..e731ce43c 100755 --- a/tests/test_InteHEAD.cpp +++ b/tests/test_InteHEAD.cpp @@ -159,10 +159,11 @@ BOOST_AUTO_TEST_CASE(WellTableDimensions) const auto maxPerf = 29; const auto maxWellInGroup = 3; const auto maxGroupInField = 14; + const auto maxWellInField = 20; const auto ih = Opm::RestartIO::InteHEAD{} .wellTableDimensions({ - numWells, maxPerf, maxWellInGroup, maxGroupInField, 0 + numWells, maxPerf, maxWellInGroup, maxGroupInField, maxWellInField }); const auto& v = ih.data();