Merge pull request #1088 from bska/further-decouple-from-libecl

Further Decouple OPM-Common From libecl
This commit is contained in:
Bård Skaflestad 2019-10-14 08:12:40 -05:00 committed by GitHub
commit 1db06277ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 532 additions and 302 deletions

View File

@ -39,6 +39,8 @@ public:
const std::vector<std::string>& keywordList() const { return keyword; }
int timestepIdxAtReportstepStart(const int reportStep) const;
private:
int nVect, nI, nJ, nK;
std::string path="";

View File

@ -20,7 +20,7 @@
#ifndef OPM_IO_CONFIG_HPP
#define OPM_IO_CONFIG_HPP
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <string>
namespace Opm {

View File

@ -18,6 +18,7 @@
#include <opm/io/eclipse/ESmry.hpp>
#include <exception>
#include <string>
#include <string.h>
#include <sstream>
@ -28,6 +29,7 @@
#include <limits>
#include <limits.h>
#include <set>
#include <stdexcept>
#include <opm/io/eclipse/EclFile.hpp>
@ -442,4 +444,18 @@ std::vector<float> ESmry::get_at_rstep(const std::string& name) const
return rstep_vector;
}
int ESmry::timestepIdxAtReportstepStart(const int reportStep) const
{
const auto nReport = static_cast<int>(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

View File

@ -49,15 +49,14 @@
#include <cstdlib>
#include <cctype>
#include <memory> // unique_ptr
#include <stdexcept>
#include <sstream>
#include <unordered_map>
#include <utility> // move
#include <ert/ecl/EclFilename.hpp>
#include <ert/ecl/ecl_util.hpp>
#include <ert/util/util.h>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
// 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() {

View File

@ -21,7 +21,7 @@
#include <stdexcept>
#include <vector>
#include <ert/ecl/ecl_grid_dims.hpp>
#include <opm/io/eclipse/EGrid.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
@ -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<std::string>(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];
}
}

View File

@ -17,9 +17,10 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <sstream>
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
@ -32,9 +33,6 @@
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <ert/ecl/EclFilename.hpp>
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;
}

View File

@ -20,13 +20,13 @@
#include <algorithm>
#include <iostream>
#include <iterator>
#include <iomanip>
#include <sstream>
#include <boost/lexical_cast.hpp>
#include <opm/parser/eclipse/Utility/Functional.hpp>
#include <ert/ecl/ecl_util.h>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
@ -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;
}

View File

@ -19,8 +19,6 @@
#include <ostream>
#include <type_traits>
#include <ert/ecl/ecl_util.h>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
@ -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 );
}

View File

@ -26,7 +26,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
#include <ert/util/util.h>
#include <fnmatch.h>
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;

View File

@ -21,7 +21,8 @@
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <ert/util/util.h>
#include <fnmatch.h>
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
@ -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 );
}
}

View File

@ -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<std::size_t>(cnt);
}
}
}

View File

@ -20,10 +20,10 @@
#ifndef STAR_TOKEN_HPP
#define STAR_TOKEN_HPP
#include <cctype>
#include <string>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
#include <ert/util/ssize_t.h>
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;
};

View File

@ -18,6 +18,9 @@ WATER
GAS
METRIC
UNIFIN
UNIFOUT
WELLDIMS
-- MAX CONN WELLS IN
-- WELLS PR WELL GROUPS GROUP

View File

@ -25,6 +25,9 @@ OIL
GAS
WATER
UNIFIN
UNIFOUT
GRID
DX

71
tests/WorkArea.cpp Normal file
View File

@ -0,0 +1,71 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
// NOTE: This file is inteded to be copy-pasted into user code
// through an #include statement.
#include <string>
#include <boost/filesystem.hpp>
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);
}
std::string currentWorkingDirectory() const
{
return this->area_.generic_string();
}
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

View File

@ -21,6 +21,9 @@ OIL
GAS
WATER
UNIFIN
UNIFOUT
GRID
DX

View File

@ -17,22 +17,19 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE WTEST
#define BOOST_TEST_MODULE MSIM_BASIC
#include <boost/test/unit_test.hpp>
#include <ert/util/test_work_area.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_sum.hpp>
#include <ert/ecl/ecl_file.hpp>
#include <ert/ecl/ecl_file_view.hpp>
#include <ert/ecl/ecl_rsthead.hpp>
#include <opm/msim/msim.hpp>
#include <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#include <opm/io/eclipse/ERst.hpp>
#include <opm/io/eclipse/ESmry.hpp>
#include <opm/output/data/Wells.hpp>
#include <opm/output/eclipse/EclipseIO.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
@ -41,8 +38,11 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <tests/WorkArea.cpp>
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<double>("DOUBHEAD", step);
const auto& press = rst.getRst<float>("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 );
}
}

View File

@ -17,16 +17,14 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <iostream>
#define BOOST_TEST_MODULE ACTIONX_SIM
#include <boost/test/unit_test.hpp>
#include <ert/util/test_work_area.h>
#include <ert/ecl/ecl_sum.hpp>
#include <opm/msim/msim.hpp>
#include <stdexcept>
#include <iostream>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
@ -40,13 +38,15 @@
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
#include <opm/io/eclipse/ESmry.hpp>
#include <opm/output/eclipse/EclipseIO.hpp>
#include <opm/msim/msim.hpp>
#include <tests/WorkArea.cpp>
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<int>(smry.get("TIME").size());
}
int ecl_sum_get_last_report_step(const EclIO::ESmry& smry)
{
return static_cast<int>(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 );
}
}

View File

@ -26,8 +26,6 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <ert/util/util.h>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>

View File

@ -30,8 +30,6 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
//#include <ert/util/test_work_area.h>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>

View File

@ -17,11 +17,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_MODULE InitConfigTests
#include <sys/stat.h>
#include <sys/types.h>
#include <boost/test/unit_test.hpp>
@ -31,7 +27,7 @@
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <ert/util/test_work_area.hpp>
#include <tests/WorkArea.cpp>
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);
}
// --------------------------------------------------------------------

View File

@ -21,8 +21,6 @@ along with OPM. If not, see <http://www.gnu.org/licenses/>.
#include <boost/test/unit_test.hpp>
#include <ert/ecl/ecl_util.h>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
@ -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( ));
}

View File

@ -30,6 +30,9 @@ OIL
GAS
WATER
UNIFIN
UNIFOUT
GRID
DX

View File

@ -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();

View File

@ -39,18 +39,52 @@
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/io/eclipse/OutputStream.hpp>
#include <opm/io/eclipse/EclIOdata.hpp>
#include <opm/io/eclipse/ERst.hpp>
#include <tuple>
// 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>
#include <tests/WorkArea.cpp>
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<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");
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<double>("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<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;
{
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 {

View File

@ -25,17 +25,12 @@
#include <cstddef>
#include <exception>
#include <memory>
#include <stdexcept>
#include <unordered_map>
#include <cctype>
#include <ctime>
#include <ert/ecl/ecl_sum.h>
#include <ert/ecl/smspec_node.h>
#include <ert/util/ert_unique_ptr.hpp>
#include <ert/util/util.h>
#include <ert/util/test_work_area.h>
#include <opm/output/data/Wells.hpp>
#include <opm/output/eclipse/Summary.hpp>
@ -50,6 +45,10 @@
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/io/eclipse/ESmry.hpp>
#include <tests/WorkArea.cpp>
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<EclIO::ESmry>(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());