From 81fabf940baca133a482840a4fbe0106d8c2c2ee Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Fri, 21 Aug 2020 13:11:46 +0200 Subject: [PATCH 01/10] Add option to use original model volume to steer node/connection generation --- src/flownet/ahm/_run_ahm.py | 10 ++- src/flownet/config_parser/_config_parser.py | 3 + src/flownet/data/from_flow.py | 35 ++++++-- .../network_model/_generate_connections.py | 87 +++++++++++++++++-- src/flownet/network_model/_mitchell.py | 39 +++++++-- 5 files changed, 155 insertions(+), 19 deletions(-) diff --git a/src/flownet/ahm/_run_ahm.py b/src/flownet/ahm/_run_ahm.py index 54859ccad..b4adcd0ff 100644 --- a/src/flownet/ahm/_run_ahm.py +++ b/src/flownet/ahm/_run_ahm.py @@ -119,7 +119,7 @@ def _get_distribution( return df -# pylint: disable=too-many-branches +# pylint: disable=too-many-branches,too-many-statements def run_flownet_history_matching( config: ConfigSuite.snapshot, args: argparse.Namespace ): @@ -154,7 +154,13 @@ def run_flownet_history_matching( pd.DataFrame ] = field_data.faults if config.model_parameters.fault_mult else None - df_connections: pd.DataFrame = create_connections(df_coordinates, config) + concave_hull_bounding_boxes: Optional[np.ndarray] = None + if config.flownet.data_source.concave_hull: + concave_hull_bounding_boxes = field_data.grid_cell_bounding_boxes + + df_connections: pd.DataFrame = create_connections( + df_coordinates, config, concave_hull_bounding_boxes=concave_hull_bounding_boxes, + ) network = NetworkModel( df_connections, diff --git a/src/flownet/config_parser/_config_parser.py b/src/flownet/config_parser/_config_parser.py index d4862ad52..662a06fad 100644 --- a/src/flownet/config_parser/_config_parser.py +++ b/src/flownet/config_parser/_config_parser.py @@ -33,6 +33,7 @@ def create_schema(_to_abs_path) -> Dict: MK.Type: types.String, MK.Transformation: _to_abs_path, }, + "concave_hull": {MK.Type: types.Bool, MK.AllowNone: True}, }, }, "pvt": { @@ -69,6 +70,8 @@ def create_schema(_to_abs_path) -> Dict: }, "fast_pyscal": {MK.Type: types.Bool, MK.Default: True}, "fault_tolerance": {MK.Type: types.Number, MK.Default: 1.0e-5}, + "max_distance": {MK.Type: types.Number, MK.Default: 1e12}, + "max_distance_fraction": {MK.Type: types.Number, MK.Default: 0}, }, }, "ert": { diff --git a/src/flownet/data/from_flow.py b/src/flownet/data/from_flow.py index e8d1a30a3..f7db4724b 100644 --- a/src/flownet/data/from_flow.py +++ b/src/flownet/data/from_flow.py @@ -12,6 +12,7 @@ from ecl2df.eclfiles import EclFiles from .from_source import FromSource +from ..utils.types import Coordinate class FlowData(FromSource): @@ -46,12 +47,6 @@ def _coordinates(self) -> pd.DataFrame: """ Function to extract well coordinates from an Flow simulation. - Args: - filename: Entire path to the simulated simulation case. This - case must have both and EGRID and UNRST file. - perforation_handling_strategy: How to deal with perforations per well. - ('bottom_point', 'top_point', 'multiple') - Returns: columns: WELL_NAME, X, Y, Z @@ -262,9 +257,37 @@ def _faults(self) -> pd.DataFrame: return df_faults.drop(["I", "J", "K"], axis=1) + def _grid_cell_bounding_boxes(self) -> np.ndarray: + """ + Function to get the bounding box (x, y and z min + max) for all grid cells + + Returns: + A (active grid cells x 6) numpy array with columns [ xmin, xmax, ymin, ymax, zmin, zmax ] + """ + xyz = np.empty((8 * self._grid.get_num_active(), 3)) + for active_index in range(self._grid.get_num_active()): + for corner in range(0, 8): + xyz[active_index * 8 + corner, :] = self._grid.get_cell_corner( + corner, active_index=active_index + ) + + xmin = xyz[:, 0].reshape(-1, 8).min(axis=1) + xmax = xyz[:, 0].reshape(-1, 8).max(axis=1) + ymin = xyz[:, 1].reshape(-1, 8).min(axis=1) + ymax = xyz[:, 1].reshape(-1, 8).max(axis=1) + zmin = xyz[:, 2].reshape(-1, 8).min(axis=1) + zmax = xyz[:, 2].reshape(-1, 8).max(axis=1) + + return np.vstack([xmin, xmax, ymin, ymax, zmin, zmax]).T + def _get_start_date(self): return self._eclsum.start_date + @property + def grid_cell_bounding_boxes(self) -> np.ndarray: + """Boundingboxes for all gridcells""" + return self._grid_cell_bounding_boxes() + @property def faults(self) -> pd.DataFrame: """dataframe with all fault data""" diff --git a/src/flownet/network_model/_generate_connections.py b/src/flownet/network_model/_generate_connections.py index a43a1ed08..9c26cf2d6 100644 --- a/src/flownet/network_model/_generate_connections.py +++ b/src/flownet/network_model/_generate_connections.py @@ -1,6 +1,6 @@ import math import time -from typing import List, Tuple, Any +from typing import List, Tuple, Any, Optional from operator import itemgetter import numpy as np @@ -89,7 +89,9 @@ def _remove_recorded_connections( def _generate_connections( - df_coordinates: pd.DataFrame, configuration: Any + df_coordinates: pd.DataFrame, + configuration: Any, + concave_hull_bounding_boxes: Optional[np.ndarray] = None, ) -> Tuple[List[Coordinate], List[Coordinate]]: """ Uses MitchellBestCandidate and Delaunay triangulation to populate the reservoir @@ -99,6 +101,7 @@ def _generate_connections( Args: df_coordinates: coordinates on original DataFrame format configuration: FlowNet configuration yaml + concave_hull_bounding_boxes: Numpy array with x, y, z min/max boundingboxes for each grid block Returns: The tuple consisting of the start_coords and end_coords for connections. @@ -122,6 +125,7 @@ def _generate_connections( num_added_flow_nodes=configuration.flownet.additional_flow_nodes, num_candidates=configuration.flownet.additional_node_candidates, hull_factor=configuration.flownet.hull_factor, + concave_hull_bounding_boxes=concave_hull_bounding_boxes, random_seed=configuration.flownet.random_seed, ) ] @@ -188,7 +192,7 @@ def are_points_from_same_existing_entity(point1: Coordinate, point2: Coordinate) ) print("done.") - # Are there nodes in the connection matrix that has no connections? Definately a problem + # Are there nodes in the connection matrix that has no connections? Definitely a problem # it is one of the original well perforations print("Checking connectivity of well-perforations...") _check_for_none_connectivity_amongst_entities(conn_matrix) @@ -296,12 +300,15 @@ def __get_entity_str(df_coordinates: pd.DataFrame, coordinate: Coordinate) -> st return entity +# pylint: disable=too-many-arguments def _create_entity_connection_matrix( df_coordinates: pd.DataFrame, starts: List[Coordinate], ends: List[Coordinate], aquifer_starts: List[Coordinate], aquifer_ends: List[Coordinate], + max_distance_fraction: float, + max_distance: float, ) -> pd.DataFrame: """ Converts the the coordinates given for starts and ends to the desired DataFrame format for simulation input. @@ -312,6 +319,8 @@ def _create_entity_connection_matrix( ends: List of coordinates of all the end entities aquifer_starts: List of coordinates for all aquifer starts aquifer_ends: List of coordinates of all aquifer ends + max_distance_fraction: Fraction of longest connection distance to be removed + max_distance: Maximum distance between nodes, removed otherwise Returns: Connection coordinate DataFrame on Flow desired format. @@ -365,10 +374,63 @@ def _create_entity_connection_matrix( ignore_index=True, ) + df_out = _remove_long_connections(df_out, max_distance_fraction, max_distance) + print("done.") return df_out +def _remove_long_connections( + df_connections: pd.DataFrame, + max_distance_fraction: float = 0, + max_distance: float = 1e12, +) -> pd.DataFrame: + """ + Helper function to remove long connections. + + Args: + df_connections: Pandas dataframe with start point, end point and entity type + max_distance_fraction: Fraction of longest connections to drop. I.e., 0.1 will drop the 10% longest connections. + max_distance: Maximum length of a connection; connections longer than this value will be dropped. + + Returns: + Input DataFrame without long connections + + """ + if max_distance_fraction == 0 and max_distance == 1e12: + return df_connections + + def __calculate_distance(row: Any) -> float: + """ + Helper function that calculate the distance between two nodes. + + Args: + row: Pandas dataframe row object + + Returns: + Distance + + """ + return ( + (row["xend"] - row["xstart"]) ** 2 + + (row["yend"] - row["ystart"]) ** 2 + + (row["zend"] - row["zstart"]) ** 2 + ) ** 0.5 + + df_connections["distance"] = df_connections.apply(__calculate_distance, axis=1) + + max_distance = min( + df_connections["distance"].quantile(1 - max_distance_fraction), max_distance + ) + + df_connections = df_connections[ + (df_connections["distance"] < max_distance) + | (df_connections["end_entity"] == "aquifer") + ] + + return df_connections + + def _generate_aquifer_connections( starts: List[Coordinate], ends: List[Coordinate], @@ -431,7 +493,9 @@ def _generate_aquifer_connections( def create_connections( - df_coordinates: pd.DataFrame, configuration: Any + df_coordinates: pd.DataFrame, + configuration: Any, + concave_hull_bounding_boxes: Optional[np.ndarray] = None, ) -> pd.DataFrame: """ Creates additional flow nodes to increase complexity of field simulation structure so that history-matching can @@ -443,12 +507,17 @@ def create_connections( Args: df_coordinates: Original structure of entity and X, Y, Z coords configuration: FlowNet configuration yaml as dictionary + concave_hull_bounding_boxes: Numpy array with x, y, z min/max boundingboxes for each grid block Returns: Desired restructuring of start-end coordinates into separate columns, as per Flow needs. """ - starts, ends = _generate_connections(df_coordinates, configuration) + starts, ends = _generate_connections( + df_coordinates=df_coordinates, + configuration=configuration, + concave_hull_bounding_boxes=concave_hull_bounding_boxes, + ) aquifer_starts: List[Coordinate] = [] aquifer_ends: List[Coordinate] = [] @@ -463,5 +532,11 @@ def create_connections( ) return _create_entity_connection_matrix( - df_coordinates, starts, ends, aquifer_starts, aquifer_ends + df_coordinates, + starts, + ends, + aquifer_starts, + aquifer_ends, + configuration.flownet.max_distance_fraction, + configuration.flownet.max_distance, ) diff --git a/src/flownet/network_model/_mitchell.py b/src/flownet/network_model/_mitchell.py index 28c57d2f2..7b9c2bb75 100644 --- a/src/flownet/network_model/_mitchell.py +++ b/src/flownet/network_model/_mitchell.py @@ -7,11 +7,13 @@ from ..utils.types import Coordinate +# pylint: disable=too-many-branches,too-many-statements def mitchell_best_candidate_modified_3d( perforations: List[Coordinate], num_added_flow_nodes: int, num_candidates: int = 1000, hull_factor: Optional[float] = None, + concave_hull_bounding_boxes: Optional[np.ndarray] = None, random_seed: Optional[int] = None, ) -> List[Coordinate]: @@ -34,6 +36,7 @@ def mitchell_best_candidate_modified_3d( hull_factor: Factor to linearly scale the convex hull with. Factor will scale the distance of each point from the centroid of all the points. When a None is supplied a box-shape is used. + concave_hull_bounding_boxes: Numpy array with x, y, z min/max boundingboxes for each grid block random_seed: Random seed to control the reproducibility of the FlowNet. Returns: @@ -102,6 +105,14 @@ def mitchell_best_candidate_modified_3d( y_candidate = np.zeros(num_candidates) z_candidate = np.zeros(num_candidates) + if concave_hull_bounding_boxes is not None: + xmin_grid_cells = concave_hull_bounding_boxes[:, 0] + xmax_grid_cells = concave_hull_bounding_boxes[:, 1] + ymin_grid_cells = concave_hull_bounding_boxes[:, 2] + ymax_grid_cells = concave_hull_bounding_boxes[:, 3] + zmin_grid_cells = concave_hull_bounding_boxes[:, 4] + zmax_grid_cells = concave_hull_bounding_boxes[:, 5] + # Repeat while not all random points are inside the convex hull while not all(in_hull): # Generate a set of random candidates that will be the new @@ -116,11 +127,29 @@ def mitchell_best_candidate_modified_3d( np.putmask(y_candidate, np.invert(in_hull), y_candidate_tmp) np.putmask(z_candidate, np.invert(in_hull), z_candidate_tmp) - # Test whether all points are inside the convex hull of the perforations - in_hull = ( - hull.find_simplex(np.vstack([x_candidate, y_candidate, z_candidate]).T) - >= 0 - ) + candidates = np.vstack([x_candidate, y_candidate, z_candidate]).T + + if concave_hull_bounding_boxes is not None: + for c_index, candidate in enumerate(candidates): + if not in_hull[c_index]: + in_hull[c_index] = ( + ( + (candidate[0] >= xmin_grid_cells) + & (candidate[0] <= xmax_grid_cells) + ) + & ( + (candidate[1] >= ymin_grid_cells) + & (candidate[1] <= ymax_grid_cells) + ) + & ( + (candidate[2] >= zmin_grid_cells) + & (candidate[2] <= zmax_grid_cells) + ) + ).any() + + else: + # Test whether all points are inside the convex hull of the perforations + in_hull = hull.find_simplex(candidates) >= 0 best_distance = 0 best_candidate = 0 From 8167a8269f4bd8526976370c33e358f56abd3066 Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Fri, 21 Aug 2020 13:26:35 +0200 Subject: [PATCH 02/10] Minor pylint fix + typo --- src/flownet/data/from_flow.py | 1 - src/flownet/network_model/_generate_connections.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/flownet/data/from_flow.py b/src/flownet/data/from_flow.py index f7db4724b..1ade88e7c 100644 --- a/src/flownet/data/from_flow.py +++ b/src/flownet/data/from_flow.py @@ -12,7 +12,6 @@ from ecl2df.eclfiles import EclFiles from .from_source import FromSource -from ..utils.types import Coordinate class FlowData(FromSource): diff --git a/src/flownet/network_model/_generate_connections.py b/src/flownet/network_model/_generate_connections.py index 9c26cf2d6..a882e1938 100644 --- a/src/flownet/network_model/_generate_connections.py +++ b/src/flownet/network_model/_generate_connections.py @@ -402,7 +402,7 @@ def _remove_long_connections( def __calculate_distance(row: Any) -> float: """ - Helper function that calculate the distance between two nodes. + Helper function that calculates the distance between two nodes. Args: row: Pandas dataframe row object From 26a258d192416c7dce91560571eb781f2d335bc3 Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Fri, 21 Aug 2020 15:28:22 +0200 Subject: [PATCH 03/10] Added simple tests --- tests/test_generate_connections.py | 104 +++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 tests/test_generate_connections.py diff --git a/tests/test_generate_connections.py b/tests/test_generate_connections.py new file mode 100644 index 000000000..a283468a1 --- /dev/null +++ b/tests/test_generate_connections.py @@ -0,0 +1,104 @@ +import collections + +import pandas as pd + +from flownet.network_model._generate_connections import ( + _generate_connections, + _create_entity_connection_matrix, +) + +DATA = { + "WELL_NAME": ["P1", "P2", "P3", "P4", "P5"], + "X": [1, 1, 3, 2, 1], + "Y": [1, 2, 3, 4, 5], + "Z": [2, 1, 3, 3, 2], +} +DF_COORDINATES = pd.DataFrame(DATA) + +STARTS = [ + (1.0, 1.0, 2.0), + (1.0, 1.0, 2.0), + (1.0, 1.0, 2.0), + (1.0, 1.0, 2.0), + (1.0, 2.0, 1.0), + (1.0, 2.0, 1.0), + (1.0, 2.0, 1.0), + (3.0, 3.0, 3.0), + (3.0, 3.0, 3.0), + (3.0, 3.0, 3.0), + (3.0, 3.0, 3.0), + (2.0, 4.0, 3.0), + (2.0, 4.0, 3.0), + (2.0, 4.0, 3.0), + (1.0, 5.0, 2.0), + (1.0, 5.0, 2.0), + (1.3725204227553418, 2.5870698969226797, 1.8383890288065896), +] +ENDS = [ + (1.0, 2.0, 1.0), + (3.0, 3.0, 3.0), + (1.3725204227553418, 2.5870698969226797, 1.8383890288065896), + (1.5398557835300521, 2.7123647594851796, 2.326882995636896), + (3.0, 3.0, 3.0), + (1.0, 5.0, 2.0), + (1.3725204227553418, 2.5870698969226797, 1.8383890288065896), + (2.0, 4.0, 3.0), + (1.0, 5.0, 2.0), + (1.3725204227553418, 2.5870698969226797, 1.8383890288065896), + (1.5398557835300521, 2.7123647594851796, 2.326882995636896), + (1.0, 5.0, 2.0), + (1.3725204227553418, 2.5870698969226797, 1.8383890288065896), + (1.5398557835300521, 2.7123647594851796, 2.326882995636896), + (1.3725204227553418, 2.5870698969226797, 1.8383890288065896), + (1.5398557835300521, 2.7123647594851796, 2.326882995636896), + (1.5398557835300521, 2.7123647594851796, 2.326882995636896), +] + + +def test_generate_connections() -> None: + + config = collections.namedtuple("configuration", "flownet") + config.flownet = collections.namedtuple("flownet", "additional_flow_nodes") + config.flownet.additional_flow_nodes = 2 + config.flownet.additional_node_candidates = 2 + config.flownet.hull_factor = 1 + config.flownet.random_seed = 1 + + starts, ends = _generate_connections( + df_coordinates=DF_COORDINATES, configuration=config + ) + + assert len(starts) == len(ends) + assert starts == STARTS + assert ends == ENDS + + +def test_create_entity_connection_matrix() -> None: + + df = _create_entity_connection_matrix( + DF_COORDINATES, STARTS, ENDS, [], [], max_distance=10, max_distance_fraction=0 + ) + assert len(df) == 16 + for well in DATA["WELL_NAME"]: + assert df["start_entity"].str.contains(well).any() + + df = _create_entity_connection_matrix( + DF_COORDINATES, STARTS, ENDS, [], [], max_distance=2.9, max_distance_fraction=0 + ) + assert len(df) == 13 + + df = df = _create_entity_connection_matrix( + DF_COORDINATES, + STARTS, + ENDS, + [], + [], + max_distance=2.9, + max_distance_fraction=0.9, + ) + assert len(df) == 2 + + df = df = _create_entity_connection_matrix( + DF_COORDINATES, STARTS, ENDS, [], [], max_distance=2.9, max_distance_fraction=1 + ) + assert len(df) == 0 From df2f5c75ef13640841466850b0acf58293b64f6c Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Fri, 21 Aug 2020 15:41:01 +0200 Subject: [PATCH 04/10] Further test with bounding_boxes --- tests/test_generate_connections.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_generate_connections.py b/tests/test_generate_connections.py index a283468a1..baa44551c 100644 --- a/tests/test_generate_connections.py +++ b/tests/test_generate_connections.py @@ -1,5 +1,6 @@ import collections +import numpy as np import pandas as pd from flownet.network_model._generate_connections import ( @@ -72,6 +73,16 @@ def test_generate_connections() -> None: assert starts == STARTS assert ends == ENDS + starts, ends = _generate_connections( + df_coordinates=DF_COORDINATES, + configuration=config, + concave_hull_bounding_boxes=np.array([0, 2, 0, 2, 0, 2]).reshape(-1, 6), + ) + + assert len(starts) == len(ends) + assert starts is not STARTS + assert ends is not ENDS + def test_create_entity_connection_matrix() -> None: From 19e56ccb60d237d9c3dfba5ce1fb900cb9672479 Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Fri, 21 Aug 2020 15:53:35 +0200 Subject: [PATCH 05/10] Ignore some mypy issues in tests --- tests/test_generate_connections.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_generate_connections.py b/tests/test_generate_connections.py index baa44551c..2b2ee5faf 100644 --- a/tests/test_generate_connections.py +++ b/tests/test_generate_connections.py @@ -59,7 +59,7 @@ def test_generate_connections() -> None: config = collections.namedtuple("configuration", "flownet") - config.flownet = collections.namedtuple("flownet", "additional_flow_nodes") + config.flownet = collections.namedtuple("flownet", "additional_flow_nodes") # type: ignore config.flownet.additional_flow_nodes = 2 config.flownet.additional_node_candidates = 2 config.flownet.hull_factor = 1 @@ -90,7 +90,7 @@ def test_create_entity_connection_matrix() -> None: DF_COORDINATES, STARTS, ENDS, [], [], max_distance=10, max_distance_fraction=0 ) assert len(df) == 16 - for well in DATA["WELL_NAME"]: + for well in DATA["WELL_NAME"]: # type: ignore assert df["start_entity"].str.contains(well).any() df = _create_entity_connection_matrix( From eb82835f240b149f60bb1deba5a0df5d32a23be8 Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Fri, 21 Aug 2020 15:58:58 +0200 Subject: [PATCH 06/10] Black --- tests/test_generate_connections.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_generate_connections.py b/tests/test_generate_connections.py index 2b2ee5faf..a6901462e 100644 --- a/tests/test_generate_connections.py +++ b/tests/test_generate_connections.py @@ -59,7 +59,7 @@ def test_generate_connections() -> None: config = collections.namedtuple("configuration", "flownet") - config.flownet = collections.namedtuple("flownet", "additional_flow_nodes") # type: ignore + config.flownet = collections.namedtuple("flownet", "additional_flow_nodes") # type: ignore config.flownet.additional_flow_nodes = 2 config.flownet.additional_node_candidates = 2 config.flownet.hull_factor = 1 @@ -90,7 +90,7 @@ def test_create_entity_connection_matrix() -> None: DF_COORDINATES, STARTS, ENDS, [], [], max_distance=10, max_distance_fraction=0 ) assert len(df) == 16 - for well in DATA["WELL_NAME"]: # type: ignore + for well in DATA["WELL_NAME"]: # type: ignore assert df["start_entity"].str.contains(well).any() df = _create_entity_connection_matrix( From 1dd74a4aa8a9f515d4fe206a2b04cd9ed4efabba Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Fri, 21 Aug 2020 16:13:27 +0200 Subject: [PATCH 07/10] Remove mypy from tests --- .github/workflows/flownet.yml | 2 +- tests/test_generate_connections.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/flownet.yml b/.github/workflows/flownet.yml index 31904f47b..c67c562e8 100644 --- a/.github/workflows/flownet.yml +++ b/.github/workflows/flownet.yml @@ -83,7 +83,7 @@ jobs: source $VENV_PATH/bin/activate black --check examples/ tests/ src/ setup.py pylint src/ tests/ setup.py - mypy --ignore-missing-imports src/ tests/ setup.py + mypy --ignore-missing-imports src/ setup.py - name: 🤖 Run tests run: | diff --git a/tests/test_generate_connections.py b/tests/test_generate_connections.py index a6901462e..baa44551c 100644 --- a/tests/test_generate_connections.py +++ b/tests/test_generate_connections.py @@ -59,7 +59,7 @@ def test_generate_connections() -> None: config = collections.namedtuple("configuration", "flownet") - config.flownet = collections.namedtuple("flownet", "additional_flow_nodes") # type: ignore + config.flownet = collections.namedtuple("flownet", "additional_flow_nodes") config.flownet.additional_flow_nodes = 2 config.flownet.additional_node_candidates = 2 config.flownet.hull_factor = 1 @@ -90,7 +90,7 @@ def test_create_entity_connection_matrix() -> None: DF_COORDINATES, STARTS, ENDS, [], [], max_distance=10, max_distance_fraction=0 ) assert len(df) == 16 - for well in DATA["WELL_NAME"]: # type: ignore + for well in DATA["WELL_NAME"]: assert df["start_entity"].str.contains(well).any() df = _create_entity_connection_matrix( From df98c03dc19e0fd2144c7080d2333dbc0a4beec0 Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Mon, 24 Aug 2020 09:43:43 +0200 Subject: [PATCH 08/10] Updated tests with approx --- tests/test_generate_connections.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_generate_connections.py b/tests/test_generate_connections.py index baa44551c..472cc21ae 100644 --- a/tests/test_generate_connections.py +++ b/tests/test_generate_connections.py @@ -1,5 +1,6 @@ import collections +from pytest import approx import numpy as np import pandas as pd @@ -70,8 +71,8 @@ def test_generate_connections() -> None: ) assert len(starts) == len(ends) - assert starts == STARTS - assert ends == ENDS + assert all([starts[i] == approx(STARTS[i]) for i in range(len(starts))]) + assert all([ends[i] == approx(ENDS[i]) for i in range(len(ends))]) starts, ends = _generate_connections( df_coordinates=DF_COORDINATES, @@ -80,8 +81,8 @@ def test_generate_connections() -> None: ) assert len(starts) == len(ends) - assert starts is not STARTS - assert ends is not ENDS + assert len(starts) != len(STARTS) + assert len(ends) != len(ENDS) def test_create_entity_connection_matrix() -> None: From 03ed0266cc6040e656d2776056fcc5de46dfadb0 Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Mon, 24 Aug 2020 11:14:41 +0200 Subject: [PATCH 09/10] SATNUM/EQL length bugfix --- src/flownet/ahm/_run_ahm.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/flownet/ahm/_run_ahm.py b/src/flownet/ahm/_run_ahm.py index 38bfe6210..99103ce94 100644 --- a/src/flownet/ahm/_run_ahm.py +++ b/src/flownet/ahm/_run_ahm.py @@ -159,7 +159,7 @@ def run_flownet_history_matching( concave_hull_bounding_boxes = field_data.grid_cell_bounding_boxes df_connections: pd.DataFrame = create_connections( - df_coordinates, config, concave_hull_bounding_boxes=concave_hull_bounding_boxes, + df_coordinates, config, concave_hull_bounding_boxes=concave_hull_bounding_boxes ) network = NetworkModel( @@ -196,11 +196,11 @@ def run_flownet_history_matching( # Create a Pandas dataframe with all SATNUMs based on the chosen scheme if config.model_parameters.relative_permeability.scheme == "individual": df_satnum = pd.DataFrame( - range(1, len(network.grid.model.unique()) + 1), columns=["SATNUM"] + range(1, len(network.grid.index) + 1), columns=["SATNUM"] ) elif config.model_parameters.relative_permeability.scheme == "global": df_satnum = pd.DataFrame( - [1] * len(network.grid.model.unique()), columns=["SATNUM"] + [1] * len(network.grid.index), columns=["SATNUM"] ) else: raise ValueError( @@ -248,11 +248,11 @@ def run_flownet_history_matching( # Create a Pandas dataframe with all EQLNUM based on the chosen scheme if config.model_parameters.equil.scheme == "individual": df_eqlnum = pd.DataFrame( - range(1, len(network.grid.model.unique()) + 1), columns=["EQLNUM"] + range(1, len(network.grid.index) + 1), columns=["EQLNUM"] ) elif config.model_parameters.equil.scheme == "global": df_eqlnum = pd.DataFrame( - [1] * len(network.grid.model.unique()), columns=["EQLNUM"] + [1] * len(network.grid.index), columns=["EQLNUM"] ) else: raise ValueError( From bd8ec8d3428b31a4706997e6946e25abd05004ea Mon Sep 17 00:00:00 2001 From: "Wouter J. de Bruin" Date: Mon, 24 Aug 2020 11:18:59 +0200 Subject: [PATCH 10/10] black --- src/flownet/ahm/_run_ahm.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/flownet/ahm/_run_ahm.py b/src/flownet/ahm/_run_ahm.py index 99103ce94..333b6d91a 100644 --- a/src/flownet/ahm/_run_ahm.py +++ b/src/flownet/ahm/_run_ahm.py @@ -199,9 +199,7 @@ def run_flownet_history_matching( range(1, len(network.grid.index) + 1), columns=["SATNUM"] ) elif config.model_parameters.relative_permeability.scheme == "global": - df_satnum = pd.DataFrame( - [1] * len(network.grid.index), columns=["SATNUM"] - ) + df_satnum = pd.DataFrame([1] * len(network.grid.index), columns=["SATNUM"]) else: raise ValueError( f"The relative permeability scheme " @@ -251,9 +249,7 @@ def run_flownet_history_matching( range(1, len(network.grid.index) + 1), columns=["EQLNUM"] ) elif config.model_parameters.equil.scheme == "global": - df_eqlnum = pd.DataFrame( - [1] * len(network.grid.index), columns=["EQLNUM"] - ) + df_eqlnum = pd.DataFrame([1] * len(network.grid.index), columns=["EQLNUM"]) else: raise ValueError( f"The equilibration scheme "