При движении среды по трубопроводу зависимость потерь давления в трубопроводе от расхода является квадратичной зависимостью:
$$\Delta p = RQ^2,$$где $R$ - коэффициент, задающий крутизну параболы. Чем больше значение $R$, тем круче парабола. Назовём $R$ гидравлическим сопротивлением (по аналогии с электрическим сопротивлением). Для определения значения $R$ необходимо найти расчётным или опытным путём потери давления в трубопроводе при каком либо расходе.
Под потерями давления подразумевается снижение значения полного давления, вызванное потерями энергии при движении среды в связи с наличием трения и местными потерями. Нивелирная составляющая (давление, вызванное разницей в высотных положениях входного и выходного сечения трубопровода) не должна входить в $\Delta p$. Размерности величин расхода и давлений не важны, главное - не менять выбранные размерности во время дальнейшего расчёта. В нашем случае потери давления будут выражаться в метрах столба жидкости $\Delta H \equiv \Delta p$, а расход в $м^3/ч$.
Один раз определив для трубопровода значение $R$, мы сможем находить значение потерь давления для любого расхода, а так же по потерям давления определять расход. Следует заметить, что значение коэффициента трения при при малых скоростях движения среды зависит от скорости движения среды. В связи с этим, при низких скоростях движения среды, значение $R$ при разных расходах будет отличаться.
from scipy.interpolate import interp1d #класс для интерполяции для моделирования
#напорной характеристики насоса
import numpy as np #работа с массивами
from math import sqrt
class Pipeline(object):
"""Объект трубопровод"""
def __init__(self, Q, dH):
"""
Q, dH: значение расхода и потерь давления при заданном расходе (единицы измерения не важны)
"""
self.Q = Q
self.dH = dH
self.R = dH / Q / Q # гидравлическое сопротивление
def dH_Q(self, Q, H_start = 0):
"""
Q: расход через трубопровод
H_start: - начальная ордината, откуда выходит характеристика сети
return: значение потерь давления при заданном расходе + H_start
"""
return self.R * Q * Q + H_start
def Q_dH(self, dH, H_start = 0 ):
"""
dH: потери давления
return: расход, при котором потери давления составляют dH - H_start
"""
return sqrt((dH - H_start) / self.R)
def get_curve (self, Qmin, Qmax, H_start=0., n=51):
"""
Возвращает характеристику трубопровода
Qmin: начальная абсцисса
Qmax: конечная абсцисса
H_start: значение H при Q = 0
n: число точек в графике
return: кортеж (Q, H), где Q - список значений расхода,
H - список значений потерь давления для заданных Q
"""
H = []
Q = []
dq = (Qmax - Qmin) / (n-1)
q = Qmin
for _ in range(n):
Q.append(q)
H.append(self.dH_Q(q) + H_start)
q += dq
return Q, H
В приведённом выше коде класса Pipeline
требует пояснения переменная H_start
- начальная ордината характеристики трубопровода. Данная переменная нужна для приведения системы координат характеристики трубопровода к системе коодинат напорной характеристики насоса.
Предположим, что насос качает жидкость из бака, уровень жидкости в котором относительно оси всаса насоса составляет 4 м. Уровень жидкости в баке поддерживается постоянным вне зависимости от величины расхода из него. Высотное положение конца трубопровода такое же как и у его начала (всаса насоса), жидкость из трубопровода выливается в приёмный бак, уровень жидкости в котором расположен ниже оси трубопровода.
В данном случае часть работы по преодолению сопротивления трубопровода движению жидкости совержается за счёт давления столба жидкости высотой 4 метра. Данный столб жидкости можно рассматривать как насос с напором 4 м, установленный на всасе исследуемого насоса. Расход через трубопровод будет больше, чем в случае отсутствия "помощника". Чтобы отразить в системе координат напорной характеристики исследуемого насоса наличие "помощника" и увеличения в связи с этим расхода, начало характеристики трубопровода необходимо сместить на 4 метра вниз, т.е. значение нивелирной составляющей потери напора составляетH_start = -4
.
Теперь рассмотрим случай, когда уровень жидкости в баке-источнике ниже уровня жидкости в баке-приёмнике на те же 4 м. В этом случае исследуемый насос, кроме сопротивления трубопровода, должен совершить работу по подъёму жидкости на высоту 4 метра. Расход жидкости в трубопроводе будет меньше, чем при отсутствии необходимости подъёма жидкости. Чтобы отразить в системе координат напорной характеристики исследуемого насоса уменьшение расхода в связи с необходимостью совершения насосом дополнительной работы по подъёму жидкости, точка начала характеристики трубопровода сдвигается на 4 метра вверх, т.е. значение нивелирной составляющей потери напора составляет H_start = 4
.
Пусть имеется трубопровод потери давления в котором при расходе $Q = 3\ м^3/ч$ составляют $\Delta H = 14\ м$
Q_nom = 3; dH_nom = 14
pl = Pipeline(Q_nom, dH_nom) #создаём объект Трубопровод
Так же нам нужен насос.
Пример моделирования напорной характеристики насоса с учётом производственных допусков по подаче и напору и с учётом деградации рабочих характеристик насоса с течением времени см. в статье Моделирование напорной характеристики насоса. В данной статье в качестве примера будет взят тот же насос.
#Возьмём несколько точек с напорной характеристики (включая две крайних)
Qs = np.array([1.19, 2, 3, 4, 4.43])
Hs = np.array([18.01, 16.55, 13.64, 8.91, 6.14])
#Напорная характеристика насоса
f_pump = interp1d(Qs, Hs, kind = 'cubic')
Qs_int = np.linspace(Qs[0], Qs[-1], 51) #значения подач для построения напорной характеристики насоса
Qs_pl, Hs_pl = pl.get_curve(0, 4) #создаём набор точек для построения характеристики трубопровода
Hs_pl = np.array(Hs_pl)
height = 4 #нивелирная составляющая, м
#https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brentq.html#scipy.optimize.brentq
from scipy.optimize import brentq #решение нелинейных уравнений
#Функция для поиска решения. Решение - значение Q при котором функция возвращает ноль.
#Данная функция передаётся в качестве первого параметра в brentq,
#который ищет Q при котором функция возвращает ноль,
#второй и третий параметр brentq - границы диапазона, внутри которого ищется решение.
def f(Q):
return pl.dH_Q(Q) + H_start - f_pump(Q)
#Варианты значений нивелирных составляющих
Hs_start = [-height, 0, height]
#С помощью brentq найдём значения Q точек пересечения характеристик трубопроводов с напорной
#характеристикой насоса (поиск корня нелинейного уравнения pl.dH_Q(Q) + H_start - f_pump(Q) = 0)
Qs_pl_pump = []
for h in Hs_start:
H_start = h
Qs_pl_pump.append(brentq(f,Qs[0], Qs[-1]))
#Найдём значения H точек пересечения характеристик трубопроводов с напорной характеристикой насоса
Hs_pl_pump = []
for i in range(len(Hs_start)):
Hs_pl_pump.append(pl.dH_Q(Qs_pl_pump[i], Hs_start[i]))
import matplotlib.pyplot as plt #библотека для построения графиков
plt.rcParams['figure.figsize'] = [14, 7]
plt.rcParams.update({'font.size': 14})
plt.plot(Qs_int, interp1d(Qs, Hs, kind='cubic')(Qs_int), label = "Напорная характеристика насоса")
plt.plot(Qs_pl, Hs_pl, label = "Нивелирная составляющая отсутствует")
plt.plot(Qs_pl, Hs_pl + height, label = "Подъём жидкости на 4 м")
plt.plot(Qs_pl, Hs_pl - height, label = "Подпор 4 м столба жидкости на всасе ")
plt.plot(Qs_pl_pump, Hs_pl_pump, 'o', label = "Найденные с помощью brentq решения")
plt.xlabel('$Q, м^3/ч$'); plt.ylabel('$H, м$')
plt.xlim(Qs[0],Qs[-1]); plt.ylim(Hs[-1],Hs[0])
plt.xlim(0, 4.6); plt.ylim(-4, 20)
plt.xticks(np.arange(0, 4.61, 0.2)); plt.yticks(np.arange(-4, 21, 2))
plt.legend(); plt.grid()
Инженерные расчёты на Python, С.В. Медведев, 2020
Использование Python и Jupyter Notebook для инженерных расчётов, С.В. Медведев, 2020