Repository navigation
Document UDQ support in PYACTION #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -169,3 +169,90 @@ Use this code snippet with the example `MSW-3D-TWO-PRODUCERS <https://github.com | |
| 'wellcontroller.py' / | ||
|
|
||
| to the ``SCHEDULE`` section of ``MSW-3D-TWO-PRODUCERS.DATA``. | ||
|
|
||
| Inserting user defined quantity (UDQ) keywords | ||
| ---------------------------------------------- | ||
|
|
||
| The ``UDQ`` keyword can be inserted from a PYACTION script. These features are supported: | ||
|
|
||
| - ``ASSIGN`` and ``DEFINE`` for field (``FU_``) and well (``WU_``) variables. | ||
| - Well variables for named wells, for example ``ASSIGN WU_FLAG 'OP01' 5 /``. | ||
| - New UDQ variables that are not declared in the DATA file. To write a new variable to | ||
| the summary output, list it in the SUMMARY section. | ||
|
|
||
| Inserting UDQ keywords | ||
| ~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import opm_embedded | ||
|
|
||
| summary_state = opm_embedded.current_summary_state | ||
| schedule = opm_embedded.current_schedule | ||
|
|
||
| # Run the insertion only once | ||
| if 'setup_done' not in globals(): | ||
| done = False | ||
| setup_done = True | ||
|
|
||
| wells = ["OP0{}".format(i) for i in range(1, 10)] | ||
| if not done and any(summary_state.well_var(w, "WGOR") >= summary_state["FU_GOR2"] for w in wells): | ||
| opm_embedded.OpmLog.info("PYACTION PYACTION_UDQ triggered") | ||
| schedule.insert_keywords(""" | ||
| UDQ | ||
| DEFINE WU_NEW WOPR * 2 / | ||
| ASSIGN WU_FLAG 'OP01' 5 / | ||
| / | ||
| """) | ||
| done = True | ||
|
|
||
| Here ``WU_NEW`` and ``WU_FLAG`` are already declared in the UDQ section of the DATA file. | ||
|
|
||
| Computing UDQ values in Python | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Instead of inserting the ``UDQ`` keyword, a PYACTION script can also compute the values | ||
| in Python and write them into the summary state. Then the DATA file needs no ``UDQ`` | ||
| keyword; the variables are only listed in the SUMMARY section, so they are written to | ||
| the summary output: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| summary_state = opm_embedded.current_summary_state | ||
|
|
||
| if "FU_TIME" not in summary_state: | ||
| summary_state["FU_TIME"] = 0.0 | ||
| summary_state["FU_TIME"] += summary_state["TIMESTEP"] | ||
| summary_state["FU_VAR19"] = summary_state.well_var("INJ1", "WWIR") | ||
|
|
||
| Complete examples in opm-tests, each with an ACTIONX version that gives the same results | ||
| (serial and with 4 MPI processes): | ||
|
|
||
| - Inserting UDQ keywords: | ||
| `PYACTION_UDQ_INSERT_KW.DATA <https://github.com/OPM/opm-tests/blob/master/pyaction/PYACTION_UDQ_INSERT_KW.DATA>`_ | ||
| with the script | ||
| `pyaction_udq_insert_kw.py <https://github.com/OPM/opm-tests/blob/master/pyaction/pyaction_udq_insert_kw.py>`_; | ||
| ACTIONX version | ||
| `ACTIONX_UDQ_INSERT_KW.DATA <https://github.com/OPM/opm-tests/blob/master/actionx/ACTIONX_UDQ_INSERT_KW.DATA>`_. | ||
| - Computing UDQ values in Python: | ||
| `UDQ_M3_PYACTION.DATA <https://github.com/OPM/opm-tests/blob/master/udq_pyaction/UDQ_M3_PYACTION.DATA>`_ | ||
| with the script | ||
| `udq_m3_pyaction.py <https://github.com/OPM/opm-tests/blob/master/udq_pyaction/udq_m3_pyaction.py>`_; | ||
| ACTIONX version | ||
| `UDQ_M3.DATA <https://github.com/OPM/opm-tests/blob/master/udq_actionx/UDQ_M3.DATA>`_. | ||
|
|
||
| .. warning:: | ||
|
|
||
| The well name ``'?'`` (for example ``ASSIGN WU_Q '?' 7 /``) is **not supported yet**. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a warning for the schedule or for the summary? Its position seems to make it as a warning for inserting quantities to the summary, but the contents show the scheduler.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is C++ error and Python pass it back as a runtime error. |
||
| In ACTIONX, ``'?'`` means the wells that matched the condition. A PYACTION script | ||
| has no ACTIONX condition, so Flow stops with | ||
| ``UDQ assignment for WU_Q does not have an associate match set``. | ||
| Instead, find the wells in Python and write their names into the string: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| wells = ["OP0{}".format(i) for i in range(1, 10)] | ||
| matched = [w for w in wells if summary_state.well_var(w, "WGOR") >= summary_state["FU_GOR2"]] | ||
| kw = "UDQ\n" + "".join(f"ASSIGN WU_Q '{w}' 7 /\n" for w in matched) + "/\n" | ||
| schedule.insert_keywords(kw) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when the user has more than one pyaction? Is this variable shared among all python scripts or is there one for each one? If there is only one globally, we need to be careful to advertise this generic variable name as it would only be initialized by the first script.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a very interesting point. I already tested it. The test result says that every pyaction has its own global
step_done. Let's say you have action_a.py and action_b.py. If action_a.py fires first, then we havedone = true. After that, checkstep_donein action_b.py; it is stillfalse.Should I have to add anything about this to the document?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SoilRos. I investigated whether this is the intention or a bug. The commit of Joakim in 2020. He said, "The purpose of this dictionary is to allow PYACTION scripts to store state between invocations". Claude found it.... In addition, the code in
PyRunModule.cppalso shows that each Python script has its own namespace. Each script is imported bypy::module::import(file name)andglobals()in Python is a dictionary of the module that the code is in.As I said before, this structure makes sense because the execution of script a.py should not immediately be the reason to stop the execution of b.py.
So, I will find the place to write this note. Still not sure where, because I think it is a topic outside UDQ.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be another pull request because it is a topic outside UDQ. What do you think @SoilRos