resqpy 5.0.0__tar.gz → 5.1.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-5.0.0 → resqpy-5.1.1}/PKG-INFO +2 -2
- {resqpy-5.0.0 → resqpy-5.1.1}/pyproject.toml +1 -1
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/__init__.py +1 -1
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid_surface/_find_faces.py +95 -29
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/model/_forestry.py +12 -6
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/model/_model.py +5 -7
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/multi_processing/wrappers/grid_surface_mp.py +93 -45
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/triangulation.py +16 -15
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/_collection_get_attributes.py +2 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/_surface.py +174 -22
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/_tri_mesh.py +3 -1
- {resqpy-5.0.0 → resqpy-5.1.1}/LICENSE +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/README.md +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/crs.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_add_edges_per_column_property_array.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_add_faults.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_add_one_blocked_well_property.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_add_one_grid_property_array.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_add_single_cell_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_add_wells_from_ascii_file.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_add_zone_by_layer_property.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_coarsened_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_common.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_copy_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_drape_to_surface.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_extract_box.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_extract_box_for_well.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_fault_throw_scaling.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_gather_ensemble.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_interpolated_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_local_depth_adjustment.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_refined_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_tilted_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_unsplit_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_zonal_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/derived_model/_zone_layer_ranges_from_array.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/fault/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/fault/_gcs_functions.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/fault/_grid_connection_set.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_cell_properties.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_connection_sets.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_create_grid_xml.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_defined_geometry.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_extract_functions.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_face_functions.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_faults.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_grid_types.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_intervals_info.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_pillars.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_pixel_maps.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_points_functions.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_regular_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_transmissibility.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_write_hdf5_from_caches.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_write_nexus_corp.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid/_xyz.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid_surface/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid_surface/_blocked_well_populate.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid_surface/_grid_skin.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid_surface/_grid_surface.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid_surface/_trajectory_intersects.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/grid_surface/grid_surface_cuda.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/lines/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/lines/_common.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/lines/_polyline.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/lines/_polyline_set.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/model/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/model/_catalogue.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/model/_context.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/model/_grids.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/model/_hdf5.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/model/_xml.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/multi_processing/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/multi_processing/_multiprocessing.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/multi_processing/wrappers/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/multi_processing/wrappers/blocked_well_mp.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/multi_processing/wrappers/mesh_mp.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/ab_toolbox.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/base.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/box_utilities.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/class_dict.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/consolidation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/data/build.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/data/properties.json +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/dataframe.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/exceptions.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/factors.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/fine_coarse.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/grid_functions.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/intersection.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/keyword_files.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/load_data.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/point_inclusion.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/random_seed.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/read_nexus_fault.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/relperm.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/simple_lines.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/time.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/trademark.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/transmission.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/uuid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/vdb.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/vector_utilities.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/volume.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/wellspec_keywords.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/write_data.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/write_hdf5.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/xml_et.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/xml_namespaces.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/olio/zmap_reader.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/_utils.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/boundary_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/boundary_feature_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/earth_model_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/fault_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/fluid_boundary_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/frontier_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/generic_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/genetic_boundary_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/geobody_boundary_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/geobody_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/geobody_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/geologic_unit_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/horizon_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/organization_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/rock_fluid_unit_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/structural_organization_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/tectonic_boundary_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/wellbore_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/organize/wellbore_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/_collection_add_part.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/_collection_create_xml.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/_collection_support.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/_property.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/attribute_property_set.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/grid_property_collection.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/property_collection.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/property_common.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/property_kind.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/string_lookup.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/well_interval_property.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/well_interval_property_collection.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/well_log.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/property/well_log_collection.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/rq_import/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/rq_import/_add_ab_properties.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/rq_import/_add_surfaces.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/rq_import/_grid_from_cp.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/rq_import/_import_nexus.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/rq_import/_import_vdb_all_grids.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/rq_import/_import_vdb_ensemble.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/strata/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/strata/_binary_contact_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/strata/_geologic_unit_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/strata/_strata_common.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/strata/_stratigraphic_column.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/strata/_stratigraphic_column_rank.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/strata/_stratigraphic_unit_feature.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/strata/_stratigraphic_unit_interpretation.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/_base_surface.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/_combined_surface.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/_mesh.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/_pointset.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/_tri_mesh_stencil.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/surface/_triangulated_patch.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/time_series/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/time_series/_any_time_series.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/time_series/_from_nexus_summary.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/time_series/_functions.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/time_series/_geologic_time_series.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/time_series/_time_duration.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/time_series/_time_series.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/unstructured/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/unstructured/_hexa_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/unstructured/_prism_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/unstructured/_pyramid_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/unstructured/_tetra_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/unstructured/_unstructured_grid.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/weights_and_measures/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/weights_and_measures/nexus_units.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/weights_and_measures/weights_and_measures.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/__init__.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/_blocked_well.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/_deviation_survey.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/_md_datum.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/_trajectory.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/_wellbore_frame.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/_wellbore_marker.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/_wellbore_marker_frame.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/blocked_well_frame.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/well_object_funcs.py +0 -0
- {resqpy-5.0.0 → resqpy-5.1.1}/resqpy/well/well_utils.py +0 -0
@@ -880,7 +880,8 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
880
880
|
return_properties = None,
|
881
881
|
raw_bisector = False,
|
882
882
|
n_batches = 20,
|
883
|
-
packed_bisectors = False
|
883
|
+
packed_bisectors = False,
|
884
|
+
patch_indices = None):
|
884
885
|
"""Returns a grid connection set containing those cell faces which are deemed to represent the surface.
|
885
886
|
|
886
887
|
argumants:
|
@@ -916,11 +917,14 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
916
917
|
threading allows some parallelism between the batches)
|
917
918
|
packed_bisectors (bool, default False): if True and return properties include 'grid bisector' then
|
918
919
|
non curtain bisectors are returned in packed form
|
920
|
+
patch_indices (numpy int array, optional): if present, an array over grid cells indicating which
|
921
|
+
patch of surface is applicable in terms of a bisector, for each cell
|
919
922
|
|
920
923
|
returns:
|
921
924
|
gcs or (gcs, gcs_props)
|
922
925
|
where gcs is a new GridConnectionSet with a single feature, not yet written to hdf5 nor xml created;
|
923
|
-
gcs_props is a dictionary mapping from requested return_properties string to numpy array
|
926
|
+
gcs_props is a dictionary mapping from requested return_properties string to numpy array (or tuple
|
927
|
+
of numpy array and curtain bool in the case of grid bisector)
|
924
928
|
|
925
929
|
notes:
|
926
930
|
this function is designed for aligned regular grids only;
|
@@ -929,7 +933,9 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
929
933
|
no trimming of the surface is carried out here: for computational efficiency, it is recommended
|
930
934
|
to trim first;
|
931
935
|
organisational objects for the feature are created if needed;
|
932
|
-
if the offset return property is requested, the implicit units will be the z units of the grid's crs
|
936
|
+
if the offset return property is requested, the implicit units will be the z units of the grid's crs;
|
937
|
+
if patch_indices is present and grid bisectors are being returned, a composite bisector array is returned
|
938
|
+
with elements set from individual bisectors for each patch of surface
|
933
939
|
"""
|
934
940
|
|
935
941
|
assert isinstance(grid, grr.RegularGrid)
|
@@ -959,7 +965,10 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
959
965
|
return_flange_bool = "flange bool" in return_properties
|
960
966
|
if return_flange_bool:
|
961
967
|
return_triangles = True
|
962
|
-
|
968
|
+
patchwork = return_bisector and patch_indices is not None
|
969
|
+
if patchwork:
|
970
|
+
return_triangles = True # triangle numbers are used to infer patch index
|
971
|
+
assert patch_indices.shape == tuple(grid.extent_kji)
|
963
972
|
if title is None:
|
964
973
|
title = name
|
965
974
|
|
@@ -1165,7 +1174,7 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1165
1174
|
k_faces_kji0 = k_faces_kji0,
|
1166
1175
|
j_faces_kji0 = j_faces_kji0,
|
1167
1176
|
i_faces_kji0 = i_faces_kji0,
|
1168
|
-
remove_duplicates =
|
1177
|
+
remove_duplicates = not patchwork,
|
1169
1178
|
k_properties = k_props,
|
1170
1179
|
j_properties = j_props,
|
1171
1180
|
i_properties = i_props,
|
@@ -1176,6 +1185,7 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1176
1185
|
# log.debug('finished coversion to gcs')
|
1177
1186
|
|
1178
1187
|
# NB. following assumes faces have been added to gcs in a particular order!
|
1188
|
+
all_tris = None
|
1179
1189
|
if return_triangles:
|
1180
1190
|
# log.debug('preparing triangles array')
|
1181
1191
|
k_triangles = np.empty((0,), dtype = np.int32) if k_props is None else k_props.pop(0)
|
@@ -1186,6 +1196,7 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1186
1196
|
assert all_tris.shape == (gcs.count,)
|
1187
1197
|
|
1188
1198
|
# NB. following assumes faces have been added to gcs in a particular order!
|
1199
|
+
all_depths = None
|
1189
1200
|
if return_depths:
|
1190
1201
|
# log.debug('preparing depths array')
|
1191
1202
|
k_depths = np.empty((0,), dtype = np.float64) if k_props is None else k_props.pop(0)
|
@@ -1196,6 +1207,7 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1196
1207
|
assert all_depths.shape == (gcs.count,)
|
1197
1208
|
|
1198
1209
|
# NB. following assumes faces have been added to gcs in a particular order!
|
1210
|
+
all_offsets = None
|
1199
1211
|
if return_offsets:
|
1200
1212
|
# log.debug('preparing offsets array')
|
1201
1213
|
k_offsets = np.empty((0,), dtype = np.float64) if k_props is None else k_props[0]
|
@@ -1205,6 +1217,7 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1205
1217
|
# log.debug(f'gcs count: {gcs.count}; all offsets shape: {all_offsets.shape}')
|
1206
1218
|
assert all_offsets.shape == (gcs.count,)
|
1207
1219
|
|
1220
|
+
all_flange = None
|
1208
1221
|
if return_flange_bool:
|
1209
1222
|
# log.debug('preparing flange array')
|
1210
1223
|
flange_bool_uuid = surface.model.uuid(title = "flange bool",
|
@@ -1217,8 +1230,9 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1217
1230
|
assert all_flange.shape == (gcs.count,)
|
1218
1231
|
|
1219
1232
|
# note: following is a grid cells property, not a gcs property
|
1233
|
+
bisector = None
|
1220
1234
|
if return_bisector:
|
1221
|
-
if is_curtain:
|
1235
|
+
if is_curtain and not patchwork:
|
1222
1236
|
log.debug("preparing columns bisector")
|
1223
1237
|
if j_faces_kji0 is None:
|
1224
1238
|
j_faces_ji0 = np.empty((0, 2), dtype = np.int32)
|
@@ -1230,8 +1244,51 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1230
1244
|
i_faces_ji0 = i_faces_kji0[:, 1:]
|
1231
1245
|
bisector = column_bisector_from_face_indices((grid.nj, grid.ni), j_faces_ji0, i_faces_ji0)
|
1232
1246
|
# log.debug('finished preparing columns bisector')
|
1247
|
+
elif patchwork:
|
1248
|
+
n_patches = surface.number_of_patches()
|
1249
|
+
nkf = len(k_faces_kji0)
|
1250
|
+
njf = len(j_faces_kji0)
|
1251
|
+
nif = len(i_faces_kji0)
|
1252
|
+
# fetch patch indices for triangle hits
|
1253
|
+
assert all_tris is not None and len(all_tris) == nkf + njf + nif
|
1254
|
+
patch_indices_k = surface.patch_indices_for_triangle_indices(all_tris[:nkf])
|
1255
|
+
patch_indices_j = surface.patch_indices_for_triangle_indices(all_tris[nkf:nkf + njf])
|
1256
|
+
patch_indices_i = surface.patch_indices_for_triangle_indices(all_tris[nkf + njf:])
|
1257
|
+
# add extra dimension to bisector array (at axis 0) for patches
|
1258
|
+
pb_shape = tuple([n_patches] + list(grid.extent_kji))
|
1259
|
+
if packed_bisectors:
|
1260
|
+
bisector = np.ones(_shape_packed(grid.extent_kji), dtype = np.uint8)
|
1261
|
+
else:
|
1262
|
+
bisector = np.ones(tuple(grid.extent_kji), dtype = np.bool_)
|
1263
|
+
# populate 4D bisector with an axis zero slice for each patch
|
1264
|
+
for patch in range(n_patches):
|
1265
|
+
mask = (patch_indices == patch)
|
1266
|
+
if np.count_nonzero(mask) == 0:
|
1267
|
+
log.warning(f'patch {patch} of surface {surface.title} is not applicable to any cells in grid')
|
1268
|
+
continue
|
1269
|
+
if packed_bisectors:
|
1270
|
+
mask = np.packbits(mask, axis = -1)
|
1271
|
+
patch_bisector, is_curtain = \
|
1272
|
+
packed_bisector_from_face_indices(tuple(grid.extent_kji),
|
1273
|
+
k_faces_kji0[(patch_indices_k == patch).astype(bool)],
|
1274
|
+
j_faces_kji0[(patch_indices_j == patch).astype(bool)],
|
1275
|
+
i_faces_kji0[(patch_indices_i == patch).astype(bool)],
|
1276
|
+
raw_bisector)
|
1277
|
+
bisector = np.bitwise_or(np.bitwise_and(mask, patch_bisector), bisector)
|
1278
|
+
else:
|
1279
|
+
patch_bisector, is_curtain = \
|
1280
|
+
bisector_from_face_indices(tuple(grid.extent_kji),
|
1281
|
+
k_faces_kji0[(patch_indices_k == patch).astype(bool)],
|
1282
|
+
j_faces_kji0[(patch_indices_j == patch).astype(bool)],
|
1283
|
+
i_faces_kji0[(patch_indices_i == patch).astype(bool)],
|
1284
|
+
raw_bisector)
|
1285
|
+
bisector[mask] = patch_bisector[mask]
|
1286
|
+
if is_curtain:
|
1287
|
+
# TODO: downgrade following to debug once downstream functionality tested
|
1288
|
+
log.warning(f'ignoring curtain nature of bisector for patch {patch} of surface: {surface.title}')
|
1289
|
+
is_curtain = False
|
1233
1290
|
else:
|
1234
|
-
log.debug("preparing cells bisector")
|
1291
|
+
log.debug("preparing singlular cells bisector")
|
1235
1292
|
if ((k_faces_kji0 is None or len(k_faces_kji0) == 0) and
|
1236
1293
|
(j_faces_kji0 is None or len(j_faces_kji0) == 0) and (i_faces_kji0 is None or len(i_faces_kji0) == 0)):
|
1237
1294
|
bisector = np.ones((grid.nj, grid.ni), dtype = bool)
|
@@ -1249,6 +1306,7 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1249
1306
|
bisector = bisector[0] # reduce to a columns property
|
1250
1307
|
|
1251
1308
|
# note: following is a grid cells property, not a gcs property
|
1309
|
+
shadow = None
|
1252
1310
|
if return_shadow:
|
1253
1311
|
log.debug("preparing cells shadow")
|
1254
1312
|
shadow = shadow_from_face_indices(tuple(grid.extent_kji), k_faces_kji0)
|
@@ -1261,7 +1319,7 @@ def find_faces_to_represent_surface_regular_optimised(grid,
|
|
1261
1319
|
# if returning properties, construct dictionary
|
1262
1320
|
if return_properties:
|
1263
1321
|
props_dict = {}
|
1264
|
-
if
|
1322
|
+
if 'triangle' in return_properties:
|
1265
1323
|
props_dict["triangle"] = all_tris
|
1266
1324
|
if return_depths:
|
1267
1325
|
props_dict["depth"] = all_depths
|
@@ -1363,7 +1421,7 @@ def bisector_from_faces( # type: ignore
|
|
1363
1421
|
- the face sets must form a single 'sealed' cut of the grid (eg. not waving in and out of the grid)
|
1364
1422
|
- any 'boxed in' parts of the grid (completely enclosed by bisecting faces) will be consistently
|
1365
1423
|
assigned to either the True or False part
|
1366
|
-
- this function is DEPRECATED,
|
1424
|
+
- this function is DEPRECATED, use newer indices based approach instead: bisector_from_face_indices()
|
1367
1425
|
"""
|
1368
1426
|
warnings.warn('DEPRECATED: grid_surface.bisector_from_faces() function; use bisector_from_face_indices() instead')
|
1369
1427
|
assert len(grid_extent_kji) == 3
|
@@ -1408,10 +1466,13 @@ def bisector_from_faces( # type: ignore
|
|
1408
1466
|
# check all array elements are not the same
|
1409
1467
|
true_count = np.count_nonzero(array)
|
1410
1468
|
cell_count = array.size
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1469
|
+
if 0 < true_count < cell_count:
|
1470
|
+
# negate the array if it minimises the mean k and determine if the surface is a curtain
|
1471
|
+
is_curtain = _shallow_or_curtain(array, true_count, raw_bisector)
|
1472
|
+
else:
|
1473
|
+
assert raw_bisector, 'face set for surface is leaky or empty (surface does not intersect grid)'
|
1474
|
+
log.error('face set for surface is leaky or empty (surface does not intersect grid)')
|
1475
|
+
is_curtain = False
|
1415
1476
|
|
1416
1477
|
return array, is_curtain
|
1417
1478
|
|
@@ -1482,10 +1543,13 @@ def bisector_from_face_indices( # type: ignore
|
|
1482
1543
|
# check all array elements are not the same
|
1483
1544
|
true_count = np.count_nonzero(array)
|
1484
1545
|
cell_count = array.size
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1546
|
+
if 0 < true_count < cell_count:
|
1547
|
+
# negate the array if it minimises the mean k and determine if the surface is a curtain
|
1548
|
+
is_curtain = _shallow_or_curtain(array, true_count, raw_bisector)
|
1549
|
+
else:
|
1550
|
+
assert raw_bisector, 'face set for surface is leaky or empty (surface does not intersect grid)'
|
1551
|
+
log.error('face set for surface is leaky or empty (surface does not intersect grid)')
|
1552
|
+
is_curtain = False
|
1489
1553
|
|
1490
1554
|
return array, is_curtain
|
1491
1555
|
|
@@ -1572,12 +1636,14 @@ def packed_bisector_from_face_indices( # type: ignore
|
|
1572
1636
|
else:
|
1573
1637
|
true_count = _bitwise_count_njit(array) # note: will usually include some padding bits, so not so true!
|
1574
1638
|
cell_count = np.prod(grid_extent_kji)
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1639
|
+
if 0 < true_count < cell_count:
|
1640
|
+
# negate the array if it minimises the mean k and determine if the surface is a curtain
|
1641
|
+
# TODO: switch to _packed_shallow_or_curtain_temp_bitwise_count() when numba supports np.bitwise_count()
|
1642
|
+
is_curtain = _packed_shallow_or_curtain_temp_bitwise_count(array, true_count, raw_bisector)
|
1643
|
+
else:
|
1644
|
+
assert raw_bisector, 'face set for surface is leaky or empty (surface does not intersect grid)'
|
1645
|
+
log.error('face set for surface is leaky or empty (surface does not intersect grid)')
|
1646
|
+
is_curtain = False
|
1581
1647
|
|
1582
1648
|
return array, is_curtain
|
1583
1649
|
|
@@ -2227,12 +2293,12 @@ def get_boundary_from_indices( # type: ignore
|
|
2227
2293
|
k_faces_kji0: Union[np.ndarray, None], j_faces_kji0: Union[np.ndarray, None],
|
2228
2294
|
i_faces_kji0: Union[np.ndarray, None], grid_extent_kji: Tuple[int, int, int]) -> np.ndarray:
|
2229
2295
|
"""Return python protocol box containing indices"""
|
2230
|
-
k_min_kji0 = None if k_faces_kji0 is None else np.min(k_faces_kji0, axis = 0)
|
2231
|
-
k_max_kji0 = None if k_faces_kji0 is None else np.max(k_faces_kji0, axis = 0)
|
2232
|
-
j_min_kji0 = None if j_faces_kji0 is None else np.min(j_faces_kji0, axis = 0)
|
2233
|
-
j_max_kji0 = None if j_faces_kji0 is None else np.max(j_faces_kji0, axis = 0)
|
2234
|
-
i_min_kji0 = None if i_faces_kji0 is None else np.min(i_faces_kji0, axis = 0)
|
2235
|
-
i_max_kji0 = None if i_faces_kji0 is None else np.max(i_faces_kji0, axis = 0)
|
2296
|
+
k_min_kji0 = None if (k_faces_kji0 is None or k_faces_kji0.size == 0) else np.min(k_faces_kji0, axis = 0)
|
2297
|
+
k_max_kji0 = None if (k_faces_kji0 is None or k_faces_kji0.size == 0) else np.max(k_faces_kji0, axis = 0)
|
2298
|
+
j_min_kji0 = None if (j_faces_kji0 is None or j_faces_kji0.size == 0) else np.min(j_faces_kji0, axis = 0)
|
2299
|
+
j_max_kji0 = None if (j_faces_kji0 is None or j_faces_kji0.size == 0) else np.max(j_faces_kji0, axis = 0)
|
2300
|
+
i_min_kji0 = None if (i_faces_kji0 is None or i_faces_kji0.size == 0) else np.min(i_faces_kji0, axis = 0)
|
2301
|
+
i_max_kji0 = None if (i_faces_kji0 is None or i_faces_kji0.size == 0) else np.max(i_faces_kji0, axis = 0)
|
2236
2302
|
box = np.empty((2, 3), dtype = np.int32)
|
2237
2303
|
box[0, :] = grid_extent_kji
|
2238
2304
|
box[1, :] = -1
|
@@ -686,17 +686,23 @@ def _copy_referenced_parts(model, other_model, realization, consolidate, force,
|
|
686
686
|
resident_uuid_int = model.consolidation.map[ref_uuid_int]
|
687
687
|
assert resident_uuid_int is not None
|
688
688
|
# find referring node for ref_uuid_int and modify its reference to resident_uuid_int
|
689
|
-
if reference_node_dict is None:
|
689
|
+
if reference_node_dict is None: # now mapping uuid int to list of nodes
|
690
690
|
ref_nodes = rqet.list_obj_references(root_node)
|
691
691
|
reference_node_dict = {}
|
692
692
|
for ref_node in ref_nodes:
|
693
693
|
uuid_node = rqet.find_tag(ref_node, 'UUID')
|
694
694
|
uuid_int = bu.uuid_from_string(uuid_node.text).int
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
695
|
+
if uuid_int in reference_node_dict:
|
696
|
+
reference_node_dict[uuid_int].append(uuid_node)
|
697
|
+
else:
|
698
|
+
reference_node_dict[uuid_int] = [uuid_node]
|
699
|
+
uuid_node_list = reference_node_dict.pop(ref_uuid_int)
|
700
|
+
for uuid_node in uuid_node_list:
|
701
|
+
uuid_node.text = str(bu.uuid_from_int(resident_uuid_int))
|
702
|
+
if resident_uuid_int in reference_node_dict:
|
703
|
+
reference_node_dict[resident_uuid_int] += uuid_node_list
|
704
|
+
else:
|
705
|
+
reference_node_dict[resident_uuid_int] = uuid_node_list
|
700
706
|
|
701
707
|
|
702
708
|
def _copy_relationships_for_present_targets(model, other_model, consolidate, force, resident_uuid, root_node):
|
@@ -2100,6 +2100,11 @@ class Model():
|
|
2100
2100
|
if other_model is self:
|
2101
2101
|
return part
|
2102
2102
|
assert part is not None
|
2103
|
+
# check whether already existing in this model
|
2104
|
+
if part in self.parts_forest.keys():
|
2105
|
+
return part
|
2106
|
+
if m_c._type_of_part(other_model, part) == 'obj_EpcExternalPartReference':
|
2107
|
+
return None
|
2103
2108
|
if realization is not None:
|
2104
2109
|
assert isinstance(realization, int) and realization >= 0
|
2105
2110
|
if force:
|
@@ -2110,13 +2115,6 @@ class Model():
|
|
2110
2115
|
self_h5_file_name = self.h5_file_name(file_must_exist = False)
|
2111
2116
|
hdf5_copy_needed = not os.path.samefile(self_h5_file_name, other_h5_file_name)
|
2112
2117
|
|
2113
|
-
# check whether already existing in this model
|
2114
|
-
if part in self.parts_forest.keys():
|
2115
|
-
return part
|
2116
|
-
|
2117
|
-
if m_c._type_of_part(other_model, part) == 'obj_EpcExternalPartReference':
|
2118
|
-
return None
|
2119
|
-
|
2120
2118
|
return m_f._copy_part_from_other_model(self,
|
2121
2119
|
other_model,
|
2122
2120
|
part,
|
@@ -4,8 +4,10 @@ import logging
|
|
4
4
|
|
5
5
|
log = logging.getLogger(__name__)
|
6
6
|
|
7
|
+
import os
|
7
8
|
import numpy as np
|
8
9
|
import uuid
|
10
|
+
import ast
|
9
11
|
from typing import Tuple, Union, List, Optional, Callable
|
10
12
|
from pathlib import Path
|
11
13
|
from uuid import UUID
|
@@ -18,33 +20,38 @@ import resqpy.surface as rqs
|
|
18
20
|
import resqpy.olio.uuid as bu
|
19
21
|
|
20
22
|
|
21
|
-
def find_faces_to_represent_surface_regular_wrapper(
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
23
|
+
def find_faces_to_represent_surface_regular_wrapper(
|
24
|
+
index: int,
|
25
|
+
parent_tmp_dir: str,
|
26
|
+
use_index_as_realisation: bool,
|
27
|
+
grid_epc: str,
|
28
|
+
grid_uuid: Union[UUID, str],
|
29
|
+
surface_epc: str,
|
30
|
+
surface_uuid: Union[UUID, str],
|
31
|
+
name: str,
|
32
|
+
title: Optional[str] = None,
|
33
|
+
agitate: bool = False,
|
34
|
+
random_agitation: bool = False,
|
35
|
+
feature_type: str = 'fault',
|
36
|
+
trimmed: bool = False,
|
37
|
+
is_curtain = False,
|
38
|
+
extend_fault_representation: bool = False,
|
39
|
+
flange_inner_ring: bool = False,
|
40
|
+
saucer_parameter: Optional[float] = None,
|
41
|
+
retriangulate: bool = False,
|
42
|
+
related_uuid: Optional[Union[UUID, str]] = None,
|
43
|
+
progress_fn: Optional[Callable] = None,
|
44
|
+
extra_metadata = None,
|
45
|
+
return_properties: Optional[List[str]] = None,
|
46
|
+
raw_bisector: bool = False,
|
47
|
+
use_pack: bool = False,
|
48
|
+
flange_radius: Optional[float] = None,
|
49
|
+
reorient: bool = True,
|
50
|
+
n_threads: int = 20,
|
51
|
+
patchwork: bool = False,
|
52
|
+
grid_patching_property_uuid: Optional[Union[UUID, str]] = None,
|
53
|
+
surface_patching_property_uuid: Optional[Union[UUID, str]] = None) -> \
|
54
|
+
Tuple[int, bool, str, List[Union[UUID, str]]]:
|
48
55
|
"""Multiprocessing wrapper function of find_faces_to_represent_surface_regular_optimised.
|
49
56
|
|
50
57
|
arguments:
|
@@ -98,8 +105,17 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
98
105
|
flange_radius (float, optional): the radial distance to use for outer flange extension points; if None,
|
99
106
|
a large value will be calculated from the grid size; units are xy units of grid crs
|
100
107
|
reorient (bool, default True): if True, the points are reoriented to minimise the
|
101
|
-
|
108
|
+
z range prior to retriangulation (ie. z axis is approximate normal to plane of points), to enhace the triangulation
|
102
109
|
n_threads (int, default 20): the number of parallel threads to use in numba points in triangles function
|
110
|
+
patchwork (bool, default False): if True and grid bisector is included in return properties, a compostite
|
111
|
+
bisector is generated, based on individual ones for each patch of the surface; the following two
|
112
|
+
arguments must be set if patchwork is True
|
113
|
+
grid_patching_property_uuid (uuid, optional): required if patchwork is True, the uuid of a discrete or
|
114
|
+
categorical cells property on the grid which will be used to determine which patch of the surface is
|
115
|
+
relevant to a cell
|
116
|
+
surface_patching_property_uuid (uuid, optional): required if patchwork is True, the uuid of a discrete or
|
117
|
+
categorical property on the patches of the surface, identifying the value of the grid patching property
|
118
|
+
that each patch relates to
|
103
119
|
|
104
120
|
returns:
|
105
121
|
Tuple containing:
|
@@ -109,18 +125,15 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
109
125
|
- uuid_list (List[str]): list of UUIDs of relevant objects
|
110
126
|
|
111
127
|
notes:
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
the saucer_parameter is
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
+ve angles result in the shift being in the direction of the -ve z hemisphere; -ve angles result in
|
122
|
-
the shift being in the +ve z hemisphere; in either case the direction of the shift is perpendicular
|
123
|
-
to the average plane of the original points
|
128
|
+
- use this function as argument to the multiprocessing function; it will create a new model that is saved
|
129
|
+
in a temporary epc file and returns the required values, which are used in the multiprocessing function to
|
130
|
+
recombine all the objects into a single epc file
|
131
|
+
- the saucer_parameter is between -90.0 and 90.0 and is interpreted as an angle to apply out of
|
132
|
+
the plane of the original points, to give a simple saucer shape;
|
133
|
+
+ve angles result in the shift being in the direction of the -ve z hemisphere; -ve angles result in
|
134
|
+
the shift being in the +ve z hemisphere; in either case the direction of the shift is perpendicular
|
135
|
+
to the average plane of the original points
|
136
|
+
- patchwork is not compatible with re-triangulation
|
124
137
|
"""
|
125
138
|
tmp_dir = Path(parent_tmp_dir) / f"{uuid.uuid4()}"
|
126
139
|
tmp_dir.mkdir(parents = True, exist_ok = True)
|
@@ -148,12 +161,20 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
148
161
|
if flange_radius is None:
|
149
162
|
flange_radius = 5.0 * np.sum(np.array(grid.extent_kji, dtype = float) * np.array(grid.aligned_dxyz()))
|
150
163
|
s_model = rq.Model(surface_epc, quiet = True)
|
151
|
-
|
164
|
+
surface_uuid = str(surface_uuid)
|
165
|
+
model.copy_uuid_from_other_model(s_model, uuid = surface_uuid)
|
166
|
+
if surface_patching_property_uuid is not None:
|
167
|
+
model.copy_uuid_from_other_model(s_model, uuid = surface_patching_property_uuid)
|
168
|
+
uuid_list.append(surface_patching_property_uuid)
|
152
169
|
repr_type = model.type_of_part(model.part(uuid = surface_uuid), strip_obj = True)
|
153
170
|
assert repr_type in ['TriangulatedSetRepresentation', 'PointSetRepresentation']
|
171
|
+
assert repr_type == 'TriangulatedSetRepresentation' or not patchwork, \
|
172
|
+
'patchwork only implemented for triangulated set surfaces'
|
173
|
+
|
154
174
|
extended = False
|
155
175
|
retriangulated = False
|
156
176
|
flange_bool = None
|
177
|
+
|
157
178
|
if repr_type == 'PointSetRepresentation':
|
158
179
|
# trim pointset to grid xyz box
|
159
180
|
pset = rqs.PointSet(model, uuid = surface_uuid)
|
@@ -193,19 +214,26 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
193
214
|
inherit_interpretation_relationship(model, surface_uuid, surf.uuid)
|
194
215
|
surface_uuid = surf.uuid
|
195
216
|
|
196
|
-
surface = rqs.Surface(parent_model = model, uuid =
|
217
|
+
surface = rqs.Surface(parent_model = model, uuid = surface_uuid)
|
197
218
|
surf_title = surface.title
|
198
219
|
assert surf_title
|
199
220
|
surface.change_crs(grid.crs)
|
221
|
+
normal_vector = None
|
222
|
+
if reorient:
|
223
|
+
normal_vector = surface.normal()
|
224
|
+
if patchwork: # disable trimming as whole patches could be trimmed out, changing the patch indexing from that expected
|
225
|
+
trimmed = True
|
200
226
|
if not trimmed and surface.triangle_count() > 100:
|
201
227
|
if not surf_title.endswith('trimmed'):
|
202
228
|
surf_title += ' trimmed'
|
203
229
|
trimmed_surf = rqs.Surface(model, crs_uuid = grid.crs.uuid, title = surf_title)
|
204
230
|
# trimmed_surf.set_to_trimmed_surface(surf, xyz_box = xyz_box, xy_polygon = parent_seg.polygon)
|
205
231
|
trimmed_surf.set_to_trimmed_surface(surface, xyz_box = grid.xyz_box(local = True))
|
232
|
+
trimmed_surf.extra_metadata = surface.extra_metadata
|
206
233
|
surface = trimmed_surf
|
207
234
|
trimmed = True
|
208
235
|
if (extend_fault_representation and not extended) or (retriangulate and not retriangulated):
|
236
|
+
assert not patchwork, 'extension or re-triangulation are not compatible with patchwork'
|
209
237
|
_, p = surface.triangles_and_points()
|
210
238
|
pset = rqs.PointSet(model, points_array = p, crs_uuid = grid.crs.uuid, title = surf_title)
|
211
239
|
if extend_fault_representation and not surf_title.endswith('extended'):
|
@@ -218,7 +246,8 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
218
246
|
flange_inner_ring = flange_inner_ring,
|
219
247
|
saucer_parameter = saucer_parameter,
|
220
248
|
flange_radial_distance = flange_radius,
|
221
|
-
make_clockwise = False
|
249
|
+
make_clockwise = False,
|
250
|
+
normal_vector = normal_vector)
|
222
251
|
del pset
|
223
252
|
extended = extend_fault_representation
|
224
253
|
retriangulated = True
|
@@ -242,7 +271,23 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
242
271
|
discrete = True,
|
243
272
|
dtype = np.uint8)
|
244
273
|
uuid_list.append(flange_p.uuid)
|
245
|
-
|
274
|
+
|
275
|
+
if not patchwork:
|
276
|
+
uuid_list.append(surface_uuid)
|
277
|
+
|
278
|
+
patch_indices = None
|
279
|
+
if patchwork: # generate a patch indices array over grid cells based on supplied patching properties
|
280
|
+
assert grid_patching_property_uuid is not None and surface_patching_property_uuid is not None
|
281
|
+
g_patching_array = rqp.Property(g_model, uuid = grid_patching_property_uuid).array_ref()
|
282
|
+
assert g_patching_array.shape == tuple(grid.extent_kji)
|
283
|
+
s_patches_array = rqp.Property(model, uuid = surface_patching_property_uuid).array_ref()
|
284
|
+
patch_count = surface.number_of_patches()
|
285
|
+
assert s_patches_array.shape == (patch_count,)
|
286
|
+
p_dtype = (np.int8 if s_patches_array.shape[0] < 128 else np.int32)
|
287
|
+
patch_indices = np.full(g_patching_array.shape, -1, dtype = p_dtype)
|
288
|
+
for patch in range(patch_count):
|
289
|
+
gp = s_patches_array[patch]
|
290
|
+
patch_indices[(g_patching_array == gp).astype(bool)] = patch
|
246
291
|
|
247
292
|
returns = rqgs.find_faces_to_represent_surface_regular_optimised(grid,
|
248
293
|
surface,
|
@@ -256,7 +301,8 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
256
301
|
return_properties,
|
257
302
|
raw_bisector = raw_bisector,
|
258
303
|
n_batches = n_threads,
|
259
|
-
packed_bisectors = use_pack
|
304
|
+
packed_bisectors = use_pack,
|
305
|
+
patch_indices = patch_indices)
|
260
306
|
|
261
307
|
success = False
|
262
308
|
|
@@ -286,6 +332,7 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
286
332
|
|
287
333
|
if success and return_properties is not None and len(return_properties):
|
288
334
|
log.debug(f'{name} requested properties: {return_properties}')
|
335
|
+
assert isinstance(returns, tuple)
|
289
336
|
properties = returns[1]
|
290
337
|
realisation = index if use_index_as_realisation else None
|
291
338
|
property_collection = rqp.PropertyCollection(support = gcs)
|
@@ -346,6 +393,7 @@ def find_faces_to_represent_surface_regular_wrapper(index: int,
|
|
346
393
|
if grid_pc is None:
|
347
394
|
grid_pc = rqp.PropertyCollection()
|
348
395
|
grid_pc.set_support(support = grid)
|
396
|
+
assert array.ndim == (2 if is_curtain else 3)
|
349
397
|
grid_pc.add_cached_array_to_imported_list(array,
|
350
398
|
f"from find_faces function for {surface.title}",
|
351
399
|
f'{surface.title} {p_name}',
|