-
Notifications
You must be signed in to change notification settings - Fork 473
A new X-MeshGraphNet example for reservoir simulation. #1186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
cd58455
784342c
b6c172f
388ce1c
bbe573e
65d335a
e4cf2ce
95b1aac
91b56f4
7508549
a2cdfaf
be88a7d
97613c2
bb0bd8a
69d82dd
f635750
b8b6003
8ce3778
d705514
803c377
0c910f9
0635fd1
8a73d0b
db2e534
37aa62e
616c78d
8c5a8dc
048d693
bb2fc5d
444d92f
6c524e1
295cf6b
76cf0a0
17e44e8
d81302c
f2c87d3
0656882
a3109b4
ba5e928
2a0e61b
1d8cf62
c1c9edf
c95f833
cec0923
859a651
fcc5420
d492de4
84b3e6f
744cabd
271fabb
b29cf29
7279bd0
5bdeac1
149c6c0
965f0ca
3978c9f
bdfc71c
21bcf76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| # Simulation Utilities | ||
|
|
||
| ## Overview | ||
|
|
||
| The `sim_utils` package provides utilities for processing ECL/IX style binary | ||
| output files to prepare datasets for training. These scripts can read industry | ||
| standard simulator output formats (ECLIPSE, IX, OPM) and convert them into | ||
| various data structures suitable for different ML architectures. | ||
|
|
||
| ## Supported Formats | ||
|
|
||
| - `.INIT` | ||
| - `.EGRID` | ||
| - `.UNRST` or `.X00xx` | ||
| - `.UNSMRY` or `.S00xx` | ||
|
|
||
| ## Modules | ||
|
|
||
| ### `ecl_reader.py` | ||
|
|
||
| Main class for reading ECLIPSE-style binary output files. | ||
|
|
||
| **Usage**: | ||
|
|
||
| ```python | ||
| from sim_utils import EclReader | ||
tonishi-nv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Initialize reader with case name | ||
| reader = EclReader("path/to/CASE.DATA") | ||
|
|
||
| # Read static properties | ||
| init_data = reader.read_init(["PORV", "PERMX", "PERMY", "PERMZ"]) | ||
|
|
||
| # Read grid geometry | ||
| egrid_data = reader.read_egrid(["COORD", "ZCORN", "FILEHEAD", "NNC1", "NNC2"]) | ||
|
|
||
| # Read dynamic properties (all timesteps) | ||
| restart_data = reader.read_restart(["PRESSURE", "SWAT", "SGAS"]) | ||
| ``` | ||
|
|
||
| **Common Keywords**: | ||
|
|
||
| Static properties (INIT): | ||
|
|
||
| - `PORV`: Pore volume | ||
| - `PERMX`, `PERMY`, `PERMZ`: Permeability in X, Y, Z directions | ||
| - `PORO`: Porosity | ||
| - `TRANX`, `TRANY`, `TRANZ`: Transmissibility in X, Y, Z directions | ||
|
|
||
| Dynamic properties (UNRST): | ||
|
|
||
| - `PRESSURE`: Cell pressure | ||
| - `SWAT`: Water saturation | ||
| - `SGAS`: Gas saturation | ||
| - `SOIL`: Oil saturation | ||
|
|
||
| Grid geometry (EGRID): | ||
|
|
||
| - `COORD`: Grid pillar coordinates | ||
| - `ZCORN`: Grid corner depths | ||
| - `FILEHEAD`: File header information | ||
| - `NNC1`, `NNC2`: Non-neighboring connections | ||
|
|
||
| ### `grid.py` | ||
|
|
||
| **Grid** - Handles reservoir grid structure and operations. | ||
|
|
||
| **Features**: | ||
|
|
||
| - Grid dimensions and active cells | ||
| - Cell center coordinates computation | ||
| - Connection/edge computation for graph construction | ||
| - Aggregating directional transmissibilities for edge features | ||
| - Non-Neighboring Connections (NNC) | ||
| - Well completion arrays | ||
|
|
||
| **Usage**: | ||
|
|
||
| ```python | ||
| from sim_utils import Grid | ||
tonishi-nv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Initialize grid from simulation data | ||
| grid = Grid(init_data, egrid_data) | ||
|
|
||
| # Get connections and transmissibilities for graph construction | ||
| connections, transmissibilities = grid.get_conx_tran() | ||
|
|
||
| # Create completion arrays for wells | ||
| completion_inj, completion_prd = grid.create_completion_array(wells) | ||
|
|
||
| # Access grid properties | ||
| print(f"Grid dimensions: {grid.nx} x {grid.ny} x {grid.nz}") | ||
| print(f"Active cells: {grid.nact}") | ||
| print(f"Cell coordinates: X={grid.X}, Y={grid.Y}, Z={grid.Z}") | ||
| ``` | ||
|
|
||
| ### `well.py` | ||
|
|
||
| **Well** and **Completion** - Well and completion data structures. Typically, | ||
| use results from `UNRST` (well name, type, status, I, J, K, etc.) to | ||
| instantiate the object. | ||
|
|
||
| **Usage**: | ||
|
|
||
| ```python | ||
| from sim_utils import Well, Completion | ||
tonishi-nv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Create a well | ||
| well = Well(name="INJ1", type_id=3, stat=1) # Water injector | ||
|
|
||
| # Add completions | ||
| well.add_completion( | ||
| I=10, # Grid I-index | ||
| J=10, # Grid J-index | ||
| K=5, # Grid K-index | ||
| dir=3, # Direction (1=X, 2=Y, 3=Z) | ||
| stat=1, # Status (1=OPEN) | ||
| conx_factor=1.0 # Connection factor | ||
| ) | ||
|
|
||
| # Check well properties | ||
| print(f"Well type: {well.type}") # 'INJ' or 'PRD' | ||
| print(f"Well status: {well.status}") # 'OPEN' or 'SHUT' | ||
| print(f"Number of completions: {len(well.completions)}") | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2023 - 2024 NVIDIA CORPORATION & AFFILIATES. | ||
| # SPDX-FileCopyrightText: All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """ | ||
| Reservoir Utilities | ||
|
|
||
| Shared utilities for processing reservoir simulation data across different | ||
| machine learning architectures (XMeshGraphNet, FNO, DeepONet, etc.). | ||
|
|
||
| This package contains: | ||
| - ecl_reader: Read ECLIPSE-style simulation output files (.INIT, .EGRID, .UNRST, etc.) | ||
| - grid: Grid data structures and operations for reservoir simulations | ||
| - well: Well and completion data structures | ||
| """ | ||
|
|
||
| from .ecl_reader import EclReader | ||
| from .grid import Grid | ||
| from .well import Well, Completion | ||
|
|
||
| __all__ = ["EclReader", "Grid", "Well", "Completion"] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please verify the code for all these utilities is written by NVIDIA. If the code has been taken from somewhere else, even if partially, we need to modify the license header. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I reused part of an open source code (my repository with Apache license: https://github.com/GEG-ETHZ/pyflowdiagnostics/tree/v0.1.0) and modified a bit. Do we need to add something to the license header? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, in that case, please include the original license header first, followed by the NVIDIA license header. Add |
||
|
|
||
| __version__ = "1.0.0" | ||
Uh oh!
There was an error while loading. Please reload this page.