diff --git a/opm/simulators/flow/python/PyBlackOilSimulator.hpp b/opm/simulators/flow/python/PyBlackOilSimulator.hpp index 57639407cd5..b708d00aed7 100644 --- a/opm/simulators/flow/python/PyBlackOilSimulator.hpp +++ b/opm/simulators/flow/python/PyBlackOilSimulator.hpp @@ -23,7 +23,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -46,18 +48,27 @@ class PyBlackOilSimulator void advance(int report_step); bool checkSimulationFinished(); int currentStep(); + py::array_t getFluidStateVariable(const std::string &name) const; py::array_t getCellVolumes(); double getDT(); py::array_t getPorosity(); + py::array_t getPrimaryVariable(const std::string &variable) const; + py::array_t getPrimaryVarMeaning(const std::string &variable) const; + std::map getPrimaryVarMeaningMap(const std::string &variable) const; int run(); void setPorosity( py::array_t array); + void setPrimaryVariable( + const std::string &idx_name, + py::array_t array); int step(); int stepCleanup(); int stepInit(); private: Opm::FlowMain& getFlowMain() const; + PyFluidState& getFluidState() const; PyMaterialState& getMaterialState() const; const std::string deck_filename_; @@ -71,6 +82,7 @@ class PyBlackOilSimulator std::unique_ptr> main_ebos_; Simulator *ebos_simulator_; + std::unique_ptr> fluid_state_; std::unique_ptr> material_state_; std::shared_ptr deck_; std::shared_ptr eclipse_state_; diff --git a/opm/simulators/flow/python/PyFluidState.hpp b/opm/simulators/flow/python/PyFluidState.hpp new file mode 100644 index 00000000000..6df866b4240 --- /dev/null +++ b/opm/simulators/flow/python/PyFluidState.hpp @@ -0,0 +1,71 @@ +/* + Copyright 2023 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 . +*/ + +#ifndef OPM_PY_FLUID_STATE_HEADER_INCLUDED +#define OPM_PY_FLUID_STATE_HEADER_INCLUDED + +#include + +#include +#include +#include +#include +#include +#include + +namespace Opm::Pybind +{ + template + class PyFluidState { + using Simulator = GetPropType; + using Problem = GetPropType; + using Model = GetPropType; + using ElementContext = GetPropType; + using FluidSystem = GetPropType; + using Indices = GetPropType; + using GridView = GetPropType; + using PrimaryVariables = GetPropType; + + enum class VariableType { + // Primary variables: Sw, Sg, po, pg, Rs, Rv + Sw, Sg, So, pw, pg, po, Rs, Rv, rho_w, rho_g, rho_o, T + }; + public: + PyFluidState(Simulator *ebos_simulator); + std::vector getFluidStateVariable(const std::string &name) const; + std::vector getPrimaryVarMeaning(const std::string &variable) const; + std::map getPrimaryVarMeaningMap(const std::string &variable) const; + std::vector getPrimaryVariable(const std::string &idx_name) const; + void setPrimaryVariable(const std::string &idx_name, const double *data, std::size_t size); + + private: + std::size_t getPrimaryVarIndex_(const std::string &idx_name) const; + int getVariableMeaning_(PrimaryVariables &primary_vars, const std::string &variable) const; + VariableType getVariableType_(const std::string &name) const; + template double getVariableValue_( + FluidState &fs, VariableType var_type, const std::string &name) const; + void variableNotFoundError_(const std::string &name) const; + + Simulator *ebos_simulator_; + }; +} +#include "PyFluidState_impl.hpp" + +#endif // OPM_PY_FLUID_STATE_HEADER_INCLUDED + diff --git a/opm/simulators/flow/python/PyFluidState_impl.hpp b/opm/simulators/flow/python/PyFluidState_impl.hpp new file mode 100644 index 00000000000..fc426c199ee --- /dev/null +++ b/opm/simulators/flow/python/PyFluidState_impl.hpp @@ -0,0 +1,336 @@ +/* + Copyright 2023 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 . +*/ +#include +#include +#include +#include + +namespace Opm::Pybind { + +template +PyFluidState:: +PyFluidState(Simulator* ebos_simulator) : ebos_simulator_(ebos_simulator) +{ + +} + +// Public methods alphabetically sorted +// ------------------------------------ + +template +std::vector +PyFluidState:: +getPrimaryVarMeaning(const std::string &variable) const { + Model &model = this->ebos_simulator_->model(); + auto &sol = model.solution(/*timeIdx*/0); + auto size = model.numGridDof(); + std::vector array(size); + for (unsigned dof_idx = 0; dof_idx < size; ++dof_idx) { + auto primary_vars = sol[dof_idx]; + array[dof_idx] = getVariableMeaning_(primary_vars, variable); + } + return array; +} + +template +std::map +PyFluidState:: +getPrimaryVarMeaningMap(const std::string &variable) const +{ + if (variable.compare("pressure") == 0) { + return {{ "Po", static_cast(PrimaryVariables::PressureMeaning::Po) }, + { "Pw", static_cast(PrimaryVariables::PressureMeaning::Pw) }, + { "Pg", static_cast(PrimaryVariables::PressureMeaning::Pg) }}; + } + else if (variable.compare("water") == 0) { + return {{ "Sw", static_cast(PrimaryVariables::WaterMeaning::Sw) }, + { "Rvw", static_cast(PrimaryVariables::WaterMeaning::Rvw) }, + { "Rsw", static_cast(PrimaryVariables::WaterMeaning::Rsw) }, + { "Disabled", static_cast(PrimaryVariables::WaterMeaning::Disabled) }}; + } + else if (variable.compare("gas") == 0) { + return {{ "Sg", static_cast(PrimaryVariables::GasMeaning::Sg) }, + { "Rs", static_cast(PrimaryVariables::GasMeaning::Rs) }, + { "Rv", static_cast(PrimaryVariables::GasMeaning::Rv) }, + { "Disabled", static_cast(PrimaryVariables::GasMeaning::Disabled) }}; + } + else if (variable.compare("brine") == 0) { + return {{ "Cs", static_cast(PrimaryVariables::BrineMeaning::Cs) }, + { "Sp", static_cast(PrimaryVariables::BrineMeaning::Sp) }, + { "Disabled", static_cast(PrimaryVariables::BrineMeaning::Disabled) }}; + } + else { + const std::string msg = fmt::format( + "Unknown variable meaning '{}': Expected pressure, water, gas, or brine", variable); + throw std::runtime_error(msg); + } +} + +/* Meaning of the primary variables: Sw, Sg, po, pg, Rs, Rv + * 1. Sw_po_Sg -> threephase case + * 2. Sw_po_Rs -> water + oil case + * 3. Sw_pg_Rv -> water + gas case + */ + +/* Variables: + Sw = Water saturation, + So = Oil saturation, + Sg = Gas saturation, + pw = Water pressure, + po = Oil pressure, + pg = Gas pressure, + Rs = The solution gas oil ratio: The amount of gas dissolved in the oil + Rv = The oil vaporization factor of the gas phase + invB = The inverse formation volume factor of a fluid phase + rho_w = Water density, + rho_o = Oil density, + rho_g = Gas density, + mu_w = Water viscosity, + mu_o = Oil viscosity, + mu_g = Gas viscosity, + kr_w = Water relperm, + kr_o = Oil relperm, + kr_g = Gas relperm, + */ +template +std::vector +PyFluidState:: +getFluidStateVariable(const std::string &name) const +{ + //using ElementIterator = typename GridView::template Codim<0>::Iterator; + //using Element = typename GridView::template Codim<0>::Entity; + + Model &model = this->ebos_simulator_->model(); + auto size = model.numGridDof(); + std::cout << "model size=" << size << std::endl; + std::vector array(size); + const auto& grid_view = this->ebos_simulator_->vanguard().gridView(); + /* NOTE: grid_view.size(0) should give the same value as + * model.numGridDof() + */ + ElementContext elem_ctx(*this->ebos_simulator_); + //ElementIterator elem_itr = grid_view.template begin(); + //const ElementIterator& elem_end_itr = grid_view.template end(); + auto var_type = getVariableType_(name); + // JENKINS dummy line + int i = 0; + for (const auto& elem : elements(grid_view, Dune::Partitions::interior)) { + //for (; elem_itr != elem_end_itr; ++elem_itr) { + std::cout << "i=" << i << std::endl; + //const Element& elem = *elem_itr; + setenv("OPM_DEBUG", "1", /*overwrite=*/1); + elem_ctx.updatePrimaryStencil(elem); + std::cout << "r" << std::endl; + elem_ctx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); + std::cout << "s" << std::endl; + for (unsigned dof_idx = 0; dof_idx < elem_ctx.numPrimaryDof(/*timeIdx=*/0); ++dof_idx) { + std::cout << "j=" << dof_idx << std::endl; + const auto& int_quants = elem_ctx.intensiveQuantities(dof_idx, /*timeIdx=*/0); + std::cout << "j1" << std::endl; + const auto& fs = int_quants.fluidState(); + unsigned global_dof_idx = elem_ctx.globalSpaceIndex(dof_idx, /*timeIdx=*/0); + array[global_dof_idx] = getVariableValue_(fs, var_type, name); + } + i+=1; + } + return array; +} + +template +std::vector +PyFluidState:: +getPrimaryVariable(const std::string &idx_name) const +{ + std::size_t primary_var_idx = getPrimaryVarIndex_(idx_name); + Model &model = this->ebos_simulator_->model(); + auto &sol = model.solution(/*timeIdx*/0); + auto size = model.numGridDof(); + std::vector array(size); + for (unsigned dof_idx = 0; dof_idx < size; ++dof_idx) { + auto primary_vars = sol[dof_idx]; + array[dof_idx] = primary_vars[primary_var_idx]; + } + return array; +} + +template +void +PyFluidState:: +setPrimaryVariable(const std::string &idx_name, const double *data, std::size_t size) +{ + std::size_t primary_var_idx = getPrimaryVarIndex_(idx_name); + Model &model = this->ebos_simulator_->model(); + auto &sol = model.solution(/*timeIdx*/0); + auto model_size = model.numGridDof(); + if (model_size != size) { + const std::string msg = fmt::format( + "Cannot set primary variable. Expected array of size {} but got array of size: {}", + model_size, size); + throw std::runtime_error(msg); + } + for (unsigned dof_idx = 0; dof_idx < size; ++dof_idx) { + auto &primary_vars = sol[dof_idx]; + primary_vars[primary_var_idx] = data[dof_idx]; + } +} + +// Private methods alphabetically sorted +// ------------------------------------- + +template +std::size_t +PyFluidState:: +getPrimaryVarIndex_(const std::string &idx_name) const +{ + if (idx_name.compare("pressure") == 0) { + return Indices::pressureSwitchIdx; + } + else if (idx_name.compare("water_saturation") == 0) { + return Indices::waterSwitchIdx; + } + else if (idx_name.compare("composition") == 0) { + return Indices::compositionSwitchIdx; + } + else { + const std::string msg = fmt::format("Unknown primary variable index name: {}", idx_name); + throw std::runtime_error(msg); + } +} + +template +int +PyFluidState:: +getVariableMeaning_(PrimaryVariables &primary_vars, const std::string &variable) const +{ + if (variable.compare("pressure") == 0) { + return static_cast(primary_vars.primaryVarsMeaningPressure()); + } + else if(variable.compare("water") == 0) { + return static_cast(primary_vars.primaryVarsMeaningWater()); + } + else if (variable.compare("gas") == 0) { + return static_cast(primary_vars.primaryVarsMeaningGas()); + } + else if (variable.compare("brine") == 0) { + return static_cast(primary_vars.primaryVarsMeaningBrine()); + } + else { + const std::string msg = fmt::format( + "Unknown variable meaning '{}': Expected pressure, water, gas, or brine", variable); + throw std::runtime_error(msg); + } +} + +template +typename PyFluidState::VariableType +PyFluidState:: +getVariableType_(const std::string &name) const +{ + static std::map variable_type_map = + { + {"Sw", VariableType::Sw}, + {"Sg", VariableType::Sg}, + {"So", VariableType::So}, + {"pw", VariableType::pw}, + {"pg", VariableType::pg}, + {"po", VariableType::po}, + {"Rs", VariableType::Rs}, + {"Rv", VariableType::Rv}, + {"rho_w", VariableType::rho_w}, + {"rho_g", VariableType::rho_g}, + {"rho_o", VariableType::rho_o}, + {"T", VariableType::T} + }; + + if (variable_type_map.count(name) == 0) { + variableNotFoundError_(name); + } + return variable_type_map.at(name); +} + +template +template +double +PyFluidState:: +getVariableValue_(FluidState &fs, VariableType var_type, const std::string &name) const +{ + double value; + switch(var_type) { + case VariableType::pw : + value = Opm::getValue( + fs.pressure(FluidSystem::waterPhaseIdx)); + break; + case VariableType::pg : + value = Opm::getValue( + fs.pressure(FluidSystem::gasPhaseIdx)); + break; + case VariableType::po : + value = Opm::getValue( + fs.pressure(FluidSystem::oilPhaseIdx)); + break; + case VariableType::rho_w : + value = Opm::getValue( + fs.density(FluidSystem::waterPhaseIdx)); + break; + case VariableType::rho_g : + value = Opm::getValue( + fs.density(FluidSystem::gasPhaseIdx)); + break; + case VariableType::rho_o : + value = Opm::getValue( + fs.density(FluidSystem::oilPhaseIdx)); + break; + case VariableType::Rs : + value = Opm::getValue(fs.Rs()); + break; + case VariableType::Rv : + value = Opm::getValue(fs.Rv()); + break; + case VariableType::Sw : + value = Opm::getValue( + fs.saturation(FluidSystem::waterPhaseIdx)); + break; + case VariableType::Sg : + value = Opm::getValue( + fs.saturation(FluidSystem::gasPhaseIdx)); + break; + case VariableType::So : + value = Opm::getValue( + fs.saturation(FluidSystem::oilPhaseIdx)); + break; + case VariableType::T : + value = Opm::getValue( + fs.temperature(FluidSystem::waterPhaseIdx)); + break; + default: + variableNotFoundError_(name); + } + return value; +} + +template +void +PyFluidState:: +variableNotFoundError_(const std::string &name) const +{ + const std::string msg = fmt::format("Access to variable '{}' is not implemented yet!", name); + throw std::runtime_error(msg); +} + +} // namespace Opm::Pybind diff --git a/opm/simulators/flow/python/PyMaterialState.hpp b/opm/simulators/flow/python/PyMaterialState.hpp index d1bf20ad3fa..86831d0a3f3 100644 --- a/opm/simulators/flow/python/PyMaterialState.hpp +++ b/opm/simulators/flow/python/PyMaterialState.hpp @@ -45,8 +45,8 @@ namespace Opm::Pybind PyMaterialState(Simulator *ebos_simulator) : ebos_simulator_(ebos_simulator) { } - std::unique_ptr getCellVolumes( std::size_t *size); - std::unique_ptr getPorosity( std::size_t *size); + std::vector getCellVolumes(); + std::vector getPorosity(); void setPorosity(const double *poro, std::size_t size); private: Simulator *ebos_simulator_; diff --git a/opm/simulators/flow/python/PyMaterialState_impl.hpp b/opm/simulators/flow/python/PyMaterialState_impl.hpp index e8d07be5375..2181b49ef67 100644 --- a/opm/simulators/flow/python/PyMaterialState_impl.hpp +++ b/opm/simulators/flow/python/PyMaterialState_impl.hpp @@ -22,29 +22,29 @@ namespace Opm::Pybind { template -std::unique_ptr +std::vector PyMaterialState:: -getCellVolumes( std::size_t *size) +getCellVolumes() { Model &model = this->ebos_simulator_->model(); - *size = model.numGridDof(); - auto array = std::make_unique(*size); - for (unsigned dof_idx = 0; dof_idx < *size; ++dof_idx) { + auto size = model.numGridDof(); + std::vector array(size); + for (unsigned dof_idx = 0; dof_idx < size; ++dof_idx) { array[dof_idx] = model.dofTotalVolume(dof_idx); } return array; } template -std::unique_ptr +std::vector PyMaterialState:: -getPorosity( std::size_t *size) +getPorosity() { Problem &problem = this->ebos_simulator_->problem(); Model &model = this->ebos_simulator_->model(); - *size = model.numGridDof(); - auto array = std::make_unique(*size); - for (unsigned dof_idx = 0; dof_idx < *size; ++dof_idx) { + auto size = model.numGridDof(); + std::vector array(size); + for (unsigned dof_idx = 0; dof_idx < size; ++dof_idx) { array[dof_idx] = problem.referencePorosity(dof_idx, /*timeIdx*/0); } return array; diff --git a/opm/simulators/flow/python/Pybind11Exporter.hpp b/opm/simulators/flow/python/Pybind11Exporter.hpp index 1feedd30542..e87955d528c 100644 --- a/opm/simulators/flow/python/Pybind11Exporter.hpp +++ b/opm/simulators/flow/python/Pybind11Exporter.hpp @@ -3,6 +3,7 @@ #include #include +#include //#include namespace py = pybind11; diff --git a/python/simulators/CMakeLists.txt b/python/simulators/CMakeLists.txt index 67f16677c26..515a79c8f06 100644 --- a/python/simulators/CMakeLists.txt +++ b/python/simulators/CMakeLists.txt @@ -44,21 +44,13 @@ if(OPM_ENABLE_PYTHON_TESTS) # splitting the python tests into multiple add_test() tests instead # of having a single "python -m unittest" test call that will run all # the tests in the "test" sub directory. - add_test(NAME python_basic - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/python - COMMAND ${CMAKE_COMMAND} - -E env PYTHONPATH=${PYTHON_PATH} ${PYTHON_EXECUTABLE} - -m unittest test/test_basic.py) - add_test(NAME python_schedule - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/python - COMMAND ${CMAKE_COMMAND} - -E env PYTHONPATH=${PYTHON_PATH} ${PYTHON_EXECUTABLE} - -m unittest test/test_schedule.py) - add_test(NAME python_throw - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/python - COMMAND ${CMAKE_COMMAND} - -E env PYTHONPATH=${PYTHON_PATH} ${PYTHON_EXECUTABLE} - -m unittest test/test_throw.py) + foreach(case_name IN ITEMS basic fluidstate_variables primary_variables schedule throw) + add_test(NAME python_${case_name} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/python + COMMAND ${CMAKE_COMMAND} + -E env PYTHONPATH=${PYTHON_PATH} ${PYTHON_EXECUTABLE} + -m unittest test/test_${case_name}.py) + endforeach() endif() find_file(PYTHON_INSTALL_PY install.py diff --git a/python/simulators/PyBlackOilSimulator.cpp b/python/simulators/PyBlackOilSimulator.cpp index 2389546e94e..e1db2492961 100644 --- a/python/simulators/PyBlackOilSimulator.cpp +++ b/python/simulators/PyBlackOilSimulator.cpp @@ -27,12 +27,15 @@ //#include #include #include +#include +#include #include // NOTE: EXIT_SUCCESS, EXIT_FAILURE is defined in cstdlib #include #include #include #include +#include namespace py = pybind11; @@ -82,9 +85,8 @@ int PyBlackOilSimulator::currentStep() } py::array_t PyBlackOilSimulator::getCellVolumes() { - std::size_t len; - auto array = getMaterialState().getCellVolumes(&len); - return py::array(len, array.get()); + auto vector = getMaterialState().getCellVolumes(); + return py::array(vector.size(), vector.data()); } double PyBlackOilSimulator::getDT() { @@ -93,9 +95,41 @@ double PyBlackOilSimulator::getDT() { py::array_t PyBlackOilSimulator::getPorosity() { - std::size_t len; - auto array = getMaterialState().getPorosity(&len); - return py::array(len, array.get()); + auto vector = getMaterialState().getPorosity(); + return py::array(vector.size(), vector.data()); +} + +py::array_t +PyBlackOilSimulator:: +getFluidStateVariable(const std::string &name) const +{ + setenv("OPM_DEBUG", "1", /*overwrite=*/1); + std::cout << "getFluidStateVariable: " << name << std::endl; + auto vector = getFluidState().getFluidStateVariable(name); + return py::array(vector.size(), vector.data()); +} + +py::array_t +PyBlackOilSimulator:: +getPrimaryVariable(const std::string &variable) const +{ + auto vector = getFluidState().getPrimaryVariable(variable); + return py::array(vector.size(), vector.data()); +} + +py::array_t +PyBlackOilSimulator:: +getPrimaryVarMeaning(const std::string &variable) const +{ + auto vector = getFluidState().getPrimaryVarMeaning(variable); + return py::array(vector.size(), vector.data()); +} + +std::map +PyBlackOilSimulator:: +getPrimaryVarMeaningMap(const std::string &variable) const +{ + return getFluidState().getPrimaryVarMeaningMap(variable); } int PyBlackOilSimulator::run() @@ -112,6 +146,19 @@ void PyBlackOilSimulator::setPorosity( py::array_t array +) +{ + std::size_t size_ = array.size(); + const double *data = array.data(); + getFluidState().setPrimaryVariable(idx_name, data, size_); +} + int PyBlackOilSimulator::step() { if (!this->has_run_init_) { @@ -164,6 +211,7 @@ int PyBlackOilSimulator::stepInit() int result = this->main_ebos_->executeInitStep(); this->has_run_init_ = true; this->ebos_simulator_ = this->main_ebos_->getSimulatorPtr(); + this->fluid_state_ = std::make_unique>(this->ebos_simulator_); this->material_state_ = std::make_unique>(this->ebos_simulator_); return result; } @@ -187,7 +235,20 @@ Opm::FlowMain& } } -PyMaterialState& +PyFluidState& +PyBlackOilSimulator:: +getFluidState() const +{ + if (this->fluid_state_) { + return *this->fluid_state_; + } + else { + throw std::runtime_error("BlackOilSimulator not initialized: " + "Cannot get reference to FlowMain object" ); + } +} + +PyMaterialState& PyBlackOilSimulator::getMaterialState() const { if (this->material_state_) { @@ -209,18 +270,29 @@ void export_PyBlackOilSimulator(py::module& m) std::shared_ptr, std::shared_ptr, std::shared_ptr >()) + .def("advance", &PyBlackOilSimulator::advance, py::arg("report_step")) + .def("current_step", &PyBlackOilSimulator::currentStep) .def("get_cell_volumes", &PyBlackOilSimulator::getCellVolumes, py::return_value_policy::copy) .def("get_dt", &PyBlackOilSimulator::getDT) + .def("get_fluidstate_variable", &PyBlackOilSimulator::getFluidStateVariable, + py::return_value_policy::copy, py::arg("name")) .def("get_porosity", &PyBlackOilSimulator::getPorosity, py::return_value_policy::copy) + .def("get_primary_variable_meaning", &PyBlackOilSimulator::getPrimaryVarMeaning, + py::return_value_policy::copy, py::arg("variable")) + .def("get_primary_variable_meaning_map", &PyBlackOilSimulator::getPrimaryVarMeaningMap, + py::return_value_policy::copy, py::arg("variable")) + .def("get_primary_variable", &PyBlackOilSimulator::getPrimaryVariable, + py::return_value_policy::copy, py::arg("variable")) .def("run", &PyBlackOilSimulator::run) .def("set_porosity", &PyBlackOilSimulator::setPorosity) + .def("set_primary_variable", &PyBlackOilSimulator::setPrimaryVariable, + py::arg("idx_name"), py::arg("value")) .def("current_step", &PyBlackOilSimulator::currentStep) .def("step", &PyBlackOilSimulator::step) - .def("advance", &PyBlackOilSimulator::advance, py::arg("report_step")) - .def("step_init", &PyBlackOilSimulator::stepInit) - .def("step_cleanup", &PyBlackOilSimulator::stepCleanup); + .def("step_cleanup", &PyBlackOilSimulator::stepCleanup) + .def("step_init", &PyBlackOilSimulator::stepInit); } } // namespace Opm::Pybind diff --git a/python/test/test_basic.py b/python/test/test_basic.py index b530b9c1129..9aa3a0caacd 100755 --- a/python/test/test_basic.py +++ b/python/test/test_basic.py @@ -1,6 +1,5 @@ import os import unittest -from contextlib import contextmanager from pathlib import Path from opm.simulators import BlackOilSimulator from .pytest_common import pushd diff --git a/python/test/test_fluidstate_variables.py b/python/test/test_fluidstate_variables.py new file mode 100644 index 00000000000..0f5025314c8 --- /dev/null +++ b/python/test/test_fluidstate_variables.py @@ -0,0 +1,24 @@ +import os +import unittest +from pathlib import Path +from opm.simulators import BlackOilSimulator +from .pytest_common import pushd + +class TestBasic(unittest.TestCase): + @classmethod + def setUpClass(cls): + # NOTE: See comment in test_basic.py for the reason why we are + # only using a single test_all() function instead of splitting + # it up in multiple test functions + test_dir = Path(os.path.dirname(__file__)) + cls.data_dir = test_dir.parent.joinpath("test_data/SPE1CASE1a") + + + def test_all(self): + with pushd(self.data_dir): + sim = BlackOilSimulator("SPE1CASE1.DATA") + sim.step_init() + sim.step() + oil_pressure = sim.get_fluidstate_variable(name='po') + assert True + #self.assertAlmostEqual(oil_pressure[0], 41729978.837, places=2, msg='value of oil pressure') diff --git a/python/test/test_primary_variables.py b/python/test/test_primary_variables.py new file mode 100644 index 00000000000..4e160c4232c --- /dev/null +++ b/python/test/test_primary_variables.py @@ -0,0 +1,43 @@ +import os +import unittest +from pathlib import Path +from opm.simulators import BlackOilSimulator +from .pytest_common import pushd + +class TestBasic(unittest.TestCase): + @classmethod + def setUpClass(cls): + # NOTE: See comment in test_basic.py for the reason why we are + # only using a single test_all() function instead of splitting + # it up in multiple test functions + test_dir = Path(os.path.dirname(__file__)) + cls.data_dir = test_dir.parent.joinpath("test_data/SPE1CASE1a") + + + def test_all(self): + with pushd(self.data_dir): + sim = BlackOilSimulator("SPE1CASE1.DATA") + sim.step_init() + sim.step() + pressure = sim.get_primary_variable(variable='pressure') + self.assertAlmostEqual(pressure[0], 41729978.837, places=2, msg='value of pressure') + pressure_meaning = sim.get_primary_variable_meaning( + variable='pressure') + pressure_meaning_map = sim.get_primary_variable_meaning_map( + variable='pressure') + self.assertEqual(pressure_meaning[0], pressure_meaning_map["Po"]) + water_meaning = sim.get_primary_variable_meaning( + variable='water') + water_meaning_map = sim.get_primary_variable_meaning_map( + variable='water') + self.assertEqual(water_meaning[0], water_meaning_map["Sw"]) + gas_meaning = sim.get_primary_variable_meaning( + variable='gas') + gas_meaning_map = sim.get_primary_variable_meaning_map( + variable='gas') + self.assertEqual(gas_meaning[0], gas_meaning_map["Sg"]) + brine_meaning = sim.get_primary_variable_meaning( + variable='brine') + brine_meaning_map = sim.get_primary_variable_meaning_map( + variable='brine') + self.assertEqual(brine_meaning[0], brine_meaning_map["Disabled"]) diff --git a/python/test/test_schedule.py b/python/test/test_schedule.py index 0aa442f72d5..584615b2522 100755 --- a/python/test/test_schedule.py +++ b/python/test/test_schedule.py @@ -1,6 +1,5 @@ import os import unittest -from contextlib import contextmanager import datetime as dt from pathlib import Path import re