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; } const std::vector<std::string>& keywordList() const { return keyword; }
int timestepIdxAtReportstepStart(const int reportStep) const;
private: private:
int nVect, nI, nJ, nK; int nVect, nI, nJ, nK;
std::string path=""; std::string path="";

View File

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

View File

@ -18,6 +18,7 @@
#include <opm/io/eclipse/ESmry.hpp> #include <opm/io/eclipse/ESmry.hpp>
#include <exception>
#include <string> #include <string>
#include <string.h> #include <string.h>
#include <sstream> #include <sstream>
@ -28,6 +29,7 @@
#include <limits> #include <limits>
#include <limits.h> #include <limits.h>
#include <set> #include <set>
#include <stdexcept>
#include <opm/io/eclipse/EclFile.hpp> #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; 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 }} // namespace Opm::ecl

View File

@ -49,15 +49,14 @@
#include <cstdlib> #include <cstdlib>
#include <cctype> #include <cctype>
#include <memory> // unique_ptr #include <memory> // unique_ptr
#include <stdexcept>
#include <sstream>
#include <unordered_map> #include <unordered_map>
#include <utility> // move #include <utility> // move
#include <ert/ecl/EclFilename.hpp> #include <boost/filesystem.hpp>
#include <ert/ecl/ecl_util.hpp> #include <boost/system/error_code.hpp>
#include <ert/util/util.h>
// namespace start here since we don't want the ERT headers in it
namespace Opm {
namespace { namespace {
inline std::string uppercase( std::string x ) { inline std::string uppercase( std::string x ) {
@ -67,8 +66,34 @@ inline std::string uppercase( std::string x ) {
return 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 { class EclipseIO::Impl {
public: public:
Impl( const EclipseState&, EclipseGrid, const Schedule&, const SummaryConfig& ); 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 ) { 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, const auto ext = '.'
this->baseName, + (formatted ? std::string{"F"} : std::string{})
ECL_EGRID_FILE, + "EGRID";
ioConfig.getFMTOUT() ));
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 ) if( !this->impl->output_enabled )
return; return;
{
const auto& outputDir = this->impl->outputDir;
// make sure that the output directory exists, if not try to create it ensure_directory_exists( this->impl->outputDir );
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");
}
}
} }
const out::Summary& EclipseIO::summary() { const out::Summary& EclipseIO::summary() {

View File

@ -21,7 +21,7 @@
#include <stdexcept> #include <stdexcept>
#include <vector> #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/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp> #include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
@ -140,15 +140,11 @@ namespace Opm {
void GridDims::binary_init(const Deck& deck) { void GridDims::binary_init(const Deck& deck) {
const DeckKeyword& gdfile_kw = deck.getKeyword("GDFILE"); const DeckKeyword& gdfile_kw = deck.getKeyword("GDFILE");
const std::string& gdfile_arg = gdfile_kw.getRecord(0).getItem("filename").get<std::string>(0); const std::string& gdfile_arg = gdfile_kw.getRecord(0).getItem("filename").get<std::string>(0);
std::string filename = deck.makeDeckPath(gdfile_arg); const EclIO::EGrid egrid( deck.makeDeckPath(gdfile_arg) );
ecl_grid_dims_type * grid_dims = ecl_grid_dims_alloc( filename.c_str(), nullptr ); const auto& dimens = egrid.dimension();
if (grid_dims) { m_nx = dimens[0];
const auto& dims = ecl_grid_dims_iget_dims(grid_dims, 0); m_ny = dimens[1];
m_nx = dims->nx; m_nz = dimens[2];
m_ny = dims->ny;
m_nz = dims->nz;
} else
throw std::invalid_argument("Could not determine grid dimensions from: " + filename);
} }
} }

View File

@ -17,9 +17,10 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdio.h> #include <iomanip>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <sstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
@ -32,9 +33,6 @@
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp> #include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
#include <ert/ecl/EclFilename.hpp>
namespace Opm { namespace Opm {
namespace { namespace {
@ -190,9 +188,28 @@ namespace Opm {
std::string IOConfig::getRestartFileName(const std::string& restart_base, int report_step, bool output) const { std::string IOConfig::getRestartFileName(const std::string& restart_base, int report_step, bool output) const {
bool unified = output ? getUNIFOUT() : getUNIFIN(); bool unified = output ? getUNIFOUT() : getUNIFIN();
bool fmt_file = output ? getFMTOUT() : getFMTIN(); 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 <algorithm>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <iomanip>
#include <sstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <opm/parser/eclipse/Utility/Functional.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/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp> #include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.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) { 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; auto ext = std::string{};
char * c_str = ecl_util_alloc_filename( NULL , restart_base.c_str() , file_type, fmt_file , report_step); if (unified) {
std::string restart_filename = c_str; ext = fmt_file ? "FUNRST" : "UNRST";
free( c_str ); }
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 <ostream>
#include <type_traits> #include <type_traits>
#include <ert/ecl/ecl_util.h>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp> #include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.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. available phases in Eclipse restart and init files.
*/ */
int Runspec::eclPhaseMask( ) const noexcept { int Runspec::eclPhaseMask( ) const noexcept {
return ( active_phases.active( Phase::WATER ) ? ECL_WATER_PHASE : 0 ) const int water = 1 << 2;
| ( active_phases.active( Phase::OIL ) ? ECL_OIL_PHASE : 0 ) const int oil = 1 << 0;
| ( active_phases.active( Phase::GAS ) ? ECL_GAS_PHASE : 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/WellInjectionProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
#include <ert/util/util.h> #include <fnmatch.h>
namespace Opm { 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 Well2::wellNameInWellNamePattern(const std::string& wellName, const std::string& wellNamePattern) {
bool wellNameInPattern = false; 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; wellNameInPattern = true;
} }
return wellNameInPattern; return wellNameInPattern;

View File

@ -21,7 +21,8 @@
#include <iostream> #include <iostream>
#include <boost/algorithm/string.hpp> #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/ErrorGuard.hpp>
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp> #include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
@ -266,7 +267,7 @@ namespace Opm {
const char * c_pattern = pattern.c_str(); const char * c_pattern = pattern.c_str();
for (const auto& pair : m_errorContexts) { for (const auto& pair : m_errorContexts) {
const std::string& key = pair.first; 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 ); updateKey( key , action );
} }
} }

View File

@ -143,13 +143,14 @@ namespace Opm {
m_count = 1; m_count = 1;
} }
else { 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? // TODO: decorate the deck with a warning instead?
throw std::invalid_argument("Specifing zero repetitions is not allowed. Token: \'" + token + "\'."); 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 #ifndef STAR_TOKEN_HPP
#define STAR_TOKEN_HPP #define STAR_TOKEN_HPP
#include <cctype>
#include <string> #include <string>
#include <opm/parser/eclipse/Utility/Stringview.hpp> #include <opm/parser/eclipse/Utility/Stringview.hpp>
#include <ert/util/ssize_t.h>
namespace Opm { namespace Opm {
bool isStarToken(const string_view& token, bool isStarToken(const string_view& token,
@ -49,7 +49,7 @@ public:
init_(token); init_(token);
} }
size_t count() const { std::size_t count() const {
return m_count; return m_count;
} }
@ -78,7 +78,7 @@ private:
// must be set before calling this method. // must be set before calling this method.
void init_(const string_view& token); void init_(const string_view& token);
ssize_t m_count; std::size_t m_count;
std::string m_countString; std::string m_countString;
std::string m_valueString; std::string m_valueString;
}; };

View File

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

View File

@ -25,6 +25,9 @@ OIL
GAS GAS
WATER WATER
UNIFIN
UNIFOUT
GRID GRID
DX 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 GAS
WATER WATER
UNIFIN
UNIFOUT
GRID GRID
DX DX

View File

@ -17,22 +17,19 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdexcept> #define BOOST_TEST_MODULE MSIM_BASIC
#include <iostream>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE WTEST
#include <boost/test/unit_test.hpp> #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 <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/data/Wells.hpp>
#include <opm/output/eclipse/EclipseIO.hpp> #include <opm/output/eclipse/EclipseIO.hpp>
#include <opm/parser/eclipse/Units/Units.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/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp> #include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <tests/WorkArea.cpp>
using namespace Opm; 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) { 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(); 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)); 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) { BOOST_AUTO_TEST_CASE(RUN) {
Parser parser; Parser parser;
@ -71,45 +78,35 @@ BOOST_AUTO_TEST_CASE(RUN) {
msim.well_rate("PROD", data::Rates::opt::oil, prod_opr); msim.well_rate("PROD", data::Rates::opt::oil, prod_opr);
msim.solution("PRESSURE", pressure); 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); EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
msim.run(schedule, io, false); msim.run(schedule, io, false);
for (const auto& fname : {"SPE1CASE1.INIT", "SPE1CASE1.UNRST", "SPE1CASE1.EGRID", "SPE1CASE1.SMSPEC", "SPE1CASE1.UNSMRY"}) 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", ":"); const auto smry = EclIO::ESmry("SPE1CASE1");
int param_index = ecl_sum_get_general_var_params_index(ecl_sum, "WOPR:PROD"); const auto& time = smry.get("TIME");
for (int time_index=0; time_index < ecl_sum_get_data_length(ecl_sum); time_index++) { const auto& press = smry.get("WOPR:PROD");
double seconds_elapsed = ecl_sum_iget_sim_days(ecl_sum, time_index) * 86400;
double opr = ecl_sum_iget(ecl_sum, time_index, param_index); for (auto nstep = time.size(), time_index=0*nstep; time_index < nstep; time_index++) {
BOOST_CHECK_CLOSE(seconds_elapsed, opr, 1e-3); 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; auto rst = EclIO::ERst("SPE1CASE1.UNRST");
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;
{ for (const auto& step : rst.listOfReportStepNumbers()) {
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_view, report_step); const auto& dh = rst.getRst<double>("DOUBHEAD", step);
const ecl_kw_type * p = ecl_file_view_iget_named_kw(rst_view, "PRESSURE", 0); const auto& press = rst.getRst<float>("PRESSURE", step);
BOOST_CHECK_CLOSE( ecl_kw_iget_float(p, 0), rst_head->sim_days * 86400, 1e-3 );
ecl_rsthead_free( rst_head ); // DOUBHEAD[0] is elapsed time in days since start of simulation.
} BOOST_CHECK_CLOSE( press[0], dh[0] * 86400, 1e-3 );
report_step++;
} }
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/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdexcept>
#include <iostream>
#define BOOST_TEST_MODULE ACTIONX_SIM #define BOOST_TEST_MODULE ACTIONX_SIM
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <ert/util/test_work_area.h> #include <opm/msim/msim.hpp>
#include <ert/ecl/ecl_sum.hpp>
#include <stdexcept>
#include <iostream>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp> #include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.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/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp> #include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
#include <opm/io/eclipse/ESmry.hpp>
#include <opm/output/eclipse/EclipseIO.hpp> #include <opm/output/eclipse/EclipseIO.hpp>
#include <opm/msim/msim.hpp> #include <tests/WorkArea.cpp>
using namespace Opm; using namespace Opm;
namespace {
struct test_data { struct test_data {
Deck deck; Deck deck;
@ -118,6 +118,33 @@ double inj_wir_INJ(const EclipseState& , const Schedule& sched, const SummarySta
return -99; 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 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 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 ); test_data td( actionx );
msim sim(td.state); 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); EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
sim.well_rate("P1", data::Rates::opt::oil, prod_opr); 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(w1.getStatus() == Well2::Status::OPEN );
BOOST_CHECK(w4.getStatus() == Well2::Status::SHUT ); 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 ); test_data td( actionx1 );
msim sim(td.state); 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); EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
sim.well_rate("P1", data::Rates::opt::oil, prod_opr); 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_10.getStatus() == Well2::Status::OPEN );
BOOST_CHECK(w4_11.getStatus() == Well2::Status::SHUT ); 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 ); test_data td( actionx1 );
msim sim(td.state); 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); EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
sim.well_rate("P1", data::Rates::opt::oil, prod_opr); 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(); 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:P1") );
BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUBHP:P2") ); 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:P3") );
BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUOPRL:P4") ); 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, "WUBHP:P1"), "BARSA");
BOOST_CHECK_EQUAL( ecl_sum_get_unit(ecl_sum, "WUOPRL:P1"), "SM3/DAY"); 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:P1"), 11);
BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUBHP:P2"), 12); 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: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:P3"), 20);
BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUOPRL:P4"), 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 ); test_data td( actionx1 );
msim sim(td.state); 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); EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
sim.well_rate("P1", data::Rates::opt::oil, prod_opr); 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); sim.run(td.schedule, io, false);
const auto& base_name = td.state.getIOConfig().getBaseName(); 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++) { for (int step = 0; step < ecl_sum_get_data_length(ecl_sum); step++) {
double wopr_sum = 0; double wopr_sum = 0;
@ -300,9 +322,6 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) {
ecl_sum_get_general_var(ecl_sum, step, "FUOPR")); ecl_sum_get_general_var(ecl_sum, step, "FUOPR"));
BOOST_CHECK_EQUAL( wopr_sum, ecl_sum_get_general_var(ecl_sum, step, "FOPR")); 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("P4", data::Rates::opt::wat, prod_wpr_P4);
sim.well_rate("INJ", data::Rates::opt::wat, inj_wir_INJ); 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); sim.run(td.schedule, io, true);
const auto& base_name = td.state.getIOConfig().getBaseName(); 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 // 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; double wwpr_sum = 0;
{ {
int prev_tstep = ecl_sum_iget_report_end(ecl_sum, report_step - 1); 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); 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/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.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/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>

View File

@ -30,8 +30,6 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.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/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.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/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define BOOST_TEST_MODULE InitConfigTests #define BOOST_TEST_MODULE InitConfigTests
#include <sys/stat.h>
#include <sys/types.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -31,7 +27,7 @@
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp> #include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/Units/Units.hpp> #include <opm/parser/eclipse/Units/Units.hpp>
#include <ert/util/test_work_area.hpp> #include <tests/WorkArea.cpp>
using namespace Opm; using namespace Opm;
@ -188,8 +184,10 @@ BOOST_AUTO_TEST_CASE( EquilOperations ) {
} }
BOOST_AUTO_TEST_CASE(RestartCWD) { BOOST_AUTO_TEST_CASE(RestartCWD) {
test_work_area_type * work_area = test_work_area_alloc("restart_cwd"); WorkArea output_area;
mkdir("simulation", 0777);
output_area.makeSubDir("simulation");
{ {
std::fstream fs; std::fstream fs;
fs.open ("simulation/CASE.DATA", std::fstream::out); fs.open ("simulation/CASE.DATA", std::fstream::out);
@ -229,8 +227,6 @@ BOOST_AUTO_TEST_CASE(RestartCWD) {
Opm::InitConfig init_config(deck); Opm::InitConfig init_config(deck);
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "/abs/path/BASE"); 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 <boost/test/unit_test.hpp>
#include <ert/ecl/ecl_util.h>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp> #include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/Parser/Parser.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::GAS ) );
BOOST_CHECK( phases.active( Phase::WATER ) ); BOOST_CHECK( phases.active( Phase::WATER ) );
BOOST_CHECK( !phases.active( Phase::POLYMW ) ); 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( )); BOOST_CHECK_EQUAL( ECL_OIL_PHASE + ECL_WATER_PHASE , runspec.eclPhaseMask( ));
} }

View File

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

View File

@ -159,10 +159,11 @@ BOOST_AUTO_TEST_CASE(WellTableDimensions)
const auto maxPerf = 29; const auto maxPerf = 29;
const auto maxWellInGroup = 3; const auto maxWellInGroup = 3;
const auto maxGroupInField = 14; const auto maxGroupInField = 14;
const auto maxWellInField = 20;
const auto ih = Opm::RestartIO::InteHEAD{} const auto ih = Opm::RestartIO::InteHEAD{}
.wellTableDimensions({ .wellTableDimensions({
numWells, maxPerf, maxWellInGroup, maxGroupInField, 0 numWells, maxPerf, maxWellInGroup, maxGroupInField, maxWellInField
}); });
const auto& v = ih.data(); const auto& v = ih.data();

View File

@ -39,18 +39,52 @@
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/io/eclipse/OutputStream.hpp> #include <opm/io/eclipse/OutputStream.hpp>
#include <opm/io/eclipse/EclIOdata.hpp>
#include <opm/io/eclipse/ERst.hpp>
#include <tuple>
// ERT stuff // ERT stuff
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_util.h> #include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl_well/well_info.h> #include <tests/WorkArea.cpp>
#include <ert/ecl_well/well_state.h>
#include <ert/util/test_work_area.h>
using namespace Opm; 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" ) { inline std::string input( const std::string& rst_name = "FIRST_SIM" ) {
return std::string( return std::string(
"RUNSPEC\n" "RUNSPEC\n"
@ -541,8 +575,8 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData) {
{"SWAT" , UnitSystem::measure::identity}, {"SWAT" , UnitSystem::measure::identity},
{"SGAS" , UnitSystem::measure::identity}, {"SGAS" , UnitSystem::measure::identity},
{"TEMP" , UnitSystem::measure::temperature}}; {"TEMP" , UnitSystem::measure::temperature}};
test_work_area_type * test_area = test_work_area_alloc("test_restart"); WorkArea test_area("test_restart");
test_work_area_copy_file( test_area, "FIRST_SIM.DATA"); test_area.copyIn("FIRST_SIM.DATA");
Setup setup("FIRST_SIM.DATA"); Setup setup("FIRST_SIM.DATA");
EclipseIO eclWriter( setup.es, setup.grid, setup.schedule, setup.summary_config); 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}} ) , std::runtime_error );
BOOST_CHECK_THROW( second_sim( eclWriter, st, {{"SOIL", UnitSystem::measure::pressure, true}}) , 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; namespace OS = ::Opm::EclIO::OutputStream;
Setup setup("FIRST_SIM.DATA"); 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& io_config = setup.es.getIOConfig();
{ {
auto num_cells = setup.grid.getNumActive( ); auto num_cells = setup.grid.getNumActive( );
@ -574,9 +607,7 @@ BOOST_AUTO_TEST_CASE(ECL_FORMATTED) {
io_config.setEclCompatibleRST( false ); io_config.setEclCompatibleRST( false );
restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3}); restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3});
const auto outputDir = std::string { const auto outputDir = test_area.currentWorkingDirectory();
test_work_area_get_cwd(test_area)
};
{ {
const auto seqnum = 1; const auto seqnum = 1;
@ -599,12 +630,10 @@ BOOST_AUTO_TEST_CASE(ECL_FORMATTED) {
const auto rstFile = ::Opm::EclIO::OutputStream:: const auto rstFile = ::Opm::EclIO::OutputStream::
outputFileName({outputDir, "OPM_FILE"}, "UNRST"); outputFileName({outputDir, "OPM_FILE"}, "UNRST");
ecl_file_type * rst_file = ecl_file_open( rstFile.c_str() , 0 ); EclIO::ERst rst{ rstFile };
ecl_kw_type * swat = ecl_file_iget_named_kw(rst_file, "SWAT", 0);
BOOST_CHECK_EQUAL( ECL_DOUBLE_TYPE, ecl_kw_get_type(swat)); BOOST_CHECK_MESSAGE(rst.hasKey("SWAT"), "Restart file must have SWAT vector");
BOOST_CHECK( ecl_file_has_kw(rst_file, "EXTRA")); BOOST_CHECK_MESSAGE(rst.hasKey("EXTRA"), "Restart file must have EXTRA vector");
ecl_file_close(rst_file);
} }
io_config.setEclCompatibleRST( true ); io_config.setEclCompatibleRST( true );
@ -629,18 +658,15 @@ BOOST_AUTO_TEST_CASE(ECL_FORMATTED) {
const auto rstFile = ::Opm::EclIO::OutputStream:: const auto rstFile = ::Opm::EclIO::OutputStream::
outputFileName({outputDir, "ECL_FILE"}, "UNRST"); outputFileName({outputDir, "ECL_FILE"}, "UNRST");
ecl_file_type * rst_file = ecl_file_open( rstFile.c_str() , 0 ); EclIO::ERst rst{ rstFile };
ecl_kw_type * swat = ecl_file_iget_named_kw(rst_file, "SWAT", 0);
BOOST_CHECK_EQUAL( ECL_FLOAT_TYPE, ecl_kw_get_type(swat)); BOOST_CHECK_MESSAGE(rst.hasKey("SWAT"), "Restart file must have SWAT vector");
BOOST_CHECK( !ecl_file_has_kw(rst_file, "EXTRA")); BOOST_CHECK_MESSAGE(!rst.hasKey("EXTRA"), "Restart file must NOT have EXTRA vector");
BOOST_CHECK( !ecl_file_has_kw(rst_file, "OPM_XWEL")); BOOST_CHECK_MESSAGE(!rst.hasKey("OPM_IWEL"), "Restart file must NOT have OPM_IWEL vector");
BOOST_CHECK( !ecl_file_has_kw(rst_file, "OPM_IWEL")); BOOST_CHECK_MESSAGE(!rst.hasKey("OPM_XWEL"), "Restart file must NOT have OPM_XWEL vector");
ecl_file_close(rst_file);
} }
} }
} }
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), std::vector<RestartKey> solution_keys {RestartKey("SWAT", UnitSystem::measure::identity),
RestartKey("SGAS", UnitSystem::measure::identity)}; RestartKey("SGAS", UnitSystem::measure::identity)};
test_work_area_type * test_area = test_work_area_alloc("test_Restart"); WorkArea test_area("test_Restart");
test_work_area_copy_file( test_area, "FIRST_SIM.DATA"); test_area.copyIn("FIRST_SIM.DATA");
Setup setup("FIRST_SIM.DATA"); Setup setup("FIRST_SIM.DATA");
EclipseIO eclWriter( setup.es, setup.grid, setup.schedule, setup.summary_config); EclipseIO eclWriter( setup.es, setup.grid, setup.schedule, setup.summary_config);
SummaryState st(std::chrono::system_clock::now()); 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 state1 = first_sim( setup.es , eclWriter , st, true);
auto state2 = second_sim( eclWriter ,st, solution_keys ); auto state2 = second_sim( eclWriter ,st, solution_keys );
compare_equal( state1 , state2 , solution_keys); compare_equal( state1 , state2 , solution_keys);
test_work_area_free( test_area );
} }
BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) { BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) {
namespace OS = ::Opm::EclIO::OutputStream; namespace OS = ::Opm::EclIO::OutputStream;
WorkArea test_area("test_Restart");
test_area.copyIn("FIRST_SIM.DATA");
Setup setup("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 num_cells = setup.grid.getNumActive( ) + 1;
auto cells = mkSolution( num_cells ); auto cells = mkSolution( num_cells );
@ -702,7 +728,7 @@ BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) {
const auto seqnum = 1; const auto seqnum = 1;
auto rstFile = OS::Restart { 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 } OS::Formatted { false }, OS::Unified { true }
}; };
@ -715,7 +741,6 @@ BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) {
sumState), sumState),
std::runtime_error); 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) { BOOST_AUTO_TEST_CASE(ExtraData_content) {
namespace OS = ::Opm::EclIO::OutputStream; namespace OS = ::Opm::EclIO::OutputStream;
WorkArea test_area("test_Restart");
test_area.copyIn("FIRST_SIM.DATA");
Setup setup("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 num_cells = setup.grid.getNumActive( );
auto cells = mkSolution( num_cells ); 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}); restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3});
const auto outputDir = std::string { const auto outputDir = test_area.currentWorkingDirectory();
test_work_area_get_cwd(test_area)
};
{ {
const auto seqnum = 1; const auto seqnum = 1;
@ -780,17 +804,12 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) {
outputFileName({outputDir, "FILE"}, "UNRST"); outputFileName({outputDir, "FILE"}, "UNRST");
{ {
ecl_file_type * f = ecl_file_open( rstFile.c_str() , 0 ); EclIO::ERst rst{ rstFile };
BOOST_CHECK( ecl_file_has_kw( f , "EXTRA")); BOOST_CHECK_MESSAGE( rst.hasKey("EXTRA"), "Restart file is expexted to have EXTRA vector");
{
ecl_kw_type * ex = ecl_file_iget_named_kw( f , "EXTRA" , 0 );
BOOST_CHECK_EQUAL( ecl_kw_get_header( ex) , "EXTRA" );
BOOST_CHECK_EQUAL( 4 , ecl_kw_get_size( ex ));
BOOST_CHECK_CLOSE( 10 , units.to_si( UnitSystem::measure::pressure, ecl_kw_iget_double( ex, 0 )), 0.00001); const auto& ex = rst.getRst<double>("EXTRA", 1);
BOOST_CHECK_CLOSE( units.from_si( UnitSystem::measure::pressure, 3), ecl_kw_iget_double( ex, 3 ), 0.00001); 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);
ecl_file_close( f );
} }
BOOST_CHECK_THROW( RestartIO::load( rstFile , 1 , st, {}, setup.es, setup.grid , setup.schedule, 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) { BOOST_AUTO_TEST_CASE(STORE_THPRES) {
namespace OS = ::Opm::EclIO::OutputStream; namespace OS = ::Opm::EclIO::OutputStream;
WorkArea test_area("test_Restart_THPRES");
test_area.copyIn("FIRST_SIM_THPRES.DATA");
Setup setup("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 num_cells = setup.grid.getNumActive( );
auto cells = mkSolution( num_cells ); auto cells = mkSolution( num_cells );
auto wells = mkWells(); auto wells = mkWells();
const auto outputDir = std::string { const auto outputDir = test_area.currentWorkingDirectory();
test_work_area_get_cwd(test_area)
};
{ {
RestartValue restart_value(cells, wells); RestartValue restart_value(cells, wells);
RestartValue restart_value2(cells, wells); RestartValue restart_value2(cells, wells);
@ -897,34 +914,36 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) {
const auto rstFile = ::Opm::EclIO::OutputStream:: const auto rstFile = ::Opm::EclIO::OutputStream::
outputFileName({outputDir, "FILE2"}, "UNRST"); 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; 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["STARTSOL"] < kw_pos["THRESHPR"] );
BOOST_CHECK( kw_pos["THRESHPR"] < kw_pos["ENDSOL"] ); BOOST_CHECK( kw_pos["THRESHPR"] < kw_pos["ENDSOL"] );
BOOST_CHECK( kw_pos["ENDSOL"] < kw_pos["EXTRA"] ); 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, "THRESHPR"), 1);
BOOST_CHECK_EQUAL( ecl_file_get_num_named_kw(rst_file, "EXTRA"), 1); BOOST_CHECK_EQUAL( ecl_file_get_num_named_kw(rst, "EXTRA"), 1);
BOOST_CHECK_EQUAL( ecl_kw_get_type(ecl_file_iget_named_kw(rst_file, "THRESHPR", 0)), ECL_DOUBLE_TYPE); BOOST_CHECK_MESSAGE( ecl_kw_get_type(ecl_file_iget_named_kw(rst, "THRESHPR", 1)) == EclIO::eclArrType::DOUB,
ecl_file_close(rst_file); R"("THRESHPR" vector must have type DOUB)");
} }
} }
} }
test_work_area_free(test_area);
} }
BOOST_AUTO_TEST_CASE(Restore_Cumulatives) BOOST_AUTO_TEST_CASE(Restore_Cumulatives)
{ {
WorkArea wa{"test_Restart"};
wa.copyIn("FIRST_SIM.DATA");
Setup setup("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. // Write fully ECLIPSE compatible output. This also saves cumulatives.
setup.es.getIOConfig().setEclCompatibleRST(true); setup.es.getIOConfig().setEclCompatibleRST(true);
@ -936,7 +955,7 @@ BOOST_AUTO_TEST_CASE(Restore_Cumulatives)
namespace OS = ::Opm::EclIO::OutputStream; 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; const auto seqnum = 1;
{ {
auto rstFile = OS::Restart { auto rstFile = OS::Restart {

View File

@ -25,17 +25,12 @@
#include <cstddef> #include <cstddef>
#include <exception> #include <exception>
#include <memory>
#include <stdexcept> #include <stdexcept>
#include <unordered_map> #include <unordered_map>
#include <cctype> #include <cctype>
#include <ctime> #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/data/Wells.hpp>
#include <opm/output/eclipse/Summary.hpp> #include <opm/output/eclipse/Summary.hpp>
@ -50,6 +45,10 @@
#include <opm/parser/eclipse/Units/Units.hpp> #include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/io/eclipse/ESmry.hpp>
#include <tests/WorkArea.cpp>
using namespace Opm; using namespace Opm;
using rt = data::Rates::opt; using rt = data::Rates::opt;
@ -75,6 +74,7 @@ namespace SegmentResultHelpers {
data::Well inje01_results(); data::Well inje01_results();
} // SegmentResultHelpers } // SegmentResultHelpers
namespace {
/* conversion factor for whenever 'day' is the unit of measure, whereas we /* conversion factor for whenever 'day' is the unit of measure, whereas we
* expect input in SI units (seconds) * expect input in SI units (seconds)
*/ */
@ -261,10 +261,75 @@ static data::Wells result_wells() {
return wellrates; return wellrates;
} }
ERT::ert_unique_ptr< ecl_sum_type, ecl_sum_free > readsum( const std::string& base ) { std::unique_ptr< EclIO::ESmry > readsum( const std::string& base ) {
return ERT::ert_unique_ptr< ecl_sum_type, ecl_sum_free >( return std::make_unique<EclIO::ESmry>(base);
ecl_sum_fread_alloc_case( base.c_str(), ":" ) }
);
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 { struct setup {
@ -275,7 +340,7 @@ struct setup {
SummaryConfig config; SummaryConfig config;
data::Wells wells; data::Wells wells;
std::string name; std::string name;
test_work_area_type * ta; WorkArea ta;
/*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/
@ -287,29 +352,10 @@ struct setup {
config( deck, schedule, es.getTableManager()), config( deck, schedule, es.getTableManager()),
wells( result_wells() ), wells( result_wells() ),
name( toupper(std::move(fname)) ), name( toupper(std::move(fname)) ),
ta( test_work_area_alloc("summary_test")) ta( "summary_test" )
{ {}
}
~setup() {
test_work_area_free(this->ta);
}
}; };
} // Anonymous namespace
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);
}
}
BOOST_AUTO_TEST_SUITE(Summary) 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 // Force to run in a directory, to make sure the basename with
// leading path works. // leading path works.
util_make_path( "PATH" ); cfg.ta.makeSubDir( "PATH" );
cfg.name = "PATH/CASE"; cfg.name = "PATH/CASE";
SummaryState st(std::chrono::system_clock::now()); 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(); 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_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 ); 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"); BOOST_CHECK_EQUAL( std::string(ecl_sum_get_unit(resp, "WUBHP:W_1")), "BARSA");
#endif
} }
BOOST_AUTO_TEST_CASE(group_keywords) { BOOST_AUTO_TEST_CASE(group_keywords) {
@ -776,49 +825,49 @@ BOOST_AUTO_TEST_CASE(completion_kewords) {
const auto* resp = res.get(); const auto* resp = res.get();
/* Production rates */ /* 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.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 ), 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 ), 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 */ /* 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.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 ), 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 ), 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 ), 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 ), 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 ), 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 * 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 ), 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 ), 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 * 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 ), 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 ), 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 */ /* 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.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 ), 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 ), 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 ), 1e-5 ); BOOST_CHECK_CLOSE( 300.0 * 2.5, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CCIR", 3, 1, 1 ), 1e-5 );
/* Injection totals */ /* Injection totals */
BOOST_CHECK_CLOSE( 300.0, ecl_sum_get_well_completion_var( resp, 1, "W_3", "CWIT", 3 ), 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 ), 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 ), 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 ), 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 ), 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 ), 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 ), 1e-5 ); BOOST_CHECK_CLOSE( 2 * 300.3, ecl_sum_get_well_completion_var( resp, 2, "W_3", "CNIT", 3, 1, 1 ), 1e-5 );
BOOST_CHECK_CLOSE( 300.0 * 1.5 + 300.0 * 2.5, BOOST_CHECK_CLOSE( 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 /* Solvent flow rate + or - Note OPM uses negative values for producers, while CNFR outputs positive
values for producers*/ 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( -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 ), 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) { 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) { BOOST_AUTO_TEST_CASE(report_steps_time) {
setup cfg( "test_summary_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_iget_sim_days( resp, 2 ), 10 );
BOOST_CHECK_EQUAL( ecl_sum_get_sim_length( resp ), 10 ); BOOST_CHECK_EQUAL( ecl_sum_get_sim_length( resp ), 10 );
} }
#endif
BOOST_AUTO_TEST_CASE(skip_unknown_var) { BOOST_AUTO_TEST_CASE(skip_unknown_var) {
setup cfg( "test_summary_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( ecl_sum_has_general_var( resp , "ROPR:1"));
BOOST_CHECK_CLOSE(ecl_sum_get_general_var( resp , 1 , "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_1:1,1,1") +
ecl_sum_get_general_var( resp , 1 , "COPR:W_2:2") + ecl_sum_get_general_var( resp , 1 , "COPR:W_2:2,1,1") +
ecl_sum_get_general_var( resp , 1 , "COPR:W_3:3"), 1e-5); 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( ecl_sum_has_general_var( resp , "RGPT:1"));
BOOST_CHECK_CLOSE(ecl_sum_get_general_var( resp , 2 , "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_1:1,1,1") +
ecl_sum_get_general_var( resp , 2 , "CGPT:W_2:2") + ecl_sum_get_general_var( resp , 2 , "CGPT:W_2:2,1,1") +
ecl_sum_get_general_var( resp , 2 , "CGPT:W_3:3"), 1e-5); ecl_sum_get_general_var( resp , 2 , "CGPT:W_3:3,1,1"), 1e-5);
} }
BOOST_AUTO_TEST_CASE(region_injection) { 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( ecl_sum_has_general_var( resp , "RWIR:1"));
BOOST_CHECK_CLOSE(ecl_sum_get_general_var( resp , 1 , "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_1:1,1,1") +
ecl_sum_get_general_var( resp , 1 , "CWIR:W_2:2") + ecl_sum_get_general_var( resp , 1 , "CWIR:W_2:2,1,1") +
ecl_sum_get_general_var( resp , 1 , "CWIR:W_3:3"), 1e-5); 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( ecl_sum_has_general_var( resp , "RGIT:1"));
BOOST_CHECK_CLOSE(ecl_sum_get_general_var( resp , 2 , "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_1:1,1,1") +
ecl_sum_get_general_var( resp , 2 , "CGIT:W_2:2") + ecl_sum_get_general_var( resp , 2 , "CGIT:W_2:2,1,1") +
ecl_sum_get_general_var( resp , 2 , "CGIT:W_3:3"), 1e-5); 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( 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( 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( 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) , 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", 102) , 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) , 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( 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) , 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 // Cell is not active
BOOST_CHECK( !ecl_sum_has_general_var( resp , "BPR:2,1,10")); 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( 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, 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 ), 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 { namespace {
bool hasSegmentVariable_Prod01(const ecl_sum_type* ecl_sum, bool hasSegmentVariable_Prod01(const Opm::EclIO::ESmry* ecl_sum,
const char* vector, const char* vector,
const int segID) const int segID)
{ {
const auto lookup_kw = genKeyPROD01(vector, 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, double getSegmentVariable_Prod01(const Opm::EclIO::ESmry* ecl_sum,
const int timeIdx, const int timeIdx,
const char* vector, const char* vector,
const int segID) const int segID)
{ {
const auto lookup_kw = genKeyPROD01(vector, 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 } // Anonymous
@ -3134,6 +3185,7 @@ BOOST_AUTO_TEST_CASE(SummaryState_TOTAL) {
BOOST_CHECK_EQUAL(st.get_elapsed(), 200); BOOST_CHECK_EQUAL(st.get_elapsed(), 200);
} }
namespace {
bool equal(const SummaryState& st1 , const SummaryState& st2) { bool equal(const SummaryState& st1 , const SummaryState& st2) {
if (st1.size() != st2.size()) if (st1.size() != st2.size())
return false; return false;
@ -3185,7 +3237,7 @@ void test_serialize(const SummaryState& st) {
st2.deserialize(serial); st2.deserialize(serial);
BOOST_CHECK( equal(st, st2)); BOOST_CHECK( equal(st, st2));
} }
} // Anonymous namespace
BOOST_AUTO_TEST_CASE(serialize_sumary_state) { BOOST_AUTO_TEST_CASE(serialize_sumary_state) {
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());