From a8461fd1211b352be279a91a76430d192d575fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Skille?= Date: Wed, 25 Nov 2020 10:55:22 +0100 Subject: [PATCH] Updating class ERst - rename member function from getRst -> getRestartData - adding support for parsing and reading data for LGRs - a number of member functions made const - updated python bindings for this class --- CMakeLists_files.cmake | 2 + opm/io/eclipse/ERst.hpp | 47 +++- python/cxx/eclipse_io.cpp | 21 +- src/opm/io/eclipse/ERst.cpp | 197 +++++++++++++-- src/opm/io/eclipse/rst/state.cpp | 32 +-- src/opm/output/eclipse/LoadRestart.cpp | 2 +- test_util/EclRegressionTest.cpp | 20 +- test_util/convertECL.cpp | 4 +- tests/LGR_TESTMOD.UNRST | Bin 0 -> 510880 bytes tests/LGR_TESTMOD.X0002 | Bin 0 -> 127684 bytes tests/msim/test_msim.cpp | 4 +- tests/test_ERst.cpp | 332 ++++++++++++++++++++----- tests/test_EclipseIO.cpp | 10 +- tests/test_OutputStream.cpp | 30 +-- tests/test_Restart.cpp | 4 +- 15 files changed, 550 insertions(+), 155 deletions(-) create mode 100644 tests/LGR_TESTMOD.UNRST create mode 100644 tests/LGR_TESTMOD.X0002 diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index fc78d018e..304843075 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -481,6 +481,8 @@ if(ENABLE_ECL_INPUT) tests/ECLFILE.FINIT tests/LGR_TESTMOD.EGRID tests/LGR_TESTMOD.INIT + tests/LGR_TESTMOD.UNRST + tests/LGR_TESTMOD.X0002 tests/MODEL1_IX.INIT tests/MODEL1_IX.SMSPEC tests/MODEL1_IX.UNSMRY diff --git a/opm/io/eclipse/ERst.hpp b/opm/io/eclipse/ERst.hpp index a0fa0f741..cd2959884 100644 --- a/opm/io/eclipse/ERst.hpp +++ b/opm/io/eclipse/ERst.hpp @@ -27,6 +27,7 @@ #include #include + namespace Opm { namespace EclIO { namespace OutputStream { class Restart; }}} @@ -37,43 +38,73 @@ class ERst : public EclFile { public: explicit ERst(const std::string& filename); + bool hasReportStepNumber(int number) const; + bool hasLGR(const std::string& gridname, int reportStepNumber) const; void loadReportStepNumber(int number); template - const std::vector& getRst(const std::string& name, int reportStepNumber, int occurrence); + const std::vector& getRestartData(const std::string& name, int reportStepNumber) + { + return getRestartData(name,reportStepNumber, 0); + } template - const std::vector& getRst(int index, int reportStepNumber){ + const std::vector& getRestartData(const std::string& name, int reportStepNumber, int occurrence); + + template + const std::vector& getRestartData(const std::string& name, int reportStepNumber, const std::string& lgr_name); + + template + const std::vector& getRestartData(int index, int reportStepNumber) + { auto indRange = this->getIndexRange(reportStepNumber); return this->get(index + std::get<0>(indRange)); } - int count(const std::string& name, int reportStepNumber) const; + template + const std::vector& getRestartData(int index, int reportStepNumber, const std::string& lgr_name) + { + auto indRange = this->getIndexRange(reportStepNumber); + + if ((std::get<0>(indRange) + index) > std::get<1>(indRange)) + OPM_THROW(std::invalid_argument, "getRestartData, index out of range"); + + int start_ind = get_start_index_lgrname(reportStepNumber, lgr_name); + return this->get(index + start_ind); + } + + int occurrence_count(const std::string& name, int reportStepNumber) const; size_t numberOfReportSteps() const { return seqnum.size(); }; const std::vector& listOfReportStepNumbers() const { return seqnum; } - + std::vector listOfRstArrays(int reportStepNumber); + std::vector listOfRstArrays(int reportStepNumber, const std::string& lgr_name); friend class OutputStream::Restart; private: int nReports; std::vector seqnum; // report step numbers, from SEQNUM array in restart file - std::unordered_map reportLoaded; + mutable std::unordered_map reportLoaded; std::map> arrIndexRange; // mapping report step number to array indeces (start and end) + std::vector> lgr_names; // report step numbers, from SEQNUM array in restart file void initUnified(); void initSeparate(const int number); - int getArrayIndex(const std::string& name, int seqnum, int occurrence) const; - std::tuple getIndexRange(int reportStepNumber) const; + int get_start_index_lgrname(int number, const std::string& lgr_name); + + int getArrayIndex(const std::string& name, int seqnum, int occurrence); + int getArrayIndex(const std::string& name, int number, const std::string& lgr_name); + + std::tuple getIndexRange(int reportStepNumber) const; std::streampos restartStepWritePosition(const int seqnumValue) const; - + }; }} // namespace Opm::EclIO diff --git a/python/cxx/eclipse_io.cpp b/python/cxx/eclipse_io.cpp index 58f09476b..162c497f4 100644 --- a/python/cxx/eclipse_io.cpp +++ b/python/cxx/eclipse_io.cpp @@ -121,7 +121,7 @@ npArray get_vector_occurrence(Opm::EclIO::EclFile * file_ptr, const std::string& bool erst_contains(Opm::EclIO::ERst * file_ptr, std::tuple keyword) { - bool hasKeyAtReport = file_ptr->count(std::get<0>(keyword), std::get<1>(keyword)) > 0 ? true : false; + bool hasKeyAtReport = file_ptr->occurrence_count(std::get<0>(keyword), std::get<1>(keyword)) > 0 ? true : false; return hasKeyAtReport; } @@ -135,19 +135,19 @@ npArray get_erst_by_index(Opm::EclIO::ERst * file_ptr, size_t index, size_t rste auto array_type = std::get<1>(arrList[index]); if (array_type == Opm::EclIO::INTE) - return std::make_tuple (convert::numpy_array( file_ptr->getRst(index, rstep)), array_type); + return std::make_tuple (convert::numpy_array( file_ptr->getRestartData(index, rstep)), array_type); if (array_type == Opm::EclIO::REAL) - return std::make_tuple (convert::numpy_array( file_ptr->getRst(index, rstep)), array_type); + return std::make_tuple (convert::numpy_array( file_ptr->getRestartData(index, rstep)), array_type); if (array_type == Opm::EclIO::DOUB) - return std::make_tuple (convert::numpy_array( file_ptr->getRst(index, rstep)), array_type); + return std::make_tuple (convert::numpy_array( file_ptr->getRestartData(index, rstep)), array_type); if (array_type == Opm::EclIO::LOGI) - return std::make_tuple (convert::numpy_array( file_ptr->getRst(index, rstep)), array_type); + return std::make_tuple (convert::numpy_array( file_ptr->getRestartData(index, rstep)), array_type); if (array_type == Opm::EclIO::CHAR) - return std::make_tuple (convert::numpy_string_array( file_ptr->getRst(index, rstep)), array_type); + return std::make_tuple (convert::numpy_string_array( file_ptr->getRestartData(index, rstep)), array_type); throw std::logic_error("Data type not supported"); } @@ -155,7 +155,7 @@ npArray get_erst_by_index(Opm::EclIO::ERst * file_ptr, size_t index, size_t rste npArray get_erst_vector(Opm::EclIO::ERst * file_ptr, const std::string& key, size_t rstep, size_t occurrence) { - if (occurrence >= static_cast(file_ptr->count(key, rstep))) + if (occurrence >= static_cast(file_ptr->occurrence_count(key, rstep))) throw std::out_of_range("file have less than " + std::to_string(occurrence + 1) + " arrays in selected report step"); auto array_list = file_ptr->listOfRstArrays(rstep); @@ -331,9 +331,12 @@ void python::common::export_IO(py::module& m) { .def("load_report_step", &Opm::EclIO::ERst::loadReportStepNumber) .def_property_readonly("report_steps", &Opm::EclIO::ERst::listOfReportStepNumbers) .def("__len__", &Opm::EclIO::ERst::numberOfReportSteps) - .def("count", &Opm::EclIO::ERst::count) + .def("count", &Opm::EclIO::ERst::occurrence_count) .def("__contains", &erst_contains) - .def("__get_list_of_arrays", &Opm::EclIO::ERst::listOfRstArrays) + .def("__get_list_of_arrays", (std::vector< std::tuple > + (Opm::EclIO::ERst::*)(int) ) &Opm::EclIO::ERst::listOfRstArrays) + .def("__get_list_of_arrays", (std::vector< std::tuple > + (Opm::EclIO::ERst::*)(int, const std::string&) ) &Opm::EclIO::ERst::listOfRstArrays) .def("__get_data", &get_erst_by_index) .def("__get_data", &get_erst_vector); diff --git a/src/opm/io/eclipse/ERst.cpp b/src/opm/io/eclipse/ERst.cpp index db400460e..b4964bb92 100644 --- a/src/opm/io/eclipse/ERst.cpp +++ b/src/opm/io/eclipse/ERst.cpp @@ -28,8 +28,6 @@ #include #include -#include - namespace { int seqnumFromSeparateFilename(const std::string& filename) @@ -80,9 +78,9 @@ void ERst::loadReportStepNumber(int number) } std::vector arrayIndexList; - arrayIndexList.reserve(arrIndexRange[number].second - arrIndexRange[number].first + 1); + arrayIndexList.reserve(arrIndexRange.at(number).second - arrIndexRange.at(number).first + 1); - for (int i = arrIndexRange[number].first; i < arrIndexRange[number].second; i++) { + for (int i = arrIndexRange.at(number).first; i < arrIndexRange.at(number).second; i++) { arrayIndexList.push_back(i); } @@ -93,6 +91,12 @@ void ERst::loadReportStepNumber(int number) std::vector ERst::listOfRstArrays(int reportStepNumber) +{ + return this->listOfRstArrays(reportStepNumber, "global"); +} + + +std::vector ERst::listOfRstArrays(int reportStepNumber, const std::string& lgr_name) { std::vector list; @@ -101,36 +105,66 @@ std::vector ERst::listOfRstArrays(int reportStepNumber) OPM_THROW(std::invalid_argument, message); } - const auto& rng = this->arrIndexRange[reportStepNumber]; - list.reserve(rng.second - rng.first); - - for (int i = rng.first; i < rng.second; i++) { - list.emplace_back(array_name[i], array_type[i], array_size[i]); + if ((lgr_name != "global") && (!this->hasLGR(lgr_name, reportStepNumber))) { + std::string message = "Trying to get list of arrays from non existing LGR " + lgr_name; + OPM_THROW(std::invalid_argument, message); } + std::string lgr_name_upper = lgr_name; + std::transform(lgr_name_upper.begin(), lgr_name_upper.end(),lgr_name_upper.begin(), ::toupper); + + int start_ind_lgr; + std::string last_array_name; + + if ((lgr_name == "") or (lgr_name_upper == "GLOBAL")){ + auto rng = this->arrIndexRange.at(reportStepNumber); + start_ind_lgr = std::get<0>(rng); + + // if keyword LGR not found, loop will be stopped with keyword SEQNUM (next report step) + // or last array (end of file) + // Opm flow can have extra keywords after ENDSOL, which maks ENDSOL + // not usable for a global arrays end signal. + + last_array_name = "LGR"; + } else { + start_ind_lgr = get_start_index_lgrname(reportStepNumber, lgr_name); + last_array_name = "ENDLGR"; + } + + int n = start_ind_lgr; + list.emplace_back(array_name[n], array_type[n], array_size[n]); + + do { + n++; + + if ((array_name[n] != "SEQNUM") && (array_name[n] != "LGR")) + list.emplace_back(array_name[n], array_type[n], array_size[n]); + + } while ((array_name[n] != "SEQNUM") && (array_name[n] != last_array_name) && (n < static_cast(array_name.size()) -1 )); + return list; } -int ERst::count(const std::string& name, int reportStepNumber) const -{ +int ERst::occurrence_count(const std::string& name, int reportStepNumber) const +{ if (!hasReportStepNumber(reportStepNumber)) { std::string message = "Trying to count vectors of name " + name + " from non existing sequence " + std::to_string(reportStepNumber); OPM_THROW(std::invalid_argument, message); } - + int count = 0; - + auto range_it = arrIndexRange.find(reportStepNumber); std::pair indexRange = range_it->second; - + for (int i=std::get<0>(indexRange); i(indexRange);i++){ if (array_name[i] == name){ count++; } } - + return count; } @@ -145,10 +179,15 @@ void ERst::initUnified() auto seqn = get(i); seqnum.push_back(seqn[0]); firstIndex.push_back(i); + lgr_names.push_back({}); + } + + if (array_name[i] == "LGRNAMES") { + auto names = getImpl(i, CHAR, char_array, "string"); + lgr_names[seqnum.size() -1 ] = names; } } - for (size_t i = 0; i < seqnum.size(); i++) { std::pair range; range.first = firstIndex[i]; @@ -169,6 +208,21 @@ void ERst::initUnified() } } +bool ERst::hasLGR(const std::string& gridname, int reportStepNumber) const +{ + if (!hasReportStepNumber(reportStepNumber)) { + std::string message = "Checking for LGR name in non existing sequence " + std::to_string(reportStepNumber); + OPM_THROW(std::invalid_argument, message); + } + + auto it_seqnum = std::find(seqnum.begin(), seqnum.end(), reportStepNumber); + int report_index = std::distance(seqnum.begin(), it_seqnum); + auto it_lgrname = std::find(lgr_names[report_index].begin(), lgr_names[report_index].end(), gridname); + + return (it_lgrname != lgr_names[report_index].end()); +} + + void ERst::initSeparate(const int number) { auto& range = this->arrIndexRange[number]; @@ -178,6 +232,41 @@ void ERst::initSeparate(const int number) this->seqnum.assign(1, number); this->nReports = 1; this->reportLoaded[number] = false; + this->lgr_names.push_back({}); + + for (int i = range.first; i < range.second; i++) { + if (array_name[i] == "LGRNAMES") { + auto names = getImpl(i, CHAR, char_array, "string"); + lgr_names[0] = names; + } + } +} + +int ERst::get_start_index_lgrname(int number, const std::string& lgr_name) +{ + if (!hasReportStepNumber(number)) { + std::string message = "Trying to get a restart vector from non report step " + std::to_string(number); + OPM_THROW(std::invalid_argument, message); + } + + auto range_it = arrIndexRange.find(number); + std::pair indexRange = range_it->second; + int start_ind_lgr = -1; + + for (int n = indexRange.first; n < indexRange.second; n++) { + if (array_name[n] == "LGR") { + auto arr = getImpl(n, CHAR, char_array, "string"); + if (arr[0] == lgr_name) + start_ind_lgr = n; + } + } + + if (start_ind_lgr == -1){ + std::string message = "LGR '" + lgr_name + "'not found in restart file"; + OPM_THROW(std::runtime_error, message); + } + + return start_ind_lgr; } std::tuple ERst::getIndexRange(int reportStepNumber) const { @@ -186,19 +275,20 @@ std::tuple ERst::getIndexRange(int reportStepNumber) const { std::string message = "Trying to get index range for non existing sequence " + std::to_string(reportStepNumber); OPM_THROW(std::invalid_argument, message); } - + auto range_it = arrIndexRange.find(reportStepNumber); - + return range_it->second; } -int ERst::getArrayIndex(const std::string& name, int number, int occurrenc) const +int ERst::getArrayIndex(const std::string& name, int number, int occurrenc) { if (!hasReportStepNumber(number)) { std::string message = "Trying to get vector " + name + " from non existing sequence " + std::to_string(number); OPM_THROW(std::invalid_argument, message); } - + + auto range_it = arrIndexRange.find(number); std::pair indexRange = range_it->second; @@ -209,7 +299,7 @@ int ERst::getArrayIndex(const std::string& name, int number, int occurrenc) cons for (int t = 0; t < occurrenc; t++){ it = std::find(it + 1 , array_name.begin() + indexRange.second, name); } - + if (std::distance(array_name.begin(),it) == indexRange.second) { std::string message = "Array " + name + " not found in sequence " + std::to_string(number); OPM_THROW(std::runtime_error, message); @@ -218,6 +308,25 @@ int ERst::getArrayIndex(const std::string& name, int number, int occurrenc) cons return std::distance(array_name.begin(), it); } +int ERst::getArrayIndex(const std::string& name, int number, const std::string& lgr_name) +{ + auto range_it = arrIndexRange.find(number); + std::pair indexRange = range_it->second; + + int start_ind_lgr = get_start_index_lgrname(number, lgr_name); + + auto it = std::find(array_name.begin() + start_ind_lgr, + array_name.begin() + indexRange.second, name); + + if (std::distance(array_name.begin(),it) == indexRange.second) { + std::string message = "Array " + name + " not found for " + lgr_name; + OPM_THROW(std::runtime_error, message); + } + + return std::distance(array_name.begin(), it); +} + + std::streampos ERst::restartStepWritePosition(const int seqnumValue) const { @@ -229,38 +338,74 @@ ERst::restartStepWritePosition(const int seqnumValue) const } template<> -const std::vector& ERst::getRst(const std::string& name, int reportStepNumber, int occurrence) +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber, int occurrence) { int ind = getArrayIndex(name, reportStepNumber, occurrence); return getImpl(ind, INTE, inte_array, "integer"); } template<> -const std::vector& ERst::getRst(const std::string& name, int reportStepNumber, int occurrence) +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber, int occurrence) { int ind = getArrayIndex(name, reportStepNumber, occurrence); return getImpl(ind, REAL, real_array, "float"); } template<> -const std::vector& ERst::getRst(const std::string& name, int reportStepNumber, int occurrence) +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber, int occurrence) { int ind = getArrayIndex(name, reportStepNumber, occurrence); return getImpl(ind, DOUB, doub_array, "double"); } template<> -const std::vector& ERst::getRst(const std::string& name, int reportStepNumber, int occurrence) +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber, int occurrence) { int ind = getArrayIndex(name, reportStepNumber, occurrence); return getImpl(ind, LOGI, logi_array, "bool"); } template<> -const std::vector& ERst::getRst(const std::string& name, int reportStepNumber, int occurrence) +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber, int occurrence) { int ind = getArrayIndex(name, reportStepNumber, occurrence); return getImpl(ind, CHAR, char_array, "string"); } +template<> +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber,const std::string& lgr_name) +{ + int ind = getArrayIndex(name, reportStepNumber, lgr_name); + return getImpl(ind, REAL, real_array, "float"); +} + +template<> +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber,const std::string& lgr_name) +{ + int ind = getArrayIndex(name, reportStepNumber, lgr_name); + return getImpl(ind, DOUB, doub_array, "double"); +} + +template<> +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber,const std::string& lgr_name) +{ + int ind = getArrayIndex(name, reportStepNumber, lgr_name); + return getImpl(ind, INTE, inte_array, "int"); +} + +template<> +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber,const std::string& lgr_name) +{ + int ind = getArrayIndex(name, reportStepNumber, lgr_name); + return getImpl(ind, LOGI, logi_array, "bool"); +} + +template<> +const std::vector& ERst::getRestartData(const std::string& name, int reportStepNumber,const std::string& lgr_name) +{ + int ind = getArrayIndex(name, reportStepNumber, lgr_name); + return getImpl(ind, CHAR, char_array, "char"); +} + + }} // namespace Opm::ecl diff --git a/src/opm/io/eclipse/rst/state.cpp b/src/opm/io/eclipse/rst/state.cpp index bb2e34720..262846796 100644 --- a/src/opm/io/eclipse/rst/state.cpp +++ b/src/opm/io/eclipse/rst/state.cpp @@ -209,32 +209,32 @@ const RstWell& RstState::get_well(const std::string& wname) const { RstState RstState::load(EclIO::ERst& rst_file, int report_step) { rst_file.loadReportStepNumber(report_step); - const auto& intehead = rst_file.getRst("INTEHEAD", report_step, 0); - const auto& logihead = rst_file.getRst("LOGIHEAD", report_step, 0); - const auto& doubhead = rst_file.getRst("DOUBHEAD", report_step, 0); + const auto& intehead = rst_file.getRestartData("INTEHEAD", report_step, 0); + const auto& logihead = rst_file.getRestartData("LOGIHEAD", report_step, 0); + const auto& doubhead = rst_file.getRestartData("DOUBHEAD", report_step, 0); auto unit_id = intehead[VI::intehead::UNIT]; ::Opm::UnitSystem unit_system(unit_id); if (intehead[VI::intehead::NWELLS] != 0) { - const auto& zgrp = rst_file.getRst("ZGRP", report_step, 0); - const auto& igrp = rst_file.getRst("IGRP", report_step, 0); - const auto& sgrp = rst_file.getRst("SGRP", report_step, 0); - const auto& xgrp = rst_file.getRst("XGRP", report_step, 0); + const auto& zgrp = rst_file.getRestartData("ZGRP", report_step, 0); + const auto& igrp = rst_file.getRestartData("IGRP", report_step, 0); + const auto& sgrp = rst_file.getRestartData("SGRP", report_step, 0); + const auto& xgrp = rst_file.getRestartData("XGRP", report_step, 0); - const auto& zwel = rst_file.getRst("ZWEL", report_step, 0); - const auto& iwel = rst_file.getRst("IWEL", report_step, 0); - const auto& swel = rst_file.getRst("SWEL", report_step, 0); - const auto& xwel = rst_file.getRst("XWEL", report_step, 0); + const auto& zwel = rst_file.getRestartData("ZWEL", report_step, 0); + const auto& iwel = rst_file.getRestartData("IWEL", report_step, 0); + const auto& swel = rst_file.getRestartData("SWEL", report_step, 0); + const auto& xwel = rst_file.getRestartData("XWEL", report_step, 0); - const auto& icon = rst_file.getRst("ICON", report_step, 0); - const auto& scon = rst_file.getRst("SCON", report_step, 0); - const auto& xcon = rst_file.getRst("XCON", report_step, 0); + const auto& icon = rst_file.getRestartData("ICON", report_step, 0); + const auto& scon = rst_file.getRestartData("SCON", report_step, 0); + const auto& xcon = rst_file.getRestartData("XCON", report_step, 0); if (rst_file.hasKey("ISEG")) { - const auto& iseg = rst_file.getRst("ISEG", report_step, 0); - const auto& rseg = rst_file.getRst("RSEG", report_step, 0); + const auto& iseg = rst_file.getRestartData("ISEG", report_step, 0); + const auto& rseg = rst_file.getRestartData("RSEG", report_step, 0); return RstState(unit_system, intehead, logihead, doubhead, diff --git a/src/opm/output/eclipse/LoadRestart.cpp b/src/opm/output/eclipse/LoadRestart.cpp index b5bd06994..1ad47f7c1 100644 --- a/src/opm/output/eclipse/LoadRestart.cpp +++ b/src/opm/output/eclipse/LoadRestart.cpp @@ -148,7 +148,7 @@ public: const std::vector& getKeyword(const std::string& vector) { - return this->rst_file_->getRst(vector, this->report_step_, 0); + return this->rst_file_->getRestartData(vector, this->report_step_, 0); } const std::vector& intehead() diff --git a/test_util/EclRegressionTest.cpp b/test_util/EclRegressionTest.cpp index bbfd2e2cc..50fd20fa3 100644 --- a/test_util/EclRegressionTest.cpp +++ b/test_util/EclRegressionTest.cpp @@ -856,16 +856,16 @@ void ECLRegressionTest::results_rst() std::cout << "Comparing " << keywords1[i] << " ... "; if (arrayType1[i] == INTE) { - auto vect1 = rst1.getRst(keywords1[i], seqn, 0); - auto vect2 = rst2.getRst(keywords2[ind2], seqn, 0); + auto vect1 = rst1.getRestartData(keywords1[i], seqn, 0); + auto vect2 = rst2.getRestartData(keywords2[ind2], seqn, 0); compareVectors(vect1, vect2, keywords1[i], reference); } else if (arrayType1[i] == REAL) { - auto vect1 = rst1.getRst(keywords1[i], seqn, 0); - auto vect2 = rst2.getRst(keywords2[ind2], seqn, 0); + auto vect1 = rst1.getRestartData(keywords1[i], seqn, 0); + auto vect2 = rst2.getRestartData(keywords2[ind2], seqn, 0); compareFloatingPointVectors(vect1, vect2, keywords1[i], reference); } else if (arrayType1[i] == DOUB) { - auto vect1 = rst1.getRst(keywords1[i], seqn, 0); - auto vect2 = rst2.getRst(keywords2[ind2], seqn, 0); + auto vect1 = rst1.getRestartData(keywords1[i], seqn, 0); + auto vect2 = rst2.getRestartData(keywords2[ind2], seqn, 0); // hack in order to not test doubhead[1], dependent on simulation results // All ohter items in DOUBHEAD are tested with strict tolerances @@ -874,12 +874,12 @@ void ECLRegressionTest::results_rst() } compareFloatingPointVectors(vect1, vect2, keywords1[i], reference); } else if (arrayType1[i] == LOGI) { - auto vect1 = rst1.getRst(keywords1[i], seqn, 0); - auto vect2 = rst2.getRst(keywords2[ind2], seqn, 0); + auto vect1 = rst1.getRestartData(keywords1[i], seqn, 0); + auto vect2 = rst2.getRestartData(keywords2[ind2], seqn, 0); compareVectors(vect1, vect2, keywords1[i], reference); } else if (arrayType1[i] == CHAR) { - auto vect1 = rst1.getRst(keywords1[i], seqn, 0); - auto vect2 = rst2.getRst(keywords2[ind2], seqn, 0); + auto vect1 = rst1.getRestartData(keywords1[i], seqn, 0); + auto vect2 = rst2.getRestartData(keywords2[ind2], seqn, 0); compareVectors(vect1, vect2, keywords1[i], reference); } else if (arrayType1[i] == MESS) { // shold not be any associated data diff --git a/test_util/convertECL.cpp b/test_util/convertECL.cpp index 979028913..3d907f765 100644 --- a/test_util/convertECL.cpp +++ b/test_util/convertECL.cpp @@ -24,7 +24,7 @@ template void write(EclOutput& outFile, ERst& file1, const std::string& name, int index, int reportStepNumber) { - auto vect = file1.getRst(index, reportStepNumber); + auto vect = file1.getRestartData(index, reportStepNumber); outFile.write(name, vect); } @@ -177,7 +177,7 @@ int main(int argc, char **argv) { for (auto seqn : reportStepList) { - std::vector inteh = rst1.getRst("INTEHEAD", seqn, 0); + std::vector inteh = rst1.getRestartData("INTEHEAD", seqn, 0); std::cout << "Report step number: " << std::setfill(' ') << std::setw(4) << seqn << " Date: " << inteh[66] << "/" diff --git a/tests/LGR_TESTMOD.UNRST b/tests/LGR_TESTMOD.UNRST new file mode 100644 index 0000000000000000000000000000000000000000..a238983b430e9a0151f8a64caca4cd0c5ed34e97 GIT binary patch literal 510880 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

U-L-mkqk%%Bmn_MJ^_Mf7M-df~MIb

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 F{|_WI_T>No literal 0 HcmV?d00001 diff --git a/tests/LGR_TESTMOD.X0002 b/tests/LGR_TESTMOD.X0002 new file mode 100644 index 0000000000000000000000000000000000000000..131b7c395aaafd138793077dc5eeaf895b3d6462 GIT binary patch literal 127684 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 literal 0 HcmV?d00001 diff --git a/tests/msim/test_msim.cpp b/tests/msim/test_msim.cpp index 22eb142c4..bf2ebe522 100644 --- a/tests/msim/test_msim.cpp +++ b/tests/msim/test_msim.cpp @@ -147,8 +147,8 @@ BOOST_AUTO_TEST_CASE(RUN) { auto rst = EclIO::ERst("SPE1CASE1.UNRST"); for (const auto& step : rst.listOfReportStepNumbers()) { - const auto& dh = rst.getRst("DOUBHEAD", step, 0); - const auto& press = rst.getRst("PRESSURE", step, 0); + const auto& dh = rst.getRestartData("DOUBHEAD", step, 0); + const auto& press = rst.getRestartData("PRESSURE", step, 0); // DOUBHEAD[0] is elapsed time in days since start of simulation. BOOST_CHECK_CLOSE( press[0], dh[0] * 86400, 1e-3 ); diff --git a/tests/test_ERst.cpp b/tests/test_ERst.cpp index 58f3b7e78..e543528f7 100644 --- a/tests/test_ERst.cpp +++ b/tests/test_ERst.cpp @@ -19,6 +19,7 @@ #include "config.h" #include +#include #define BOOST_TEST_MODULE Test EclIO #include @@ -36,7 +37,7 @@ #include #include #include -#include +#include #include @@ -128,28 +129,28 @@ BOOST_AUTO_TEST_CASE(TestERst_1) { // non exising report step number, should throw exception - BOOST_CHECK_THROW(std::vector vect1=rst1.getRst("ICON",0, 0) , std::invalid_argument ); - BOOST_CHECK_THROW(std::vector vect2=rst1.getRst("PRESSURE",0, 0) , std::invalid_argument ); - BOOST_CHECK_THROW(std::vector vect3=rst1.getRst("XGRP",0, 0) , std::invalid_argument ); - BOOST_CHECK_THROW(std::vector vect4=rst1.getRst("LOGIHEAD",0, 0) , std::invalid_argument ); - BOOST_CHECK_THROW(std::vector vect4=rst1.getRst("ZWEL",0, 0) , std::invalid_argument ); + BOOST_CHECK_THROW(std::vector vect1=rst1.getRestartData("ICON",0, 0) , std::invalid_argument ); + BOOST_CHECK_THROW(std::vector vect2=rst1.getRestartData("PRESSURE",0, 0) , std::invalid_argument ); + BOOST_CHECK_THROW(std::vector vect3=rst1.getRestartData("XGRP",0, 0) , std::invalid_argument ); + BOOST_CHECK_THROW(std::vector vect4=rst1.getRestartData("LOGIHEAD",0, 0) , std::invalid_argument ); + BOOST_CHECK_THROW(std::vector vect4=rst1.getRestartData("ZWEL",0, 0) , std::invalid_argument ); - // calling getRst member function with wrong type, should throw exception + // calling getRestartData member function with wrong type, should throw exception - BOOST_CHECK_THROW(std::vector vect1=rst1.getRst("ICON",5, 0) , std::runtime_error ); - BOOST_CHECK_THROW(std::vector vect2=rst1.getRst("PRESSURE",5, 0), std::runtime_error ); - BOOST_CHECK_THROW(std::vector vect3=rst1.getRst("XGRP",5, 0), std::runtime_error ); - BOOST_CHECK_THROW(std::vector vect4=rst1.getRst("LOGIHEAD",5, 0), std::runtime_error ); - BOOST_CHECK_THROW(std::vector vect5=rst1.getRst("ZWEL",5, 0), std::runtime_error ); + BOOST_CHECK_THROW(std::vector vect1=rst1.getRestartData("ICON",5, 0) , std::runtime_error ); + BOOST_CHECK_THROW(std::vector vect2=rst1.getRestartData("PRESSURE",5, 0), std::runtime_error ); + BOOST_CHECK_THROW(std::vector vect3=rst1.getRestartData("XGRP",5, 0), std::runtime_error ); + BOOST_CHECK_THROW(std::vector vect4=rst1.getRestartData("LOGIHEAD",5, 0), std::runtime_error ); + BOOST_CHECK_THROW(std::vector vect5=rst1.getRestartData("ZWEL",5, 0), std::runtime_error ); // report step number exists, but data is not loaded. Vector should in this case // be loaded on demand. Hence not throwing an exception - std::vector vect1=rst1.getRst("ICON",10, 0); - std::vector vect2=rst1.getRst("PRESSURE",10, 0); - std::vector vect3=rst1.getRst("XGRP",10, 0); - std::vector vect4=rst1.getRst("LOGIHEAD",10, 0); - std::vector vect5=rst1.getRst("ZWEL",10, 0); + std::vector vect1=rst1.getRestartData("ICON",10, 0); + std::vector vect2=rst1.getRestartData("PRESSURE",10, 0); + std::vector vect3=rst1.getRestartData("XGRP",10, 0); + std::vector vect4=rst1.getRestartData("LOGIHEAD",10, 0); + std::vector vect5=rst1.getRestartData("ZWEL",10, 0); BOOST_CHECK_EQUAL(ref_icon_10==vect1, true); @@ -164,11 +165,11 @@ BOOST_AUTO_TEST_CASE(TestERst_1) { rst1.loadReportStepNumber(25); - vect1 = rst1.getRst("ICON",25, 0); - vect2 = rst1.getRst("PRESSURE",25, 0); - vect3 = rst1.getRst("XGRP",25, 0); - vect4 = rst1.getRst("LOGIHEAD",25, 0); - vect5 = rst1.getRst("ZWEL",25, 0); + vect1 = rst1.getRestartData("ICON",25, 0); + vect2 = rst1.getRestartData("PRESSURE",25, 0); + vect3 = rst1.getRestartData("XGRP",25, 0); + vect4 = rst1.getRestartData("LOGIHEAD",25, 0); + vect5 = rst1.getRestartData("ZWEL",25, 0); BOOST_CHECK_EQUAL(ref_icon_25==vect1, true); @@ -183,24 +184,25 @@ BOOST_AUTO_TEST_CASE(TestERst_1) { } + static void readAndWrite(EclOutput& eclTest, ERst& rst1, const std::string& name, int seqnum, eclArrType arrType) { if (arrType == INTE) { - std::vector vect = rst1.getRst(name, seqnum, 0); + std::vector vect = rst1.getRestartData(name, seqnum, 0); eclTest.write(name, vect); } else if (arrType == REAL) { - std::vector vect = rst1.getRst(name, seqnum, 0); + std::vector vect = rst1.getRestartData(name, seqnum, 0); eclTest.write(name, vect); } else if (arrType == DOUB) { - std::vector vect = rst1.getRst(name, seqnum, 0); + std::vector vect = rst1.getRestartData(name, seqnum, 0); eclTest.write(name, vect); } else if (arrType == LOGI) { - std::vector vect = rst1.getRst(name, seqnum, 0); + std::vector vect = rst1.getRestartData(name, seqnum, 0); eclTest.write(name, vect); } else if (arrType == CHAR) { - std::vector vect = rst1.getRst(name, seqnum, 0); + std::vector vect = rst1.getRestartData(name, seqnum, 0); eclTest.write(name, vect); } else if (arrType == MESS) { eclTest.write(name, std::vector()); @@ -246,6 +248,7 @@ BOOST_AUTO_TEST_CASE(TestERst_2) { }; } + BOOST_AUTO_TEST_CASE(TestERst_3) { std::string testFile="SPE1_TESTCASE.FUNRST"; @@ -278,6 +281,7 @@ BOOST_AUTO_TEST_CASE(TestERst_3) { }; } + BOOST_AUTO_TEST_CASE(TestERst_4) { std::string testFile1="./SPE1_TESTCASE.UNRST"; @@ -302,13 +306,223 @@ BOOST_AUTO_TEST_CASE(TestERst_4) { BOOST_CHECK_EQUAL(rst3.hasReportStepNumber(4), false); BOOST_CHECK_EQUAL(rst3.hasReportStepNumber(25), true); - std::vector pres1 = rst1.getRst("PRESSURE",25, 0); - std::vector pres2 = rst2.getRst("PRESSURE",25, 0); - std::vector pres3 = rst3.getRst("PRESSURE",25, 0); + std::vector pres1 = rst1.getRestartData("PRESSURE",25, 0); + std::vector pres2 = rst2.getRestartData("PRESSURE",25, 0); + std::vector pres3 = rst3.getRestartData("PRESSURE",25, 0); BOOST_CHECK_EQUAL(pres1==pres2, true); BOOST_CHECK_EQUAL(pres1==pres3, true); +} + +BOOST_AUTO_TEST_CASE(TestERst_5a) { + + std::string testRstFile = "LGR_TESTMOD.X0002"; + + ERst rst1(testRstFile); + + BOOST_CHECK_EQUAL(rst1.hasReportStepNumber(2), true); + BOOST_CHECK_EQUAL(rst1.hasReportStepNumber(0), false); + + // invalied report step number + BOOST_CHECK_THROW(rst1.hasLGR("LGR1", 99) , std::invalid_argument ); + + BOOST_CHECK_EQUAL(rst1.hasLGR("LGR1", 2), true); + BOOST_CHECK_EQUAL(rst1.hasLGR("XXXX", 2), false); +} + + +BOOST_AUTO_TEST_CASE(TestERst_5b) { + + std::string testRstFile = "LGR_TESTMOD.UNRST"; + + std::vector ref_reports = {0, 1, 2, 3}; + + std::vector ref_names_global = {"SEQNUM", "INTEHEAD", "LOGIHEAD", "DOUBHEAD", + "IGRP", "SGRP", "XGRP", "ZGRP", "IWEL", "SWEL", "XWEL", "ZWEL", "ZWLS", "IWLS", "ICON", + "SCON", "XCON", "DLYTIM", "HIDDEN", "STARTSOL", "PRESSURE", "SWAT", "SGAS", "RS", + "REGDIMS", "FIPFAMNA", "REGRPT", "FIPOIL", "FIPWAT", "FIPGAS", "PBUB", "LGRNAMES", + "ENDSOL" }; + + std::vector ref_size_global = { 1, 411, 121, 229, 400, 448, 720, 20, 310, 244, 260, 6, + 3, 3, 1250, 2050, 2900, 30, 58, 0, 30, 30, 30, 30, 40, 1, 304, 30, 30, 30, 30, 2, 0 }; + + std::vector ref_names_lgr1 = { "LGR", "LGRHEADI", "LGRHEADQ", "LGRHEADD", "INTEHEAD", + "LOGIHEAD", "DOUBHEAD", "IGRP", "SGRP", "XGRP", "ZGRP", "IWEL", "SWEL", "XWEL", "ZWEL", "LGWEL", + "ZWLS", "IWLS", "ICON", "SCON", "XCON", "DLYTIM", "HIDDEN", "STARTSOL", "PRESSURE", "SWAT", + "SGAS", "RS", "PBUB", "ENDSOL", "ENDLGR"}; + + std::vector ref_size_lgr1 = {1, 45, 5, 5, 411, 121, 229, 200, 224, 360, 10, 155, 122, 130, + 3, 1, 1, 1, 625, 1025, 1450, 30, 58, 0, 128, 128, 128, 128, 128, 0, 1 }; + + std::vector ref_names_lgr2 = {"LGR", "LGRHEADI", "LGRHEADQ", "LGRHEADD", "INTEHEAD", + "LOGIHEAD", "DOUBHEAD", "IGRP", "SGRP", "XGRP", "ZGRP", "IWEL", "SWEL", "XWEL", "ZWEL", "LGWEL", + "ZWLS", "IWLS", "ICON", "SCON", "XCON", "DLYTIM", "HIDDEN", "STARTSOL", "PRESSURE", "SWAT", + "SGAS", "RS", "PBUB", "ENDSOL", "ENDLGR" }; + + std::vector ref_size_lgr2 = {1, 45, 5, 5, 411, 121, 229, 200, 224, 360, 10, 155, 122, 130, 3, + 1, 1, 1, 625, 1025, 1450, 30, 58, 0, 192, 192, 192, 192, 192, 0, 1}; + + ERst rst1(testRstFile); + + auto report_list = rst1.listOfReportStepNumbers(); + + BOOST_CHECK_EQUAL(report_list==ref_reports, true); + + BOOST_CHECK_EQUAL(rst1.hasReportStepNumber(1), true); + BOOST_CHECK_EQUAL(rst1.hasReportStepNumber(5), false); + + // invalied report step number + BOOST_CHECK_THROW(rst1.hasLGR("LGR1", 99) , std::invalid_argument ); + + BOOST_CHECK_EQUAL(rst1.hasLGR("LGR1", 2), true); + + int rstep = 0; + + auto array_list_1 = rst1.listOfRstArrays(rstep); + + BOOST_CHECK_EQUAL(array_list_1.size(), ref_names_global.size()); + BOOST_CHECK_EQUAL(array_list_1.size(), ref_size_global.size()); + + for (size_t n = 0; n < array_list_1.size(); n++){ + BOOST_CHECK_EQUAL(std::get<0>(array_list_1[n]), ref_names_global[n]); + BOOST_CHECK_EQUAL(std::get<2>(array_list_1[n]), ref_size_global[n]); + } + + for (size_t index = 0; index < array_list_1.size(); index++){ + + std::string name = std::get<0>(array_list_1[index]); + + if (std::get<1>(array_list_1[index]) == Opm::EclIO::INTE){ + auto vect1 = rst1.getRestartData(name, rstep); + auto vect2 = rst1.getRestartData(index, rstep); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_1[index]) == Opm::EclIO::REAL){ + auto vect1 = rst1.getRestartData(name, rstep); + auto vect2 = rst1.getRestartData(index, rstep); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_1[index]) == Opm::EclIO::DOUB){ + auto vect1 = rst1.getRestartData(name, rstep); + auto vect2 = rst1.getRestartData(index, rstep); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_1[index]) == Opm::EclIO::LOGI){ + auto vect1 = rst1.getRestartData(name, rstep); + auto vect2 = rst1.getRestartData(index, rstep); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_1[index]) == Opm::EclIO::CHAR){ + auto vect1 = rst1.getRestartData(name, rstep); + auto vect2 = rst1.getRestartData(index, rstep); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + } + + // ------------------------------- + + std::string lgr_name = "LGR1"; + + BOOST_CHECK_THROW(rst1.listOfRstArrays(0, "XXXX") , std::invalid_argument ); + + auto array_list_2 = rst1.listOfRstArrays(0, lgr_name); + + BOOST_CHECK_EQUAL(array_list_2.size(), ref_names_lgr1.size()); + BOOST_CHECK_EQUAL(array_list_2.size(), ref_size_lgr1.size()); + + for (size_t n = 0; n < array_list_2.size(); n++){ + BOOST_CHECK_EQUAL(std::get<0>(array_list_2[n]), ref_names_lgr1[n]); + BOOST_CHECK_EQUAL(std::get<2>(array_list_2[n]), ref_size_lgr1[n]); + } + + for (size_t index = 0; index < array_list_2.size(); index++){ + + std::string name = std::get<0>(array_list_2[index]); + + if (std::get<1>(array_list_2[index]) == Opm::EclIO::INTE){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_2[index]) == Opm::EclIO::REAL){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_2[index]) == Opm::EclIO::DOUB){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_2[index]) == Opm::EclIO::LOGI){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_2[index]) == Opm::EclIO::CHAR){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + } + + // ------------------------------- + + lgr_name = "LGR2"; + + auto array_list_3 = rst1.listOfRstArrays(0, lgr_name); + + BOOST_CHECK_EQUAL(array_list_3.size(), ref_names_lgr2.size()); + BOOST_CHECK_EQUAL(array_list_3.size(), ref_size_lgr2.size()); + + for (size_t n = 0; n < array_list_2.size(); n++){ + BOOST_CHECK_EQUAL(std::get<0>(array_list_3[n]), ref_names_lgr2[n]); + BOOST_CHECK_EQUAL(std::get<2>(array_list_3[n]), ref_size_lgr2[n]); + } + + for (size_t index = 0; index < array_list_3.size(); index++){ + + std::string name = std::get<0>(array_list_3[index]); + + if (std::get<1>(array_list_3[index]) == Opm::EclIO::INTE){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_3[index]) == Opm::EclIO::REAL){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_3[index]) == Opm::EclIO::DOUB){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_3[index]) == Opm::EclIO::LOGI){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + + if (std::get<1>(array_list_3[index]) == Opm::EclIO::CHAR){ + auto vect1 = rst1.getRestartData(name, rstep, lgr_name); + auto vect2 = rst1.getRestartData(index, rstep, lgr_name); + BOOST_CHECK_EQUAL(vect1 == vect2, true); + } + } } @@ -443,7 +657,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) rst.loadReportStepNumber(1); { - const auto& I = rst.getRst("I", 1, 0); + const auto& I = rst.getRestartData("I", 1, 0); const auto expect_I = std::vector{ 1, 7, 2, 9 }; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -451,7 +665,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& L = rst.getRst("L", 1, 0); + const auto& L = rst.getRestartData("L", 1, 0); const auto expect_L = std::vector { true, false, false, true, }; @@ -462,7 +676,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& S = rst.getRst("S", 1, 0); + const auto& S = rst.getRestartData("S", 1, 0); const auto expect_S = std::vector{ 3.1f, 4.1f, 59.265f, }; @@ -471,7 +685,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& D = rst.getRst("D", 1, 0); + const auto& D = rst.getRestartData("D", 1, 0); const auto expect_D = std::vector{ 2.71, 8.21, }; @@ -480,7 +694,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& Z = rst.getRst("Z", 1, 0); + const auto& Z = rst.getRestartData("Z", 1, 0); const auto expect_Z = std::vector{ "W1", "W2", // ERst trims trailing blanks }; @@ -541,7 +755,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) rst.loadReportStepNumber(5); { - const auto& I = rst.getRst("I", 5, 0); + const auto& I = rst.getRestartData("I", 5, 0); const auto expect_I = std::vector{ 1, 2, 3, 4 }; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -549,7 +763,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& L = rst.getRst("L", 5, 0); + const auto& L = rst.getRestartData("L", 5, 0); const auto expect_L = std::vector { false, false, false, true, }; @@ -560,7 +774,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& S = rst.getRst("S", 5, 0); + const auto& S = rst.getRestartData("S", 5, 0); const auto expect_S = std::vector{ 1.23e-04f, 1.234e5f, -5.4321e-9f, }; @@ -569,7 +783,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& D = rst.getRst("D", 5, 0); + const auto& D = rst.getRestartData("D", 5, 0); const auto expect_D = std::vector{ 0.6931, 1.6180, }; @@ -578,7 +792,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& Z = rst.getRst("Z", 5, 0); + const auto& Z = rst.getRestartData("Z", 5, 0); const auto expect_Z = std::vector{ "HELLO", ",", "WORLD", // ERst trims trailing blanks }; @@ -639,7 +853,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) rst.loadReportStepNumber(13); { - const auto& I = rst.getRst("I", 13, 0); + const auto& I = rst.getRestartData("I", 13, 0); const auto expect_I = std::vector{ 35, 51, 13}; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -647,7 +861,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& L = rst.getRst("L", 13, 0); + const auto& L = rst.getRestartData("L", 13, 0); const auto expect_L = std::vector { true, true, true, false, }; @@ -658,7 +872,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& S = rst.getRst("S", 13, 0); + const auto& S = rst.getRestartData("S", 13, 0); const auto expect_S = std::vector{ 17.29e-02f, 1.4142f, }; @@ -667,7 +881,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& D = rst.getRst("D", 13, 0); + const auto& D = rst.getRestartData("D", 13, 0); const auto expect_D = std::vector{ 0.6931, 1.6180, 123.45e6, }; @@ -676,7 +890,7 @@ BOOST_AUTO_TEST_CASE(Unformatted) } { - const auto& Z = rst.getRst("Z", 13, 0); + const auto& Z = rst.getRestartData("Z", 13, 0); const auto expect_Z = std::vector{ "G1", "FIELD", // ERst trims trailing blanks }; @@ -747,7 +961,7 @@ BOOST_AUTO_TEST_CASE(Formatted) rst.loadReportStepNumber(13); { - const auto& I = rst.getRst("I", 13, 0); + const auto& I = rst.getRestartData("I", 13, 0); const auto expect_I = std::vector{ 35, 51, 13 }; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -755,7 +969,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& L = rst.getRst("L", 13, 0); + const auto& L = rst.getRestartData("L", 13, 0); const auto expect_L = std::vector { true, true, true, false, }; @@ -766,7 +980,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& S = rst.getRst("S", 13, 0); + const auto& S = rst.getRestartData("S", 13, 0); const auto expect_S = std::vector{ 17.29e-02f, 1.4142f, }; @@ -775,7 +989,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& D = rst.getRst("D", 13, 0); + const auto& D = rst.getRestartData("D", 13, 0); const auto expect_D = std::vector{ 0.6931, 1.6180, 123.45e6, }; @@ -784,7 +998,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& Z = rst.getRst("Z", 13, 0); + const auto& Z = rst.getRestartData("Z", 13, 0); const auto expect_Z = std::vector{ "G1", "FIELD", // ERst trims trailing blanks }; @@ -836,7 +1050,7 @@ BOOST_AUTO_TEST_CASE(Formatted) rst.loadReportStepNumber(5); { - const auto& I = rst.getRst("I", 5, 0); + const auto& I = rst.getRestartData("I", 5, 0); const auto expect_I = std::vector{ 1, 2, 3, 4 }; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -855,7 +1069,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& S = rst.getRst("S", 5, 0); + const auto& S = rst.getRestartData("S", 5, 0); const auto expect_S = std::vector{ 1.23e-04f, 1.234e5f, -5.4321e-9f, }; @@ -864,7 +1078,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& D = rst.getRst("D", 5, 0); + const auto& D = rst.getRestartData("D", 5, 0); const auto expect_D = std::vector{ 0.6931, 1.6180, }; @@ -873,7 +1087,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& Z = rst.getRst("Z", 5, 0); + const auto& Z = rst.getRestartData("Z", 5, 0); const auto expect_Z = std::vector{ "HELLO", ",", "WORLD", // ERst trims trailing blanks }; @@ -917,7 +1131,7 @@ BOOST_AUTO_TEST_CASE(Formatted) rst.loadReportStepNumber(13); { - const auto& I = rst.getRst("I", 13, 0); + const auto& I = rst.getRestartData("I", 13, 0); const auto expect_I = std::vector{ 35, 51, 13 }; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -925,7 +1139,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& L = rst.getRst("L", 13, 0); + const auto& L = rst.getRestartData("L", 13, 0); const auto expect_L = std::vector { true, true, true, false, }; @@ -936,7 +1150,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& S = rst.getRst("S", 13, 0); + const auto& S = rst.getRestartData("S", 13, 0); const auto expect_S = std::vector{ 17.29e-02f, 1.4142f, }; @@ -945,7 +1159,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& D = rst.getRst("D", 13, 0); + const auto& D = rst.getRestartData("D", 13, 0); const auto expect_D = std::vector{ 0.6931, 1.6180, 123.45e6, }; @@ -954,7 +1168,7 @@ BOOST_AUTO_TEST_CASE(Formatted) } { - const auto& Z = rst.getRst("Z", 13, 0); + const auto& Z = rst.getRestartData("Z", 13, 0); const auto expect_Z = std::vector{ "G1", "FIELD", // ERst trims trailing blanks }; diff --git a/tests/test_EclipseIO.cpp b/tests/test_EclipseIO.cpp index d8f9afcc5..1c9f6ad3e 100644 --- a/tests/test_EclipseIO.cpp +++ b/tests/test_EclipseIO.cpp @@ -198,7 +198,7 @@ void checkRestartFile( int timeStepIdx ) { const auto& knownVec = rstFile.listOfRstArrays(i); if (keywordExists(knownVec, "PRESSURE")) { - const auto& press = rstFile.getRst("PRESSURE", i, 0); + const auto& press = rstFile.getRestartData("PRESSURE", i, 0); for( auto& x : sol.data("PRESSURE") ) x /= Metric::Pressure; @@ -206,22 +206,22 @@ void checkRestartFile( int timeStepIdx ) { } if (keywordExists(knownVec, "SWAT")) { - const auto& swat = rstFile.getRst("SWAT", i, 0); + const auto& swat = rstFile.getRestartData("SWAT", i, 0); compareErtData( sol.data("SWAT"), swat, 1e-4 ); } if (keywordExists(knownVec, "SGAS")) { - const auto& sgas = rstFile.getRst("SGAS", i, 0); + const auto& sgas = rstFile.getRestartData("SGAS", i, 0); compareErtData( sol.data("SGAS"), sgas, 1e-4 ); } if (keywordExists(knownVec, "KRO")) { - const auto& kro = rstFile.getRst("KRO", i, 0); + const auto& kro = rstFile.getRestartData("KRO", i, 0); BOOST_CHECK_CLOSE(1.0 * i * kro.size(), sum(kro), 1.0e-8); } if (keywordExists(knownVec, "KRG")) { - const auto& krg = rstFile.getRst("KRG", i, 0); + const auto& krg = rstFile.getRestartData("KRG", i, 0); BOOST_CHECK_CLOSE(10.0 * i * krg.size(), sum(krg), 1.0e-8); } } diff --git a/tests/test_OutputStream.cpp b/tests/test_OutputStream.cpp index dd46a7d07..35ecf3f8e 100644 --- a/tests/test_OutputStream.cpp +++ b/tests/test_OutputStream.cpp @@ -563,7 +563,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) rst.loadReportStepNumber(13); { - const auto& I = rst.getRst("I", 13, 0); + const auto& I = rst.getRestartData("I", 13, 0); const auto expect_I = std::vector{ 35, 51, 13}; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -571,7 +571,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& L = rst.getRst("L", 13, 0); + const auto& L = rst.getRestartData("L", 13, 0); const auto expect_L = std::vector { true, true, true, false, }; @@ -582,7 +582,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& S = rst.getRst("S", 13, 0); + const auto& S = rst.getRestartData("S", 13, 0); const auto expect_S = std::vector{ 17.29e-02f, 1.4142f, }; @@ -591,7 +591,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& D = rst.getRst("D", 13, 0); + const auto& D = rst.getRestartData("D", 13, 0); const auto expect_D = std::vector{ 0.6931, 1.6180, 123.45e6, }; @@ -600,7 +600,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& Z = rst.getRst("Z", 13, 0); + const auto& Z = rst.getRestartData("Z", 13, 0); const auto expect_Z = std::vector{ "G1", "FIELD", // ERst trims trailing blanks }; @@ -662,7 +662,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) rst.loadReportStepNumber(5); { - const auto& I = rst.getRst("I", 5, 0); + const auto& I = rst.getRestartData("I", 5, 0); const auto expect_I = std::vector{ 1, 2, 3, 4 }; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -670,7 +670,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& L = rst.getRst("L", 5, 0); + const auto& L = rst.getRestartData("L", 5, 0); const auto expect_L = std::vector { false, false, false, true, }; @@ -681,7 +681,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& S = rst.getRst("S", 5, 0); + const auto& S = rst.getRestartData("S", 5, 0); const auto expect_S = std::vector{ 1.23e-04f, 1.234e5f, -5.4321e-9f, }; @@ -690,7 +690,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& D = rst.getRst("D", 5, 0); + const auto& D = rst.getRestartData("D", 5, 0); const auto expect_D = std::vector{ 0.6931, 1.6180, }; @@ -699,7 +699,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& Z = rst.getRst("Z", 5, 0); + const auto& Z = rst.getRestartData("Z", 5, 0); const auto expect_Z = std::vector{ "HELLO", ",", "WORLD", // ERst trims trailing blanks }; @@ -761,7 +761,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) rst.loadReportStepNumber(13); { - const auto& I = rst.getRst("I", 13, 0); + const auto& I = rst.getRestartData("I", 13, 0); const auto expect_I = std::vector{ 35, 51, 13}; BOOST_CHECK_EQUAL_COLLECTIONS(I.begin(), I.end(), expect_I.begin(), @@ -769,7 +769,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& L = rst.getRst("L", 13, 0); + const auto& L = rst.getRestartData("L", 13, 0); const auto expect_L = std::vector { true, true, true, false, }; @@ -780,7 +780,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& S = rst.getRst("S", 13, 0); + const auto& S = rst.getRestartData("S", 13, 0); const auto expect_S = std::vector{ 17.29e-02f, 1.4142f, }; @@ -789,7 +789,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& D = rst.getRst("D", 13, 0); + const auto& D = rst.getRestartData("D", 13, 0); const auto expect_D = std::vector{ 0.6931, 1.6180, 123.45e6, }; @@ -798,7 +798,7 @@ BOOST_AUTO_TEST_CASE(Unformatted_Unified) } { - const auto& Z = rst.getRst("Z", 13, 0); + const auto& Z = rst.getRestartData("Z", 13, 0); const auto expect_Z = std::vector{ "G1", "FIELD", // ERst trims trailing blanks }; diff --git a/tests/test_Restart.cpp b/tests/test_Restart.cpp index a366ac858..c03249732 100644 --- a/tests/test_Restart.cpp +++ b/tests/test_Restart.cpp @@ -650,7 +650,7 @@ BOOST_AUTO_TEST_CASE(ExtraData_KEYS) { BOOST_CHECK_THROW( restart_value.addExtra("KEY", {0,1,1}), std::runtime_error); /* The keys must be unique across solution and extra_data */ - BOOST_CHECK_THROW( restart_value.addExtra("PRESSURE", {0,1}), std::runtime_error); + BOOST_CHECK_THROW( restart_value.addExtra("PRESSURE", {0,1}), std::runtime_error); /* Must avoid using reserved keys like 'LOGIHEAD' */ BOOST_CHECK_THROW( restart_value.addExtra("LOGIHEAD", {0,1}), std::runtime_error); @@ -705,7 +705,7 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) { EclIO::ERst rst{ rstFile }; BOOST_CHECK_MESSAGE( rst.hasKey("EXTRA"), "Restart file is expexted to have EXTRA vector"); - const auto& ex = rst.getRst("EXTRA", 1, 0); + const auto& ex = rst.getRestartData("EXTRA", 1, 0); 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); }