Dynamically update schedule from Python

Adds some methods that enables Opm::Schedule to be dynamically modified
from Python. A test case in test_schedule.py illustrates the use case.
This commit is contained in:
Håkon Hægland
2022-05-02 18:43:04 +02:00
parent ea82bebb3a
commit 91ac3a2a32
7 changed files with 124 additions and 19 deletions

View File

@@ -14,7 +14,8 @@ pybind11_add_module(simulators ${PYBIND11_SYSTEM}
PyBlackOilSimulator.cpp
Pybind11Exporter.cpp)
set_target_properties( simulators PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/python/opm2 )
set(PYTHON_OPM_SIMULATORS_PACKAGE_PATH ${PROJECT_BINARY_DIR}/python/opm2/simulators)
set_target_properties( simulators PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PYTHON_OPM_SIMULATORS_PACKAGE_PATH} )
target_sources(simulators
PRIVATE
@@ -46,6 +47,9 @@ file( COPY ${PROJECT_SOURCE_DIR}/python/test
DESTINATION ${PROJECT_BINARY_DIR}/python)
file( COPY ${PROJECT_SOURCE_DIR}/python/test_data
DESTINATION ${PROJECT_BINARY_DIR}/python)
file( MAKE_DIRECTORY ${PYTHON_OPM_SIMULATORS_PACKAGE_PATH} )
file( COPY ${PROJECT_SOURCE_DIR}/python/simulators/__init__.py
DESTINATION ${PYTHON_OPM_SIMULATORS_PACKAGE_PATH})
if(OPM_ENABLE_PYTHON_TESTS)
if(Python3_EXECUTABLE AND NOT PYTHON_EXECUTABLE)

View File

@@ -52,6 +52,11 @@ PyBlackOilSimulator::PyBlackOilSimulator(
{
}
bool PyBlackOilSimulator::checkSimulationFinished()
{
return this->mainEbos_->getSimTimer()->done();
}
const Opm::FlowMainEbos<typename Opm::Pybind::PyBlackOilSimulator::TypeTag>&
PyBlackOilSimulator::getFlowMainEbos() const
{
@@ -85,6 +90,13 @@ void PyBlackOilSimulator::setPorosity( py::array_t<double,
materialState_->setPorosity(poro, size_);
}
void PyBlackOilSimulator::advance(int report_step)
{
while (currentStep() < report_step) {
step();
}
}
int PyBlackOilSimulator::step()
{
if (!hasRunInit_) {
@@ -93,9 +105,27 @@ int PyBlackOilSimulator::step()
if (hasRunCleanup_) {
throw std::logic_error("step() called after step_cleanup()");
}
return mainEbos_->executeStep();
if(checkSimulationFinished()) {
throw std::logic_error("step() called, but simulation is done");
}
//if (this->debug_)
// this->mainEbos_->getSimTimer()->report(std::cout);
auto result = mainEbos_->executeStep();
return result;
}
// This returns the report step number that will be executed next time step()
// is called.
int PyBlackOilSimulator::currentStep()
{
return this->mainEbos_->getSimTimer()->currentStepNum();
// NOTE: this->ebosSimulator_->episodeIndex() would also return the current
// report step number, but this number is always delayed by 1 step relative
// to this->mainEbos_->getSimTimer()->currentStepNum()
// See details in runStep() in file SimulatorFullyImplicitBlackoilEbos.hpp
}
int PyBlackOilSimulator::stepCleanup()
{
hasRunCleanup_ = true;
@@ -153,7 +183,9 @@ void export_PyBlackOilSimulator(py::module& m)
py::return_value_policy::copy)
.def("run", &PyBlackOilSimulator::run)
.def("set_porosity", &PyBlackOilSimulator::setPorosity)
.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);
}

View File

@@ -0,0 +1,12 @@
# Instead of having the pybind11 extension module, e.g.
# simulators.cpython-310-x86_64-linux-gnu.so located
# directly in the opm2 directory, we create a package (sub
# directory) with the same name and place it there.
# In this way we can do (if needed in the future)
#
# from opm.simulators import BlackOilSimulator, FoamSimulator, PurePythonUtils, ...
#
# where FoamSimulator and PurePythonUtils does not currently exists,
# but could be possible future extensions..
#
from .simulators import BlackOilSimulator