本文是从一个初学者的角度学习wntr,默认有一定的水力学、python、数据科学库与epanet知识,希望能帮助大家。初学者错误在所难免,希望大家指正交流。
前言
wntr是一个与EPANET兼容的Python包,用于模拟和分析配水网络。https://wntr.readthedocs.io/en/stable/ 是wntr的官方文档。
在写作论文时,可以引用以下文献:(官方文档可查)
美国环境保护署(EPA)通过其研究与开发办公室资助并与能源部桑迪亚国家实验室达成了一项跨部门协议,进行了wntr的开发研究。
推荐查看同济大学翻译的epaneth汉化版用户手册来学习epanet的基本用法。
本文运行软件采用epanet2.2版本,epaneth(同济大学汉化2.0版本)会导致在调用wntr包时传入.inp文件时显示编码错误。
一、导入包以及传入.inp文件(第一个实例)
首先打开epanet2.2调节缺省值单位:
LPS(升每秒)隐含了全部单位为公有制(SI)。
然后创建出同济大学汉化手册的2.2管网示例模型:
在添加时间分析和延时分析的情况下:
导出管网成为.inp文件:
#coding = utf-8
import wntr#导入包
import matplotlib.pyplot as plt#plt画图工具
#传入.inp文件生成管网模型,默认命名为wn
wn = wntr.network.WaterNetworkModel(r'c:\Users\wen EX\Desktop\WNTR-master\examples\networks\STUDY1.inp')
print(wn.junction_name_list)#打印junction连接点名称
print(wn.node_name_list)#打印node节点(包含水库 水池和连接点点)
print(wn.link_name_list)#打印管段名称
结果与我们的epanet中模型相同
"C:\Users\wen EX\condaex\anaconda3\python.exe" "C:/Users/wen EX/Desktop/WNTR-master/examples/mystudy1/s1.py"
['2', '3', '4', '5', '6', '7']#连接点名称
['2', '3', '4', '5', '6', '7', '1', '8']#节点
['1', '2', '3', '4', '5', '6', '7', '8', '9']#管段名称
Process finished with exit code 0
画图:
#coding = utf-8
import wntr
import matplotlib.pyplot as plt
wn = wntr.network.WaterNetworkModel(r'c:\Users\wen EX\Desktop\WNTR-master\examples\networks\STUDY1.inp')
# Graph the network
wntr.graphics.plot_network(wn, title=wn.name,node_labels=True,link_labels=True,node_size=15,node_range=[1,8])
plt.show()
由于我们在epanet里面画图比较随性,xy坐标不严格,所以看起来有点奇怪,但是大致位置是这样的。
二、执行分析
1.模拟的结果调用
模拟的结果作为一个对象储存,包含
创建结果时的时间戳
网络名称
节点的模拟结果
管段的模拟结果
节点和管段的结果保存成pandas的DataFrames。其中的键是link和node的属性(需水量 流量等)值是DataFrame。按照时间进行索引,节点管段名称进行标记。
# Simulate hydraulics
sim = wntr.sim.EpanetSimulator(wn)
results = sim.run_sim()
print(results)
node_keys = results.node.keys()
link_keys = results.link.keys()
print(node_keys)
print(link_keys)
可以看出,results作为一个对象进行保存,node和link的keys分别为如下所示
<wntr.sim.results.SimulationResults object at 0x000001F8449259A0>
dict_keys(['demand', 'head', 'pressure', 'quality'])
dict_keys(['quality', 'flowrate', 'headloss', 'velocity', 'status',
'setting', 'friction_factor', 'reaction_rate'])
2.节点与管段的结果数据与作图
例如我们想要输出node 5这个节点的压力值时间序列:
pressure = results.node['pressure']
pressure_at_node5 = pressure.loc[:,'5']
print(pressure_at_node5)
0 26.599703
3600 27.491543
7200 36.011997
10800 36.011997
14400 36.011997
...
244800 16.872286
248400 16.522007
252000 16.211201
255600 13.444185
259200 26.487152
Name: 5, Length: 73, dtype: float32
可以看到 我们设置的一共模拟72小时,每小时计算一次,所以结果的标签单位是秒,72*3600=259200。在epanet里面输出节点压力的时间序列图像也是相同的:
在wntr里面绘制图像
ax = pressure_at_node5.plot()
text = ax.set_xlabel("Time (s)")
text = ax.set_ylabel("Pressure (m)")
plt.show()
比如调取管段5的流量:
flowrate = results.link['flowrate']
flowrate_at_link5 = flowrate.loc[:,'5']
print(flowrate_at_link5)
0 -0.013440
3600 -0.013280
7200 -0.010723
10800 -0.010723
14400 -0.010723
...
244800 -0.024375
248400 -0.024551
252000 -0.024698
255600 -0.025734
259200 -0.013460
Name: 5, Length: 73, dtype: float32
流量是负数代表与我们画图的时候管线的方向相反,可以在wntr.graphics.plot_network()中选择流向箭头来判断。
用wntr包来绘制也是一样,调用.plot()方法就行。
ax = flowrate_at_link5.plot()
text = ax.set_xlabel("Time (s)")
text = ax.set_ylabel("Flowrate(m^3/s)")
plt.show()
由于我们epanet的单位是L/S,而mntr的单位默认是立方米/s 所以单位上有换算关系,可以查看官方文档的unit单元。
同时,如何查看同一时间段的所有数据,只需要对.loc[]参数改变就可以:
pressure = results.node['pressure']
pressure_at_1hr = pressure.loc[3600,:]
print(pressure_at_1hr.head())
name#所有连接点的压力
2 40.597904
3 32.944923
4 30.789911
5 27.491543
6 28.665012
其他功能熟练掌握Pandas都基本可以实现
总结
通过对官方文档以及源代码的解读,基本了解输入输出以及画图的情况,大家有什么问题可以提出来相互交流。