USEPA / WNTR

An EPANET compatible python package to simulate and analyze water distribution networks under disaster scenarios.
Other
309 stars 179 forks source link

Cleaning up .inp file from InfoWater or similar proprietary program for use in PDD WNTR simulation #154

Closed kalebsm closed 3 years ago

kalebsm commented 3 years ago

This is a generalized question for some specific issues I am having with an .inp file consisting of a large network. This .inp file was probably converted from a gis based hydraulic modeling program. The specific issues I have are with controls being misread and the simulation failing to converge (determined after removing all controls to see what the next issue would be). 1) Before going into the specifics (probably in a separate issue) I want to ask if there are any general guidelines for cleaning up an .inp file to work in the WNTRSimulator? 2) For example, and especially for a large network (10000+nodes), is it required to skeletonize the network to get the simulation to converge or are there other fixes I need to make first/as well?

(A few notes) I am using wntr==0.2.2 in an anaconda environment. As far as I can tell, none of the limitations detailed for WNTR are conflict with the .inp file. Also, the .inp model runs perfectly fine with the EpanetSimulator (and the EPANET GUI) with relatively few warning messages, but neither the DD or PDD simulators work for WNTRSimulator.

kaklise commented 3 years ago

I have not run into this issue before, with large networks or with INP files converted from proprietary software. We often clean up file formatting issues by loading the INP file into the EPANET GUI and then exporting a new INP file. If that doesn't work, then I'd be happy to look into the issue but would probably need the INP file to debug. If you can share the file, you can send it to me directly at kaklise@sandia.gov. The dev branch on USEPA/WNTR now supports EPANET 2.2. This allows you to use PDD with the EpanetSimulator.

kalebsm commented 3 years ago

I've tried to load and export a new INP file but that does not seem to work. Unfortunately, I cannot share the INP file, and the process I am using through the PDD simulator utilizes the leak model, which is not utilized in EPANET 2.2 GUI and so I think wouldn't be on the dev branch EpanetSimulator either (if I understand correctly).

Recently, I have tried to neglect convergence error and tried to utilize some different scipy solvers but those don't appear to work either. I get the same traceback that others have commented on in other issues, saying that the "Simulation failed to converge. Jacobian is singular at iteration 0".

I've been thinking of other ways to go about this. If there was a way for me to set the pressures of the initial guess to be the results of a run using EPANETsolver maybe it would converge.

kalebsm commented 3 years ago

Maybe I'm trying to solve the wrong problem first. This is the error concerning the controls that I am getting.

Traceback (most recent call last):

File "", line 1, in runfile('PDD_test.py', wdir='HydraulicSimulation')

File "Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile execfile(filename, namespace)

File "Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile exec(compile(f.read(), filename, 'exec'), namespace)

File "PDD_test.py", line 34, in results = epanet_sim.run_sim()

File "Anaconda3\lib\site-packages\wntr\sim\core.py", line 905, in run_sim self._run_postsolve_controls()

File "Anaconda3\lib\site-packages\wntr\sim\core.py", line 772, in _run_postsolve_controls postsolve_controls_to_run = self._postsolve_controls.check()

File "Anaconda3\lib\site-packages\wntr\network\controls.py", line 2201, in check do, back = c.is_control_action_required()

File "Anaconda3\lib\site-packages\wntr\network\controls.py", line 1974, in is_control_action_required do = self._condition.evaluate()

File "Anaconda3\lib\site-packages\wntr\network\controls.py", line 734, in evaluate cur_value = getattr(self._source_obj, self._source_attr)

AttributeError: 'Junction' object has no attribute 'pressure'

kalebsm commented 3 years ago

I've been looking the the controls.py code and it may be that my controls might not be written correctly for the WNTR rules. For instance it says "Words, such as 'below', are only accepted from the EPANET rules conditions (see ...)". I think the brackets are missing some information. Does this mean a 'below' statement is only accepted in the EpanetSimulator and not the WNTRsimulator?

I have a number of controls that look like this: Link 'P' Open If Node 'N' Below 'X' (where X is an integer for the pressure)

If this is indeed the error, how should I fix the inp file control statement?

dbhart commented 3 years ago

Hi @kalebsm I'm sorry this has taken so long to respond. I'm not sure why this isn't working for PDD, but I'm working on it.

dbhart commented 3 years ago

So, Net6.inp in the examples has controls in the same format as you are describing. I'm not seeing an error when I run with the most recent version of WNTR (3.0, or the dev branch). Is there a difference between your controls and the examples in that example network? I'm having trouble replicating your issue using Net6 as a base.

kalebsm commented 3 years ago

@dbhart I am back working on this. I am still sifting through the base code for WNTR to try determine what the differences between the WNTR and EPANET simulator are that lead to this bullet point in the discrepancies section of the documentation. image

This is where I suspect the problem lies. I also got Net6 to work with a PDD WNTRSimulator, so you are right that it's not the control condition I cited.

kalebsm commented 3 years ago

I have isolated the problem and replicated it in Net6. The original issue I posted doesn't do a good job of getting to the actual problem - I'll post what I have learned here and if you think it is a good idea, create a new issue post with a clearer question.

I believe WNTRSimulator does not know how to handle a simple control that initiates a pump action based on an individual node pressure reading (as opposed to tank and its level, which is the case for all the simple controls in Net6). Say for example, a distribution network has a SCADA system tied to a pressure gauge at a critical junction, and at a certain pressure it triggers the pumps.

First, I isolated that type of simple control in my input file to show that it was indeed the problem. Then I replicated it in Net6 by adding the highlighted simple control: image

Also, I tried writing the control through the WNTR API language, but it also gave me the same error message I have described previously.

`Pump = wntr_obj.get_link('Pump2')

Junction = wntr_obj.get_node('Junction')

pump_cond0 = controls.ValueCondition(Junction, 'pressure', '>', 50/3.28)

pump_act0 = controls.ControlAction(pump, 'status', 0)

pump_rule0 = controls.Rule(pump_cond0, [pump_act0], name='rule3')

wntr_obj.add_control('rule3', pump_rule0)`

So I believe the problem is that the Control API for WNTRSimulator does not include a case for a "ValueCondition" for Junction pressure.

dbhart commented 3 years ago

Hi @kalebsm . Thanks for the update and information. I think you are right, here. I'm going to start going in on this, but I agree, it would be good to create a clearer issue so that the title makes more sense in case others are looking for the same issue.

Tanks!