diff --git a/cmake/modules/OpmPythonGenerateDocStrings.cmake b/cmake/modules/OpmPythonGenerateDocStrings.cmake index 619abc3..498e535 100644 --- a/cmake/modules/OpmPythonGenerateDocStrings.cmake +++ b/cmake/modules/OpmPythonGenerateDocStrings.cmake @@ -1,15 +1,29 @@ # Set the path to the input docstrings.json file and the output .hpp file -set(PYTHON_DOCSTRINGS_FILE "${PROJECT_SOURCE_DIR}/docs/docstrings.json") -set(DOCSTRINGS_GENERATED_HPP "PyBlackOilSimulatorDoc.hpp") -set(DOCSTRINGS_GENERATED_HEADER_PATH "${PROJECT_BINARY_DIR}/${TEMP_GEN_DIR}/${DOCSTRINGS_GENERATED_HPP}") +set(PYBLACKOIL_DOCSTRINGS_FILE "${PROJECT_SOURCE_DIR}/docs/docstrings_simulators.json") +set(PYBLACKOIL_DOCSTRINGS_GENERATED_HPP "PyBlackOilSimulatorDoc.hpp") +set(PYBLACKOIL_DOCSTRINGS_GENERATED_HEADER_PATH "${PROJECT_BINARY_DIR}/${TEMP_GEN_DIR}/${PYBLACKOIL_DOCSTRINGS_GENERATED_HPP}") -# Command to run the Python script to generate the .hpp file +set(COMMON_DOCSTRINGS_FILE "${PROJECT_SOURCE_DIR}/docs/docstrings_common.json") +set(COMMON_DOCSTRINGS_GENERATED_HPP "OpmCommonPythonDoc.hpp") +set(COMMON_DOCSTRINGS_GENERATED_HEADER_PATH "${PROJECT_BINARY_DIR}/${TEMP_GEN_DIR}/${COMMON_DOCSTRINGS_GENERATED_HPP}") + +# Commands to run the Python script to generate the .hpp file + +add_custom_command( + OUTPUT ${PYBLACKOIL_DOCSTRINGS_GENERATED_HEADER_PATH} + COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/helper_scripts/generate_docstring_hpp.py ${PYBLACKOIL_DOCSTRINGS_FILE} "${PYBLACKOIL_DOCSTRINGS_GENERATED_HEADER_PATH}" + PYBLACKOILSIMULATORDOC_HPP "Opm::Pybind::DocStrings" + DEPENDS ${PYBLACKOIL_DOCSTRINGS_FILE} + COMMENT "Generating ${PYBLACKOIL_DOCSTRINGS_GENERATED_HPP} from JSON file" +) add_custom_command( - OUTPUT ${DOCSTRINGS_GENERATED_HEADER_PATH} - COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/helper_scripts/generate_docstring_hpp.py ${PYTHON_DOCSTRINGS_FILE} "${DOCSTRINGS_GENERATED_HEADER_PATH}" - DEPENDS ${PYTHON_DOCSTRINGS_FILE} - COMMENT "Generating ${DOCSTRINGS_GENERATED_HPP} from JSON file" + OUTPUT ${COMMON_DOCSTRINGS_GENERATED_HEADER_PATH} + COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/helper_scripts/generate_docstring_hpp.py ${COMMON_DOCSTRINGS_FILE} "${COMMON_DOCSTRINGS_GENERATED_HEADER_PATH}" + OPMCOMMONPYTHONDOC_HPP "Opm::Common::DocStrings" + DEPENDS ${COMMON_DOCSTRINGS_FILE} + COMMENT "Generating ${COMMON_DOCSTRINGS_GENERATED_HPP} from JSON file" ) -# Create a custom target for the generated header file -add_custom_target(generate_docstring_hpp DEPENDS ${DOCSTRINGS_GENERATED_HEADER_PATH}) +# Create custom targets for the generated header files +add_custom_target(pyblackoil_generate_docstring_hpp DEPENDS ${PYBLACKOIL_DOCSTRINGS_GENERATED_HEADER_PATH}) +add_custom_target(common_generate_docstring_hpp DEPENDS ${COMMON_DOCSTRINGS_GENERATED_HEADER_PATH}) diff --git a/cmake/modules/OpmPythonSetupOpmSimulatorsBindings.cmake b/cmake/modules/OpmPythonSetupOpmSimulatorsBindings.cmake index d37f4cb..e7e2aa7 100644 --- a/cmake/modules/OpmPythonSetupOpmSimulatorsBindings.cmake +++ b/cmake/modules/OpmPythonSetupOpmSimulatorsBindings.cmake @@ -13,7 +13,8 @@ function (build_opm_simulators_pybind11_module) "${MODULE_VERSION_OBJECT_FILE}" ) # Make sure the module depends on the generated header file - add_dependencies(simulators generate_docstring_hpp) + add_dependencies(simulators pyblackoil_generate_docstring_hpp) + add_dependencies(simulators common_generate_docstring_hpp) set_target_properties( simulators PROPERTIES @@ -26,4 +27,4 @@ function (build_opm_simulators_pybind11_module) target_include_directories(simulators PRIVATE "${PROJECT_BINARY_DIR}/${TEMP_GEN_DIR}") endfunction() -build_opm_simulators_pybind11_module() \ No newline at end of file +build_opm_simulators_pybind11_module() diff --git a/docs/docs/common.rst b/docs/docs/common.rst new file mode 100644 index 0000000..c28c406 --- /dev/null +++ b/docs/docs/common.rst @@ -0,0 +1,4 @@ +OPM Common Python Documentation +=============================== + +.. opm_common_docstrings:: diff --git a/docs/docs/conf.py b/docs/docs/conf.py index d4e990c..ce24a81 100644 --- a/docs/docs/conf.py +++ b/docs/docs/conf.py @@ -1,6 +1,6 @@ # Configuration file for the Sphinx documentation builder. -project = "opm" +project = "OPM Python Documentation" copyright = "2024 Equinor ASA" author = "Håkon Hægland" @@ -37,7 +37,8 @@ def extract_opm_python_release(): # Our sphinx extension that will use the docstrings.json file to generate documentation extensions = ["opm_python_docs.sphinx_ext_docstrings"] # Path to docstrings.json -opm_python_docstrings_path = os.path.abspath('../docstrings.json') +opm_simulators_docstrings_path = os.path.abspath('../docstrings_simulators.json') +opm_common_docstrings_path = os.path.abspath('../docstrings_common.json') templates_path = ["_templates"] exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] diff --git a/docs/docs/embedded.rst b/docs/docs/embedded.rst new file mode 100644 index 0000000..85d176f --- /dev/null +++ b/docs/docs/embedded.rst @@ -0,0 +1,52 @@ +OPM Embedded Python Documentation +================================= + +The PYACTION keyword is a flow specific keyword which allows for executing embedded Python +code in the SCHEDULE section. The embedded Python code will then be executed at the end of each successful timestep. + +The PYACTION keyword is inspired +by the ACTIONX keyword, but instead of a .DATA formatted condition you +are allowed to implement the condition with a general Python script. The +ACTIONX keywords are very clearly separated in a condition part and an +action part in the form of a list of keywords which are effectively injected in +the SCHEDULE section when the condition evaluates to true. +This is not so for PYACTION where there is one Python script in which both +conditions can be evaluated and changes applied. + +In order to enable the PYACTION keyword: + +1. OPM flow must be compiled with the cmake switches -DOPM ENABLE EMBEDDED PYTHON=ON and -DOPM ENABLE PYTHON=ON, the default is to build with these switches set to OFF. + +2. The keyword PYACTION must be added to the SCHEDULE section: + +.. code-block:: python + + / + / + +3. You need to provide the Python script. + + +To interact with the simulator in the embedded Python code, you can access four variables from the simulator: + +.. code-block:: python + + # Python module opm_embedded + import opm_embedded + # The current EclipseState + ecl_state = opm_embedded.current_ecl_state + # The current Schedule + schedule = opm_embedded.current_schedule + # The current SummaryState + summary_state = opm_embedded.current_summary_state + # The current report step + report_step = opm_embedded.current_report_step + + +- current_ecl_state: An instance of the `EclipseState `_ class - this is a representation of all static properties in the model, ranging from porosity to relperm tables. The content of the ecl state is immutable - you are not allowed to change the static properties at runtime. + +- current_schedule: An instance of the `Schedule `_ class - this is a representation of all the content from the SCHEDULE section, notably all well and group information and the timestepping. + +- current_report_step: This is an integer for the report step we are currently working on. Observe that the PYACTION is called for every simulator timestep, i.e. it will typically be called multiple times with the same value for the report step argument. + +- current_summary_state: An instance of the `SummaryState `_ class, this is where the current summary results of the simulator are stored. The SummaryState class has methods to get hold of well, group and general variables. diff --git a/docs/docs/index.rst b/docs/docs/index.rst index e97b593..30c2956 100644 --- a/docs/docs/index.rst +++ b/docs/docs/index.rst @@ -1,13 +1,15 @@ -Welcome to the Python documentation for opm-simulators! -======================================================= +Welcome to the Python documentation for OPM Flow! +================================================= .. toctree:: :maxdepth: 1 :caption: Contents: introduction - python - + common + simulators + embedded + Indices and tables ================== diff --git a/docs/docs/introduction.rst b/docs/docs/introduction.rst index a923777..40d6af6 100644 --- a/docs/docs/introduction.rst +++ b/docs/docs/introduction.rst @@ -1,4 +1,4 @@ Introduction ============ -Documentation for the ``opm.simulators`` Python module. \ No newline at end of file +Documentation for the OPM Python interfaces. diff --git a/docs/docs/python.rst b/docs/docs/python.rst deleted file mode 100644 index 8221adc..0000000 --- a/docs/docs/python.rst +++ /dev/null @@ -1,4 +0,0 @@ -Python Module Documentation -=========================== - -.. opm_python_docstrings:: diff --git a/docs/docs/simulators.rst b/docs/docs/simulators.rst new file mode 100644 index 0000000..a157f2b --- /dev/null +++ b/docs/docs/simulators.rst @@ -0,0 +1,5 @@ +OPM Simulators Python Documentation +=================================== + +.. opm_simulators_docstrings:: + diff --git a/docs/docstrings.json b/docs/docstrings.json deleted file mode 100644 index 4ab2c02..0000000 --- a/docs/docstrings.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "PyBlackOilSimulator_filename_constructor": { - "signature": "__init__(deck_filename: str) -> None", - "doc": "Constructor using a deck file name.\n\n:param deck_filename: The file name of the deck to be used for the simulation.\n:type deck_filename: str" - }, - "PyBlackOilSimulator_objects_constructor": { - "signature": "__init__(deck: Deck, state: EclipseState, schedule: Schedule, summary_config: SummaryConfig) -> None", - "doc": "Constructor using Deck, EclipseState, Schedule, and SummaryConfig objects.\n\n:param deck: Deck object.\n:type deck: Deck\n:param state: EclipseState object.\n:type state: EclipseState\n:param schedule: Schedule object.\n:type schedule: Schedule\n:param summary_config: SummaryConfig object.\n:type summary_config: SummaryConfig" - }, - "advance": { - "signature": "advance(report_step: int) -> None", - "doc": "Advance the simulation to a specific report step.\n\n:param report_step: Target report step to advance to.\n:type report_step: int" - }, - "checkSimulationFinished": { - "signature": "check_simulation_finished() -> bool", - "doc": "Check if the simulation has finished.\n\n:return: True if the simulation is finished, False otherwise." - }, - "currentStep": { - "signature": "current_step() -> int", - "doc": "Get the current simulation step.\n\n:return: The current step number." - }, - "getCellVolumes": { - "signature": "get_cell_volumes() -> NDArray[float]", - "doc": "Retrieve the cell volumes of the simulation grid.\n\n:return: An array of cell volumes.\n:type return: NDArray[float]" - }, - "getDT": { - "signature": "get_dt() -> float", - "doc": "Get the timestep size of the last completed step.\n\n:return: Timestep size in days.\n:type return: float" - }, - "getFluidStateVariables": { - "signature": "get_fluid_state_variables(name: str) -> NDArray[float]", - "doc": "Retrieve a fluid state variable for the simulation grid.\n\n:para name: The name of the variable. Valid names are 'pw' (pressure water), 'pg' (pressure gas), 'po' (pressure oil), 'rho_w' (density water), 'rho_g' (density gas), 'rho_o' (density oil)'Rs' (soultion gas-oil ratio), 'Rv' (volatile gas-oil ratio), 'Sw' (water saturation), 'Sg' (gas saturation), 'So' (oil saturation), and 'T' (temperature).\n:type name: str\n\n:return: An array of fluid state variables.\n:type return: NDArray[float]" - }, - "getPorosity": { - "signature": "get_porosity() -> numpy.ndarray", - "doc": "Retrieve the porosity values of the simulation grid.\n\n:return: An array of porosity values.\n:type return: numpy.ndarray" - }, - "getPrimaryVarMeaning": { - "signature": "get_primary_var_meaning(variable: str) -> NDArray[int]", - "doc": "Retrieve the primary variable meaning of the simulation grid.\n\n:para variable: The name of the variable. Valid names are 'pressure', 'water', 'gas', and 'brine'.\n:type variable: str\n\n:return: An array of primary variable meanings. See ``get_primary_variable_meaning_map()`` for more information.\n:type return: NDArray[int]" - }, - "getPrimaryVarMeaningMap": { - "signature": "get_primary_var_meaning_map(variable: str) -> dict[str, int]", - "doc": "Retrieve the primary variable meaning map for each primary variable.\n\n:para variable: The name of the variable. Valid names are 'pressure', 'water', 'gas', and 'brine'.\n:type variable: str\n\n:return: A dictionary of primary variable meanings. The keys are the primary variable meanings and the values are the corresponding integer codes. The integer codes are used to represent the primary variable meanings in the simulation grid. For variable name 'pressure', the valid keys are: 'Po', 'Pg', and 'Pw', for variable name 'water', the valid keys are: 'Sw', 'Rvw', 'Rsw', and 'Disabled', for variable name 'gas', the valid keys are: 'Sg', 'Rs', 'Rv', and 'Disabled', for variable name 'brine', the valid keys are: 'Cs', 'Sp', and 'Disabled'.\n:type return: dict[str, int]" - }, - "getPrimaryVariable": { - "signature": "get_primary_variable(variable: str) -> NDArray[float]", - "doc": "Retrieve the primary variable's values for the simulation grid.\n\n:para variable: The name of the variable. Valid names are 'pressure', 'water', 'gas', and 'brine'.\n:type variable: str\n\n:return: An array of primary variable values. See ``get_primary_variable_meaning()`` for more information.\n:type return: NDArray[float]" - }, - "run": { - "signature": "run() -> int", - "doc": "Runs the simulation to completion with the provided deck file or previously set deck.\n\n:return: EXIT_SUCCESS if the simulation completes successfully." - }, - "setPorosity": { - "signature": "set_porosity(array: NDArray[float]) -> None", - "doc": "Set the porosity values for the simulation grid.\n\n:param array: An array of porosity values to be set.\n:type array: NDArray[float]" - }, - "setPrimaryVariable": { - "signature": "set_primary_variable(variable: str, value: NDArray[float]) -> None", - "doc": "Set the primary variable's values for the simulation grid.\n\n:para variable: The name of the variable. Valid names are 'pressure', 'water', 'gas', and 'brine'.\n:type variable: str\n:para value: An array of primary variable values to be set. See ``get_primary_variable()`` for more information.\n:type value: NDArray[float]" - }, - "step": { - "signature": "step() -> int", - "doc": "Execute the next simulation report step.\n\n:return: Result of the simulation step." - }, - "stepCleanup": { - "signature": "step_cleanup() -> int", - "doc": "Perform cleanup after the last simulation step.\n\n:return: EXIT_SUCCESS if cleanup is successful." - }, - "stepInit": { - "signature": "step_init() -> int", - "doc": "Initialize the simulation before taking the first report step. This method should be called before the first call to ``step()``\n\n:return: EXIT_SUCCESS if the initialization is successful." - } -} \ No newline at end of file diff --git a/docs/docstrings_common.json b/docs/docstrings_common.json new file mode 100644 index 0000000..8ef531a --- /dev/null +++ b/docs/docstrings_common.json @@ -0,0 +1,155 @@ +{ + "SummaryStateClass":{ + "type": "class", + "signature": "opm.io.sim.SummaryState", + "doc": "The SummaryState class - this is where the current summary results of the simulator are stored.\nThe SummaryState class has methods to get hold of well, group and general variables." + }, + "SummaryState_update_well_var": { + "signature": "opm.io.sim.SummaryState.update_well_var(well_name: str, variable_name: str, new_value: double) -> None", + "doc": "Update the variable of a well.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param variable_name: The name of the variable to update.\n:type variable_name: str\n:param new_value: The new value of the variable.\n:type new_value: double" + }, + "SummaryState_update_group_var": { + "signature": "opm.io.sim.SummaryState.update_group_var(group_name: str, variable_name: str, new_value: double) -> None", + "doc": "Update the variable of a group.\n\n:param group_name: The name of the group.\n:type group_name: str\n:param variable_name: The name of the variable to update.\n:type variable_name: str\n:param new_value: The new value of the variable.\n:type new_value: double" + }, + "SummaryState_well_var": { + "signature": "opm.io.sim.SummaryState.well_var(well_name: str, variable_name: str) -> double", + "doc": "Get the value of a variable for a well.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param variable_name: The name of the variable to retrieve.\n:type variable_name: str\n\n:return: The value of the specified variable for the well. \n:type return: double" + }, + "SummaryState_group_var": { + "signature": "opm.io.sim.SummaryState.group_var(group_name: str, variable_name: str) -> double", + "doc": "Get the value of a variable for a group.\n\n:param group_name: The name of the group.\n:type group_name: str\n:param variable_name: The name of the variable to retrieve.\n:type variable_name: str\n\n:return: The value of the specified variable for the group. \n:type return: double" + }, + "SummaryState_elapsed": { + "signature": "opm.io.sim.SummaryState.elapsed() -> double", + "doc": "Return the elapsed time in seconds of the current simulation.\n\n:return: The elapsed time in seconds. \n:type return: double" + }, + "SummaryState_groups": { + "signature": "opm.io.sim.SummaryState.groups -> list", + "doc": "Return a list of strings containing all group names.\n\n:return: A list of strings representing all group names. \n:type return: list" + }, + "SummaryState_wells": { + "signature": "opm.io.sim.SummaryState.wells -> list", + "doc": "Return a list of strings containing all well names.\n\n:return: A list of strings representing all well names. \n:type return: list" + }, + "SummaryState_has_well_var": { + "signature": "opm.io.sim.SummaryState.has_well_var(well_name: str, variable_name: str) -> bool", + "doc": "Check if a well variable exists.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param variable_name: The name of the variable to check.\n:type variable_name: str\n\n:return: True if the variable exists for the well, False otherwise. \n:type return: bool" + }, + "SummaryState_has_group_var": { + "signature": "opm.io.sim.SummaryState.has_group_var(group_name: str, variable_name: str) -> bool", + "doc": "Check if a group variable exists.\n\n:param group_name: The name of the group.\n:type group_name: str\n:param variable_name: The name of the variable to check.\n:type variable_name: str\n\n:return: True if the variable exists for the group, False otherwise. \n:type return: bool" + }, + "EclipseStateClass": { + "type": "class", + "signature": "opm.io.ecl_state.EclipseState", + "doc": "The EclipseState class - this is a representation of all static properties in the model,ranging from porosity to relperm tables.\nThe content of the EclipseState is immutable and may not be changed at runtime." + }, + "EclipseState_input_nnc": { + "signature": "opm.io.ecl_state.EclipseState.input_nnc() -> list", + "doc": "Returns a list of non-neighboring connections.\n\nOne non-neighboring connection is a tuple containing the following elements:\n- index1 (int): Index of the first cell.\n- index2 (int): Index of the second cell.\n- transmissibility (double): Transmissibility between the two cells.\n\n:return: A list of non-neighboring connections. \n:type return: list" + }, + "EclipseState_faultNames": { + "signature": "opm.io.ecl_state.EclipseState.faultNames() -> list", + "doc": "Returns a list of fault names.\n\n:return: A list containing the names of faults. \n:type return: list" + }, + "EclipseState_faultFaces": { + "signature": "opm.io.ecl_state.EclipseState.faultFaces(fault_name: str) -> list", + "doc": "Returns a list of faces of a fault with the given name.\n\n:param fault_name: The name of the fault.\n:type fault_name: str\n\n:return: A list containing the faces of the specified fault. \n:type return: list" + }, + "EclipseState_jfunc": { + "signature": "opm.io.ecl_state.EclipseState.jfunc() -> dict", + "doc": "Function returning a dictionary with the following entries: ['FLAG', 'DIRECTION', 'ALPHA_FACTOR', 'BETA_FACTOR', 'OIL_WATER', 'GAS_OIL']\n\n:return: A dictionary containing the specified entries. \n:type return: dict" + }, + "EclipseState_simulation": { + "signature": "opm.io.ecl_state.EclipseState.simulation() -> SimulationConfiguration", + "doc": "Returns the simulation configuration.\n\n:return: The simulation configuration. \n:type return: SimulationConfiguration" + }, + "ScheduleClass": { + "type": "class", + "signature": "opm.io.schedule.Schedule", + "doc": "The Schedule class - this is a representation of all the content from the SCHEDULE section, notably all well and group information and the timestepping." + }, + "Schedule_getitem": { + "signature": "opm.io.schedule.Schedule.__getitem__(report_step: int) -> ScheduleState", + "doc": "Return the ScheduleState at the given report step.\n\n:param report_step: The report step.\n:type report_step: int\n\n:return: The ScheduleState at the given report step.\n:type return: ScheduleState" + }, + "Schedule_shut_well_well_name_step": { + "signature": "opm.io.schedule.Schedule.shut_well(well_name: str, step: int) -> None", + "doc": "Shut down a well at a given report step.\n\n:param well_name: The name of the well to shut down.\n:type well_name: str\n:param step: The report step at which to shut down the well.\n:type step: int" + }, + "Schedule_shut_well_well_name": { + "signature": "opm.io.schedule.Schedule.shut_well(well_name: str) -> None", + "doc": "Shut down a well at the current report step.\n\n:param well_name: The name of the well to shut down.\n:type well_name: str" + }, + "Schedule_open_well_well_name_step": { + "signature": "opm.io.schedule.Schedule.open_well(well_name: str, step: int) -> None", + "doc": "Open a well at a given report step.\n\n:param well_name: The name of the well to open.\n:type well_name: str\n:param step: The report step at which to open the well.\n:type step: int\n:raises ValueError: If the report step is in the past or exceeds the duration of the simulation." + }, + "Schedule_open_well_well_name": { + "signature": "opm.io.schedule.Schedule.open_well(well_name: str) -> None", + "doc": "Open a well at the current report step.\n\n:param well_name: The name of the well to open.\n:type well_name: str" + }, + "Schedule_stop_well_well_name_step":{ + "signature": "opm.io.schedule.Schedule.stop_well(well_name: str, step: int) -> None", + "doc": "Stop a well at a given report step.\n\n:param well_name: The name of the well to stop.\n:type well_name: str\n:param step: The report step at which to stop the well.\n:type step: int\n:raises ValueError: If the report step is in the past or exceeds the duration of the simulation." + }, + "Schedule_stop_well_well_name": { + "signature": "opm.io.schedule.Schedule.stop_well(well_name: str) -> None", + "doc": "Stop a well at the current report step.\n\n:param well_name: The name of the well to stop.\n:type well_name: str" + }, + "Schedule_get_injection_properties": { + "signature": "opm.io.schedule.Schedule.get_injection_properties(well_name: str, report_step: int) -> dict", + "doc": "Get injection properties for a well at a specific report step.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param report_step: The report step to retrieve properties for.\n:type report_step: int\n\n:return: A dict containing the properties surf_inj_rate, resv_inj_rate, bhp_target, thp_target. \n:type return: dict" + }, + "Schedule_get_production_properties": { + "signature": "opm.io.schedule.Schedule.get_production_properties(well_name: str, report_step: int) -> dict", + "doc": "Get production properties for a well at a specific report step.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param report_step: The report step to retrieve properties for.\n:type report_step: int\n\n:return: A dict containing the properties oil_rate, gas_rate, water_rate, liquid_rate, resv_rate, bhp_target, thp_target, alq_value. \n:type return: dict" + }, + "Schedule_groups": { + "signature": "opm.io.schedule.Schedule._groups(report_step: int) -> list", + "doc": "Get a list of all groups at a specified report step.\n\n:param report_step: The report step to retrieve groups for.\n:type report_step: int\n\n:return: A list containing all groups at the specified report step. \n:type return: list" + }, + "Schedule_get_well": { + "signature": "opm.io.schedule.Schedule.get_well(well_name: str, report_step: int) -> Well", + "doc": "Retrieve a well at a given report step.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param report_step: The report step.\n:type report_step: int\n\n:return: Well object at the given report step. \n:type return: well" + }, + "Schedule_get_wells": { + "signature": "opm.io.schedule.Schedule.get_wells(well_name_pattern: str) -> list", + "doc": "Get the names of wells matching a specified pattern.\n\n:param well_name_pattern: The pattern for well names, where '*' acts as a wildcard.\n:type well_name_pattern: str\n\n:return: A list containing the names of wells that match the specified pattern. \n:type return: list" + }, + "ScheduleStateClass": { + "signature": "ScheduleState", + "type": "class", + "doc": "The ScheduleState class." + }, + "ScheduleState_nupcol": { + "signature": "ScheduleState.nupcol", + "doc": "The NUPCOL value at this Schedule State. This is a positive integer that defines the maximum number of Newton iterations used to update well targets within a time step." + }, + "ScheduleState_get_group": { + "signature": "ScheduleState.get_group(group_name: str) -> group", + "doc": "Get the group with the specified name from the schedule state.\n\n:param group_name: The name of the group to retrieve from the schedule state.\n:type group_name: str\n\n:return: The group with the specified name from the schedule state. \n:type return: group" + }, + "WellClass": { + "type": "class", + "signature": "Well", + "doc": "The Well class." + }, + "Well_pos": { + "signature": "Well.pos() -> tuple", + "doc": "Retrieve the position of the well.\n\n:return: A tuple containing the (i, j) coordinates and the reference depth of the well. \n:type return: tuple" + }, + "Well_isdefined": { + "signature": "Well.isdefined(report_step: int) -> bool", + "doc": "Check if the well is defined at a specific report step.\n\n:param report_step: The report step to check for the well's definition.\n:type report_step: int\n\n:return: True if the well is defined at the specified report step, False otherwise. \n:type return: bool" + }, + "Well_available_gctrl": { + "signature": "Well.available_gctrl() -> bool", + "doc": "Check if the well is available for group control.\n\n:return: True if the well is available for group control, False otherwise. \n:type return: bool" + }, + "Well_connections": { + "signature": "Well.connections() -> list", + "doc": "Get a list of all connections associated with the well.\n\n:return: A list containing all connections of the well. \n:type return: list" + } +} diff --git a/docs/docstrings_simulators.json b/docs/docstrings_simulators.json new file mode 100644 index 0000000..93e656c --- /dev/null +++ b/docs/docstrings_simulators.json @@ -0,0 +1,83 @@ +{ + "PyBlackOilSimulator":{ + "type": "class", + "signature": "opm.simulators.BlackOilSimulator", + "doc": "The BlackOilSimulator." + }, + "PyBlackOilSimulator_filename_constructor": { + "signature": "opm.simulators.BlackOilSimulator.__init__(deck_filename: str) -> None", + "doc": "Constructor using a deck file name.\n\n:param deck_filename: The file name of the deck to be used for the simulation.\n:type deck_filename: str" + }, + "PyBlackOilSimulator_objects_constructor": { + "signature": "opm.simulators.BlackOilSimulator.__init__(deck: Deck, state: EclipseState, schedule: Schedule, summary_config: SummaryConfig) -> None", + "doc": "Constructor using Deck, EclipseState, Schedule, and SummaryConfig objects.\n\n:param deck: Deck object.\n:type deck: Deck\n:param state: EclipseState object.\n:type state: EclipseState\n:param schedule: Schedule object.\n:type schedule: Schedule\n:param summary_config: SummaryConfig object.\n:type summary_config: SummaryConfig" + }, + "advance": { + "signature": "opm.simulators.BlackOilSimulator.advance(report_step: int) -> None", + "doc": "Advance the simulation to a specific report step.\n\n:param report_step: Target report step to advance to.\n:type report_step: int" + }, + "checkSimulationFinished": { + "signature": "opm.simulators.BlackOilSimulator.check_simulation_finished() -> bool", + "doc": "Check if the simulation has finished.\n\n:return: True if the simulation is finished, False otherwise." + }, + "currentStep": { + "signature": "opm.simulators.BlackOilSimulator.current_step() -> int", + "doc": "Get the current simulation step.\n\n:return: The current step number." + }, + "getCellVolumes": { + "signature": "opm.simulators.BlackOilSimulator.get_cell_volumes() -> NDArray[float]", + "doc": "Retrieve the cell volumes of the simulation grid.\n\n:return: An array of cell volumes.\n:type return: NDArray[float]" + }, + "getDT": { + "signature": "opm.simulators.BlackOilSimulator.get_dt() -> float", + "doc": "Get the timestep size of the last completed step.\n\n:return: Timestep size in days.\n:type return: float" + }, + "getFluidStateVariable": { + "signature": "opm.simulators.BlackOilSimulator.get_fluid_state_variable(name: str) -> NDArray[float]", + "doc": "Retrieve a fluid state variable for the simulation grid.\n\n:param name: The name of the variable. Valid names are 'pw' (pressure water), 'pg' (pressure gas), 'po' (pressure oil), 'rho_w' (density water), 'rho_g' (density gas), 'rho_o' (density oil)'Rs' (soultion gas-oil ratio), 'Rv' (volatile gas-oil ratio), 'Sw' (water saturation), 'Sg' (gas saturation), 'So' (oil saturation), and 'T' (temperature).\n:type name: str\n\n:return: An array of fluid state variables.\n:type return: NDArray[float]" + }, + "getPorosity": { + "signature": "opm.simulators.BlackOilSimulator.get_porosity() -> numpy.ndarray", + "doc": "Retrieve the porosity values of the simulation grid.\n\n:return: An array of porosity values.\n:type return: numpy.ndarray" + }, + "getPrimaryVarMeaning": { + "signature": "opm.simulators.BlackOilSimulator.get_primary_var_meaning(variable: str) -> NDArray[int]", + "doc": "Retrieve the primary variable meaning of the simulation grid.\n\n:param variable: The name of the variable. Valid names are 'pressure', 'water', 'gas', and 'brine'.\n:type variable: str\n\n:return: An array of primary variable meanings. See ``get_primary_variable_meaning_map()`` for more information.\n:type return: NDArray[int]" + }, + "getPrimaryVarMeaningMap": { + "signature": "opm.simulators.BlackOilSimulator.get_primary_var_meaning_map(variable: str) -> dict[str, int]", + "doc": "Retrieve the primary variable meaning map for each primary variable.\n\n:param variable: The name of the variable. Valid names are 'pressure', 'water', 'gas', and 'brine'.\n:type variable: str\n\n:return: A dictionary of primary variable meanings. The keys are the primary variable meanings and the values are the corresponding integer codes. The integer codes are used to represent the primary variable meanings in the simulation grid. For variable name 'pressure', the valid keys are: 'Po', 'Pg', and 'Pw', for variable name 'water', the valid keys are: 'Sw', 'Rvw', 'Rsw', and 'Disabled', for variable name 'gas', the valid keys are: 'Sg', 'Rs', 'Rv', and 'Disabled', for variable name 'brine', the valid keys are: 'Cs', 'Sp', and 'Disabled'.\n:type return: dict[str, int]" + }, + "getPrimaryVariable": { + "signature": "opm.simulators.BlackOilSimulator.get_primary_variable(variable: str) -> NDArray[float]", + "doc": "Retrieve the primary variable's values for the simulation grid.\n\n:param variable: The name of the variable. Valid names are 'pressure', 'water', 'gas', and 'brine'.\n:type variable: str\n\n:return: An array of primary variable values. See ``get_primary_variable_meaning()`` for more information.\n:type return: NDArray[float]" + }, + "run": { + "signature": "opm.simulators.BlackOilSimulator.run() -> int", + "doc": "Runs the simulation to completion with the provided deck file or previously set deck.\n\n:return: EXIT_SUCCESS if the simulation completes successfully." + }, + "setPorosity": { + "signature": "opm.simulators.BlackOilSimulator.set_porosity(array: NDArray[float]) -> None", + "doc": "Set the porosity values for the simulation grid.\n\n:param array: An array of porosity values to be set.\n:type array: NDArray[float]" + }, + "setPrimaryVariable": { + "signature": "opm.simulators.BlackOilSimulator.set_primary_variable(variable: str, value: NDArray[float]) -> None", + "doc": "Set the primary variable's values for the simulation grid.\n\n:param variable: The name of the variable. Valid names are 'pressure', 'water', 'gas', and 'brine'.\n:type variable: str\n:param value: An array of primary variable values to be set. See ``get_primary_variable()`` for more information.\n:type value: NDArray[float]" + }, + "setupMpi": { + "signature": "opm.simulators.BlackOilSimulator.mpi_init(init: bool, finalize: bool) -> None", + "doc": "Setup MPI for parallel simulation. This method should be called before any other method.\n:param init: Whether to call ``MPI_Init()`` or not.\n:param finalize:Whether to call ``MPI_Finalize()```when the simulator object goes out of scope.\n\n:return: None" + }, + "step": { + "signature": "opm.simulators.BlackOilSimulator.step() -> int", + "doc": "Execute the next simulation report step.\n\n:return: Result of the simulation step." + }, + "stepCleanup": { + "signature": "opm.simulators.BlackOilSimulator.step_cleanup() -> int", + "doc": "Perform cleanup after the last simulation step.\n\n:return: EXIT_SUCCESS if cleanup is successful." + }, + "stepInit": { + "signature": "opm.simulators.BlackOilSimulator.step_init() -> int", + "doc": "Initialize the simulation before taking the first report step. This method should be called before the first call to ``step()``\n\n:return: EXIT_SUCCESS if the initialization is successful." + } +} diff --git a/docs/src/opm_python_docs/sphinx_ext_docstrings.py b/docs/src/opm_python_docs/sphinx_ext_docstrings.py index c323604..e951771 100644 --- a/docs/src/opm_python_docs/sphinx_ext_docstrings.py +++ b/docs/src/opm_python_docs/sphinx_ext_docstrings.py @@ -4,43 +4,57 @@ from sphinx.util.docutils import SphinxDirective from docutils import nodes -class PybindDocstringsDirective(SphinxDirective): +def readDocStrings(directive, docstrings_path): + print(docstrings_path) + with open(docstrings_path, 'r') as file: + docstrings = json.load(file) + result = [] + for name, item in docstrings.items(): + # Create a ViewList instance for the function signature and docstring + rst = ViewList() + + # Check if signature exists and prepend it to the docstring + signature = item.get('signature', '') + item_type = item.get('type', 'method') + signature_line = f".. py:{item_type}:: {signature}" if signature else f".. py:{item_type}:: {name}()" + rst.append(signature_line, source="") + rst.append("", source="") + + # Add the docstring text if it exists + docstring = item.get('doc', '') + if docstring: + for line in docstring.split('\n'): + rst.append(f" {line}", source="") + + # Create a node that will be populated by nested_parse_with_titles + node = nodes.section() + node.document = directive.state.document + # Parse the rst content + nested_parse_with_titles(directive.state, rst, node) + + result.extend(node.children) + return result + +class SimulatorsDirective(SphinxDirective): + required_arguments = 0 + optional_arguments = 0 + final_argument_whitespace = False + option_spec = {} + + def run(self): + return readDocStrings(self, self.state.document.settings.env.app.config.opm_simulators_docstrings_path) + +class CommonDirective(SphinxDirective): required_arguments = 0 optional_arguments = 0 final_argument_whitespace = False option_spec = {} def run(self): - env = self.state.document.settings.env - docstrings_path = env.app.config.opm_python_docstrings_path - with open(docstrings_path, 'r') as file: - docstrings = json.load(file) - result = [] - for func_name, doc_info in docstrings.items(): - signature = doc_info.get('signature', '') - docstring = doc_info.get('doc', '') - - # Create a ViewList instance for the function signature and docstring - rst = ViewList() - - # Check if signature exists and prepend it to the docstring - signature_line = f".. py:function:: {signature}" if signature else f".. py:function:: {func_name}()" - rst.append(signature_line, source="") - rst.append("", source="") - # Add the docstring text if it exists - if docstring: - for line in docstring.split('\n'): - rst.append(f" {line}", source="") - - # Create a node that will be populated by nested_parse_with_titles - node = nodes.section() - node.document = self.state.document - # Parse the rst content - nested_parse_with_titles(self.state, rst, node) - - result.extend(node.children) - return result + return readDocStrings(self, self.state.document.settings.env.app.config.opm_common_docstrings_path) def setup(app): - app.add_config_value('opm_python_docstrings_path', None, 'env') - app.add_directive("opm_python_docstrings", PybindDocstringsDirective) + app.add_config_value('opm_simulators_docstrings_path', None, 'env') + app.add_config_value('opm_common_docstrings_path', None, 'env') + app.add_directive("opm_simulators_docstrings", SimulatorsDirective) + app.add_directive("opm_common_docstrings", CommonDirective) diff --git a/helper_scripts/generate_docstring_hpp.py b/helper_scripts/generate_docstring_hpp.py index 9c1d7f6..c9203fc 100755 --- a/helper_scripts/generate_docstring_hpp.py +++ b/helper_scripts/generate_docstring_hpp.py @@ -1,41 +1,42 @@ import json import sys -def generate_hpp_from_json(json_path: str, output_hpp_path: str): +def generate_hpp_from_json(json_path: str, output_hpp_path: str, macro: str, namespace: str): with open(json_path, 'r', encoding='utf-8') as file: docstrings = json.load(file) - hpp_content = """\ -#ifndef PYBLACKOILSIMULATORDOC_HPP -#define PYBLACKOILSIMULATORDOC_HPP + hpp_content = f"""\ +#ifndef {macro} +#define {macro} -// Generated docstrings for PyBlackOilSimulator -namespace Opm::Pybind::DocStrings { -""" +// Generated docstrings +namespace {namespace} """ + hpp_content += "{" for func_name, info in docstrings.items(): - signature = info['signature'] doc = info['doc'].replace('\n', '\n ') hpp_content += f""" static constexpr char {func_name}_docstring[] = R\"doc( {doc} )doc\";\n""" + hpp_content += "}" + hpp_content += f"""\ + // namespace {namespace} - hpp_content += """\ -} // namespace Opm::Pybind::DocStrings - -#endif // PYBLACKOILSIMULATORDOC_HPP +#endif // {macro} """ with open(output_hpp_path, 'w', encoding='utf-8') as file: file.write(hpp_content) if __name__ == "__main__": - # Check that exactly two command line arguments are provided - if len(sys.argv) != 3: - print("Usage: python generate_docstring_hpp.py ") + # Check that exactly three command line arguments are provided + if len(sys.argv) != 5: + print("Usage: python generate_docstring_hpp.py ") sys.exit(1) # Extract json_path and output_hpp_path from command line arguments json_path = sys.argv[1] output_hpp_path = sys.argv[2] - generate_hpp_from_json(json_path, output_hpp_path) + macro = sys.argv[3] + namespace = sys.argv[4] + generate_hpp_from_json(json_path, output_hpp_path, macro, namespace) diff --git a/pybind11/opmcommon/eclipse_state.cpp b/pybind11/opmcommon/eclipse_state.cpp index 5fd4874..e0ee1ca 100644 --- a/pybind11/opmcommon/eclipse_state.cpp +++ b/pybind11/opmcommon/eclipse_state.cpp @@ -5,6 +5,9 @@ #include "export.hpp" +// NOTE: This file will be generated at compile time and placed in the build directory +// See python/generate_docstring_hpp.py, and python/simulators/CMakeLists.txt for details +#include "OpmCommonPythonDoc.hpp" namespace { @@ -96,6 +99,8 @@ namespace { void python::common::export_EclipseState(py::module& module) { + using namespace Opm::Common::DocStrings; + // Note: In the below class we std::shared_ptr as the holder type, see: // // https://pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html @@ -103,10 +108,7 @@ void python::common::export_EclipseState(py::module& module) { // this makes it possible to share the returned object with e.g. and // opm.simulators.BlackOilSimulator Python object // - py::class_< EclipseState, std::shared_ptr >( module, "EclipseState", R"pbdoc( - The Opm::EclipseState class - this is a representation of all static properties in the model, - ranging from porosity to relperm tables. The content of the EclipseState is immutable and may not - be changed at runtime.)pbdoc") + py::class_< EclipseState, std::shared_ptr >( module, "EclipseState", EclipseStateClass_docstring) .def(py::init()) .def_property_readonly( "title", &EclipseState::getTitle ) .def( "field_props", &get_field_props, ref_internal) @@ -114,11 +116,11 @@ void python::common::export_EclipseState(py::module& module) { .def( "config", &EclipseState::cfg, ref_internal) .def( "tables", &EclipseState::getTableManager, ref_internal) .def( "has_input_nnc", &EclipseState::hasInputNNC ) - .def( "simulation", &EclipseState::getSimulationConfig, ref_internal) - .def( "input_nnc", &getNNC ) - .def( "faultNames", &faultNames ) - .def( "faultFaces", &faultFaces, py::arg("fault_name")) - .def( "jfunc", &jfunc ) + .def( "simulation", &EclipseState::getSimulationConfig, ref_internal, EclipseState_simulation_docstring) + .def( "input_nnc", &getNNC, EclipseState_input_nnc_docstring) + .def( "faultNames", &faultNames, EclipseState_faultNames_docstring) + .def( "faultFaces", &faultFaces, py::arg("fault_name"), EclipseState_faultFaces_docstring) + .def( "jfunc", &jfunc, EclipseState_jfunc_docstring) ; } diff --git a/pybind11/opmcommon/schedule.cpp b/pybind11/opmcommon/schedule.cpp index a8f6c14..a51f42f 100644 --- a/pybind11/opmcommon/schedule.cpp +++ b/pybind11/opmcommon/schedule.cpp @@ -16,6 +16,9 @@ #include #include "export.hpp" +// NOTE: This file will be generated at compile time and placed in the build directory +// See python/generate_docstring_hpp.py, and python/simulators/CMakeLists.txt for details +#include "OpmCommonPythonDoc.hpp" namespace { @@ -192,6 +195,8 @@ namespace { void python::common::export_Schedule(py::module& module) { + using namespace Opm::Common::DocStrings; + // Note: In the below class we use std::shared_ptr as the holder type, see: // // https://pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html @@ -199,88 +204,25 @@ void python::common::export_Schedule(py::module& module) { // this makes it possible to share the returned object with e.g. and // opm.simulators.BlackOilSimulator Python object // - py::class_< Schedule, std::shared_ptr >( module, "Schedule", R"pbdoc( - The Opm::Schedule class - this is a representation of all the content from - the SCHEDULE section, notably all well and group information and the timestepping. - )pbdoc") + py::class_< Schedule, std::shared_ptr >( module, "Schedule", ScheduleClass_docstring) .def(py::init(), py::arg("deck"), py::arg("eclipse_state")) - .def("_groups", &get_groups, py::arg("report_step")) + .def("_groups", &get_groups, py::arg("report_step"), Schedule_groups_docstring) .def_property_readonly( "start", &get_start_time ) .def_property_readonly( "end", &get_end_time ) .def_property_readonly( "timesteps", &get_timesteps ) .def("__len__", &Schedule::size) - .def("__getitem__", &getitem) - .def("shut_well", py::overload_cast(&Schedule::shut_well), py::arg("well_name"), py::arg("step"), R"( - Shut down a well at a given report step. - - Args: - well_name (str): The name of the well to shut down. - report_step (int): The report step at which to shut down the well. - - Raises: - ValueError: If the report step is in the past or exceeds the duration of the simulation. - - Returns: - None - )") - .def("shut_well", py::overload_cast(&Schedule::shut_well), py::arg("well_name"), R"( - Shut down a well at the current report step. - - Args: - well_name (str): The name of the well to shut down. - - Returns: - None - )") - .def("open_well", py::overload_cast(&Schedule::open_well), py::arg("well_name"), py::arg("step"), R"( - Open a well at a given report step. - - Args: - well_name (str): The name of the well to open. - report_step (int): The report step at which to open the well. - - Raises: - ValueError: If the report step is in the past or exceeds the duration of the simulation. - - Returns: - None - )") - .def("open_well", py::overload_cast(&Schedule::open_well), py::arg("well_name"), R"( - Open a well at the current report step. - - Args: - well_name (str): The name of the well to open. - - Returns: - None - )") - .def("stop_well", py::overload_cast(&Schedule::stop_well), py::arg("well_name"), py::arg("step"), R"( - Stop a well at a given report step. - - Args: - well_name (str): The name of the well to stop. - report_step (int): The report step at which to stop the well. - - Raises: - ValueError: If the report step is in the past or exceeds the duration of the simulation. - - Returns: - None - )") - .def("stop_well", py::overload_cast(&Schedule::stop_well), py::arg("well_name"), R"( - Stop a well at the current report step. - - Args: - well_name (str): The name of the well to stop. - - Returns: - None - )") - .def( "get_wells", &Schedule::getWells, py::arg("well_name_pattern")) - .def( "get_injection_properties", &get_injection_properties, py::arg("well_name"), py::arg("report_step")) - .def( "get_production_properties", &get_production_properties, py::arg("well_name"), py::arg("report_step")) + .def("__getitem__", &getitem, py::arg("report_step"), Schedule_getitem_docstring) + .def("shut_well", py::overload_cast(&Schedule::shut_well), py::arg("well_name"), py::arg("step"), Schedule_shut_well_well_name_step_docstring) + .def("shut_well", py::overload_cast(&Schedule::shut_well), py::arg("well_name"), Schedule_shut_well_well_name_docstring) + .def("open_well", py::overload_cast(&Schedule::open_well), py::arg("well_name"), py::arg("step"), Schedule_open_well_well_name_step_docstring) + .def("open_well", py::overload_cast(&Schedule::open_well), py::arg("well_name"), Schedule_open_well_well_name_docstring) + .def("stop_well", py::overload_cast(&Schedule::stop_well), py::arg("well_name"), py::arg("step"), Schedule_stop_well_well_name_step_docstring) + .def("stop_well", py::overload_cast(&Schedule::stop_well), py::arg("well_name"), Schedule_stop_well_well_name_docstring) + .def( "get_wells", &Schedule::getWells, py::arg("well_name_pattern"), Schedule_get_wells_docstring) + .def( "get_injection_properties", &get_injection_properties, py::arg("well_name"), py::arg("report_step"), Schedule_get_injection_properties_docstring) + .def( "get_production_properties", &get_production_properties, py::arg("well_name"), py::arg("report_step"), Schedule_get_production_properties_docstring) .def("well_names", py::overload_cast(&Schedule::wellNames, py::const_), py::arg("well_name_pattern")) - .def( "get_well", &get_well, py::arg("well_name"), py::arg("report_step")) + .def( "get_well", &get_well, py::arg("well_name"), py::arg("report_step"), Schedule_get_well_docstring) .def( "insert_keywords", py::overload_cast(&insert_keywords), py::arg("keywords"), py::arg("step")) .def( "insert_keywords", py::overload_cast(&insert_keywords), py::arg("data"), py::arg("step"), py::arg("unit_system")) .def( "insert_keywords", py::overload_cast(&insert_keywords), py::arg("data"), py::arg("step")) diff --git a/pybind11/opmcommon/schedule_state.cpp b/pybind11/opmcommon/schedule_state.cpp index a2e2451..138effb 100644 --- a/pybind11/opmcommon/schedule_state.cpp +++ b/pybind11/opmcommon/schedule_state.cpp @@ -2,6 +2,10 @@ #include "export.hpp" +// NOTE: This file will be generated at compile time and placed in the build directory +// See python/generate_docstring_hpp.py, and python/simulators/CMakeLists.txt for details +#include "OpmCommonPythonDoc.hpp" + namespace { const Group& get_group(const ScheduleState& st, const std::string& group_name) { return st.groups.get(group_name); @@ -18,8 +22,10 @@ namespace { */ void python::common::export_ScheduleState(py::module& module) { + using namespace Opm::Common::DocStrings; + py::class_(module, "ScheduleState") - .def_property_readonly("nupcol", py::overload_cast<>(&ScheduleState::nupcol, py::const_)) - .def("group", &get_group, ref_internal, py::arg("group_name")) + .def_property_readonly("nupcol", py::overload_cast<>(&ScheduleState::nupcol, py::const_), ScheduleState_nupcol_docstring) + .def("group", &get_group, ref_internal, py::arg("group_name"), ScheduleState_get_group_docstring) ; } diff --git a/pybind11/opmcommon/summary_state.cpp b/pybind11/opmcommon/summary_state.cpp index 56a0e01..2fc2283 100644 --- a/pybind11/opmcommon/summary_state.cpp +++ b/pybind11/opmcommon/summary_state.cpp @@ -25,6 +25,10 @@ #include #include "export.hpp" +// NOTE: This file will be generated at compile time and placed in the build directory +// See python/generate_docstring_hpp.py, and python/simulators/CMakeLists.txt for details +#include "OpmCommonPythonDoc.hpp" + namespace { @@ -42,22 +46,21 @@ std::vector wells(const SummaryState * st) { void python::common::export_SummaryState(py::module& module) { - py::class_>(module, "SummaryState", R"pbdoc( - The Opm::SummaryState class - this is where the current summary results of the simulator are stored. - The SummaryState class has methods to get hold of well, group and general variables. - )pbdoc") + using namespace Opm::Common::DocStrings; + + py::class_>(module, "SummaryState", SummaryStateClass_docstring) .def(py::init()) .def("update", &SummaryState::update) - .def("update_well_var", &SummaryState::update_well_var, py::arg("well_name"), py::arg("variable_name"), py::arg("new_value")) - .def("update_group_var", &SummaryState::update_group_var, py::arg("group_name"), py::arg("variable_name"), py::arg("new_value")) - .def("well_var", py::overload_cast(&SummaryState::get_well_var, py::const_), py::arg("well_name"), py::arg("variable_name")) - .def("group_var", py::overload_cast(&SummaryState::get_group_var, py::const_), py::arg("group_name"), py::arg("variable_name")) - .def("elapsed", &SummaryState::get_elapsed) - .def_property_readonly("groups", groups) - .def_property_readonly("wells", wells) + .def("update_well_var", &SummaryState::update_well_var, py::arg("well_name"), py::arg("variable_name"), py::arg("new_value"), SummaryState_update_well_var_docstring) + .def("update_group_var", &SummaryState::update_group_var, py::arg("group_name"), py::arg("variable_name"), py::arg("new_value"), SummaryState_update_group_var_docstring) + .def("well_var", py::overload_cast(&SummaryState::get_well_var, py::const_), py::arg("well_name"), py::arg("variable_name"), SummaryState_well_var_docstring) + .def("group_var", py::overload_cast(&SummaryState::get_group_var, py::const_), py::arg("group_name"), py::arg("variable_name"), SummaryState_group_var_docstring) + .def("elapsed", &SummaryState::get_elapsed, SummaryState_elapsed_docstring) + .def_property_readonly("groups", groups, SummaryState_groups_docstring) + .def_property_readonly("wells", wells, SummaryState_wells_docstring) .def("__contains__", &SummaryState::has) - .def("has_well_var", py::overload_cast(&SummaryState::has_well_var, py::const_), py::arg("well_name"), py::arg("variable_name")) - .def("has_group_var", py::overload_cast(&SummaryState::has_group_var, py::const_), py::arg("group_name"), py::arg("variable_name")) + .def("has_well_var", py::overload_cast(&SummaryState::has_well_var, py::const_), py::arg("well_name"), py::arg("variable_name"), SummaryState_has_well_var_docstring) + .def("has_group_var", py::overload_cast(&SummaryState::has_group_var, py::const_), py::arg("group_name"), py::arg("variable_name"), SummaryState_has_group_var_docstring) .def("__setitem__", &SummaryState::set) .def("__getitem__", py::overload_cast(&SummaryState::get, py::const_)) ; diff --git a/pybind11/opmcommon/well.cpp b/pybind11/opmcommon/well.cpp index 5b83d5f..f1533ee 100644 --- a/pybind11/opmcommon/well.cpp +++ b/pybind11/opmcommon/well.cpp @@ -5,6 +5,9 @@ #include #include "export.hpp" +// NOTE: This file will be generated at compile time and placed in the build directory +// See python/generate_docstring_hpp.py, and python/simulators/CMakeLists.txt for details +#include "OpmCommonPythonDoc.hpp" namespace { @@ -34,17 +37,19 @@ namespace { void python::common::export_Well(py::module& module) { + using namespace Opm::Common::DocStrings; + py::class_< Well >( module, "Well") .def_property_readonly( "name", &Well::name ) .def_property_readonly( "preferred_phase", &preferred_phase ) - .def( "pos", &get_pos ) + .def( "pos", &get_pos, Well_pos_docstring) .def( "status", &status ) - .def( "isdefined", &Well::hasBeenDefined ) + .def( "isdefined", &Well::hasBeenDefined, Well_isdefined_docstring) .def( "isinjector", &Well::isInjector ) .def( "isproducer", &Well::isProducer ) .def( "group", &Well::groupName ) .def( "guide_rate", &Well::getGuideRate ) - .def( "available_gctrl", &Well::isAvailableForGroupControl ) - .def( "connections", &connections ); + .def( "available_gctrl", &Well::isAvailableForGroupControl, Well_available_gctrl_docstring) + .def( "connections", &connections, Well_connections_docstring); } diff --git a/src/opm_embedded/__init__.pyi b/src/opm_embedded/__init__.pyi index b8a4443..913628e 100644 --- a/src/opm_embedded/__init__.pyi +++ b/src/opm_embedded/__init__.pyi @@ -2704,7 +2704,7 @@ class Schedule: def stop_well(self, well_name: str) -> None: ... def well_names(self, well_name_pattern: str) -> List[str]: ... def __contains__(self, well_name: str) -> bool: ... - def __getitem__(self, arg0: int) -> ScheduleState: ... + def __getitem__(self, report_step: int) -> ScheduleState: ... def __iter__(self) -> typing.Iterator[ScheduleState]: ... def __len__(self) -> int: ... @property