Skip to content

Commit

Permalink
Merge pull request #822 from bp/optimisations
Browse files Browse the repository at this point in the history
WIP: miscellaneous optimisations
  • Loading branch information
andy-beer authored Sep 5, 2024
2 parents adef702 + b1365ef commit 36b8078
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 11 deletions.
26 changes: 15 additions & 11 deletions resqpy/fault/_grid_connection_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def from_gcs_uuid_list(cls,
gcs.model = parent_model
gcs.uuid = bu.new_uuid() # not strictly necessary as append will cause a new uuid as well
gcs.title = title
gcs.property_collection = None
# append data from the remaining grid connection sets
for another_uuid in gcs_uuid_list[1:]:
another_gcs = GridConnectionSet(source_model, uuid = another_uuid)
Expand Down Expand Up @@ -2089,6 +2090,7 @@ def grid_face_arrays(self,
if default_value is None:
default_value = -1 if dtype is int else np.NaN
gcs_prop_array = gcs_prop.array_ref()
assert gcs_prop_array.shape == (self.count,)
log.debug(f'preparing grid face arrays from gcs property: {gcs_prop.title}; from gcs:{self.title}')

baffle_mask = None
Expand All @@ -2102,29 +2104,31 @@ def grid_face_arrays(self,
ai = np.full((nk, nj, ni + 1), default_value, dtype = dtype)

# populate arrays from faces of gcs, optionally filtered by feature index
cip, fip = self.list_of_cell_face_pairs_for_feature_index(None)
assert len(cip) == self.count and len(fip) == self.count
assert gcs_prop_array.shape == (self.count,)
if feature_index is None:
indices = np.arange(self.count, dtype = int)
else:
indices = self.indices_for_feature_index(feature_index)

side_list = ([0] if lazy else [0, 1])
cip, fip = self.list_of_cell_face_pairs_for_feature_index(feature_index)

value_array = gcs_prop_array.copy()

if baffle_mask is not None:
value_array[baffle_mask] = 0 # will be cast to float (or bool) if needed

if feature_index is not None:
indices = self.indices_for_feature_index(feature_index)
value_array = value_array[indices]
if active_mask is not None:
active_mask = active_mask[indices]

if active_mask is not None:
cip = cip[active_mask, :, :]
value_array = value_array[active_mask]

side_list = ([0] if lazy else [0, 1])

for side in side_list:
cell_kji0 = cip[:, side].copy() # shape (N, 3)
axis = fip[:, side, 0] # shape (N,)
polarity = fip[:, side, 1] # shape (N,)
assert 0 <= np.min(axis) and np.max(axis) <= 2
assert 0 <= np.min(polarity) and np.max(polarity) <= 1
# assert 0 <= np.min(axis) and np.max(axis) <= 2
# assert 0 <= np.min(polarity) and np.max(polarity) <= 1

axis_mask = (axis == 0).astype(bool)
ak_kji0 = cell_kji0[axis_mask, :]
Expand Down
176 changes: 176 additions & 0 deletions tests/unit_tests/fault/test_fault_connection_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
import resqpy.lines as rql
import resqpy.model as rq
import resqpy.property as rqp
import resqpy.organize as rqo
import resqpy.olio.transmission as rqtr
import resqpy.grid_surface as rqgs
import resqpy.olio.uuid as bu


def test_fault_connection_set(tmp_path):
Expand Down Expand Up @@ -1539,3 +1541,177 @@ def test_gcs_face_surface_normal_vectors(example_model_with_properties):

# Assert
assert_array_almost_equal(face_surface_normal_vectors, face_surface_normal_vectors_expected)


def test_feature_index(tmp_path):
epc = os.path.join(tmp_path, 'gcs_with_features.epc')
model = rq.new_model(epc)
crs = rqc.Crs(model)
crs.create_xml()
grid = grr.RegularGrid(model, extent_kji = (4, 5, 6), crs_uuid = crs.uuid)
grid.create_xml()
gcs_0 = rqf.GridConnectionSet(model, find_properties = False, grid = grid, title = 'fault zero gcs')
gcs_0.set_pairs_from_kelp(
kelp_0 = [(2, 0), (2, 1), (2, 2)], # J face columns
kelp_1 = [], # I face columns
feature_name = 'fault zero',
create_organizing_objects_where_needed = True)
gcs_0.write_hdf5()
gcs_0.create_xml()
pc = gcs_0.extract_property_collection()
a = np.arange(12, dtype = int) + 100
pc.add_cached_array_to_imported_list(a,
'test',
'this is the property of a gcs',
discrete = True,
null_value = -1,
property_kind = 'kiwi',
indexable_element = 'faces')
pc.write_hdf5_for_imported_list()
uuids = pc.create_xml_for_imported_list_and_add_parts_to_model()
assert len(uuids) == 1
kiwi_uuids = uuids
gcs_1 = rqf.GridConnectionSet(model, find_properties = False, grid = grid, title = 'fault one gcs')
gcs_1.set_pairs_from_kelp(
kelp_0 = [], # J face columns
kelp_1 = [(2, 2)], # I face columns
feature_name = 'fault one',
create_organizing_objects_where_needed = True)
gcs_1.write_hdf5()
gcs_1.create_xml()
pc = gcs_1.extract_property_collection()
a = np.arange(4, dtype = int) + 200
pc.add_cached_array_to_imported_list(a,
'test',
'this is the property of a gcs',
discrete = True,
null_value = -1,
property_kind = 'kiwi',
indexable_element = 'faces')
pc.write_hdf5_for_imported_list()
uuids = pc.create_xml_for_imported_list_and_add_parts_to_model()
assert len(uuids) == 1
kiwi_uuids += uuids
gcs_2 = rqf.GridConnectionSet(model, find_properties = False, grid = grid, title = 'fault two gcs')
gcs_2.set_pairs_from_kelp(
kelp_0 = [(1, 3), (1, 4), (1, 5)], # J face columns
kelp_1 = [], # I face columns
feature_name = 'fault two',
create_organizing_objects_where_needed = True)
gcs_2.write_hdf5()
gcs_2.create_xml()
pc = gcs_2.extract_property_collection()
a = np.arange(12, dtype = int) + 300
pc.add_cached_array_to_imported_list(a,
'test',
'this is the property of a gcs',
discrete = True,
null_value = -1,
property_kind = 'kiwi',
indexable_element = 'faces')
pc.write_hdf5_for_imported_list()
uuids = pc.create_xml_for_imported_list_and_add_parts_to_model()
assert len(uuids) == 1
kiwi_uuids += uuids
model.store_epc()
# check that fault interpretations have been generated
fi_titles = model.titles(obj_type = 'FaultInterpretation')
assert len(fi_titles) == 3
assert set(fi_titles) == set(['fault zero', 'fault one', 'fault two'])
# check one of the single feature grid connexion sets
fi_one_uuid = model.uuid(obj_type = 'FaultInterpretation', title = 'fault one')
assert fi_one_uuid is not None
gcs_one_uuid = model.uuid(obj_type = 'GridConnectionSetRepresentation', related_uuid = fi_one_uuid)
assert gcs_one_uuid is not None
assert bu.matching_uuids(gcs_one_uuid, gcs_1.uuid)
gcs_reload = rqf.GridConnectionSet(model, uuid = gcs_one_uuid)
assert gcs_reload is not None
assert gcs_reload.number_of_grids() == 1
assert gcs_reload.number_of_features() == 1
assert gcs_reload.title == 'fault one gcs'
assert gcs_reload.list_of_feature_names(strip = False) == ['fault one']
# make a composite grid connexion set with 3 features
gcs = rqf.GridConnectionSet.from_gcs_uuid_list(model,
source_model = model,
gcs_uuid_list = [gcs_0.uuid, gcs_1.uuid, gcs_2.uuid],
title = 'multi feature fault system',
gcs_property_uuid_list_of_lists = [kiwi_uuids])
model.store_epc()
# above class method includes writing hdf5 and creating xml
# reopen the composite grid connexion set
gcs = rqf.GridConnectionSet(model, uuid = gcs.uuid)
assert gcs is not None
gcs.cache_arrays()
assert gcs.number_of_grids() == 1
assert gcs.number_of_features() == 3
assert gcs.count == 28
# check that a property exists on the composite gcs
pc = gcs.extract_property_collection()
# a = np.concatenate((np.arange(12, dtype = int) + 100, np.arange(4, dtype = int) + 200, np.arange(12, dtype = int) + 300))
# pc.add_cached_array_to_imported_list(a, 'test', 'this is the property of a gcs', discrete = True, null_value = -1,
# property_kind = 'kiwi', indexable_element = 'faces')
# pc.write_hdf5_for_imported_list()
# uuids = pc.create_xml_for_imported_list_and_add_parts_to_model()
# assert len(uuids) == 1
assert pc.number_of_parts() == 1
kiwi_uuid = model.uuid(obj_type = 'DiscreteProperty', related_uuid = gcs.uuid)
assert kiwi_uuid is not None
# check features
assert gcs.list_of_feature_names(strip = False) == ['fault zero', 'fault one', 'fault two']
assert gcs.list_of_fault_names(strip = False) == ['fault zero', 'fault one', 'fault two']
index, fi_uuid = gcs.feature_index_and_uuid_for_fault_name('fault two')
assert index == 2
assert fi_uuid is not None
fi = rqo.FaultInterpretation(model, uuid = fi_uuid)
assert fi is not None
assert fi.title == 'fault two'
assert gcs.feature_name_for_feature_index(0, strip = False) == 'fault zero'
assert gcs.fault_name_for_feature_index(1, strip = False) == 'fault one'
# check a few faces are associated with expected features
assert gcs.feature_index_for_cell_face((1, 3, 4), 1, 0) is None
assert gcs.feature_index_for_cell_face((2, 2, 2), 2, 1) == 1
assert gcs.feature_index_for_cell_face((2, 2, 2), 1, 1) == 0
assert gcs.feature_index_for_cell_face((0, 2, 4), 1, 0) == 2
# check faces associated with each feature
k_faces, j_faces, i_faces = gcs.grid_face_arrays(kiwi_uuid,
default_value = -1,
feature_index = 2,
active_only = False,
lazy = False,
baffle_uuid = None)
assert k_faces is not None and j_faces is not None and i_faces is not None
assert k_faces.shape == (5, 5, 6)
assert j_faces.shape == (4, 6, 6)
assert i_faces.shape == (4, 5, 7)
assert np.all(k_faces == -1)
assert np.count_nonzero(j_faces >= 0) == 12
assert np.all(i_faces == -1)
assert np.all(np.logical_or(j_faces < 0, j_faces >= 300))
k_faces, j_faces, i_faces = gcs.grid_face_arrays(kiwi_uuid,
default_value = -1,
feature_index = 1,
active_only = False,
lazy = False,
baffle_uuid = None)
assert k_faces is not None and j_faces is not None and i_faces is not None
assert k_faces.shape == (5, 5, 6)
assert j_faces.shape == (4, 6, 6)
assert i_faces.shape == (4, 5, 7)
assert np.all(k_faces == -1)
assert np.all(j_faces == -1)
assert np.count_nonzero(i_faces >= 0) == 4
assert np.all(np.logical_or(i_faces < 0, np.logical_and(i_faces >= 200, i_faces < 204)))
k_faces, j_faces, i_faces = gcs.grid_face_arrays(kiwi_uuid,
default_value = -1,
feature_index = 0,
active_only = False,
lazy = False,
baffle_uuid = None)
assert k_faces is not None and j_faces is not None and i_faces is not None
assert k_faces.shape == (5, 5, 6)
assert j_faces.shape == (4, 6, 6)
assert i_faces.shape == (4, 5, 7)
assert np.all(k_faces == -1)
assert np.count_nonzero(j_faces >= 0) == 12
assert np.all(i_faces == -1)
assert np.all(j_faces < 112)

0 comments on commit 36b8078

Please sign in to comment.