Максимизация дебита газа в системе сбора куста газовых скважин#
Производственная необходимость управления параметрами системы сбора (ССБ) продукции скважин, при наличии цифровой технологической модели, обусловлена необходимостью решения следующих задач:
Расчёт параметров ССБ на предмет соответствия техническому проекту разработки месторождения углеводородного сырья (УВС);
Обеспечения максимальной добычи УВС в пиковый период (зима, спрос) и минимальной добычи (лето, спрос);
Обеспечения оптимальных параметров работы ССБ при:
Незапланированном отключении одной или нескольких скважин;
Режимах работы скважин, не соответствующих проектным;
Определение параметров ССБ при изменении входных параметров системы подготовки газа и конденсата.
В данном практическом руководстве рассматривается задача максимизации потока (дебита) в системе сбора газа на кусте, содержащего две газовых скважины. Упрощённая система сбора включает несколько участков трубопроводов и 2 штуцера, в которых необходимо определить диаметры их отверстий.
Решение данной оптимизационной задачи позволит максимизировать дебит газа и поможет избежать в системе сбора возникновения потоков в не предусмотренных направлениях.
1. Подготовка модели системы сбора газа на платформе REPEAT VISION#
В приложении REPEAT VISION создайте новый проект с названием, например, Система сбора газа.
В процессе подготовки проекта на платформе REPEAT VISION будет продемонстрировано создание модели системы сбора газа на кусте газовых скважин (КГС), представленной на рисунке ниже.
Проект системы сбора газа на кусте двух газовых скважин#
Для создания модели системы сбора газа используется библиотека блоков Пневматика платформы REPEAT VISION.
В модели системы сбора газа принимаются следующие обозначения: левый и правый шлейфы являются входными участками трубопроводов, а нижний трубопровод принимается выходным участком системы трубопроводов.
Важно
Следует отметить, что при значительной разнице давления на устьях скважин возможно образование обратного потока, когда газ движется не только от устья одной скважины в коллектор, но и задавливает другую скважину, снижая общий дебит газа на КГС.
Для предупреждения подобных ситуаций на трубопроводных шлейфах КГС используют штуцеры.
1.1. Порядок создания модели системы сбора#
В новом проекте Система сбора газа необходимо использовать настройки модели, приведённые на рисунке ниже.
Настройки проекта#
Начнём создание модели системы сбора газа с добавления трёх блоков Резервуар (П) с различными давлениями (блоки №1, 2, 3).
Резервуары с разным давлением#
Расположите резервуары следующим образом:
Расположение резервуаров#
Первые два резервуара, предназначенные для задания давления на устьях скважин, будем считать входными и будем их обозначать как левый и правый (в коде, соответственно, будем добавлять left и right к переменным, обозначающим параметры этих резервуаров).
Третий резервуар, предназначенный для задания давления в коллекторе, считается выходным (в коде его будем обозначать как total).
Подключим к ним три одинаковых Участка трубопровода (П) (блоки №4, 5, 6) со следующими параметрами.
Параметры участка трубопровода#
Расположите участки трубопровода следующим образом:
Расположение участков трубопровода#
Для последующего изменения площади сечения отверстий в рамках решения оптимизационной задачи, создадим две глобальные переменные, приведённые в таблице ниже.
Имя переменной |
Значение переменной |
Назначение |
|---|---|---|
area_left |
0.02 |
Площадь сечения отверстия в левом входном канале тройника |
area_right |
0.02 |
Площадь сечения отверстия в правом входном канале тройника |
К двум из трех участков трубопровода подключим блоки Отверстие (П) (блоки №7, 8). Установим Тип отверстия как Постоянный. Площадь вне отверстия установим равной площади сечения трубы в пересчете из заданного для нее диаметра, а в качестве площади сечения отверстия укажем имена созданных переменных.
Параметры отверстий#
Расположите отверстия следующим образом:
Расположение отверстий#
Замкнем все созданные элементы на Узел (П) (блок №9) с двумя входами и одним выходом на участок без отверстия. Соединим все созданные блоки перевернув некоторые из них:
Подключение узла#
Для получения результатов расчёта потоков газа на разных участках системы трубопроводов, добавим Датчик расхода (П) (блоки №10, 12, 14) на каждый участок трубопровода.
Датчики расхода необходимо соединить с блоками Выходной порт (блоки №11, 13, 15) для последующего подключения оптимизатора к модели системы сбора.
Так, например, для левой ветви связанным блоком для датчика расхода является блок №4 Участок трубопровода (П), а у выходного порта (блок №11) указано пользовательское название massflow_left.
Подключение датчика расхода и выходного порта#
По аналогии добавим Датчик расхода (П) и Выходной порт к остальным участкам трубопровода, укажем в качестве пользовательского названия massflow_right и massflow_total соответственно. В итоге получаем следующую схему:
Подключение датчиков расхода и выходных портов#
Попробуем провести расчет:
Запуск расчёта#
Как видим, в левой ветке тройника зафиксирован обратный поток, а значит ток через нижнюю ветку не максимальный.
Показания датчика расхода (блок №10)#
Таблица результатов запуска
Датчик расхода |
Массовый расход, кг/с |
|---|---|
Левый |
-50.707848 |
Правый |
288.25247 |
Нижний |
237.54462 |
Проведем оптимизацию размеров отверстий, чтобы максимизировать поток через нижнюю ветку тройника.
2. Решение оптимизационной задачи с помощью ноутбука JupyterLite#
Запустим среду разработки JupyterLite, перейдя во вкладку Инструменты, выбрав Ноутбук. В открывшемся интерфейсе создадим блокнот для Python, нажав в Лаунчере на кнопку Python(Pyodide).
В открывшемся файле создадим ячейку с кодом. Установим необходимые библиотеки:
import piplite
await piplite.install('repeat')
Теперь импортируем все необходимые библиотеки. Отметим сразу, что будем использовать алгоритм дифференциальной эволюции, его реализацию из библиотеки scipy.
import pandas as pd
import numpy as np
import repeat as rp
from scipy.optimize import differential_evolution
Подключимся к необходимому проекту, используя свой токен и id созданного ранее проекта с постановкой задачи.
user = rp.User(token = YOUR_TOKEN)
app = rp.Application(user)
project = PROJECT_ID
t_interval = rp.TimeInterval(start = 1, end = 1000)
model = app.get_exploration_model(project, t_interval)
Учитывая, что для некоторых параметров расчет может быть не вещественен и выдаст ошибку, добавим обработку таких случаев с помощью конструкции try ... except.
def calculate_massflows(diameter_left: float,
diameter_right: float,
model) -> dict:
"""
Вычисляет массовые потоки на основании заданных диаметров.
Parameters
----------
diameter_left : float
Диаметр отверстия в левом канале тройника.
diameter_right : float
Диаметр отверстия в правом канале тройника.
Returns
-------
results : dict
Словарь с величинами потоков в соответствующих каналах тройника.
"""
area_left = np.pi * (diameter_left / 2) ** 2
area_right = np.pi * (diameter_right / 2) ** 2
variables = pd.Series({'area_left': area_left,
'area_right': area_right},
dtype=float)
try:
with model as md:
md.run(variables)
massflow_left = md.get_results('massflow_left').iloc[-1]
massflow_right = md.get_results('massflow_right').iloc[-1]
massflow_total = md.get_results('massflow_total').iloc[-1]
results = {
'massflow_left': massflow_left,
'massflow_right': massflow_right,
'massflow_total': massflow_total
}
except rp.errors.REPEATSolverError as e:
print(f"Ошибка: невозможно получить результаты для параметров ({area_left}, {area_right}): {e}")
results = {
'massflow_left': -np.inf,
'massflow_right': -np.inf,
'massflow_total': -np.inf
}
return results['massflow_total']
Поставим задачу оптимизации для перебора радиусов отверстий и ограничим число итераций через задание размера популяции.
Важно
Обратите внимание на знак минус перед целевой функцией calculate_massflows в коде программы ниже. Знак минус необходим оптимизатору для определения максимального расхода газа.
В ином случае оптимизатор будет решать задачу минимизации значения целевой функции.
Дополним постановку задачи, указав границы значений, которые могут принимать диаметры:
bounds = [(0.01, 0.2), (0.01, 0.2)]
Вызовем метод оптимизации, передав в него функцию calculate_massflows, и выведем возвращаемые параметры. Подробнее про то, что означают параметры popsize и maxiter можно прочитать тут.
result = differential_evolution(
func = lambda diameters: - calculate_massflows(diameters[0], diameters[1], model
),
bounds = bounds,
popsize=3,
maxiter=3
)
optimal_diameters = result.x
max_value = - result.fun
print("Оптимальные параметры:",
f"diameter_left={optimal_diameters[0]}",
f"diameter_right={optimal_diameters[1]}",
sep = "\n")
print(f"Максимальное значение функции: {max_value}")
В результате алгоритм найдет максимальный возможный поток и значения диаметров отверстий, при которых он достигается.
Оптимальные параметры:
diameter_left=0.024924022453932757
diameter_right=0.2
Максимальное значение функции: 444.67108
См. также
Функция differential_evolution пакета scipy является одним из возможных алгоритмов оптимизации, который можно использовать в данной задаче.
Также могут применяться другие подходы, например:
2.1. Код всей программы#
import piplite
await piplite.install('repeat')
import pandas as pd
import numpy as np
import repeat as rp
from scipy.optimize import differential_evolution
user = rp.User(token = YOUR_TOKEN)
app = rp.Application(user)
project = PROJECT_ID
t_interval = rp.TimeInterval(start = 1, end = 1000)
model = app.get_exploration_model(project, t_interval)
def calculate_massflows(diameter_left: float,
diameter_right: float,
model) -> dict:
"""
Вычисляет массовые потоки на основании заданных диаметров.
Parameters
----------
diameter_left : float
Диаметр отверстия в левом канале тройника.
diameter_right : float
Диаметр отверстия в правом канале тройника.
Returns
-------
results : dict
Словарь с величинами потоков в соответствующих каналах тройника.
"""
area_left = np.pi * (diameter_left / 2) ** 2
area_right = np.pi * (diameter_right / 2) ** 2
variables = pd.Series({'area_left': area_left,
'area_right': area_right},
dtype=float)
try:
with model as md:
md.run(variables)
massflow_left = md.get_results('massflow_left').iloc[-1]
massflow_right = md.get_results('massflow_right').iloc[-1]
massflow_total = md.get_results('massflow_total').iloc[-1]
results = {
'massflow_left': massflow_left,
'massflow_right': massflow_right,
'massflow_total': massflow_total
}
except rp.errors.REPEATSolverError as e:
print(f"Ошибка: невозможно получить результаты для параметров ({area_left}, {area_right}): {e}")
results = {
'massflow_left': -np.inf,
'massflow_right': -np.inf,
'massflow_total': -np.inf
}
return results['massflow_total']
bounds = [(0.01, 0.2), (0.01, 0.2)]
result = differential_evolution(
func = lambda diameters: - calculate_massflows(
diameters[0], diameters[1], model
),
bounds = bounds,
popsize = 3,
maxiter = 3
)
optimal_diameters = result.x
max_value = - result.fun
print("Оптимальные параметры:",
f"diameter_left={optimal_diameters[0]}",
f"diameter_right={optimal_diameters[1]}",
sep = "\n")
print(f"Максимальное значение функции: {max_value}")
# Оптимальные параметры:
# diameter_left=0.024924
# diameter_right=0.2
# Максимальное значение функции: 444.67108
3. Вывод#
В результате выполнения данного практического руководства вы получили навыки применения метода параметрической оптимизации совместно с моделью системы сбора газа на платформе REPEAT VISION.
Используемый алгоритм дифференциальной эволюции позволил определить оптимальные размеры отверстий, обеспечивающие максимальный поток через выходной участок трубопровода.
Полученные результаты подтверждают эффективность подхода для решения инженерных оптимизационных задач, позволяющих как проектировать трубопроводные системы, так и эффективно сопровождать эксплуатацию существующих промысловых объектов.