OpenWaterAnalytics / EPANET

The Water Distribution System Hydraulic and Water Quality Analysis Toolkit
MIT License
279 stars 204 forks source link

Tank is still draining when the minimum level is reached #623

Open fengshang1972 opened 3 years ago

fengshang1972 commented 3 years ago

Our colleagues in Sandia Lab found an issue with tanks: the minimum tank level is reached but the tank is still draining. We noticed that the head loss across the pipe (ID 50 in the model) is very small probably due to the short length and large diameter of the pipe. The result is that the pipe connected to the tank does not get closed in the function cvstatus(), which is called in tankstatus().

image image Net3_power_outage.inp.txt

LRossman commented 3 years ago

This issue has been fixed in PR #624 for thedev_tank_fix branch. The results for tank demand in the example network now look as follows: image Some more testing is probably warranted before this fix is merged into the dev branch.

allenmlowe commented 3 years ago

After applying the modifications to correct this issue, there are still some errors in pipe flows emanating from the tanks. The first pipe connected to the tank may be giving correct flows but the succeeding pipes do not. Link_50_Flow Link_289_Flow

LRossman commented 3 years ago

If you look more closely at the solution you will see that Pipe 289, connected to the closed Tank 2 Pipe 50, has a correct flow of 0 from the time that Tank 2 becomes empty at 47:15 hours until 49:30 hours. After that there is no flow out of both the River and Lake sources plus all tanks become empty. Thus to satisfy demands EPANET finds a solution with large negative pressures that will produce the necessary (spurious) flows. So that's why you see flow in Pipe 289 while Pipe 50 has none. After hour 47:15, with no sources of water available, all hydraulic results become meaningless.

If you run this network in PDA mode, which reduces demands if positive pressure can't be maintained, you will see that during the period 49:45 to 119:45 when all sources remain closed, all demands become 0 and all pipes have no flow. The flows in Pipes 50 and 289 remain consistent with one another as shown in the plot below:

image

The PDA run used a pressure range of 0 to 10 psi, a Max. Trials of 100, and to avoid becoming unbalanced when all sources were closed, an Accuracy setting changed from 0.0001 to 0.001. The latter may be an artifact of trying to achieve a flow convergence at essentially zero flow throughout. Even at the 0.001 Accuracy level, the max. head error and max. individual flow change values remained reasonable in all time periods.

allenmlowe commented 3 years ago

Thank you @LRossman for the explanation. At least now the status report show nodes are disconnected after some time which means that the results after that time are meaningless. Even in PDA mode it shows system unbalanced after some time which means the results after that are also meaningless.

terrahaxton commented 3 years ago

Hi All -

I was wondering about the status of the PR for this issue. Has the fix been tested enough to pull into the dev branch? If so, can we move forward with a new release? I hoping that this fix and other updates are enough to move forward with a minor release. We want to incorporate this new EPANET release into Water Network Tool for Resilience (WNTR), since we're examining extreme disaster scenarios which cause the tanks to drain.

LRossman commented 3 years ago

The same logic used to fix the empty-tank-still-draining issue in PR #624 was also applied to stop a full tank from filling. Unfortunately that caused a convergence problem for an example that had none before. This needs to be fixed (or revert back to the original code for full tanks) before the bug fix can be merged. I will look into it.

LRossman commented 3 years ago

The PR #624 for this issue has been updated and merged into dev. The fix is now performing as it should for both empty and full tanks.

allenmlowe commented 3 years ago

The modification to correct this issue can make tanks overflow even if the setting of CanOverflow = No. When the old code below is reverted, the tank can close and no longer shows overflowing

// If tank is full, then prevent flow into it
if (hyd->NodeHead[n1] >= tank->Hmax - hyd->Htol && !tank->CanOverflow)

instead of // Can't add flow to a full tank if (hyd->NodeHead[n1] >= tank->Hmax && !tank->CanOverflow) in hydstatus.c

report.c does not check if Tank setting CanOverflow if (Tank[i].A > 0.0 && ABS(hyd->NodeHead[n] - Tank[i].Hmax) < 0.001) newstat = OVERFLOWING;

LRossman commented 3 years ago

@allenmlowe can you please submit an example that demonstrates the behavior you describe. Thanks.

allenmlowe commented 3 years ago

Here is an example of an overflowing tank. T-3 is overflowing.

StatusReport Overflowing.zip

LRossman commented 3 years ago

Thanks @allenmlowe for the example. I had tested some of my own and didn't see any problem. What's happening in this network is that there's a pipe connected to Tank 3 that has a closed pump in front of it. Since the EPANET hydraulic solver can't produce a solution with exactly zero flow, there exists some small amount of flow (-0.00079 gpm) in the pipe as a numerical artifact. This flow is negative, causing the level in Tank 3 to drop very slightly below full thus allowing a second pipe connected to the tank to remain open and cause an overflow. I will restore the tolerance in the check for a tank being full or empty, probably making it a little larger than the 0.15 mm used before (maybe more like 1 mm).

allenmlowe commented 3 years ago

Here is a simpler example of overflowing tanks. The energy report also shows 100% utilization which confirms all 3 tanks are overflowing. Overflowing T-3.inp.txt

LRossman commented 3 years ago

@allenmlowe your last example has a pump connecting a Reservoir to a Tank. When EPANET checks to see if a link should be closed if it tries to send water into a full tank it first checks if the designated start node of the link is not a Junction. If so and the node is a Reservoir (as in your example for pump P1) then it stops checking any further, thus failing to prevent overflow at the downstream Tank node. The same can happen if both end nodes are Tanks and the upstream Tank is draining into the downstream Tank. I believe this bug was identified several years ago in a published paper but seems to have fallen through the cracks. The tankstatus() function in hydstatus.c needs to be revised so that when both end nodes of a link are not Junctions then each is checked for having a full (or empty) Tank.

LRossman commented 1 year ago

PR #705 has just been submitted which fixes the issue of status checks on links with tanks on both ends. It also simplifies the code used for tanks status checks in general (see hydstatus.c in the dev-tank-fix branch.) This update correctly solves each of the networks submitted earlier in this thread plus a new example that has two tanks (A and B) connected by a link where one of them (B) becomes empty. twotanktest.inp.txt When run with the current EPANET code, after Tank B becomes empty it still shows an outflow sent into Tank A. With the revised code, the link connecting A and B is closed when B becomes empty. Interestingly, if the direction of the link is reversed (B->A instead of A->B) then the current EPANET gives the correct solution. Also of note for this example is the need to use a smaller hydraulic time step (10 minutes) to prevent excessive instability in tank levels and link flow rate. Eliminating these instabilities is still an open issue (see #165).