-
Notifications
You must be signed in to change notification settings - Fork 129
Reservoir coupling: Communicate group potentials from slaves and compute guide rates #6170
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
Conversation
|
I will run jenkins from the opm-common PR later |
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.
Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- CMakeLists_files.cmake: Language not supported
8b5a02c to
59daa3d
Compare
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.
Thanks a lot for the contribution. A few comments for now.
Note that this does not build without MPI.
| ReservoirCouplingSlave:: | ||
| serializePotentials_(const std::vector<Potentials>& potentials) const | ||
| { | ||
| std::vector<double> pot_vec; |
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.
mabe reserve the necessary space?
| auto num_slaves = this->master_.numSlavesStarted(); | ||
| auto master_groups = this->rescoup_.masterGroups(); |
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.
Are you copying these intentionally? Maybe use const references instead?
|
Unfortunately, this needs to be rebased on master it seems. |
8183220 to
51198a8
Compare
|
@blattms Thanks for the review with useful suggestions. I have added some commits to the PR to address the comments. I also added one commit to dump all guide rates to the debug file. |
|
I am sorry for the delay. Now this needs another rebase. |
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.
Thanks a lot for rebasing.
This is looks quite good already.
My main reservation is the introduction of a reference to the simulator in the time stepping. I would hope that there is another way.
| #ifdef RESERVOIR_COUPLING_ENABLED | ||
| if (this->isReservoirCouplingMaster()) { | ||
| this->guide_rate_handler_.receiveMasterGroupPotentialsFromSlaves(); | ||
| } | ||
| #endif | ||
| //update guide rates | ||
| const auto& comm = simulator_.vanguard().grid().comm(); | ||
| std::vector<Scalar> pot(this->numPhases(), 0.0); | ||
| const Group& fieldGroup = this->schedule().getGroup("FIELD", reportStepIdx); | ||
| WellGroupHelpers<Scalar>::updateGuideRates(fieldGroup, | ||
| this->schedule(), | ||
| this->summaryState(), | ||
| this->phase_usage_, | ||
| reportStepIdx, | ||
| simulationTime, | ||
| this->wellState(), | ||
| this->groupState(), | ||
| comm, | ||
| &this->guideRate_, | ||
| pot, | ||
| local_deferredLogger); | ||
| this->guide_rate_handler_.updateGuideRates( | ||
| reportStepIdx, simulationTime, this->wellState(), this->groupState() | ||
| ); | ||
| #ifdef RESERVOIR_COUPLING_ENABLED | ||
| if (this->isReservoirCouplingSlave()) { | ||
| this->guide_rate_handler_.sendSlaveGroupPotentialsToMaster(); | ||
| } | ||
| #endif |
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.
This is probably a silly question: Why don't we do the receive and sends in GuideRateHandler::updateGuideRates?
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.
Good question. Since updateGuideRates() is not directly dependent on sending slave group potentials and updating master group potentials. Rather, it will compute the potentials from the well potentials and store those values in the GuideRate object (for non-master groups), and for master groups it will retrieve the group potentials stored in the ReservoirCouplingMaster object to compute guide rates. See updateGuideRates() in updateWellControlsAndNetworkIteration() for an example where sending slave group potentials/receiving master group potentials is not done. So the slave group potentials only need to be communicated at the start of the timestep and no update of those will be done during the nonlinear iterations.
| this->guide_rate_handler_.updateGuideRates( | ||
| reportStepIdx, simulationTime, this->wellState(), this->groupState() | ||
| ); |
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.
Maybe connected to the other comment:
There is no communication here. Why is this not needed? Please add a comment about this.
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.
Good observation. I tried to explain this in the other comment. Also added a comment in the source code, see latest commit.
| // Define a num_fields constant to be used in MPI communication to simplify serialization | ||
| // and deserialization of the struct. Note that sizeof(Potentials)/sizeof(double) is not | ||
| // guaranteed to be equal to num_fields due to padding. | ||
| static constexpr std::size_t num_fields = 3; |
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.
This does not seem to be used. I do not really get the comment. What is it for?
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.
Yes the comment was not clear. It was used by the ReservoirCouplingMpiTraits.hpp to determine the block lengths for the MPI trait for the Potentials struct. However, to avoid duplication of code when developing MPI traits for other structs in the future, I decided to make the code more generic. Luckily, as a by-product of that change, the need for the num_fields variable was also eliminated. See the added commit for details.
|
jenkins build this serial please |
|
🙈 jenkins will fail of course. Handled by opm-common PR, already |
1cbea70 to
c03f2a2
Compare
@blattms Thanks for the detailed review. I have added some commits to address the comments you posed. I am also planning to add a commit to address the comment from @bska in the companion PR in opm-common. I think we can avoid getting the slave group potentials from the |
|
jenkins build this please |
|
@blattms and @bska The last commit tries to address OPM/opm-common#4567 (comment). Then OPM/opm-common#4629 will replace OPM/opm-common#4567. I have run jenkins successfully for both mpi and serial in OPM/opm-common#4629. |
|
jenkins build this please |
|
jenkins build this please |
|
jenkins build this please |
|
jenkins build this please |
|
jenkins build this serial please |
@blattms and @bska After review by @bska, I think the companion PR OPM/opm-common#4629 can also be eliminated. I have added a commit here as a replacement, and plan to close both opm-common PRs as they are no longer needed. Jenkins builds with and without serial succeed. Let me know if anything else needs to be added to this PR. |
|
Thanks a lot. I'll take another look. |
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.
Overall this looks good. Just a few curious questions.
Personally, I would appreciate a bit more doxygen documentation for new classes.
|
Seems like I was too slow again and another Merge conflict appeared. I am really sorry. |
Send group potentials from the slaves to the master process, then use the potentials in the master process to calculate guide rates.
Added debugging code to dump all guide rates
Even if a group is a pure injection group, we still need to include its group potential in the calculation of the production potential of a higher group
Using a custom MPI datatype for the potentials, we can avoid serialization and deserialization code.
Add generic code for building MPI traits for structs
Add a comment to improve readability
Add a comment to clarify that communication of slave group potentials is not done during the nonlinear iterations
Store the group potentials in the GroupState object so we avoid recomputing them later when we need to send the slave group potentials to the master.
Avoid reusing implementation detail itemName() of class GuideRateValue
Fix bug where emplace() did not update existing keys in the map. Instead use try_emplace() for efficient conditional construction and assignment.
Remove Simulator alias since it is not used by any code
Added Doxygen documentation for the GuideRateHandler class.
|
jenkins build this please |
@blattms Good idea. I have added a commit that adds documentation for the |
|
jenkins build this serial please |
Depends on OPM/opm-common#4567
Sends group potentials from the slave processes to the master process, then use those potentials in the master process to calculate guide rates.
A future PR will calculate group target in the master based on the guide rates and send those targets to the slave groups.