这可能更像是一个算法问题,但我是用Python编写的。
我在一条管道上有一组数据,随着它的发展,它会上升和下降。我的数据是两列,沿管道的测量和测量的高度。我的数据集中有数万行。(这些将是列而不是行)
计量: 1、2、3、4、5、6、7、8、9、10
海拔: 5,7,9,15,12,13,18,14,23,9
在这个脚本中,管道将被假定为两端的上限。其目的是计算管道中任何一点从泄漏中排出的液体的总体积。压力/流量并不重要。我想要解释的主要部分是所有的渔获物/山谷(比如浴室的水槽),即使是在管道的其余部分排水沟里,液体也会留在这里,比如:
https://www.youtube.com/watch?v=o82yNzLIKYo
管道半径和泄漏位置将是用户设置的参数.
我真的在寻找一个正确的方向,我想尽可能地自己解决这个问题。我对编程很满意,但是任何关于实际逻辑的建议都会有帮助,谢谢。在这里输入图像描述
假设在这个图表中,一个泄漏出现在x轴的第9点,管道有一个已知的半径r。我正试图找出如何让我的脚本输出的液体总量(按r表示),不管时间如何,它都会被清空。如果通过损坏管道中的漏洞,空气就会进来,水就会出来,但不是所有的水都会因为管道的不同渔获量和不同的高度而产生。
发布于 2018-07-20 15:46:47
如果我正确理解这个问题,我认为可以通过从泄漏点左右遍历管道来实现这一点。在每个点上,将目前的水位与管道的高度进行比较,要么形成一个水位保持不变的淹没点,要么形成一个海滩和一个新的干峰。插值是计算海滩位置所必需的。
实现如下所示。算法的大部分在traverse函数中。希望这些评论能提供充分的说明。
#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as pp
# Positions and elevations
n = 25
h = np.random.random((n, ))
x = np.linspace(0, 1, h.size)
# Index of leak
leak = np.random.randint(0, h.size)
# Traverse a pipe with positions (x) and elevations (h) from a leak index
# (leak) in a direction (step, +1 or -1). Return the positions of the changes
# in water level (y) the elevations at these changes (g) and the water level
# values (w).
def traverse(x, h, leak, step):
# End of the index range for the traversal
end = h.size if step == 1 else -1
# Initialise 1-element output arrays with values at the leak
y, g, w = [x[leak]], [h[leak]], [h[leak]]
# Loop from the index adjacent to the leak
for i in range(leak + step, end, step):
if w[-1] > h[i]:
# The new height is less than the old water level. Location i is
# submerged. No new points are created and the water level stays
# the same.
y.append(x[i])
g.append(h[i])
w.append(w[-1])
else:
# The new height is greater than the old water level. We have a
# "beach" and a "dry peak".
# ...
# Calculate the location of the beach as the position where the old
# water level intersects the pipe section from [i-step] to [i].
# This is added as a new point. The elevation and water level are
# the same as the old water level.
# ...
# The if statement is not strictly necessary. It just prevents
# duplicate points being generated.
if w[-1] != h[i-step]:
t = (w[-1] - h[i-step])/(h[i] - h[i-step])
b = x[i-step] + (x[i] - x[i-step])*t
y.append(b)
g.append(w[-1])
w.append(w[-1])
# ...
# Add the dry peak.
y.append(x[i])
g.append(h[i])
w.append(h[i])
# Convert from list to numpy array and return
return np.array(y), np.array(g), np.array(w)
# Traverse left and right
yl, gl, wl = traverse(x, h, leak, -1)
yr, gr, wr = traverse(x, h, leak, 1)
# Combine, reversing the left arrays and deleting the repeated start point
y = np.append(yl[:0:-1], yr)
g = np.append(gl[:0:-1], gr)
w = np.append(wl[:0:-1], wr)
# Output the total volume of water by integrating water level minus elevation
print('Total volume =', np.trapz(w - g, y), 'm^3 per unit cross sectional area')
# Display
pp.plot(x, h, '.-', label='elevation')
pp.plot(y, w, '.-', label='water level')
pp.plot([x[leak]], [h[leak]], 'o', label='leak')
pp.legend()
pp.show()

发布于 2018-07-13 23:32:19
对于半径恒定且半径比高程变化小得多的管道,即管道的截面总是充满水。我认为,在这种情况下,它不工作,如果管道是在末端,一些空气必须进入,让水流出。剩余的部分被水填充在左边自由表面(绿色圆)和右边自由表面(红色正方形)之间。为了简单起见,假定管道的两端都是最高海拔点,否则管道就会自动清空。平衡可能是不稳定的。
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def find_first_intersection(x, y, y_leak):
for i in range(len(x)-1):
dy_left = y[i] - y_leak
dy_right = y[i+1] - y_leak
if dy_left*dy_right < 0:
x_free = x[i] + (y_leak - y[i])*(x[i+1] - x[i])/(y[i+1] - y[i])
break
return x_free
# Generate random data
x = np.linspace(0, 1, 10)
y = np.random.rand(*np.shape(x))
y[0], y[-1] = 1.1, 1.1
x_leak = np.random.rand(1)
# Look for the free surfaces
y_leak = np.interp(x_leak, x, y)
x_free_left = find_first_intersection(x, y, y_leak)
x_free_right = find_first_intersection(x[::-1], y[::-1], y_leak)
# Plot
plt.plot(x, y, '-', label='pipe');
plt.plot(x_leak, y_leak, 'sk', label='leak')
plt.axhline(y=y_leak, linestyle=':', label='surface level');
plt.plot(x_free_left, y_leak, 'o', label="left free surface");
plt.plot(x_free_right, y_leak, 's', label="right free surface");
plt.legend(bbox_to_anchor=(1.5, 1.)); plt.xlabel('x'); plt.ylabel('y');

我在图表上添加了一些注释。我觉得令人费解的是,水会留在“令人费解的地方”,因为我认为这只适用于非常小直径的喉管。对于一个更大的管道,这里的水会流过泄漏,然后估计管道的剩余填充部分是更复杂的。
https://stackoverflow.com/questions/51315072
复制相似问题