Skip to content

Conversation

@hakonhagland
Copy link
Contributor

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.

@hakonhagland
Copy link
Contributor Author

I will run jenkins from the opm-common PR later

Copy link

Copilot AI left a 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

@hakonhagland hakonhagland force-pushed the send_pot4 branch 2 times, most recently from 8b5a02c to 59daa3d Compare April 11, 2025 14:18
Copy link
Member

@blattms blattms left a 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;
Copy link
Member

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?

Comment on lines 91 to 92
auto num_slaves = this->master_.numSlavesStarted();
auto master_groups = this->rescoup_.masterGroups();
Copy link
Member

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?

@blattms
Copy link
Member

blattms commented Apr 28, 2025

Unfortunately, this needs to be rebased on master it seems.

@hakonhagland hakonhagland force-pushed the send_pot4 branch 2 times, most recently from 8183220 to 51198a8 Compare April 28, 2025 13:13
@hakonhagland
Copy link
Contributor Author

@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.

@hakonhagland hakonhagland added the manual:irrelevant This PR is a minor fix and should not appear in the manual label May 9, 2025
@blattms
Copy link
Member

blattms commented Jun 3, 2025

I am sorry for the delay. Now this needs another rebase.

Copy link
Member

@blattms blattms left a 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.

Comment on lines 466 to 480
#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
Copy link
Member

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?

Copy link
Contributor Author

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.

Comment on lines +1280 to +1293
this->guide_rate_handler_.updateGuideRates(
reportStepIdx, simulationTime, this->wellState(), this->groupState()
);
Copy link
Member

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.

Copy link
Contributor Author

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;
Copy link
Member

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?

Copy link
Contributor Author

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.

@blattms
Copy link
Member

blattms commented Jun 10, 2025

jenkins build this serial please

@blattms
Copy link
Member

blattms commented Jun 10, 2025

🙈 jenkins will fail of course. Handled by opm-common PR, already

@hakonhagland hakonhagland force-pushed the send_pot4 branch 2 times, most recently from 1cbea70 to c03f2a2 Compare June 11, 2025 15:45
@hakonhagland
Copy link
Contributor Author

My main reservation is the introduction of a reference to the simulator in the time stepping.

@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 GuideRate object by storing them in the GroupState object instead. This will for now cause duplication of group potentials in GuideRate and GroupState. A future PR might try to remove that duplication by removing the potentials from the GuideRate object's internal state. What do you think? Then we can simply close/delete OPM/opm-common#4567.

@hakonhagland
Copy link
Contributor Author

jenkins build this please

@hakonhagland
Copy link
Contributor Author

hakonhagland commented Jun 13, 2025

@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.

@hakonhagland
Copy link
Contributor Author

jenkins build this please

@hakonhagland
Copy link
Contributor Author

jenkins build this please

@hakonhagland
Copy link
Contributor Author

jenkins build this please

@hakonhagland
Copy link
Contributor Author

jenkins build this please

@hakonhagland
Copy link
Contributor Author

jenkins build this serial please

@hakonhagland
Copy link
Contributor Author

The last commit tries to address OPM/opm-common#4567 (comment). Then OPM/opm-common#4629 will replace OPM/opm-common#4567.

@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.

@blattms
Copy link
Member

blattms commented Jun 18, 2025

Thanks a lot. I'll take another look.

Copy link
Member

@blattms blattms left a 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.

@blattms
Copy link
Member

blattms commented Jun 20, 2025

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.
@hakonhagland
Copy link
Contributor Author

jenkins build this please

@hakonhagland
Copy link
Contributor Author

I would appreciate a bit more doxygen documentation for new classes.

@blattms Good idea. I have added a commit that adds documentation for the GuideRateHandler class.

@hakonhagland
Copy link
Contributor Author

jenkins build this serial please

@blattms blattms merged commit a032b7a into OPM:master Jun 23, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

manual:irrelevant This PR is a minor fix and should not appear in the manual

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants