从零开始学习wntr day6(随机模拟泄漏)

前言

本文是通过分析WNTR包自带的stochastic_simulation例子来分析如何在随机管段上面进行添加泄漏点模拟管网漏损,希望对以后的管网模拟算例有所帮助。

一、stochastic_simulation例子代码分析

首先导入各类包:

#coding = utf-8
import numpy as np
import wntr
import matplotlib.pyplot as plt
import pickle


# Create a water network model
inp_file = '../networks/Net3.inp'
wn = wntr.network.WaterNetworkModel(inp_file)

调整参数:

# Modify the water network model
wn.options.time.duration = 48*3600#管网模拟持续48小时,也就是两天
wn.options.time.hydraulic_timestep = 1800#管网的水力计算时间间隔为1800s,30min
wn.options.time.report_timestep = 1800#报告计算结果的时间间隔
wn.options.hydraulic.required_pressure = 15#压力驱动模式下,提供需水量的正常水压
wn.options.hydraulic.minimum_pressure = 0#最低水压 出现负压时停止供水

基于各自的直径,对每一个管段定义一个泄漏概率,所有管段的泄漏概率加起来为1,选择特定特征的管段可以使用wn.query_link_attribute()来获得所有满足特征的管段

# Define failure probability for each pipe, based on pipe diameter. Failure
# probability must sum to 1.  Net3 has a few pipes with diameter = 99 inches,
# to exclude these from the set of feasible leak locations, use
# query_link_attribute
#选择直径小于等于0.91444m的所有管段
pipe_diameters = wn.query_link_attribute('diameter', np.less_equal,
                                         0.9144,  # 36 inches = 0.9144 m
                                         link_type=wntr.network.Pipe)
#再基于管道直径算每个管段的发生泄露的概率
failure_probability = pipe_diameters/pipe_diameters.sum()

我们看看pipe_diameters里面到底有什么东西

>>>print(pipe_diameters)
>>>print(type(pipe_diameters))
>>>print(failure_probability)
60     0.6096
101    0.4572
103    0.4064
105    0.3048
107    0.3048
        ...  
323    0.3048
325    0.2032
329    0.7620
330    0.7620
333    0.7620
Length: 114, dtype: float64
<class 'pandas.core.series.Series'>
60     0.014440
101    0.010830
103    0.009627
105    0.007220
107    0.007220
         ...   
323    0.007220
325    0.004813
329    0.018051
330    0.018051
333    0.018051
Length: 114, dtype: float64

所以wn.query_link_attribute()获得满足传入参数的所有link,可以获得包括管段,阀门,水泵的各种信息。结果是一个pd.Series。索引是link名称,值是相应的link值。

接下来是模型对象的序列化保存,以便下次以相同的初始条件重新开始模拟:

# Pickle the network model and reload it for each realization
f=open('wn.pickle','wb')
pickle.dump(wn,f)
f.close()

# Run 5 realizations
#创建一个新字典用于保存模拟结果
results = {} # Initialize dictionary to store results
np.random.seed(67823) # Set random seed 设置种子 每次模拟都是相同的
for i in range(5):

    # Select the number of leaks, random value between 1 and 5
    #选择发生漏损的数量,该变量N没有引用,猜测应该传入下面的pipes_to_fail
    N = np.random.randint(1,5+1)

    # Select N unique pipes based on failure probability
    #按照管网泄露的概率随机选择5根管道,在index(管道id)里面挑五个
    pipes_to_fail = np.random.choice(failure_probability.index, 5,
                                     replace=False,
                                     p=failure_probability.values)

    # Select time of failure, uniform dist, between 1 and 10 hours
    #取泄露开始的时间,按照平均分布uniform distribution,取小数点后两位
    time_of_failure = np.round(np.random.uniform(1,10,1)[0], 2)

    # Select duration of failure, uniform dist, between 12 and 24 hours
    #取持续时间,也是按照平均分布取小数点后两位
    duration_of_failure = np.round(np.random.uniform(12,24,1)[0], 2)
    
    # Add leaks to the model
    #在管网模型里面添加leaks
    for pipe_to_fail in pipes_to_fail:
        pipe = wn.get_link(pipe_to_fail)
        #设置泄露的参数,泄露点面积leak_area
        leak_diameter = pipe.diameter*0.3
        leak_area=3.14159*(leak_diameter/2)**2
        #把该管段打断 为pipe_to_fail pipe_to_fail_B 和节点
        wn = wntr.morph.split_pipe(wn, pipe_to_fail, pipe_to_fail + '_B', pipe_to_fail+'leak_node')
        leak_node = wn.get_node(pipe_to_fail+'leak_node')
        leak_node.add_leak(wn, area=leak_area,
                          start_time=time_of_failure*3600,
                          end_time=(time_of_failure + duration_of_failure)*3600)

    # Simulate hydraulics and store results
    wn.options.hydraulic.demand_model = 'PDD'
    sim = wntr.sim.WNTRSimulator(wn)
    print('Pipe Breaks: ' + str(pipes_to_fail) + ', Start Time: ' + \
                str(time_of_failure) + ', End Time: ' + \
                str(time_of_failure+duration_of_failure))
    #把模拟的结果result对象传入到我们一开始建立的results字典里面,键是i,值是result对象
    results[i] = sim.run_sim()
    
    # Reload the water network model
    #每次模拟结束以后,reloadpickle文件,保留初始条件重新开始模拟
    f=open('wn.pickle','rb')
    wn = pickle.load(f)
    f.close()

输出结果

Pipe Breaks: ['137' '311' '60' '175' '179'], Start Time: 5.6, End Time: 28.159999999999997
Pipe Breaks: ['121' '161' '239' '193' '191'], Start Time: 7.01, End Time: 25.79
Pipe Breaks: ['191' '131' '249' '211' '193'], Start Time: 9.85, End Time: 23.310000000000002
Pipe Breaks: ['281' '179' '309' '240' '277'], Start Time: 5.72, End Time: 21.63
Pipe Breaks: ['287' '238' '245' '131' '319'], Start Time: 8.67, End Time: 23.11

看看results这个字典

>>>print(results)
{0: <wntr.sim.results.SimulationResults object at 0x0000022AF43391F0>, \n
1: <wntr.sim.results.SimulationResults object at 0x0000022AF422BFA0>, \n
2: <wntr.sim.results.SimulationResults object at 0x0000022AF6B6F280>, \n
3: <wntr.sim.results.SimulationResults object at 0x0000022AF4490160>, \n
4: <wntr.sim.results.SimulationResults object at 0x0000022AF46DEA60>}

该例子后面的代码是一个弹性模块的方法,关于出现漏水时的高位水箱的供水曲线,与我们研究的管网漏损关系不大,没有仔细研究,有兴趣的朋友仔细查看例子。

最后我们再检查里面发现变量N根本没有使用,按道理来说应该发生的泄漏次数是在1到5随机的,所以:

for i in range(5):

    # Select the number of leaks, random value between 1 and 5
    #选择发生漏损的数量,该变量N没有引用,猜测应该传入下面的pipes_to_fail
    N = np.random.randint(1,5+1)

    # Select N unique pipes based on failure probability
    #按照管网泄露的概率随机选择N根管道
    pipes_to_fail = np.random.choice(failure_probability.index, N,
                                     replace=False,
                                     p=failure_probability.values)

现在将全部代码附上:

#coding = utf-8
import numpy as np
import wntr
import matplotlib.pyplot as plt
import pickle
import random


# Create a water network model
inp_file = '../networks/Net3.inp'
wn = wntr.network.WaterNetworkModel(inp_file)

# Modify the water network model
wn.options.time.duration = 48*3600
wn.options.time.hydraulic_timestep = 1800
wn.options.time.report_timestep = 1800
wn.options.hydraulic.required_pressure = 15
wn.options.hydraulic.minimum_pressure = 0

# Define failure probability for each pipe, based on pipe diameter. Failure
# probability must sum to 1.  Net3 has a few pipes with diameter = 99 inches,
# to exclude these from the set of feasible leak locations, use
# query_link_attribute

pipe_diameters = wn.query_link_attribute('diameter', np.less_equal,
                                         0.9144,  # 36 inches = 0.9144 m
                                         link_type=wntr.network.Pipe)
failure_probability = pipe_diameters/pipe_diameters.sum()
# Pickle the network model and reload it for each realization
f=open('wn.pickle','wb')
pickle.dump(wn,f)
f.close()

# Run 5 realizations
results = {}  # Initialize dictionary to store results
np.random.seed(67823)  # Set random seed
for i in range(5):

    # Select the number of leaks, random value between 1 and 5
    N = np.random.randint(1, 5 + 1)

    # Select N unique pipes based on failure probability
    pipes_to_fail = np.random.choice(failure_probability.index, N,
                                     replace=False,
                                     p=failure_probability.values)

    # Select time of failure, uniform dist, between 1 and 10 hours
    time_of_failure = np.round(np.random.uniform(1, 10, 1)[0], 2)

    # Select duration of failure, uniform dist, between 12 and 24 hours
    duration_of_failure = np.round(np.random.uniform(12, 24, 1)[0], 2)

    # Add leaks to the model
    for pipe_to_fail in pipes_to_fail:
        pipe = wn.get_link(pipe_to_fail)
        leak_diameter = pipe.diameter * 0.3
        leak_area = 3.14159 * (leak_diameter / 2) ** 2
        wn = wntr.morph.split_pipe(wn, pipe_to_fail, pipe_to_fail + '_B', pipe_to_fail + 'leak_node')
        leak_node = wn.get_node(pipe_to_fail + 'leak_node')
        leak_node.add_leak(wn, area=leak_area,
                           start_time=time_of_failure * 3600,
                           end_time=(time_of_failure + duration_of_failure) * 3600)

    # Simulate hydraulics and store results
    wn.options.hydraulic.demand_model = 'PDD'
    sim = wntr.sim.WNTRSimulator(wn)
    print('Pipe Breaks: ' + str(pipes_to_fail) + ', Start Time: ' + \
          str(time_of_failure) + ', End Time: ' + \
          str(time_of_failure + duration_of_failure))
    results[i] = sim.run_sim()

    # Reload the water network model
    f = open('wn.pickle', 'rb')
    wn = pickle.load(f)
    f.close()

结果如下

Pipe Breaks: ['137' '311'], Start Time: 1.05, End Time: 16.95
Pipe Breaks: ['202'], Start Time: 8.92, End Time: 30.72
Pipe Breaks: ['233' '175' '247' '231' '60'], Start Time: 8.08, End Time: 28.549999999999997
Pipe Breaks: ['225' '116' '281'], Start Time: 4.31, End Time: 26.759999999999998
Pipe Breaks: ['305' '275' '179' '175' '287'], Start Time: 6.93, End Time: 27.28
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值