resqpy 4.16.11__tar.gz → 4.17.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {resqpy-4.16.11 → resqpy-4.17.1}/PKG-INFO +1 -1
- {resqpy-4.16.11 → resqpy-4.17.1}/pyproject.toml +1 -1
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/__init__.py +1 -1
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/fault/_grid_connection_set.py +224 -62
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_grid.py +4 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid_surface/__init__.py +4 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid_surface/_blocked_well_populate.py +5 -5
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid_surface/_find_faces.py +731 -212
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/model/_hdf5.py +3 -3
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/triangulation.py +17 -13
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/vector_utilities.py +175 -1
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/wellspec_keywords.py +16 -10
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/grid_property_collection.py +10 -10
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/rq_import/_import_vdb_ensemble.py +12 -13
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/_mesh.py +4 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/_surface.py +40 -24
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/_tri_mesh.py +8 -7
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/_triangulated_patch.py +71 -51
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/_blocked_well.py +28 -25
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/_trajectory.py +2 -2
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/blocked_well_frame.py +1 -1
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/well_object_funcs.py +5 -5
- {resqpy-4.16.11 → resqpy-4.17.1}/LICENSE +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/README.md +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/crs.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_add_edges_per_column_property_array.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_add_faults.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_add_one_blocked_well_property.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_add_one_grid_property_array.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_add_single_cell_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_add_wells_from_ascii_file.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_add_zone_by_layer_property.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_coarsened_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_common.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_copy_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_drape_to_surface.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_extract_box.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_extract_box_for_well.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_fault_throw_scaling.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_gather_ensemble.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_interpolated_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_local_depth_adjustment.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_refined_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_tilted_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_unsplit_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_zonal_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/derived_model/_zone_layer_ranges_from_array.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/fault/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/fault/_gcs_functions.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_cell_properties.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_connection_sets.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_create_grid_xml.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_defined_geometry.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_extract_functions.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_face_functions.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_faults.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_grid_types.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_intervals_info.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_moved_functions.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_pillars.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_pixel_maps.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_points_functions.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_regular_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_transmissibility.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_write_hdf5_from_caches.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_write_nexus_corp.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid/_xyz.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid_surface/_grid_skin.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid_surface/_grid_surface.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid_surface/_trajectory_intersects.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/grid_surface/grid_surface_cuda.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/lines/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/lines/_common.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/lines/_polyline.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/lines/_polyline_set.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/model/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/model/_catalogue.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/model/_context.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/model/_forestry.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/model/_grids.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/model/_model.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/model/_xml.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/multi_processing/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/multi_processing/_multiprocessing.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/multi_processing/wrappers/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/multi_processing/wrappers/blocked_well_mp.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/multi_processing/wrappers/grid_surface_mp.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/multi_processing/wrappers/mesh_mp.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/ab_toolbox.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/base.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/box_utilities.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/class_dict.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/consolidation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/data/build.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/data/properties.json +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/dataframe.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/exceptions.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/factors.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/fine_coarse.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/grid_functions.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/intersection.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/keyword_files.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/load_data.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/point_inclusion.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/random_seed.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/read_nexus_fault.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/relperm.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/simple_lines.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/time.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/trademark.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/transmission.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/uuid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/vdb.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/volume.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/write_data.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/write_hdf5.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/xml_et.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/xml_namespaces.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/olio/zmap_reader.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/_utils.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/boundary_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/boundary_feature_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/earth_model_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/fault_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/fluid_boundary_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/frontier_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/generic_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/genetic_boundary_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/geobody_boundary_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/geobody_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/geobody_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/geologic_unit_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/horizon_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/organization_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/rock_fluid_unit_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/structural_organization_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/tectonic_boundary_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/wellbore_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/organize/wellbore_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/_collection_add_part.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/_collection_create_xml.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/_collection_get_attributes.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/_collection_support.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/_property.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/attribute_property_set.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/property_collection.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/property_common.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/property_kind.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/string_lookup.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/well_interval_property.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/well_interval_property_collection.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/well_log.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/property/well_log_collection.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/rq_import/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/rq_import/_add_ab_properties.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/rq_import/_add_surfaces.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/rq_import/_grid_from_cp.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/rq_import/_import_nexus.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/rq_import/_import_vdb_all_grids.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/strata/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/strata/_binary_contact_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/strata/_geologic_unit_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/strata/_strata_common.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/strata/_stratigraphic_column.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/strata/_stratigraphic_column_rank.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/strata/_stratigraphic_unit_feature.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/strata/_stratigraphic_unit_interpretation.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/_base_surface.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/_combined_surface.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/_pointset.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/surface/_tri_mesh_stencil.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/time_series/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/time_series/_any_time_series.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/time_series/_from_nexus_summary.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/time_series/_functions.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/time_series/_geologic_time_series.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/time_series/_time_duration.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/time_series/_time_series.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/unstructured/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/unstructured/_hexa_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/unstructured/_prism_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/unstructured/_pyramid_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/unstructured/_tetra_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/unstructured/_unstructured_grid.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/weights_and_measures/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/weights_and_measures/nexus_units.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/weights_and_measures/weights_and_measures.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/__init__.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/_deviation_survey.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/_md_datum.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/_wellbore_frame.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/_wellbore_marker.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/_wellbore_marker_frame.py +0 -0
- {resqpy-4.16.11 → resqpy-4.17.1}/resqpy/well/well_utils.py +0 -0
@@ -10,6 +10,7 @@ import math as maths
|
|
10
10
|
import numpy as np
|
11
11
|
import pandas as pd
|
12
12
|
|
13
|
+
import resqpy.grid as grr
|
13
14
|
import resqpy.fault
|
14
15
|
import resqpy.olio.read_nexus_fault as rnf
|
15
16
|
import resqpy.olio.trademark as tm
|
@@ -118,7 +119,7 @@ class GridConnectionSet(BaseResqpy):
|
|
118
119
|
self.cell_index_pairs = None #: shape (count, 2); dtype int; index normalized for flattened array
|
119
120
|
self.cell_index_pairs_null_value = -1 #: integer null value for array above
|
120
121
|
self.grid_index_pairs = None #: shape (count, 2); dtype int; optional; used if more than one grid referenced
|
121
|
-
self.face_index_pairs = None #: shape (count, 2); dtype
|
122
|
+
self.face_index_pairs = None #: shape (count, 2); dtype int8; local to cell, ie. range 0 to 5
|
122
123
|
self.face_index_pairs_null_value = -1 #: integer null value for array above
|
123
124
|
# NB face index values 0..5 usually mean [K-, K+, J+, I+, J-, I-] respectively but there is some ambiguity
|
124
125
|
# over I & J in the Energistics RESQML Usage Guide; see comments in DevOps backlog item 269001 for more info
|
@@ -129,17 +130,18 @@ class GridConnectionSet(BaseResqpy):
|
|
129
130
|
self.feature_list = None #: ordered list, actually of interpretations, indexed by feature_indices
|
130
131
|
# feature list contains tuples: (content_type, uuid, title) for fault features (or other interpretations)
|
131
132
|
self.property_collection = None #: optional property.PropertyCollection
|
133
|
+
self.cell_index_dtype = np.int32 #: set to int64 if any grid is big, otherwise int32
|
132
134
|
|
133
135
|
# NB: RESQML documentation is not clear which order is correct; should be kept consistent with same data in property.py
|
134
136
|
# face_index_map maps from (axis, p01) to face index value in range 0..5
|
135
137
|
# this is the default as indicated on page 139 (but not p. 180) of the RESQML Usage Gude v2.0.1
|
136
138
|
# also assumes K is generally increasing downwards
|
137
139
|
# see DevOps backlog item 269001 discussion for more information
|
138
|
-
# self.face_index_map = np.array([[0, 1], [4, 2], [5, 3]], dtype =
|
139
|
-
self.face_index_map = np.array([[0, 1], [2, 4], [5, 3]], dtype =
|
140
|
+
# self.face_index_map = np.array([[0, 1], [4, 2], [5, 3]], dtype = np.int8)
|
141
|
+
self.face_index_map = np.array([[0, 1], [2, 4], [5, 3]], dtype = np.int8) # order: top, base, J-, I+, J+, I-
|
140
142
|
# and the inverse, maps from 0..5 to (axis, p01)
|
141
|
-
# self.face_index_inverse_map = np.array([[0, 0], [0, 1], [1, 1], [2, 1], [1, 0], [2, 0]], dtype =
|
142
|
-
self.face_index_inverse_map = np.array([[0, 0], [0, 1], [1, 0], [2, 1], [1, 1], [2, 0]], dtype =
|
143
|
+
# self.face_index_inverse_map = np.array([[0, 0], [0, 1], [1, 1], [2, 1], [1, 0], [2, 0]], dtype = np.int8)
|
144
|
+
self.face_index_inverse_map = np.array([[0, 0], [0, 1], [1, 0], [2, 1], [1, 1], [2, 0]], dtype = np.int8)
|
143
145
|
# note: the rework_face_pairs() method, below, overwrites the face indices based on I, J cell indices
|
144
146
|
if not title:
|
145
147
|
title = feature_name
|
@@ -196,6 +198,110 @@ class GridConnectionSet(BaseResqpy):
|
|
196
198
|
self.cache_arrays()
|
197
199
|
if find_properties:
|
198
200
|
self.extract_property_collection()
|
201
|
+
self._set_cell_index_dtype()
|
202
|
+
|
203
|
+
@classmethod
|
204
|
+
def from_faces_indices(cls,
|
205
|
+
grid,
|
206
|
+
k_faces_kji0,
|
207
|
+
j_faces_kji0,
|
208
|
+
i_faces_kji0,
|
209
|
+
remove_duplicates = True,
|
210
|
+
k_properties = None,
|
211
|
+
j_properties = None,
|
212
|
+
i_properties = None,
|
213
|
+
feature_name = None,
|
214
|
+
feature_type = 'fault',
|
215
|
+
create_organizing_objects_where_needed = True,
|
216
|
+
title = None,
|
217
|
+
originator = None,
|
218
|
+
extra_metadata = None):
|
219
|
+
"""Create a GridConnectionSet given a grid and 3 list-like arrays identifying faces by indices.
|
220
|
+
|
221
|
+
arguments:
|
222
|
+
- grid (Grid): the single grid to be referenced by the grid connection set
|
223
|
+
- k_faces_kji0 (numpy int array of shape (Nk, 3)): indices of cells on negative side of desired K faces
|
224
|
+
- j_faces_kji0 (numpy int array of shape (Nj, 3)): indices of cells on negative side of desired J faces
|
225
|
+
- i_faces_kji0 (numpy int array of shape (Ni, 3)): indices of cells on negative side of desired I faces
|
226
|
+
- remove_duplicates (bool, default True): if True, indices are sorted and duplicates removed
|
227
|
+
- k_properties (list of 1D numpy arrays, optional): if present and remove_duplicates is True, each array
|
228
|
+
is sorted and has elements removed to keep them compatible with the indices
|
229
|
+
- j_properties (list of 1D numpy arrays, optional): if present and remove_duplicates is True, each array
|
230
|
+
is sorted and has elements removed to keep them compatible with the indices
|
231
|
+
- i_properties (list of 1D numpy arrays, optional): if present and remove_duplicates is True, each array
|
232
|
+
is sorted and has elements removed to keep them compatible with the indices
|
233
|
+
- feature_name (string, optional): the feature name to use when setting from faces
|
234
|
+
- feature_type (string, default 'fault'): 'fault', 'horizon' or 'geobody boundary'
|
235
|
+
- create_organizing_objects_where_needed (boolean, default True): if True, a fault interpretation object
|
236
|
+
and tectonic boundary feature object will be created if such objects do not exist for the feature;
|
237
|
+
if False, missing organizational objects will cause an error to be logged
|
238
|
+
- title (str, optional): the citation title to use for a new grid connection set
|
239
|
+
- originator (str, optional): the name of the person creating the new grid connection set, defaults to login id
|
240
|
+
- extra_metadata (dict, optional): string key, value pairs to add as extra metadata for the grid connection set
|
241
|
+
|
242
|
+
returns:
|
243
|
+
- a new GridConnectionSet populated based on the faces indices
|
244
|
+
|
245
|
+
notes:
|
246
|
+
- this method only supports creation of single grid connection sets
|
247
|
+
- the faces indices are for cells on the negative side of the face
|
248
|
+
- the paired cell is implicitly the neighbouring cell in the positive direction of the axis
|
249
|
+
- the indices must therefore not include the last cell in the axis, though this is not checked
|
250
|
+
- if properties are passed, they should be passed in list variables which have their elements
|
251
|
+
replaced; individual property arrays should therefore be extracted from the lists afterwards
|
252
|
+
"""
|
253
|
+
assert isinstance(grid, grr.Grid)
|
254
|
+
|
255
|
+
gcs = cls(grid.model, title = title, originator = originator, extra_metadata = extra_metadata)
|
256
|
+
|
257
|
+
gcs._sort_out_organizing_objects(feature_type, feature_name, create_organizing_objects_where_needed)
|
258
|
+
|
259
|
+
nj_ni = grid.nj * grid.ni
|
260
|
+
if k_faces_kji0 is not None and len(k_faces_kji0) > 0:
|
261
|
+
ci = grid.natural_cell_indices(k_faces_kji0)
|
262
|
+
if remove_duplicates:
|
263
|
+
ci = _sort_and_remove_duplicates(ci, k_properties)
|
264
|
+
cip = np.empty((ci.size, 2), dtype = gcs.cell_index_dtype)
|
265
|
+
cip[:, 0] = ci
|
266
|
+
cip[:, 1] = ci + nj_ni
|
267
|
+
fip = np.empty(cip.shape, dtype = np.int8)
|
268
|
+
fip[:, 0] = gcs.face_index_map[0, 1]
|
269
|
+
fip[:, 1] = gcs.face_index_map[0, 0]
|
270
|
+
else:
|
271
|
+
cip = np.empty((0, 2), dtype = gcs.cell_index_dtype)
|
272
|
+
fip = np.empty((0, 2), dtype = np.int8)
|
273
|
+
if j_faces_kji0 is not None and len(j_faces_kji0) > 0:
|
274
|
+
ci = grid.natural_cell_indices(j_faces_kji0)
|
275
|
+
if remove_duplicates:
|
276
|
+
ci = _sort_and_remove_duplicates(ci, j_properties)
|
277
|
+
j_cip = np.empty((ci.size, 2), dtype = gcs.cell_index_dtype)
|
278
|
+
j_cip[:, 0] = ci
|
279
|
+
j_cip[:, 1] = ci + grid.ni
|
280
|
+
j_fip = np.empty(j_cip.shape, dtype = np.int8)
|
281
|
+
j_fip[:, 0] = gcs.face_index_map[1, 1]
|
282
|
+
j_fip[:, 1] = gcs.face_index_map[1, 0]
|
283
|
+
cip = np.concatenate((cip, j_cip), axis = 0)
|
284
|
+
fip = np.concatenate((fip, j_fip), axis = 0)
|
285
|
+
del j_cip, j_fip
|
286
|
+
if i_faces_kji0 is not None and len(i_faces_kji0) > 0:
|
287
|
+
ci = grid.natural_cell_indices(i_faces_kji0)
|
288
|
+
if remove_duplicates:
|
289
|
+
ci = _sort_and_remove_duplicates(ci, i_properties)
|
290
|
+
i_cip = np.empty((ci.size, 2), dtype = gcs.cell_index_dtype)
|
291
|
+
i_cip[:, 0] = ci
|
292
|
+
i_cip[:, 1] = ci + 1
|
293
|
+
i_fip = np.empty(i_cip.shape, dtype = np.int8)
|
294
|
+
i_fip[:, 0] = gcs.face_index_map[2, 1]
|
295
|
+
i_fip[:, 1] = gcs.face_index_map[2, 0]
|
296
|
+
cip = np.concatenate((cip, i_cip), axis = 0)
|
297
|
+
fip = np.concatenate((fip, i_fip), axis = 0)
|
298
|
+
del i_cip, i_fip
|
299
|
+
gcs.cell_index_pairs = cip
|
300
|
+
gcs.face_index_pairs = fip
|
301
|
+
gcs.count = len(gcs.cell_index_pairs)
|
302
|
+
gcs.feature_indices = np.zeros(gcs.count, dtype = np.int8)
|
303
|
+
assert len(gcs.face_index_pairs) == gcs.count
|
304
|
+
return gcs
|
199
305
|
|
200
306
|
@classmethod
|
201
307
|
def from_gcs_uuid_list(cls,
|
@@ -357,6 +463,14 @@ class GridConnectionSet(BaseResqpy):
|
|
357
463
|
self.property_collection = rqp.PropertyCollection(support = self)
|
358
464
|
return self.property_collection
|
359
465
|
|
466
|
+
def _set_cell_index_dtype(self):
|
467
|
+
"""Determines whether to use int32 or int64 for normalised cell indices."""
|
468
|
+
self.cell_index_dtype = np.int32
|
469
|
+
for g in self.grid_list:
|
470
|
+
if g.is_big():
|
471
|
+
self.cell_index_dtype = np.int64
|
472
|
+
break
|
473
|
+
|
360
474
|
def set_pairs_from_kelp(self,
|
361
475
|
kelp_0,
|
362
476
|
kelp_1,
|
@@ -394,7 +508,7 @@ class GridConnectionSet(BaseResqpy):
|
|
394
508
|
k_layer = np.zeros((grid.nk - 1, grid.ni), dtype = bool)
|
395
509
|
else:
|
396
510
|
k_layer = np.zeros((grid.nk - 1, grid.nj), dtype = bool)
|
397
|
-
kelp_a = np.array(kelp_k, dtype =
|
511
|
+
kelp_a = np.array(kelp_k, dtype = np.int32).T
|
398
512
|
k_layer[kelp_a[0], kelp_a[1]] = True
|
399
513
|
k_faces = np.zeros((grid.nk - 1, grid.nj, grid.ni), dtype = bool)
|
400
514
|
if axis == 'J':
|
@@ -408,7 +522,7 @@ class GridConnectionSet(BaseResqpy):
|
|
408
522
|
j_layer = np.zeros((grid.nj - 1, grid.ni), dtype = bool)
|
409
523
|
else:
|
410
524
|
j_layer = np.zeros((grid.nk, grid.nj - 1), dtype = bool)
|
411
|
-
kelp_a = np.array(kelp_j, dtype =
|
525
|
+
kelp_a = np.array(kelp_j, dtype = np.int32).T
|
412
526
|
j_layer[kelp_a[0], kelp_a[1]] = True
|
413
527
|
j_faces = np.zeros((grid.nk, grid.nj - 1, grid.ni), dtype = bool)
|
414
528
|
if axis == 'K':
|
@@ -422,7 +536,7 @@ class GridConnectionSet(BaseResqpy):
|
|
422
536
|
i_layer = np.zeros((grid.nj, grid.ni - 1), dtype = bool)
|
423
537
|
else:
|
424
538
|
i_layer = np.zeros((grid.nk, grid.ni - 1), dtype = bool)
|
425
|
-
kelp_a = np.array(kelp_i, dtype =
|
539
|
+
kelp_a = np.array(kelp_i, dtype = np.int32).T
|
426
540
|
i_layer[kelp_a[0], kelp_a[1]] = True
|
427
541
|
i_faces = np.zeros((grid.nk, grid.nj, grid.ni - 1), dtype = bool)
|
428
542
|
if axis == 'K':
|
@@ -438,24 +552,13 @@ class GridConnectionSet(BaseResqpy):
|
|
438
552
|
create_organizing_objects_where_needed,
|
439
553
|
feature_type = feature_type)
|
440
554
|
|
441
|
-
def
|
442
|
-
|
443
|
-
k_faces,
|
444
|
-
j_faces,
|
445
|
-
i_faces,
|
446
|
-
feature_name,
|
447
|
-
create_organizing_objects_where_needed,
|
448
|
-
feature_type = 'fault', # other feature_type values: 'horizon', 'geobody boundary'
|
449
|
-
k_sides = None,
|
450
|
-
j_sides = None,
|
451
|
-
i_sides = None):
|
452
|
-
"""Sets cell_index_pairs and face_index_pairs based on triple face masks, using simple no throw pairing."""
|
453
|
-
|
555
|
+
def _sort_out_organizing_objects(self, feature_type, feature_name, create_organizing_objects_where_needed):
|
556
|
+
"""Finds or creates interpretation and feature objects."""
|
454
557
|
assert feature_type in ['fault', 'horizon', 'geobody boundary']
|
455
558
|
if feature_name is None:
|
456
|
-
feature_name = 'feature from
|
559
|
+
feature_name = 'feature from faces' # not sure this default is wise
|
457
560
|
if len(self.grid_list) > 1:
|
458
|
-
log.warning('setting grid connection set pairs from
|
561
|
+
log.warning('setting grid connection set pairs from faces for first grid in list only')
|
459
562
|
grid = self.grid_list[0]
|
460
563
|
if feature_type == 'fault':
|
461
564
|
feature_flavour = 'TectonicBoundaryFeature'
|
@@ -512,6 +615,23 @@ class GridConnectionSet(BaseResqpy):
|
|
512
615
|
log.error('no interpretation found for feature: ' + feature_name)
|
513
616
|
return
|
514
617
|
self.feature_list = [('obj_' + interpretation_flavour, fi_uuid, str(feature_name))]
|
618
|
+
|
619
|
+
def set_pairs_from_face_masks(
|
620
|
+
self,
|
621
|
+
k_faces,
|
622
|
+
j_faces,
|
623
|
+
i_faces,
|
624
|
+
feature_name,
|
625
|
+
create_organizing_objects_where_needed,
|
626
|
+
feature_type = 'fault', # other feature_type values: 'horizon', 'geobody boundary'
|
627
|
+
k_sides = None,
|
628
|
+
j_sides = None,
|
629
|
+
i_sides = None):
|
630
|
+
"""Sets cell_index_pairs and face_index_pairs based on triple face masks, using simple no throw pairing."""
|
631
|
+
|
632
|
+
self._sort_out_organizing_objects(feature_type, feature_name, create_organizing_objects_where_needed)
|
633
|
+
|
634
|
+
grid = self.grid_list[0]
|
515
635
|
cell_pair_list = []
|
516
636
|
face_pair_list = []
|
517
637
|
nj_ni = grid.nj * grid.ni
|
@@ -548,10 +668,10 @@ class GridConnectionSet(BaseResqpy):
|
|
548
668
|
else:
|
549
669
|
cell_pair_list.append((cell, cell + 1))
|
550
670
|
face_pair_list.append((self.face_index_map[2, 1], self.face_index_map[2, 0]))
|
551
|
-
self.cell_index_pairs = np.array(cell_pair_list, dtype =
|
552
|
-
self.face_index_pairs = np.array(face_pair_list, dtype =
|
671
|
+
self.cell_index_pairs = np.array(cell_pair_list, dtype = self.cell_index_dtype)
|
672
|
+
self.face_index_pairs = np.array(face_pair_list, dtype = np.int8)
|
553
673
|
self.count = len(self.cell_index_pairs)
|
554
|
-
self.feature_indices = np.zeros(self.count, dtype =
|
674
|
+
self.feature_indices = np.zeros(self.count, dtype = np.int8)
|
555
675
|
assert len(self.face_index_pairs) == self.count
|
556
676
|
|
557
677
|
def set_pairs_from_faces_df(self,
|
@@ -609,9 +729,9 @@ class GridConnectionSet(BaseResqpy):
|
|
609
729
|
if success:
|
610
730
|
feature_index += 1
|
611
731
|
|
612
|
-
self.feature_indices = np.array(fi_list, dtype =
|
613
|
-
self.cell_index_pairs = np.array(cell_pair_list, dtype =
|
614
|
-
self.face_index_pairs = np.array(face_pair_list, dtype =
|
732
|
+
self.feature_indices = np.array(fi_list, dtype = np.int32)
|
733
|
+
self.cell_index_pairs = np.array(cell_pair_list, dtype = self.cell_index_dtype)
|
734
|
+
self.face_index_pairs = np.array(face_pair_list, dtype = np.int8)
|
615
735
|
self.count = len(self.cell_index_pairs)
|
616
736
|
assert len(self.face_index_pairs) == self.count
|
617
737
|
if create_mult_prop and self.count > 0:
|
@@ -696,7 +816,7 @@ class GridConnectionSet(BaseResqpy):
|
|
696
816
|
singleton.cell_index_pairs, singleton.face_index_pairs = \
|
697
817
|
self.raw_list_of_cell_face_pairs_for_feature_index(feature_index)
|
698
818
|
singleton.count = singleton.cell_index_pairs.shape[0]
|
699
|
-
singleton.feature_indices = np.zeros((singleton.count,), dtype =
|
819
|
+
singleton.feature_indices = np.zeros((singleton.count,), dtype = np.int32)
|
700
820
|
singleton.feature_list = [self.feature_list[feature_index]]
|
701
821
|
return singleton
|
702
822
|
|
@@ -823,7 +943,7 @@ class GridConnectionSet(BaseResqpy):
|
|
823
943
|
cache_array = True,
|
824
944
|
object = self,
|
825
945
|
array_attribute = 'cell_index_pairs',
|
826
|
-
dtype = '
|
946
|
+
dtype = 'int64' if self.cell_index_dtype is np.int64 else 'int32')
|
827
947
|
|
828
948
|
if self.face_index_pairs is None:
|
829
949
|
log.debug('caching face index pairs from hdf5')
|
@@ -834,7 +954,7 @@ class GridConnectionSet(BaseResqpy):
|
|
834
954
|
cache_array = True,
|
835
955
|
object = self,
|
836
956
|
array_attribute = 'face_index_pairs',
|
837
|
-
dtype = '
|
957
|
+
dtype = 'int8')
|
838
958
|
|
839
959
|
if len(self.grid_list) > 1 and self.grid_index_pairs is None:
|
840
960
|
grid_index_node = rqet.find_tag(self.root, 'GridIndexPairs')
|
@@ -845,7 +965,7 @@ class GridConnectionSet(BaseResqpy):
|
|
845
965
|
cache_array = True,
|
846
966
|
object = self,
|
847
967
|
array_attribute = 'grid_index_pairs',
|
848
|
-
dtype = '
|
968
|
+
dtype = 'int32' if len(self.grid_list) > 127 else 'int8')
|
849
969
|
|
850
970
|
if self.feature_list is None:
|
851
971
|
return
|
@@ -854,18 +974,18 @@ class GridConnectionSet(BaseResqpy):
|
|
854
974
|
if self.feature_indices is None:
|
855
975
|
log.debug('caching feature indices')
|
856
976
|
elements_node = rqet.find_nested_tags(interp_root, ['InterpretationIndices', 'Elements'])
|
857
|
-
#
|
977
|
+
# elements_node = rqet.find_nested_tags(interp_root, ['FaultIndices', 'Elements'])
|
858
978
|
h5_key_pair = self.model.h5_uuid_and_path_for_node(elements_node, tag = 'Values')
|
859
979
|
assert h5_key_pair is not None
|
860
980
|
self.model.h5_array_element(h5_key_pair,
|
861
981
|
cache_array = True,
|
862
982
|
object = self,
|
863
983
|
array_attribute = 'feature_indices',
|
864
|
-
dtype = '
|
984
|
+
dtype = 'int32')
|
865
985
|
assert self.feature_indices.shape == (self.count,)
|
866
986
|
|
867
987
|
cl_node = rqet.find_nested_tags(interp_root, ['InterpretationIndices', 'CumulativeLength'])
|
868
|
-
#
|
988
|
+
# cl_node = rqet.find_nested_tags(interp_root, ['FaultIndices', 'CumulativeLength'])
|
869
989
|
h5_key_pair = self.model.h5_uuid_and_path_for_node(cl_node, tag = 'Values')
|
870
990
|
assert h5_key_pair is not None
|
871
991
|
self.model.h5_array_element(h5_key_pair,
|
@@ -873,8 +993,8 @@ class GridConnectionSet(BaseResqpy):
|
|
873
993
|
object = self,
|
874
994
|
array_attribute = 'fi_cl',
|
875
995
|
dtype = 'uint32')
|
876
|
-
assert self.fi_cl.shape == (
|
877
|
-
|
996
|
+
assert self.fi_cl.shape == (self.count,), \
|
997
|
+
'connection set face pair(s) not assigned to exactly one feature' # rough check
|
878
998
|
|
879
999
|
# delattr(self, 'fi_cl') # assumed to be one-to-one mapping, so cumulative length is discarded
|
880
1000
|
|
@@ -1196,7 +1316,7 @@ class GridConnectionSet(BaseResqpy):
|
|
1196
1316
|
# uuid/InterpretationIndices/elements (N,) uint32
|
1197
1317
|
h5_reg.register_dataset(self.uuid, 'InterpretationIndices/elements', self.feature_indices)
|
1198
1318
|
# uuid/InterpretationIndices/cumulativeLength (N,) uint32
|
1199
|
-
one_to_one = np.arange(1, self.count + 1, dtype =
|
1319
|
+
one_to_one = np.arange(1, self.count + 1, dtype = np.uint32)
|
1200
1320
|
h5_reg.register_dataset(self.uuid, 'InterpretationIndices/cumulativeLength', one_to_one)
|
1201
1321
|
|
1202
1322
|
h5_reg.write(file_name, mode = mode)
|
@@ -1371,11 +1491,16 @@ class GridConnectionSet(BaseResqpy):
|
|
1371
1491
|
include_both_sides = False,
|
1372
1492
|
use_minus = False,
|
1373
1493
|
trans_mult_uuid = None):
|
1374
|
-
"""Creates a Nexus include file holding MULT keywords and data.
|
1494
|
+
"""Creates a Nexus include file holding MULT keywords and data.
|
1495
|
+
|
1496
|
+
note:
|
1497
|
+
trans_mult_uuid (optional) is the uuid of a property on the gcs containing transmissibility multiplier values;
|
1498
|
+
If not provided values of 1.0 will be used
|
1499
|
+
"""
|
1375
1500
|
if trans_mult_uuid is not None:
|
1376
1501
|
self.extract_property_collection()
|
1377
|
-
assert self.property_collection.part_in_collection(self.model.part_for_uuid(
|
1378
|
-
|
1502
|
+
assert self.property_collection.part_in_collection(self.model.part_for_uuid(trans_mult_uuid)), \
|
1503
|
+
f'trans_mult_uuid provided is not part of collection {trans_mult_uuid}'
|
1379
1504
|
tmult_array = self.property_collection.cached_part_array_ref(self.model.part_for_uuid(trans_mult_uuid))
|
1380
1505
|
assert tmult_array is not None
|
1381
1506
|
else:
|
@@ -1421,26 +1546,39 @@ class GridConnectionSet(BaseResqpy):
|
|
1421
1546
|
feature_name = self.feature_list[feature_index][2].split()[0].upper()
|
1422
1547
|
cell_index_pairs, face_index_pairs = self.list_of_cell_face_pairs_for_feature_index(feature_index)
|
1423
1548
|
if tmult_array is not None:
|
1424
|
-
feature_mask =
|
1549
|
+
feature_mask = (self.feature_indices == feature_index)
|
1425
1550
|
feat_mult_array = np.extract(feature_mask, tmult_array)
|
1426
1551
|
else:
|
1427
1552
|
feat_mult_array = np.ones(shape = (cell_index_pairs.shape[0],), dtype = float)
|
1428
1553
|
for side in sides:
|
1429
|
-
both = np.empty((cell_index_pairs.shape[0],
|
1554
|
+
both = np.empty((cell_index_pairs.shape[0], 5), dtype = np.int32) # axis, polarity, k, j, i
|
1430
1555
|
both[:, :2] = face_index_pairs[:, side, :] # axis, polarity
|
1431
|
-
both[:, 2
|
1432
|
-
both[:, -1] = feat_mult_array.flatten()
|
1433
|
-
df = pd.DataFrame(both, columns = ['axis', 'polarity', 'k', 'j', 'i', 'tmult'])
|
1434
|
-
df = df.sort_values(by = ['axis', 'polarity', 'j', 'i', 'k', 'tmult'])
|
1435
|
-
both_sorted = np.empty(both.shape, dtype =
|
1436
|
-
both_sorted[:] = df
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1556
|
+
both[:, 2:] = cell_index_pairs[:, side, :] # k, j, i
|
1557
|
+
# both[:, -1] = feat_mult_array.flatten()
|
1558
|
+
# df = pd.DataFrame(both, columns = ['axis', 'polarity', 'k', 'j', 'i', 'tmult'])
|
1559
|
+
# df = df.sort_values(by = ['axis', 'polarity', 'j', 'i', 'k', 'tmult'])
|
1560
|
+
# both_sorted = np.empty(both.shape, dtype = np.int32)
|
1561
|
+
# both_sorted[:] = df
|
1562
|
+
si = np.argsort(both[:, 2]) # k
|
1563
|
+
msi = si
|
1564
|
+
both = both[si]
|
1565
|
+
si = np.argsort(both[:, 4], kind = 'stable') # i
|
1566
|
+
msi = msi[si]
|
1567
|
+
both = both[si]
|
1568
|
+
si = np.argsort(both[:, 3], kind = 'stable') # j
|
1569
|
+
msi = msi[si]
|
1570
|
+
both = both[si]
|
1571
|
+
si = np.argsort(both[:, 1], kind = 'stable') # polarity
|
1572
|
+
msi = msi[si]
|
1573
|
+
both = both[si]
|
1574
|
+
si = np.argsort(both[:, 0], kind = 'stable') # axis
|
1575
|
+
msi = msi[si]
|
1576
|
+
both = both[si]
|
1577
|
+
cell_indices = both[:, 2:]
|
1578
|
+
face_indices = np.empty((both.shape[0], 2), dtype = np.int8)
|
1579
|
+
face_indices[:, :] = both[:, :2]
|
1580
|
+
tmult_values = feat_mult_array[msi]
|
1442
1581
|
del both
|
1443
|
-
del df
|
1444
1582
|
k = None
|
1445
1583
|
i = j = k2 = axis = polarity = None # only needed to placate flake8 which whinges incorrectly otherwise
|
1446
1584
|
for row in range(cell_indices.shape[0]):
|
@@ -1692,7 +1830,7 @@ class GridConnectionSet(BaseResqpy):
|
|
1692
1830
|
combined_values = property_value_by_column_edge.copy()
|
1693
1831
|
else:
|
1694
1832
|
combined_values = None
|
1695
|
-
combined_index = np.full((fault_by_column_edge_mask.shape), -1, dtype =
|
1833
|
+
combined_index = np.full((fault_by_column_edge_mask.shape), -1, dtype = np.int32)
|
1696
1834
|
combined_index = np.where(fault_by_column_edge_mask, feature, combined_index)
|
1697
1835
|
sum_unmasked = np.sum(fault_by_column_edge_mask)
|
1698
1836
|
else:
|
@@ -1802,7 +1940,7 @@ class GridConnectionSet(BaseResqpy):
|
|
1802
1940
|
def sorted_paired_cell_face_index_position(cell_face_index, a_or_b):
|
1803
1941
|
# pair one side (a_or_b) of cell_face_index with its position, then sort
|
1804
1942
|
count = len(cell_face_index)
|
1805
|
-
sp = np.empty((count, 2), dtype =
|
1943
|
+
sp = np.empty((count, 2), dtype = np.int32)
|
1806
1944
|
sp[:, 0] = cell_face_index[:, a_or_b]
|
1807
1945
|
sp[:, 1] = np.arange(count)
|
1808
1946
|
t = [tuple(r) for r in sp] # could use numpy fields based sort instead of tuple list?
|
@@ -1985,19 +2123,19 @@ class GridConnectionSet(BaseResqpy):
|
|
1985
2123
|
for k0 in range(entry['k1'], entry['k2'] + 1):
|
1986
2124
|
for j0 in range(entry['j1'], entry['j2'] + 1):
|
1987
2125
|
for i0 in range(entry['i1'], entry['i2'] + 1):
|
1988
|
-
neighbour = np.array([k0, j0, i0], dtype =
|
2126
|
+
neighbour = np.array([k0, j0, i0], dtype = np.int32)
|
1989
2127
|
if fp:
|
1990
2128
|
neighbour[axis] += 1
|
1991
2129
|
else:
|
1992
2130
|
neighbour[axis] -= 1
|
1993
2131
|
fi_list.append(feature_index)
|
1994
|
-
cell_pair_list.append((grid.natural_cell_index(
|
1995
|
-
|
2132
|
+
cell_pair_list.append((grid.natural_cell_index((k0, j0, i0)), \
|
2133
|
+
grid.natural_cell_index(neighbour)))
|
1996
2134
|
face_pair_list.append((self.face_index_map[axis, fp], self.face_index_map[axis, 1 - fp]))
|
1997
2135
|
if create_mult_prop:
|
1998
2136
|
mult_list.append(multiplier)
|
1999
2137
|
if fi_root is not None and fault_const_mult and fault_mult_value is not None:
|
2000
|
-
#patch extra_metadata into xml for new fault interpretation object
|
2138
|
+
# patch extra_metadata into xml for new fault interpretation object
|
2001
2139
|
rqet.create_metadata_xml(fi_root, {"Transmissibility multiplier": str(fault_mult_value)})
|
2002
2140
|
return True, const_mult
|
2003
2141
|
|
@@ -2162,3 +2300,27 @@ def _copy_organisation_objects(target_model, source_model, gcs):
|
|
2162
2300
|
for _, uuid, _ in gcs.feature_list:
|
2163
2301
|
target_model.copy_uuid_from_other_model(source_model,
|
2164
2302
|
uuid) # will copy related features as well as interpretations
|
2303
|
+
|
2304
|
+
|
2305
|
+
def _sort_and_remove_duplicates(a, props = None):
|
2306
|
+
"""Return copy of 1D array a, sorted and with duplicates removed; secondary arrays can be kept in alignment."""
|
2307
|
+
if a is None or a.size <= 1:
|
2308
|
+
return a
|
2309
|
+
assert a.ndim == 1
|
2310
|
+
si = None
|
2311
|
+
no_props = (props is None or len(props) == 0)
|
2312
|
+
if no_props:
|
2313
|
+
a = np.sort(a)
|
2314
|
+
else:
|
2315
|
+
si = np.argsort(a)
|
2316
|
+
a = a[si]
|
2317
|
+
m = np.empty(a.size, dtype = bool)
|
2318
|
+
m[0] = True
|
2319
|
+
m[1:] = (a[1:] != a[:-1])
|
2320
|
+
if np.all(m):
|
2321
|
+
return a
|
2322
|
+
if not no_props:
|
2323
|
+
for i in range(len(props)):
|
2324
|
+
p = props[i][si]
|
2325
|
+
props[i] = p[m]
|
2326
|
+
return a[m]
|
@@ -265,6 +265,10 @@ class Grid(BaseResqpy):
|
|
265
265
|
return np.count_nonzero(self.array_cell_geometry_is_defined)
|
266
266
|
return None
|
267
267
|
|
268
|
+
def is_big(self):
|
269
|
+
"""Returns True if number of cells exceeds 2^31 - 1, otherwise False."""
|
270
|
+
return (np.prod(self.extent_kji) >= 2_147_483_648)
|
271
|
+
|
268
272
|
def natural_cell_index(self, cell_kji0):
|
269
273
|
"""Returns a single integer for the cell, being the index into a flattened array."""
|
270
274
|
|
@@ -20,11 +20,13 @@ __all__ = [
|
|
20
20
|
"find_faces_to_represent_surface_staffa",
|
21
21
|
"find_faces_to_represent_surface_regular",
|
22
22
|
"find_faces_to_represent_surface_regular_optimised",
|
23
|
+
"find_faces_to_represent_surface_regular_dense_optimised",
|
23
24
|
"find_faces_to_represent_surface",
|
24
25
|
"bisector_from_faces",
|
25
26
|
"column_bisector_from_faces",
|
26
27
|
"shadow_from_faces",
|
27
28
|
"get_boundary",
|
29
|
+
"get_boundary_dict",
|
28
30
|
"_where_true",
|
29
31
|
"_first_true",
|
30
32
|
"intersect_numba",
|
@@ -56,11 +58,13 @@ from ._find_faces import (
|
|
56
58
|
find_faces_to_represent_surface_staffa,
|
57
59
|
find_faces_to_represent_surface_regular,
|
58
60
|
find_faces_to_represent_surface_regular_optimised,
|
61
|
+
find_faces_to_represent_surface_regular_dense_optimised,
|
59
62
|
find_faces_to_represent_surface,
|
60
63
|
bisector_from_faces,
|
61
64
|
column_bisector_from_faces,
|
62
65
|
shadow_from_faces,
|
63
66
|
get_boundary,
|
67
|
+
get_boundary_dict,
|
64
68
|
_where_true,
|
65
69
|
_first_true,
|
66
70
|
intersect_numba,
|
@@ -118,7 +118,7 @@ def populate_blocked_well_from_trajectory(blocked_well,
|
|
118
118
|
if xyz is None:
|
119
119
|
log.error('failed to lazily find intersection of trajectory with top surface of grid')
|
120
120
|
return None
|
121
|
-
cell_kji0 = np.array((0, col_ji0[0], col_ji0[1]), dtype =
|
121
|
+
cell_kji0 = np.array((0, col_ji0[0], col_ji0[1]), dtype = np.int32)
|
122
122
|
axis = 0
|
123
123
|
polarity = 0
|
124
124
|
|
@@ -133,7 +133,7 @@ def populate_blocked_well_from_trajectory(blocked_well,
|
|
133
133
|
else:
|
134
134
|
log.debug(f"skin intersection x,y,z: {xyz}; knot: {entry_knot}; cell kji0: {cell_kji0}; face: "
|
135
135
|
f"{'KJI'[axis]}{'-+'[polarity]}")
|
136
|
-
cell_kji0 = np.array(cell_kji0, dtype =
|
136
|
+
cell_kji0 = np.array(cell_kji0, dtype = np.int32)
|
137
137
|
|
138
138
|
previous_kji0 = cell_kji0.copy()
|
139
139
|
previous_kji0[axis] += polarity * 2 - 1 # note: previous may legitimately be 'beyond' edge of grid
|
@@ -244,9 +244,9 @@ def populate_blocked_well_from_trajectory(blocked_well,
|
|
244
244
|
|
245
245
|
blocked_well.node_mds = np.array(node_mds_list, dtype = float)
|
246
246
|
blocked_well.node_count = node_count
|
247
|
-
blocked_well.grid_indices = np.array(grid_indices_list, dtype =
|
248
|
-
blocked_well.cell_indices = np.array(cell_indices_list, dtype =
|
249
|
-
blocked_well.face_pair_indices = np.array(face_pairs_list, dtype =
|
247
|
+
blocked_well.grid_indices = np.array(grid_indices_list, dtype = np.int32)
|
248
|
+
blocked_well.cell_indices = np.array(cell_indices_list, dtype = np.int64)
|
249
|
+
blocked_well.face_pair_indices = np.array(face_pairs_list, dtype = np.int8)
|
250
250
|
blocked_well.cell_count = cell_count
|
251
251
|
blocked_well.grid_list = [grid]
|
252
252
|
|