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
When checking for zero target rates, also check wells under group control where required #5232
base: master
Are you sure you want to change the base?
Conversation
The code probably works while will come with suggestion for refactoring later. |
jenkins build this please |
d3abaad
to
2355c4c
Compare
@@ -159,7 +159,7 @@ namespace Opm | |||
const WellState& well_state, | |||
DeferredLogger& /* deferred_logger */) | |||
{ | |||
const bool stop_or_zero_rate_target = this->stopppedOrZeroRateTarget(summary_state, well_state); | |||
const bool stop_or_zero_rate_target = this->stoppedOrZeroRateTargetIndividual(summary_state, well_state); |
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 don't think setting the WQTotal
of first segment explicitly to zero for zero-target wells is strictly necessary below, so have left out the checking for zero targets from groups here.
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.
It can be debatable. If we want to be a little more systematical, we probably want to remove this stop_or_zero_rate_target
by all if it is not necessary.
I think it is not a problem when it is with the correct sign, and it might be a problem when the sign of the WQTotal
switches, which is easy for the wells without a zero rate target.
So far we do not know how to handle wells with the opposite production/injection direction.
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.
From the viewpoint of the code, we probably want to avoid different functions to be used for the same purpose, otherwise, we might get into trouble in debugging.
And also, potentially, the function stoppedOrZeroRateTargetIndividual
can be removed if we use stopppedOrZeroRateTarget
here, which is another benefit.
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 is not a problem when it is with the correct sign, and it might be a problem when the sign of the WQTotal switches, which is easy for the wells without a zero rate target.
I beleive WQTotal
is not allowed to switch sign in the Newton update, so it either has the right sign or is zero.
@@ -684,7 +684,7 @@ namespace Opm | |||
|
|||
const double dFLimit = this->param_.dwell_fraction_max_; | |||
const double max_pressure_change = this->param_.max_pressure_change_ms_wells_; | |||
const bool stop_or_zero_rate_target = this->stopppedOrZeroRateTarget(summary_state, well_state); | |||
const bool stop_or_zero_rate_target = this->stoppedOrZeroRateTargetIndividual(summary_state, well_state); |
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.
Same comment as above.
@@ -692,7 +694,7 @@ namespace Opm | |||
{ | |||
if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return; | |||
|
|||
const bool stop_or_zero_rate_target = this->stopppedOrZeroRateTarget(summary_state, well_state); | |||
const bool stop_or_zero_rate_target = this->stoppedOrZeroRateTargetIndividual(summary_state, well_state); |
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.
Same comment as for MS-wells
@@ -1183,7 +1185,7 @@ namespace Opm | |||
constexpr double stopped_factor = 1.e-4; | |||
// use stricter tolerance for dynamic thp to ameliorate network convergence | |||
constexpr double dynamic_thp_factor = 1.e-1; | |||
if (this->stopppedOrZeroRateTarget(summary_state, well_state)) { | |||
if (this->stoppedOrZeroRateTargetIndividual(summary_state, well_state)) { | |||
tol_wells = tol_wells*stopped_factor; |
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's a bit strange that zero target wells should be solved with a much stricter tollerance than others. For convenience, I've also skipped checking for zero targets from groups here.
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.
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.
If we can manage tighten the well tolerance by all, then this part of the logic can be removed. (#5280). You might have had some suggestions regarding the tighter well tolerance, we can discuss.
It was a temporary fix for a reported issue. And it is good to remove this extra logic. In the well code, there are many ad-hoc logic, and , and this one is not among the complicated ones. But it is always good to reduce them with time going forward.
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, would be happy to discuss stricter well-tolerances overall. Especially for standard wells I think this is a good idea!
I've restructered everything here, and renamed the original functions |
jenkins build this please |
Thanks for the update. Will need to think through and get back with suggestions as a whole. |
At the same time, can you check the Jenkins failures to see whether the failures are relevant? Especially the ones with related to |
Yes, will look into what's going on with these. |
Have looked at the four failing tests here. NETWORK-01-REROUTE_ and NETWORK-01-REROUTE_STD match very closely. For MOD4_GRP_GEFAC there is slightly different time-stepping with the PR, but otherwise close match. Looked a bit more closely into MOD4_GRP. This is a very problematic test where both MASTER and PR struggles a lot towards the end with control switching oscillations resulting in extremely short time steps. PR struggles a bit more than MASTER here, but since both show very erratic behavour, I can'r really faviour one above the other. Besides this last problematic part, PR and MASTER match closely. It's probably worthwhile to look more closely into why MOD4_GRP is so problematic, and try to figure out whether the problem is with flow or with the test itself. Currently, it's not well suited as a test (due to the problems, it's also quite computationally expensive). |
jenkins build this please |
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.
Sorry for the delay. I left some comments regarding how to organize the code. Let me know if you need some help or want some discussion.
I do realize this PR is a incremental change that fixes things without breaking other things, while still trying to make the code usage more systematical or reduce the number of the functions whenever possible.
Let me know.
return this->wellUnderZeroRateTargetIndividual(summaryState, well_state); | ||
} else { | ||
const auto& group_state = simulator.problem().wellModel().groupState(); | ||
return wellUnderZeroRateTargetGroup(simulator, well_state, group_state, deferred_logger); |
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.
by getting the Schedule
and SummaryState
from simulator
, the function wellUnderZeroRateTargetGroup()
can be moved to WellInterfaceGeneric
.
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 was was my first intention, but was not able to do it without a lot of other code-changes. If you see some smarter way to move it there, I'll be happy to.
@@ -159,7 +159,7 @@ namespace Opm | |||
const WellState& well_state, | |||
DeferredLogger& /* deferred_logger */) | |||
{ | |||
const bool stop_or_zero_rate_target = this->stopppedOrZeroRateTarget(summary_state, well_state); | |||
const bool stop_or_zero_rate_target = this->stoppedOrZeroRateTargetIndividual(summary_state, well_state); |
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.
From the viewpoint of the code, we probably want to avoid different functions to be used for the same purpose, otherwise, we might get into trouble in debugging.
And also, potentially, the function stoppedOrZeroRateTargetIndividual
can be removed if we use stopppedOrZeroRateTarget
here, which is another benefit.
@@ -1183,7 +1185,7 @@ namespace Opm | |||
constexpr double stopped_factor = 1.e-4; | |||
// use stricter tolerance for dynamic thp to ameliorate network convergence | |||
constexpr double dynamic_thp_factor = 1.e-1; | |||
if (this->stopppedOrZeroRateTarget(summary_state, well_state)) { | |||
if (this->stoppedOrZeroRateTargetIndividual(summary_state, well_state)) { | |||
tol_wells = tol_wells*stopped_factor; |
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.
If we can manage tighten the well tolerance by all, then this part of the logic can be removed. (#5280). You might have had some suggestions regarding the tighter well tolerance, we can discuss.
It was a temporary fix for a reported issue. And it is good to remove this extra logic. In the well code, there are many ad-hoc logic, and , and this one is not among the complicated ones. But it is always good to reduce them with time going forward.
moving the function wellUnderZeroRateTargetGroup to WellInterfaceFluidSystem removing the function stoppedOrZeroRateTargetIndividual to avoid extra logic
2355c4c
to
852678b
Compare
jenkins build this please |
1 similar comment
jenkins build this please |
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.
Looks good and can be merged assuming the test failures have been checked.
For later: Will look at improving some interfaces to possibly reduce the need to pass const Simulator&
around, and maybe avoid using logging and exceptions in the TargetCalculator.
The testing failures need to be double checked. |
Not remembering what happened with the regression test before the refactoring, will create a PR for testing purpose. |
I've gone through the failures and think they look OK. For most of them it's just a result of different time-stepping/different number of time-steps which in many cases leads to quite different results since time-steps are so large relative to the dynamics.
|
The following is some notes for information. The thing is a little worrying is that, when we check the group target for a well, the group target might not be ready. I looked at the case KRNUM-03X, the SCHUEDULE setup for the well
The VREP group control with above similar setup should be causes for many regression failures. Because ideally, for many cases, there should be no wells under zero rate target at all and should no be affected. |
Yes, but don't you think it's better in this case to treat it properly as a zero rate well than trying to solve it with an individual zero rate (as in master) which even might give singular system? |
It took some thinking to understand your point. Basically, you meant that without the checking, we will solve it with zero rate target in the master branch. I think your point is valid and I agree. My point was that |
Sorry, was trying to finnish the sentence before a meeting ;)
I see you point, I agree. |
I checked the regression test with If we regulate the time step with |
For the test failure,
|
With some discussion and help from @bska , the regression failure for Since the simulation results look generally fine and for this failure, we can update reference. But we need to wait for the release processing to unfreeze the reference result update. |
Several places in the code we check whether a well is set to inject/produce at zero rate since this case requires special treatment. This is currently done by the function
wellUnderZeroRateTarget
(often called fromstopppedOrZeroRateTarget
). Wells under group control are currently not included in this check, although the special treatments are equally required if a well is assigned zero rate from a group.I've written draft versions of the two above mentioned functions that also take group-controlled wells into account. Would just like some feedback/discussion whether this seems reasonable before I go ahead and suggest updating all relevant function calls (the new functions have temporary names
*Version
).I've verified that this approach fixes an issue with
iterateWellEqWithSwitching
which currently does not behave nicely for wells that get assigned zero rate from group.