Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 129 additions & 65 deletions resqpy/grid_surface/_find_faces.py
Original file line number Diff line number Diff line change
Expand Up @@ -1167,68 +1167,6 @@
else:
return None

log.debug("converting face sets into grid connection set")
# NB: kji0 arrays in internal face protocol: used as cell_kji0 with polarity of 1
# property lists have elements replaced with sorted and filtered equivalents
gcs = rqf.GridConnectionSet.from_faces_indices(grid = grid,
k_faces_kji0 = k_faces_kji0,
j_faces_kji0 = j_faces_kji0,
i_faces_kji0 = i_faces_kji0,
remove_duplicates = not patchwork,
k_properties = k_props,
j_properties = j_props,
i_properties = i_props,
feature_name = name,
feature_type = feature_type,
create_organizing_objects_where_needed = True,
title = title)
# log.debug('finished coversion to gcs')

# NB. following assumes faces have been added to gcs in a particular order!
all_tris = None
if return_triangles:
# log.debug('preparing triangles array')
k_triangles = np.empty((0,), dtype = np.int32) if k_props is None else k_props.pop(0)
j_triangles = np.empty((0,), dtype = np.int32) if j_props is None else j_props.pop(0)
i_triangles = np.empty((0,), dtype = np.int32) if i_props is None else i_props.pop(0)
all_tris = np.concatenate((k_triangles, j_triangles, i_triangles), axis = 0)
# log.debug(f'gcs count: {gcs.count}; all triangles shape: {all_tris.shape}')
assert all_tris.shape == (gcs.count,)

# NB. following assumes faces have been added to gcs in a particular order!
all_depths = None
if return_depths:
# log.debug('preparing depths array')
k_depths = np.empty((0,), dtype = np.float64) if k_props is None else k_props.pop(0)
j_depths = np.empty((0,), dtype = np.float64) if j_props is None else j_props.pop(0)
i_depths = np.empty((0,), dtype = np.float64) if i_props is None else i_props.pop(0)
all_depths = np.concatenate((k_depths, j_depths, i_depths), axis = 0)
# log.debug(f'gcs count: {gcs.count}; all depths shape: {all_depths.shape}')
assert all_depths.shape == (gcs.count,)

# NB. following assumes faces have been added to gcs in a particular order!
all_offsets = None
if return_offsets:
# log.debug('preparing offsets array')
k_offsets = np.empty((0,), dtype = np.float64) if k_props is None else k_props[0]
j_offsets = np.empty((0,), dtype = np.float64) if j_props is None else j_props[0]
i_offsets = np.empty((0,), dtype = np.float64) if i_props is None else i_props[0]
all_offsets = _all_offsets(grid.crs, k_offsets, j_offsets, i_offsets)
# log.debug(f'gcs count: {gcs.count}; all offsets shape: {all_offsets.shape}')
assert all_offsets.shape == (gcs.count,)

all_flange = None
if return_flange_bool:
# log.debug('preparing flange array')
flange_bool_uuid = surface.model.uuid(title = "flange bool",
obj_type = "DiscreteProperty",
related_uuid = surface.uuid)
assert (flange_bool_uuid is not None), f"No flange bool property found for surface: {surface.title}"
flange_bool = rqp.Property(surface.model, uuid = flange_bool_uuid)
flange_array = flange_bool.array_ref(dtype = bool)
all_flange = np.take(flange_array, all_tris)
assert all_flange.shape == (gcs.count,)

# note: following is a grid cells property, not a gcs property
bisector = None
if return_bisector:
Expand All @@ -1245,6 +1183,15 @@
bisector = column_bisector_from_face_indices((grid.nj, grid.ni), j_faces_ji0, i_faces_ji0)
# log.debug('finished preparing columns bisector')
elif patchwork:
# NB. following assumes faces have been added to gcs in a particular order!
all_tris = None
assert return_triangles
# log.debug('preparing triangles array')
k_triangles = np.empty((0,), dtype = np.int32) if k_props is None else k_props[0]
j_triangles = np.empty((0,), dtype = np.int32) if j_props is None else j_props[0]
i_triangles = np.empty((0,), dtype = np.int32) if i_props is None else i_props[0]
all_tris = np.concatenate((k_triangles, j_triangles, i_triangles), axis = 0)
# log.debug(f'gcs count: {gcs.count}; all triangles shape: {all_tris.shape}')
n_patches = surface.number_of_patches()
log.info(f'preparing composite cells bisector for surface: {surface.title}; number of patches: {n_patches}')
nkf = 0 if k_faces_kji0 is None else len(k_faces_kji0)
Expand Down Expand Up @@ -1328,6 +1275,98 @@
if is_curtain:
bisector = bisector[0] # reduce to a columns property

# if using patchwork, filter all faces (and properties) to those within (or on boundary of) volume corresponding to patch
if patchwork:
if k_faces_kji0 is not None:
selection = filter_faces(k_faces_kji0, patch_indices_k, patch_indices, 0)
if np.any(selection):
k_faces_kji0 = k_faces_kji0[selection]
if k_props is not None:
k_props = [prop[selection] for prop in k_props]
else:
k_faces_kji0 = None
k_props = None

Check warning on line 1288 in resqpy/grid_surface/_find_faces.py

View check run for this annotation

Codecov / codecov/patch

resqpy/grid_surface/_find_faces.py#L1287-L1288

Added lines #L1287 - L1288 were not covered by tests
if j_faces_kji0 is not None:
selection = filter_faces(j_faces_kji0, patch_indices_j, patch_indices, 1)
if np.any(selection):
j_faces_kji0 = j_faces_kji0[selection]
if j_props is not None:
j_props = [prop[selection] for prop in j_props]
else:
j_faces_kji0 = None
j_props = None

Check warning on line 1297 in resqpy/grid_surface/_find_faces.py

View check run for this annotation

Codecov / codecov/patch

resqpy/grid_surface/_find_faces.py#L1296-L1297

Added lines #L1296 - L1297 were not covered by tests
if i_faces_kji0 is not None:
selection = filter_faces(i_faces_kji0, patch_indices_i, patch_indices, 2)
if np.any(selection):
i_faces_kji0 = i_faces_kji0[selection]
if i_props is not None:
i_props = [prop[selection] for prop in i_props]
else:
i_faces_kji0 = None
i_props = None

Check warning on line 1306 in resqpy/grid_surface/_find_faces.py

View check run for this annotation

Codecov / codecov/patch

resqpy/grid_surface/_find_faces.py#L1305-L1306

Added lines #L1305 - L1306 were not covered by tests

log.debug("converting face sets into grid connection set")
# NB: kji0 arrays in internal face protocol: used as cell_kji0 with polarity of 1
# property lists have elements replaced with sorted and filtered equivalents
gcs = rqf.GridConnectionSet.from_faces_indices(grid = grid,
k_faces_kji0 = k_faces_kji0,
j_faces_kji0 = j_faces_kji0,
i_faces_kji0 = i_faces_kji0,
remove_duplicates = not patchwork,
k_properties = k_props,
j_properties = j_props,
i_properties = i_props,
feature_name = name,
feature_type = feature_type,
create_organizing_objects_where_needed = True,
title = title)
# log.debug('finished coversion to gcs')

# NB. following assumes faces have been added to gcs in a particular order!
all_tris = None
if return_triangles:
# log.debug('preparing triangles array')
k_triangles = np.empty((0,), dtype = np.int32) if k_props is None else k_props.pop(0)
j_triangles = np.empty((0,), dtype = np.int32) if j_props is None else j_props.pop(0)
i_triangles = np.empty((0,), dtype = np.int32) if i_props is None else i_props.pop(0)
all_tris = np.concatenate((k_triangles, j_triangles, i_triangles), axis = 0)
# log.debug(f'gcs count: {gcs.count}; all triangles shape: {all_tris.shape}')
assert all_tris.shape == (gcs.count,)

# NB. following assumes faces have been added to gcs in a particular order!
all_depths = None
if return_depths:
# log.debug('preparing depths array')
k_depths = np.empty((0,), dtype = np.float64) if k_props is None else k_props.pop(0)
j_depths = np.empty((0,), dtype = np.float64) if j_props is None else j_props.pop(0)
i_depths = np.empty((0,), dtype = np.float64) if i_props is None else i_props.pop(0)
all_depths = np.concatenate((k_depths, j_depths, i_depths), axis = 0)
# log.debug(f'gcs count: {gcs.count}; all depths shape: {all_depths.shape}')
assert all_depths.shape == (gcs.count,)

# NB. following assumes faces have been added to gcs in a particular order!
all_offsets = None
if return_offsets:
# log.debug('preparing offsets array')
k_offsets = np.empty((0,), dtype = np.float64) if k_props is None else k_props[0]
j_offsets = np.empty((0,), dtype = np.float64) if j_props is None else j_props[0]
i_offsets = np.empty((0,), dtype = np.float64) if i_props is None else i_props[0]
all_offsets = _all_offsets(grid.crs, k_offsets, j_offsets, i_offsets)
# log.debug(f'gcs count: {gcs.count}; all offsets shape: {all_offsets.shape}')
assert all_offsets.shape == (gcs.count,)

all_flange = None
if return_flange_bool:
# log.debug('preparing flange array')
flange_bool_uuid = surface.model.uuid(title = "flange bool",
obj_type = "DiscreteProperty",
related_uuid = surface.uuid)
assert (flange_bool_uuid is not None), f"No flange bool property found for surface: {surface.title}"
flange_bool = rqp.Property(surface.model, uuid = flange_bool_uuid)
flange_array = flange_bool.array_ref(dtype = bool)
all_flange = np.take(flange_array, all_tris)
assert all_flange.shape == (gcs.count,)

# note: following is a grid cells property, not a gcs property
shadow = None
if return_shadow:
Expand Down Expand Up @@ -2475,7 +2514,7 @@
return c


@njit
@njit # pragma: no cover
def box_intersection(box_a: np.ndarray, box_b: np.ndarray) -> np.ndarray:
"""Return a box which is the intersection of two boxes, python protocol; all zeros if no intersection."""
box = np.zeros((2, 3), dtype = np.int32)
Expand All @@ -2486,8 +2525,8 @@
return box


@njit
def get_box(mask: np.ndarray) -> Tuple[np.ndarray, int]: # pragma: no cover
@njit # pragma: no cover
def get_box(mask: np.ndarray) -> Tuple[np.ndarray, int]:
"""Returns a python protocol box enclosing True elements of 3D boolean mask, and count which is zero if all False."""
box = np.full((2, 3), -1, dtype = np.int32)
count = 0
Expand Down Expand Up @@ -2517,3 +2556,28 @@
box[1, 2] = i + 1
count += 1
return box, count


@njit # pragma: no cover
def filter_faces(faces_kji0: np.ndarray, face_patches: np.ndarray, cell_patches: np.ndarray, axis: int) -> np.ndarray:
"""Return 1D boolean selection array indicating subset of faces that are applicable to cells with matching patch."""
n: int = len(faces_kji0)
assert len(face_patches) == n
selection = np.zeros(n, dtype = np.bool_)
for f in range(n):
k: int = faces_kji0[f, 0]
j: int = faces_kji0[f, 1]
i: int = faces_kji0[f, 2]
if face_patches[f] == cell_patches[k, j, i]:
selection[f] = True
else:
if axis == 0:
if face_patches[f] == cell_patches[k + 1, j, i]:
selection[f] = True
elif axis == 1:
if face_patches[f] == cell_patches[k, j + 1, i]:
selection[f] = True
else:
if face_patches[f] == cell_patches[k, j, i + 1]:
selection[f] = True
return selection
4 changes: 3 additions & 1 deletion tests/unit_tests/surface/test_surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ def test_faces_for_surface(tmp_model):
n_batches = 2,
packed_bisectors = True,
patch_indices = grid_patch_indices)
reduced_cip = set([(9, 10), (6, 15), (19, 20), (0, 9), (16, 25), (15, 16), (10, 19), (25, 26)])
assert reduced_cip.issubset(e_cip)
cip = set([tuple(pair) for pair in gcs_optimised.cell_index_pairs])
assert cip == e_cip # note: this assumes lower cell index is first, which happens to be true
assert cip == reduced_cip # note: this assumes lower cell index is first, which happens to be true
assert props is not None
assert len(props) == 1
bisector, is_curtain = props['grid bisector']
Expand Down
Loading