epanet 2.0python调用接口

EPANETTOOLS的Python项目详细描述


epanet 2.0 python调用接口

Epanet 2.0python调用接口

从0.5.0.1版开始,这个库就有了epanet发射器引擎,支持基于压力的需求分析(http://assela.pathirana.net/EPANET-Emitter)。

因为版本是0.4.0.1,所以库与Python3.0兼容

这是什么?

一个python包,允许用户调用python脚本中的所有epanet programmers toolkit函数。

安装

Windows:

Use a Python ditribution that comes with a c copiler (use WinPython or PythonXY)

^{pr 1}$
POSIX (e.g. Linux, OS-X):

Download source archive (zip file), extract and run (as root)

^{pr 2}$

or just type

^{pr 3}$

用法:

>>> import os, pprint
>>> pp=pprint.PrettyPrinter() # we'll use this later.
>>> from  epanettools.epanettools import EPANetSimulation, Node, Link, Network, Nodes, \
... Links, Patterns, Pattern, Controls, Control # import all elements needed
>>> from epanettools.examples import simple # this is just to get the path of standard examples
>>> file = os.path.join(os.path.dirname(simple.__file__),'Net3.inp') # open an example
>>> es=EPANetSimulation(file)

节点信息

>>> len(es.network.nodes)
97
>>> list(es.network.nodes)[:5] # just get indexes of nodes
[1, 2, 3, 4, 5]
>>> [es.network.nodes[x].id for x in list(es.network.nodes)[:5]] # Get ids of first five nodes.
['10', '15', '20', '35', '40']
>>> n=es.network.nodes
>>> n[1].id
'10'
>>> n[94].id
'Lake'
>>> n['10'].index # get the index of the node with id '10'
1

现在链接

>>> m=es.network.links
>>> len(m)
119
>>> m[1].id
'20'
>>> m[3].id
'50'
>>> m[119].id
'335'

有关连接的信息

>>> [m[1].start.id,m[1].end.id] # get the two ends of a link
['3', '20']
>>> [m[118].start.id,m[118].end.id]
['Lake', '10']
>>> sorted([i.id for i in n['169'].links]) # get the links connected to a node.
['183', '185', '187', '211']

链接和节点的类型

>>> pp.pprint(Node.node_types) # these are the type codes for nodes.
{'JUNCTION': 0, 'RESERVOIR': 1, 'TANK': 2}
>>> n[94].node_type
1
>>> n[1].node_type
0
>>> n['2'].node_type
2
>>> pp.pprint(Link.link_types) # these are the type codes for links
{'CVPIPE': 0,
 'FCV': 6,
 'GPV': 8,
 'PBV': 5,
 'PIPE': 1,
 'PRV': 3,
 'PSV': 4,
 'PUMP': 2,
 'TCV': 7}
>>> m['335'].link_type # Pump
2
>>> m['101'].link_type # PIPE
1
>>> m[1].link_type #
1
>>> [y.id for x,y in m.items() if y.link_type==Link.link_types['PUMP']] # get ids of pumps
['10', '335']
>>> [y.id for x,y in n.items() if y.node_type==Node.node_types['TANK']] # get ids of tanks
['1', '2', '3']

网络属性可用(甚至在我们运行模拟之前)

>>> d=Link.value_type['EN_DIAMETER']
>>> print("%.3f" % es.network.links[1].results[d][0])
99.000

>>> p1=es.network.patterns[1]
>>> l=list(p1.values())
>>> print("%2.1f "*len(l) % tuple(l )) # doctest: +NORMALIZE_WHITESPACE
1.3 1.9 1.5 1.4 0.8 0.9 0.9 1.1 1.0 1.1 1.1 1.2 1.2 1.1 1.0 0.8 0.8 0.7 0.6 0.6 0.9 1.0 1.2 1.7

得到一些仿真结果。

>>> es.run()
>>> p=Node.value_type['EN_PRESSURE']
>>> print("%.3f" % es.network.nodes['103'].results[p][5] )
59.301
>>> d=Node.value_type['EN_DEMAND']
>>> h=Node.value_type['EN_HEAD']
>>> print("%.3f" % es.network.nodes['103'].results[d][5])
101.232
>>> print("%.3f" % es.network.nodes['103'].results[h][5])
179.858
>>> d=Link.value_type['EN_DIAMETER']
>>> print("%.3f" % es.network.links[1].results[d][0])
99.000
>>> es.runq() # run water quality simulation
>>> q=Node.value_type['EN_QUALITY']
>>> print("%.3f" % es.network.nodes['117'].results[q][4])
85.317
>>> e=Link.value_type['EN_ENERGY']
>>> print("%.5f" % es.network.links['111'].results[e][23])
0.00685

一些高级结果查询

>>> print("%.3f" % min(es.network.nodes['103'].results[p])) # minimum recorded pressure of node '103'
44.169
>>> n=es.network.nodes
>>> # All nodes recording negative pressure.
>>> sorted([y.id for x,y in n.items() if min(y.results[p])<0])
['10']
>>> # Nodes that deliver a flow of more than 4500 flow units
>>> d=Node.value_type['EN_DEMAND']
>>> j=Node.node_types['JUNCTION']
>>> sorted([y.id for x,y in n.items() if ( max(y.results[d])>4500 and y.node_type==j )])
['203']

更改网络

目前,上面新的(基于对象的)接口只支持对底层网络的读访问。要更改网络的值,建议使用传统接口调用。可以从新接口中访问遗留调用。更改网络的步骤:

  1. 使用网络文件创建epanetsimulation对象
  2. 使用ensetxxxx调用更改所需的值(仅更改epanetsimulation的属性将不起作用!)
  3. 使用ensaveinpfile将更改的数据保存到新文件中。
  4. 使用新保存的文件创建epanetsimulation对象。
Following is an example:
>>> d=Link.value_type['EN_DIAMETER']
>>> e=Node.value_type['EN_ELEVATION']
>>> es.ENgetlinkvalue(81,d)[1] #low level interface
16.0
>>> es.network.links[81].results[d] # new interface
[16.0]
>>> es.ENgetnodevalue(55,e)[1] # low level interface
15.5
>>> es.network.nodes[55].results[e] #new interface
[15.5]
>>> r=es.ENsetlinkvalue(81,d,99) # now let's change values - link
>>> r # zero means no error!
0
>>> r=es.ENsetnodevalue(55,e,18.25) # change elevation of node
>>> r #zero means no error
0
>>> # Note: the original network is not changed! Only the low level values changed. This is a limitation of current implementation
>>> es.network.links[81].results[d], es.ENgetlinkvalue(81,d)[1], es.network.nodes[55].results[e], es.ENgetnodevalue(55,e)[1]
([16.0], 99.0, [15.5], 18.25)
>>> # to permanantly change values, the changed network has to  be written to a new file
 >>> import tempfile, os
>>> f=os.path.join(tempfile.gettempdir(),"temp.inp")
>>> es.ENsaveinpfile(f) # save the changed file
0
>>> e2=EPANetSimulation(f)
>>> e2.network.links[81].results[d], e2.ENgetlinkvalue(81,d)[1], e2.network.nodes[55].results[e], e2.ENgetnodevalue(55,e)[1]
([99.0], 99.0, [18.25], 18.25)
>>> # now in both high level and low level interfaces, we have the right value.

模式操作

>>> patId = "NewPattern";
>>> ret=es.ENaddpattern(patId)
>>> print(ret)
0
>>> patFactors=[0.8, 1.1, 1.4, 1.1, 0.8, 0.7, 0.9, 0.0, 0.8, 0.8, 0.0, 0.0]
>>> ret,patIndex=es.ENgetpatternindex(patId)
>>> print(patIndex)
6
>>> es.ENsetpattern(patIndex, patFactors)
0
>>> es.ENgetpatternid(6)[1]
'NewPattern'
>>> es.ENgetpatternlen(6)
[0, 12]
>>> [round(es.ENgetpatternvalue(6,i)[1],3) for i in range(1,12+1)]
[0.8, 1.1, 1.4, 1.1, 0.8, 0.7, 0.9, 0.0, 0.8, 0.8, 0.0, 0.0]
>>> es.ENsetpatternvalue(6,9,3.3)
0
>>> [round(es.ENgetpatternvalue(6,i)[1],3) for i in range(1,12+1)]
[0.8, 1.1, 1.4, 1.1, 0.8, 0.7, 0.9, 0.0, 3.3, 0.8, 0.0, 0.0]

PDD类型分析

查看http://assela.pathirana.net/EPANET-Emitter以获取详细信息和执行相同分析的桌面(仅限Windows)应用程序。

>>> # lets create a pressure deficient network to demonstate this.
>>> d=Link.value_type['EN_DIAMETER']
>>> l=es.network.links['247'] .index # get the index of '247' node.
>>> r=es.ENsetlinkvalue(l,d,2.5) # now let's change values - link diameter to a  small value.
>>> r # zero means no error!
0
>>> f=os.path.join(tempfile.gettempdir(),"temp.inp")
>>> es.ENsaveinpfile(f) # save the changed file
0
>>> #now lets analyse this with 'normal' epanet engine
>>> e2=EPANetSimulation(f, pdd=False) #note pdd=False is default, no need to write this
>>> e2.run() #simulate
>>> p=Node.value_type['EN_PRESSURE']
>>> e2.network.nodes['225'].results[p][10] < -10.0 # we should get a large negative pressure value
True
>>> d=Node.value_type['EN_DEMAND']
>>> print("%4.2f" %e2.network.nodes['225'].results[d][10]) # the demand does not change/
25.08
>>> e3=EPANetSimulation(f,pdd=True) # now we enable pdd
>>> e3.run()
>>> p225=e3.network.nodes['225'].results[p][10] # pressure should not be a rediculous value
>>> (p225 > -3 and p225 < 500)
True
>>> d=Node.value_type['EN_DEMAND']
>>> d225=e3.network.nodes['225'].results[d][10]  # the demand should be nearly zero
>>> (d225 > -.1 and d225 < .1)
True

传统接口

除非为了兼容,否则不要使用以下方法!从版本开始>;0.8模式设置 无法使用此接口。

>>> import os
>>> from epanettools import epanet2 as et
>>> from epanettools.examples import simple
>>> file = os.path.join(os.path.dirname(simple.__file__),'Net3.inp')
>>> ret=et.ENopen(file,"Net3.rpt","")
Example 1:Retrieve simulation properties.

网络的基本性质

>>> ret,result=et.ENgetcount(et.EN_LINKCOUNT)
>>> print(ret)
0
    >>> print(result)
    119
>>> ret,result=et.ENgetcount(et.EN_NODECOUNT)
>>> print(ret)
0
>>> print(result)
97
    >>> node='105'
    >>> ret,index=et.ENgetnodeindex(node)
    >>> print(ret)
    0
    >>> print ("Node " + node + " has index : " + str(index))
    Node 105 has index : 12

获取节点列表

>>> ret,nnodes=et.ENgetcount(et.EN_NODECOUNT)
>>> nodes=[]
>>> pres=[]
>>> time=[]
>>> for index in range(1,nnodes):
...     ret,t=et.ENgetnodeid(index)
...     nodes.append(t)
...     t=[]
...     pres.append(t)
>>> print (nodes)       #doctest: +ELLIPSIS
...                     #doctest: +NORMALIZE_WHITESPACE
    ['10', '15', '20', '35', '40', '50', '60', ..., '275', 'River', 'Lake', '1', '2']

获取具有给定索引的链接两边的节点索引

>>> et.ENgetlinknodes(55) # note the first item in the list should be ignored.
[0, 5, 46]

水力模拟

>>> et.ENopenH()
0
>>> et.ENinitH(0)
0
>>> while True :
...    ret,t=et.ENrunH()
...    time.append(t)
...    # Retrieve hydraulic results for time t
...    for  i in range(0,len(nodes)):
...        ret,p=et.ENgetnodevalue(i+1, et.EN_PRESSURE )
...        pres[i].append(p)
...    ret,tstep=et.ENnextH()
...    if (tstep<=0):
...        break
>>> ret=et.ENcloseH()
>>> print([round(x,4) for x in pres[0]])   #doctest: +ELLIPSIS
...                                         #doctest: +NORMALIZE_WHITESPACE
    [-0.6398, 40.1651, 40.891, 41.0433, ..., 0.569, -0.8864, 0.2997]

节点“10”处的压力

>>> ret,ind=et.ENgetnodeindex("10")
>>> print (ind)
1
>>> print([round(x,4) for x in pres[ind+1]]) # remember epanet count starts at 1.
...                                          #doctest: +ELLIPSIS
...                                          #doctest: +NORMALIZE_WHITESPACE
    [12.5657, 12.9353, 13.4351, 14.0307, ..., 13.1174, 13.3985, 13.5478]

变更日志

1.0.0(2018-09-28)

  • 现在可以使用python>;3.4。
  • 使用适用于Windows的Visual C/C++编译器

.9.0(2016-11-13)

  • 添加了关闭管道的可用需求分数。为了提高效率,这是用c库完成的。

0.8.0(2016-10-06)

  • 完全消除了对numpy的依赖。

0.7.2(2016-09-28)

  • 错误修复

0.7.1(2016-09-21)

  • 小改动

0.7.0(2016-09-21)

  • 从6.x版大幅升级
  • 增加压力驱动需求
  • 完全还原回购结构
  • 使用ci进行更好的测试

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
图像处理Java 8 ImageIO在Linux中无法正确读取JPEG   spring如何用Java 1.4兼容版本替换@Resource注释   java Http请求参数类型传播   在web浏览器中看不到Java Maven Tomcatplugin web应用程序   jvm在Java中使用直接内存的目的是什么?   如何从列表转换为字符串java   java setAdapter gridview发送上下文   SwingJava。方法上的lang.NullPointerException   java什么是shell脚本、makefile和ant文件   当使用getGraphics()方法时,java JPanel图形会闪烁   java如何将迭代转换为递归?   java为什么我的抽屉菜单在同一个XML上有ConstraintLayout时没有响应?   java如何在图像上画一个圆?   Android studio:Rabbitmq:Error:java。lang.ClassNotFoundException:类io。千分尺。果心仪器找不到仪表注册表