Adding python bindings for c++ class ExtESmry
- Used for loading data from summary file ESMRY - python class ESmry supporting both SMSPEC/UNSMRY and ESMRY summary files.
This commit is contained in:
@@ -54,6 +54,8 @@ public:
|
||||
void loadData();
|
||||
void loadData(const std::vector<std::string>& stringVect);
|
||||
|
||||
time_point startdate() const { return m_startdat; }
|
||||
|
||||
bool hasKey(const std::string& key) const;
|
||||
|
||||
size_t numberOfTimeSteps() const { return m_nTstep; }
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/numpy.h>
|
||||
#include <pybind11/chrono.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <opm/io/eclipse/EclFile.hpp>
|
||||
#include <opm/io/eclipse/EclIOdata.hpp>
|
||||
#include <opm/io/eclipse/ERst.hpp>
|
||||
#include <opm/io/eclipse/ESmry.hpp>
|
||||
#include <opm/io/eclipse/ExtESmry.hpp>
|
||||
#include <opm/io/eclipse/EGrid.hpp>
|
||||
#include <opm/io/eclipse/ERft.hpp>
|
||||
#include <opm/io/eclipse/EclOutput.hpp>
|
||||
#include <opm/common/utility/TimeService.hpp>
|
||||
#include <opm/common/utility/FileSystem.hpp>
|
||||
|
||||
#include <opm/common/utility/numeric/calculateCellVol.hpp>
|
||||
|
||||
@@ -25,6 +28,100 @@ namespace {
|
||||
using npArray = std::tuple<py::array, Opm::EclIO::eclArrType>;
|
||||
using EclEntry = std::tuple<std::string, Opm::EclIO::eclArrType, int64_t>;
|
||||
|
||||
class ESmryBind {
|
||||
|
||||
public:
|
||||
|
||||
ESmryBind(const std::string& filename, bool loadBaseRunData)
|
||||
{
|
||||
filesystem::path m_inputFileName(filename);
|
||||
|
||||
if (m_inputFileName.extension() == ".SMSPEC"){
|
||||
m_esmry = std::make_unique<Opm::EclIO::ESmry>(m_inputFileName, loadBaseRunData);
|
||||
} else if (m_inputFileName.extension()==".ESMRY") {
|
||||
m_ext_esmry = std::make_unique<Opm::EclIO::ExtESmry>(m_inputFileName, loadBaseRunData);
|
||||
} else
|
||||
throw std::invalid_argument("Input file should have extension .SMSPEC or .ESMRY");
|
||||
}
|
||||
|
||||
bool hasKey(const std::string& key)
|
||||
{
|
||||
if (m_esmry != nullptr)
|
||||
return m_esmry->hasKey(key);
|
||||
else
|
||||
return m_ext_esmry->hasKey(key);
|
||||
}
|
||||
|
||||
void make_esmry_file()
|
||||
{
|
||||
if (m_esmry == nullptr)
|
||||
throw std::invalid_argument("make_esmry_file only available for SMSPEC input files");
|
||||
|
||||
m_esmry->make_esmry_file();
|
||||
}
|
||||
|
||||
size_t numberOfTimeSteps()
|
||||
{
|
||||
if (m_esmry != nullptr)
|
||||
return m_esmry->numberOfTimeSteps();
|
||||
else
|
||||
return m_ext_esmry->numberOfTimeSteps();
|
||||
}
|
||||
|
||||
py::array get_smry_vector(const std::string& key)
|
||||
{
|
||||
if (m_esmry != nullptr)
|
||||
return convert::numpy_array( m_esmry->get(key) );
|
||||
else
|
||||
return convert::numpy_array( m_ext_esmry->get(key) );
|
||||
}
|
||||
|
||||
py::array get_smry_vector_at_rsteps(const std::string& key)
|
||||
{
|
||||
if (m_esmry != nullptr)
|
||||
return convert::numpy_array( m_esmry->get_at_rstep(key) );
|
||||
else
|
||||
return convert::numpy_array( m_ext_esmry->get_at_rstep(key) );
|
||||
}
|
||||
|
||||
time_point smry_start_date()
|
||||
{
|
||||
time_point utc_chrono;
|
||||
|
||||
if (m_esmry != nullptr)
|
||||
utc_chrono = m_esmry->startdate();
|
||||
else
|
||||
utc_chrono = m_ext_esmry->startdate();
|
||||
|
||||
auto utc_time_t = std::chrono::system_clock::to_time_t( utc_chrono );
|
||||
auto utc_ts = Opm::TimeStampUTC( utc_time_t );
|
||||
auto local_time_t = Opm::asLocalTimeT( utc_ts );
|
||||
return TimeService::from_time_t( local_time_t );
|
||||
}
|
||||
|
||||
const std::vector<std::string>& keywordList() const
|
||||
{
|
||||
if (m_esmry != nullptr)
|
||||
return m_esmry->keywordList();
|
||||
else
|
||||
return m_ext_esmry->keywordList();
|
||||
}
|
||||
|
||||
std::vector<std::string> keywordList(const std::string& pattern) const
|
||||
{
|
||||
if (m_esmry != nullptr)
|
||||
return m_esmry->keywordList(pattern);
|
||||
else
|
||||
return m_ext_esmry->keywordList(pattern);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Opm::EclIO::ESmry> m_esmry;
|
||||
std::unique_ptr<Opm::EclIO::ExtESmry> m_ext_esmry;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class EclOutputBind {
|
||||
|
||||
public:
|
||||
@@ -166,18 +263,6 @@ npArray get_erst_vector(Opm::EclIO::ERst * file_ptr, const std::string& key, siz
|
||||
}
|
||||
|
||||
|
||||
py::array get_smry_vector(Opm::EclIO::ESmry * file_ptr, const std::string& key)
|
||||
{
|
||||
return convert::numpy_array( file_ptr->get(key) );
|
||||
}
|
||||
|
||||
|
||||
py::array get_smry_vector_at_rsteps(Opm::EclIO::ESmry * file_ptr, const std::string& key)
|
||||
{
|
||||
return convert::numpy_array( file_ptr->get_at_rstep(key) );
|
||||
}
|
||||
|
||||
|
||||
std::tuple<std::array<double,8>, std::array<double,8>, std::array<double,8>>
|
||||
get_xyz_from_ijk(Opm::EclIO::EGrid * file_ptr,int i, int j, int k)
|
||||
{
|
||||
@@ -291,14 +376,6 @@ npArray get_rft_vector_Index(Opm::EclIO::ERft * file_ptr,const std::string& name
|
||||
the pybind11 conversion.
|
||||
*/
|
||||
|
||||
time_point esmry_start_date(const Opm::EclIO::ESmry * esmry) {
|
||||
auto utc_chrono = esmry->startdate();
|
||||
auto utc_time_t = std::chrono::system_clock::to_time_t( utc_chrono );
|
||||
auto utc_ts = Opm::TimeStampUTC( utc_time_t );
|
||||
auto local_time_t = Opm::asLocalTimeT( utc_ts );
|
||||
return TimeService::from_time_t( local_time_t );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -340,18 +417,19 @@ void python::common::export_IO(py::module& m) {
|
||||
.def("__get_data", &get_erst_by_index)
|
||||
.def("__get_data", &get_erst_vector);
|
||||
|
||||
py::class_<Opm::EclIO::ESmry>(m, "ESmry")
|
||||
py::class_<ESmryBind>(m, "ESmry")
|
||||
.def(py::init<const std::string &, const bool>(), py::arg("filename"), py::arg("load_base_run") = false)
|
||||
.def("__contains__", &Opm::EclIO::ESmry::hasKey)
|
||||
.def("__len__", &Opm::EclIO::ESmry::numberOfTimeSteps)
|
||||
.def("__get_all", &get_smry_vector)
|
||||
.def("__get_at_rstep", &get_smry_vector_at_rsteps)
|
||||
.def_property_readonly("start_date", &esmry_start_date)
|
||||
.def("__contains__", &ESmryBind::hasKey)
|
||||
.def("make_esmry_file", &ESmryBind::make_esmry_file)
|
||||
.def("__len__", &ESmryBind::numberOfTimeSteps)
|
||||
.def("__get_all", &ESmryBind::get_smry_vector)
|
||||
.def("__get_at_rstep", &ESmryBind::get_smry_vector_at_rsteps)
|
||||
.def_property_readonly("start_date", &ESmryBind::smry_start_date)
|
||||
.def("keys", (const std::vector<std::string>& (ESmryBind::*) (void) const)
|
||||
&ESmryBind::keywordList)
|
||||
.def("keys", (std::vector<std::string> (ESmryBind::*) (const std::string&) const)
|
||||
&ESmryBind::keywordList);
|
||||
|
||||
.def("keys", (const std::vector<std::string>& (Opm::EclIO::ESmry::*) (void) const)
|
||||
&Opm::EclIO::ESmry::keywordList)
|
||||
.def("keys", (std::vector<std::string> (Opm::EclIO::ESmry::*) (const std::string&) const)
|
||||
&Opm::EclIO::ESmry::keywordList);
|
||||
|
||||
py::class_<Opm::EclIO::EGrid>(m, "EGrid")
|
||||
.def(py::init<const std::string &>())
|
||||
|
||||
@@ -29,7 +29,3 @@ from .libopmcommon_python import EclOutput
|
||||
from .libopmcommon_python import EModel
|
||||
from .libopmcommon_python import calc_cell_vol
|
||||
from .libopmcommon_python import SummaryState
|
||||
|
||||
#from .schedule import Well, Connection, Schedule
|
||||
#from .config import EclipseConfig
|
||||
#from .parser import parse, parse_string
|
||||
|
||||
@@ -10,15 +10,20 @@ except ImportError:
|
||||
from utils import test_path
|
||||
|
||||
|
||||
|
||||
class TestEclFile(unittest.TestCase):
|
||||
|
||||
def test_base_runs(self):
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
with self.assertRaises(ValueError):
|
||||
ESmry("/file/that/does_not_exists")
|
||||
|
||||
smry1 = ESmry(test_path("data/SPE1CASE1.SMSPEC"))
|
||||
smry1.make_esmry_file()
|
||||
|
||||
smry2 = ESmry(test_path("data/SPE1CASE1.ESMRY"))
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
smry2.make_esmry_file()
|
||||
|
||||
self.assertEqual(len(smry1), 67)
|
||||
self.assertEqual(smry1.start_date, datetime.datetime(2015,1,1) )
|
||||
@@ -100,6 +105,114 @@ class TestEclFile(unittest.TestCase):
|
||||
for key, ref in zip(list_of_keys2, ref_keys_pattern):
|
||||
self.assertEqual(key, ref)
|
||||
|
||||
|
||||
def test_base_runs_ext(self):
|
||||
|
||||
smry1 = ESmry(test_path("data/SPE1CASE1.SMSPEC"))
|
||||
smry1.make_esmry_file()
|
||||
|
||||
extsmry1 = ESmry(test_path("data/SPE1CASE1.ESMRY"))
|
||||
|
||||
self.assertEqual(len(extsmry1), 67)
|
||||
self.assertEqual(extsmry1.start_date, datetime.datetime(2015,1,1) )
|
||||
self.assertEqual(extsmry1.end_date, datetime.datetime(2020,4,29) )
|
||||
|
||||
self.assertTrue("TIME" in extsmry1)
|
||||
self.assertTrue("BPR:10,10,3" in extsmry1)
|
||||
self.assertFalse("XXXX" in extsmry1)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
test = extsmry1["XXX"]
|
||||
|
||||
time1a = extsmry1["TIME"]
|
||||
|
||||
self.assertEqual(len(time1a), len(extsmry1))
|
||||
|
||||
time1b = extsmry1["TIME", True]
|
||||
|
||||
self.assertEqual(len(time1b), 64)
|
||||
|
||||
|
||||
def test_restart_runs_ext(self):
|
||||
|
||||
base_smry = ESmry(test_path("data/SPE1CASE1.SMSPEC"))
|
||||
base_smry.make_esmry_file()
|
||||
|
||||
base_ext_smry = ESmry(test_path("data/SPE1CASE1.ESMRY"))
|
||||
|
||||
time0 = base_ext_smry["TIME"]
|
||||
self.assertEqual(time0[0], 1.0)
|
||||
|
||||
rst_smry1 = ESmry(test_path("data/SPE1CASE1_RST60.SMSPEC"))
|
||||
rst_smry1.make_esmry_file()
|
||||
|
||||
rst_ext_smry1 = ESmry(test_path("data/SPE1CASE1_RST60.ESMRY"))
|
||||
|
||||
time1 = rst_ext_smry1["TIME"]
|
||||
gor1 = rst_ext_smry1["WGOR:PROD"]
|
||||
|
||||
self.assertEqual(base_ext_smry.start_date, datetime.datetime(2015,1,1) )
|
||||
time0 = base_ext_smry["TIME"]
|
||||
self.assertEqual(time0[0], 1.0)
|
||||
|
||||
rst_ext_smry1 = ESmry(test_path("data/SPE1CASE1_RST60.ESMRY"))
|
||||
time1 = rst_ext_smry1["TIME"]
|
||||
gor1 = rst_ext_smry1["WGOR:PROD"]
|
||||
|
||||
self.assertEqual(rst_smry1.start_date, datetime.datetime(2015,1,1) )
|
||||
self.assertEqual(len(rst_smry1), 60)
|
||||
self.assertEqual(time1[0], 1856.0)
|
||||
self.assertEqual(len(time1), 60)
|
||||
self.assertEqual(len(gor1), 60)
|
||||
|
||||
rst_ext_smry2 = ESmry(test_path("data/SPE1CASE1_RST60.ESMRY"), load_base_run = True)
|
||||
time2 = rst_ext_smry2["TIME"]
|
||||
gor2 = rst_ext_smry2["WGOR:PROD"]
|
||||
|
||||
self.assertEqual(rst_ext_smry2.start_date, datetime.datetime(2015,1,1) )
|
||||
self.assertEqual(len(rst_ext_smry2), 123)
|
||||
|
||||
self.assertEqual(time2[0], 1.0)
|
||||
self.assertEqual(len(rst_ext_smry2), 123)
|
||||
self.assertEqual(len(time2), 123)
|
||||
self.assertEqual(len(gor2), 123)
|
||||
|
||||
|
||||
def test_keylist_ext(self):
|
||||
|
||||
ref_key_list = ["BPR:1,1,1", "BPR:10,10,3", "FGOR", "FOPR", "TIME", "WBHP:INJ", "WBHP:PROD",
|
||||
"WGIR:INJ", "WGIR:PROD", "WGIT:INJ", "WGIT:PROD", "WGOR:PROD", "WGPR:INJ",
|
||||
"WGPR:PROD", "WGPT:INJ", "WGPT:PROD", "WOIR:INJ", "WOIR:PROD", "WOIT:INJ",
|
||||
"WOIT:PROD", "WOPR:INJ", "WOPR:PROD", "WOPT:INJ", "WOPT:PROD", "WWIR:INJ",
|
||||
"WWIR:PROD", "WWIT:INJ", "WWIT:PROD", "WWPR:INJ", "WWPR:PROD", "WWPT:INJ",
|
||||
"WWPT:PROD"]
|
||||
|
||||
ref_keys_pattern = ["WGPR:INJ", "WGPR:PROD", "WOPR:INJ", "WOPR:PROD", "WWPR:INJ", "WWPR:PROD"]
|
||||
|
||||
smry1 = ESmry(test_path("data/SPE1CASE1.SMSPEC"))
|
||||
smry1.make_esmry_file()
|
||||
|
||||
ext_smry1 = ESmry(test_path("data/SPE1CASE1.ESMRY"))
|
||||
|
||||
list_of_keys = ext_smry1.keys()
|
||||
self.assertEqual(len(list_of_keys), len(ref_key_list))
|
||||
|
||||
for key, ref_key in zip(list_of_keys, ref_key_list):
|
||||
self.assertEqual(key, ref_key)
|
||||
|
||||
for key in list_of_keys:
|
||||
data = smry1[key]
|
||||
self.assertEqual(len(smry1), len(data))
|
||||
|
||||
list_of_keys2 = ext_smry1.keys("W?PR:*")
|
||||
|
||||
self.assertEqual(len(list_of_keys2), len(ref_keys_pattern))
|
||||
|
||||
for key, ref in zip(list_of_keys2, ref_keys_pattern):
|
||||
self.assertEqual(key, ref)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user