С самого начала численного подхода к моделированию коллектора основная задача остается неизменной - повышение скорости вычислений. С недавнего времени модели машинного обучения привлекают особое внимание как возможное приближение обычных численных моделей. Однако эта исследовательская деятельность ограничена сложностью данных о коллекторе, а также черным ящиком инструментов промышленного моделирования. Редкие, но популярные инструменты с открытым исходным кодом основаны на C или Matlab, что также ограничивает реализацию передовых моделей глубокого обучения. Сегодня мы начинаем серию публикаций, которые знакомят с современным подходом к моделированию коллектора на основе Python. Постепенно мы перейдем от простых вопросов о том, как считывать и сохранять данные, к тому, как обучить модель нейронной сети моделировать динамику коллектора и выполнять адаптацию коллектора (сопоставление истории).
В Части I мы узнаем, из чего состоит модель коллектора и как правильно читать все данные.
Часть II объясняет, как извлекать небольшие порции данных из набора моделей коллектора и преобразовывать данные в тензоры факелов.
Как представить модель коллектора на Python
Чтобы описать модель коллектора, необходимо указать ее геометрию, свойства породы и флюида в каждой точке, расположить добывающие и нагнетательные скважины, а также указать действия, применяемые к пласту, и контролировать его динамику. Позже мы рассмотрим эти компоненты более подробно, теперь нам достаточно нескольких общих стандартов для описания всех этих свойств в текстовых / числовых файлах и для определенности будем придерживаться формата ECLIPSE (работа с композитным форматы аналогичны).
Типичный проект ECLIPSE состоит из основного файла с расширением .DATA и набора дополнительных включенных текстовых / двоичных файлов с различными расширениями. Например, здесь - это образец проекта (папка RESULTS обычно большая, и мы заархивировали ее для экономии места на диске).
Первым шагом в исследовании резервуара является чтение всех файлов, представляющих резервуар, в массивы Python. Для этого воспользуемся фреймворком с открытым исходным кодом DeepField.
Чтобы установить пакет DeepField, запустите pip install git + https: //github.com/Skoltech-CHR/DeepField.git в терминале. В качестве альтернативы можно использовать предоставленный файл сборки docker.
Репозиторий DeepField https://github.com/Skoltech-CHR/DeepField содержит набор общедоступных моделей резервуаров в каталоге open_data. Мы рекомендуем клонировать все репо, чтобы получить данные локально. В частности, мы будем использовать предоставленную модель norne_simplified. После загрузки модели распакуйте архив RESULTS.zip, чтобы все было готово.
Чтобы загрузить модель в Python, мы импортируем класс Field из пакета deepfield, указываем путь к файлу .DATA и вызываем метод загрузки, как показано во фрагменте кода ниже. :
Загрузка данных занимает некоторое время, и вы увидите множество сообщений журнала, рассказывающих, что происходит в данный момент.
Чтобы пропустить сообщения, передайте параметр loglevel = ’ERROR 'в конструктор Field . Ниже мы также покажем, как существенно ускорить загрузку.
В конце сообщений журнала вы увидите сводку того, что было загружено пчелами:
INFO:Field:===== Field summary ===== INFO:Field:GRID attributes: MAPAXES, ZCORN, COORD, ACTNUM, DIMENS INFO:Field:ROCK attributes: PORO, PERMX, PERMY, PERMZ INFO:Field:STATES attributes: PRESSURE, RS, SGAS, SOIL, SWAT INFO:Field:TABLES attributes: PVTO, ROCK, PVTW, DENSITY, SWOF, SGOF, PVDG INFO:Field:WELLS attributes: WCONINJE, COMPDAT, WELSPECS, WCONPROD, RESULTS INFO:Field:=========================
Существует набор компонентов с именами GRID, ROCK, STATES, TABLES и WELLS, и каждый компонент содержит набор атрибутов. Например, компонент ROCK содержит атрибуты PORO, PERMX, PERMY и PERMZ (в руководстве ECLIPSE они также называются ключевыми словами). Прежде чем мы начнем подробно рассматривать каждый компонент и атрибут, давайте визуализируем сразу всю модель, используя метод model.show ().
model.show () включает интерактивную 3D-визуализацию. Передайте имя атрибута в метод show, чтобы указать геологическое свойство. Например, model.show (‘PORO’) визуализирует поле пористости. Подробнее о параметрах метода show см. Документацию.
Первоначальное месторождение Норн расположено на норвежском континентальном шельфе и широко используется в качестве эталонной модели. Ниже мы видим упрощенный вариант модели (в частности, без разломов), однако геометрические свойства и стволы сохранены.
Теперь перейдем к компонентам модели.
Сетка
Сетка описывает геометрию (форму) коллектора. Исходя из подхода конечно-разностного моделирования, пространственная форма модели коллектора дискретизируется на более мелкие части, называемые блоками сетки (или ячейками). Если все ячейки имеют правильную форму и одинаковый размер, мы получаем равномерную ортогональную сетку. Чтобы задать такую сетку, необходимо задать количество ячеек в каждом направлении (скажем, nx, ny и nz) и ее размеры (скажем, dx, dy, dz). Это наиболее простой тип сетки, и для ее полного определения требуется всего 6 чисел.
Как узнать пространственные характеристики подземного резервуара? Когда-то давно это было результатом бурения нескольких скважин. В настоящее время сейсморазведка помогает лучше описать коллекторы.
Модель Норна имеет более сложную сеточную структуру, в которой ячейки имеют неправильную форму и разный размер. Для задания такой сетки необходимо задать координаты углов каждой ячейки. Это тип сетки угловых точек, который в соответствии со стандартом ESCLIPSE описывается ключевыми словами DIMENS, ZCORN и COORD. Для доступа к соответствующим числовым массивам используйте model.grid.dimens, model.grid.zcorn и model.grid.coord.
Чтобы получить список доступных атрибутов (ключевых слов) в компоненте модели (в частности, компоненте сетки) введите model.grid.attributes. Обратите внимание, что атрибуты не чувствительны к регистру, поэтому model.grid.zcorn и model.grid.ZCORN одинаковы.
В частности, model.grid.dimens дает [46, 112, 22] - количество ячеек в направлениях x, y и z. Тогда model.grid.coord представляет собой массив формы (47, 113, 6) и содержит (x, y, z) координаты верхней и нижней точек столбов. которые образуют клетки. Наконец, model.grid.zcorn представляет собой массив формы (46, 112, 22, 8) и содержит глубину 8 углов для каждой ячейки. На рисунке ниже показаны эти ключевые слова для одной ячейки:
Есть несколько атрибутов компонента сетки, которые могут быть полезны в различных вычислениях:
- cell_volumes дает массив объемов ячеек;
- xyz содержит (x, y, z) координаты углов ячеек;
- cell_centroids возвращает координаты (x, y, z) центров ячеек.
Дополнительные атрибуты и методы (например, ортогонализация, масштабирование и уменьшение) см. В документации и записной книжке по классу Grid.
Рок и Штаты
Имея сетку, мы можем присвоить каждой ячейке набор статических и временных свойств. Ключевыми статическими свойствами являются тензор пористости и проницаемости породы. Грубо говоря, они описывают, сколько жидкости может содержать ячейка и насколько хорошо жидкость может течь в каждом направлении. Соответствующие атрибуты PORO, PERMX, PERMY. PERMZ содержатся в компоненте model.rock. Каждый атрибут задается массивом формы, равной model.grid.dimens. Ниже поля проницаемости показаны в 3D (с использованием метода model.show (‘PERMX’), например, для поля PERMX).
Исходные свойства породы получены из интерпретации ГИС и образцов керна. Затем информация, передаваемая по скважинам, распространяется на всю модель с использованием сейсмических профилей.
В отличие от компонента Rock, содержащего статические поля горных пород, компонент State содержит динамические поля, которые описывают давление, насыщенность нефтью / водой / газом и содержание газа в каждой ячейке. Соответствующие атрибуты - ДАВЛЕНИЕ, ПОЧВА, SWAT, SGAS и RS - задаются массивом 4D. Первая ось представляет временные шаги, а последние 3 - пространственные размеры модели. На анимации ниже показано, как давление изменяется во времени:
Следует отметить, что любое преобразование сетки (апскейлинг, даунскейлинг) требует нетривиальной повторной интерполяции свойств. Мы оставляем это за рамками Части I и обращаемся к блокнотам этот и этот за подробностями.
Уэллс
Набор колодцев удобно представить в виде древовидной структуры, где корень - это само поле, а группы колодцев, основные и конечные ветви колодцев - узлы. Метод model.wells.render_tree () показывает общую структуру дерева:
FIELD |-- INJE | |-- MANI-C | | |-- C-1H | | |-- C-2H | | |-- C-3H | | |-- C-4AH | | +-- C-4H | |-- MANI-F | | |-- F-1H | | |-- F-2H | | |-- F-3H | | +-- F-4H | +-- WI-GSEG +-- PROD |-- MANI-B2 | |-- B-1AH | |-- B-1BH | |-- B-1H | +-- B-3H |-- MANI-B1 | |-- MANI-K1 | +-- B1-DUMMY | |-- B-2H | |-- B-4AH | |-- B-4BH | |-- B-4DH | +-- B-4H |-- MANI-D1 | |-- D-1CH | |-- D-1H | |-- D-3AH | |-- D-3BH | +-- D-3H |-- MANI-D2 | |-- MANI-K2 | | +-- K-3H | +-- D2-DUMMY | |-- D-2H | |-- D-4AH | +-- D-4H |-- MANI-E1 | |-- E-1H | |-- E-3AH | |-- E-3BH | |-- E-3CH | +-- E-3H +-- MANI-E2 |-- E-2AH |-- E-2H |-- E-4AH +-- E-4H
Мы наблюдаем две основные группы: добывающие скважины (PROD) и нагнетательные скважины (INJE). Листовые узлы, например D-1CH, представляют собой отдельные лунки.
К каждому узлу можно получить доступ по его имени, например model.wells [‘B-4AH’]. Мы можем перечислить атрибуты, назначенные узлу, с помощью model.wells [‘B-4AH’]. Attributes. В результате получается список (WELSPECS, COMPDAT, RESULTS, WELLTRACK), который мы рассмотрим более подробно.
Большинство атрибутов представлены в виде таблиц pandas.DataFrame, что упрощает управление ими. Например, COMPDAT содержит информацию об открытии и закрытии интервалов перфорации:
Аналогично WCONPROD содержит параметры управления скважиной (в частности, забойное давление, BHPT):
Самая важная таблица - РЕЗУЛЬТАТЫ, которая содержит показатели добычи нефти / воды / газа (WOPR, WWPR. WGPR):
Скорость добычи можно визуализировать с помощью метода model.wells.show_rates (). Это включает интерактивную панель, на которой можно исследовать общие ставки:
или каждый узел в отдельности (скважина или группа скважин):
В следующих частях мы обсудим, как рассчитать факторы связности, дебиты, а также другие важные характеристики скважины. См. Также документацию и блокнот для дополнительных действий, например отслеживание блоков.
Таблицы PVT
Физические свойства жидкости (например, объем, вязкость, сжимаемость) зависят от давления и температуры. Отношения приведены в наборе таблиц PVT (давление-объем-температура), а также зависимости относительной проницаемости от насыщения. Таблицы содержатся в компоненте model.tables, а model.tables.attributes показывает его имена. Например, модель Norne содержит свойства PVTO, ROCK, PVTW, DENSITY, SWOF, SGOF и PVDG.
На первый взгляд таблицы выглядят как обычные объекты pandas.DataFrame. Например, ПВДГ:
Таблица PVDG описывает свойства мертвого газа и дает зависимость объемного коэффициента газообразования и вязкости газа от давления.
Как получить вязкость газа, которая соответствует, скажем, давлению = 80 или 100 (обратите внимание, что эти значения отсутствуют в таблице)? Фактически, каждая таблица требует определенной модели интерполяции (не обязательно линейной). По волшебству каждая таблица работает как функция! Вызов таблицы с набором новых значений дает интерполированные результаты:
Наконец, используя метод plot (), можно визуализировать физические зависимости:
Каждое значение в таблицах PVT является результатом физических измерений и экспериментов. Вот почему данные немногочисленны и важна интерполяция.
Больше практических примеров по PVT-таблицам можно найти в этой записной книжке.
Как ускорить ввод-вывод данных
Изменяя данные коллектора, можно сохранить проект в проекте ECLIPSE следующим образом: model.dump (‘path_to_the_directory_where_to_save’). Это обеспечивает совместимость со стандартным программным обеспечением для моделирования. Однако чтение данных из таких форматов происходит очень медленно. Значительно выигрывает работа с файлами .HDF5. Чтобы преобразовать модель в файл .HDF5, используйте model.dump (‘filename.hdf5’). Теперь сравним скорость загрузки данных модели Норна:
Загрузка модели из файла .HDF5 происходит более чем в 10 раз быстрее! Это важно, в частности, для исследований в области машинного обучения, когда у нас будет набор моделей резервуаров и мы будем многократно загружать их для обучения некоторых моделей машинного обучения.
Выводы
Типичное исследование моделей коллектора требует большой работы по предварительной обработке данных. Это ограничивает реализацию современных методов, широко используемых в проектах на основе Python. Фреймворк на основе Python DeepField - это новая инициатива с открытым исходным кодом, направленная на соединение моделей ML / DL и задач моделирования коллектора. В этом посте мы рассмотрели основные этапы загрузки данных и кратко описали основные компоненты и атрибуты моделей пластов. Следуя этой записной книжке, можно воспроизвести результаты. В следующих частях мы рассмотрим более сложные темы.
Что дальше
- Рассмотрим обучающие программы, представленные в репозитории DeepField. Они дают более практические примеры методов и атрибутов.
- Проект DeepField продолжает развиваться. Мы приветствуем вопросы и PR на странице проекта GitHub, а также любое сотрудничество!
- В следующей части мы обсудим, как работать с несколькими моделями пласта и проводить вычисления на GPU.
Автор Егор Илларионов.