USEPA / WNTR

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

'inpfile_units' affects simulation results #443

Open Walternate0 opened 1 week ago

Walternate0 commented 1 week ago

Summary

I am using WNTR to model a simple WDN. I create and modify the wn object using WNTR. Changing the 'inpfile_units' attribute provides different results from the simulation (also run in WNTR). From what I understand, this should not be the case.

Example

wn = wntr.network.WaterNetworkModel() 
# setting the options 
wn.options.hydraulic.headloss = 'D-W' 
wn.options.hydraulic.demand_model = 'DDA' 
wn.options.graphics.units = 'Meters' 
wn.options.graphics.dimensions = (0, -5, 15, 15) 

# place the different nodes 
wn.add_reservoir('Res', base_head=85, coordinates = (0,5)) 
wn.add_junction('J1', base_demand = Qdesign(1200), elevation = 58, coordinates = (5, 5))
wn.add_junction('J2', base_demand = Qdesign(1800), elevation = 28, coordinates = (10, 7.5))
wn.add_junction('J3', base_demand = Qdesign(3600), elevation = 28, coordinates = (10, 2.5)) 
wn.add_junction('J4', base_demand = Qdesign(3600), elevation = -2, coordinates = (15, 5))

# add the different pipes 
wn.add_pipe('P1', 'Res', 'J1', length = 1000, diameter = 0.4, roughness = 1.0) 
wn.add_pipe('P2', 'J1', 'J2', length = 1000, diameter = 0.3, roughness = 1.0) 
wn.add_pipe('P3', 'J1', 'J3', length = 1000, diameter = 0.1, roughness = 1.0) 
wn.add_pipe('P4', 'J2', 'J4', length = 1000, diameter = 0.2, roughness = 1.0) 
wn.add_pipe('P5', 'J4', 'J3', length = 1000, diameter = 0.2, roughness = 1.0)
wn.add_pipe('P6', 'J2', 'J3', length = 1000, diameter = 0.1, roughness = 1.0) 

# create a dataframe for links
links = pd.DataFrame({'Pipe': ['P1','P2', 'P3', 'P4', 'P5', 'P6'], 
                      'Diameter [mm]': [400 ,300, 100, 200, 200, 100]}) 

#commenting out the next line changes the results
wn.options.hydraulic.inpfile_units = "LPS"

# run the simulation
sim = wntr.sim.EpanetSimulator(wn) 

# get the results 
results_sim = sim.run_sim() 
pressure = results_sim.node['pressure'].loc[0,:]
head = results_sim.node['head'].loc[0,['Res','J1','J2', 'J3','J4']] 

print('The pressure in each node is shown in the table below: \n\n',
      pressure,
      '\n\n')

Environment Provide information on your computing environment.

kbonney commented 1 week ago

Hi @Walternate0, I cannot fully reproduce the code you shared as I don't know what Qdesign is. Can you provide the exact values you are using for the base demand of the junctions?

Walternate0 commented 1 week ago

Sorry about that. Here you go.

wn.add_junction('J1', base_demand = 0.00722222222, elevation = 58, coordinates = (5, 5))
wn.add_junction('J2', base_demand = 0.01083333333, elevation = 28, coordinates = (10, 7.5))
wn.add_junction('J3', base_demand = 0.02166666666, elevation = 28, coordinates = (10, 2.5)) 
wn.add_junction('J4', base_demand = 0.02166666666, elevation = -2, coordinates = (15, 5))
kaklise commented 1 week ago

Changing (or commenting out) wn.options.hydraulic.inpfile_units does not convert the values you used to create the WaterNetworkModel, it only changes the UNITS line in the INP file that WNTR writes. The default value is GPM. So if the values are in LPS, you'll want to make sure the INP file has units LPS. If you change the units to GPM, the values in the INP file are still the same and the results will be different.

kbonney commented 1 week ago

Thanks. My output for the default run (without setting LPS) is

 name
J1     26.384113
J2     54.709061
J3     47.950264
J4     78.631935
Res     0.000002
Name: 0, dtype: float32 

and my output for the run where LPS is set is:

 name
J1     26.214180
J2     54.018902
J3     44.879860
J4     75.778847
Res     0.000002
Name: 0, dtype: float32 

They are slightly different, particularly at J4. I did verify that WNTR is performing the correct conversion when writing the INP files, so I suspect this issue is isolated to EPANET. There are slight rounding errors introduced by EPANET when using converted values, which could explain the difference.

One potential way around this is to use the WNTRSimulator, however it cannot do D-W loss.

Walternate0 commented 1 week ago

Hi @kbonney, I arrived at a similar conclusion to yours, but then I was baffled by the scale of the difference. You think that ~3 meters of pressure is a result of rounding/conversion errors in EPANET? Thanks a lot for the fast replies BTW :)

kaklise commented 1 week ago

Changing (or commenting out) wn.options.hydraulic.inpfile_units does not convert the values you used to create the WaterNetworkModel, it only changes the UNITS line in the INP file that WNTR writes. The default value is GPM. So if the values are in LPS, you'll want to make sure the INP file has units LPS. If you change the units to GPM, the values in the INP file are still the same and the results will be different.

Sorry, this reply above is incorrect, changing the inpfile_units changes the values in the INP file and the results should be preserved. We did find a potential issue with converting the roughness coefficient, which might be causing the differences. We will look into that very soon.