LoopStructural 1.6.12__tar.gz → 1.6.14__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.
Potentially problematic release.
This version of LoopStructural might be problematic. Click here for more details.
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datatypes/_bounding_box.py +2 -1
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/__init__.py +10 -2
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_finite_difference_interpolator.py +18 -12
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_p1interpolator.py +1 -1
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_3d_structured_grid.py +3 -2
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/__init__.py +11 -3
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/_base_geological_feature.py +1 -1
- loopstructural-1.6.14/LoopStructural/modelling/features/_lambda_geological_feature.py +161 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/builders/_fault_builder.py +131 -144
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/builders/_geological_feature_builder.py +1 -1
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fault/_fault_function.py +4 -2
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fault/_fault_segment.py +1 -1
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/__init__.py +1 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/_surface.py +1 -1
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/helper.py +1 -24
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/maths.py +74 -17
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/regions.py +45 -41
- loopstructural-1.6.14/LoopStructural/version.py +1 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural.egg-info/PKG-INFO +1 -1
- {loopstructural-1.6.12 → loopstructural-1.6.14}/PKG-INFO +1 -1
- loopstructural-1.6.12/LoopStructural/modelling/features/_lambda_geological_feature.py +0 -103
- loopstructural-1.6.12/LoopStructural/version.py +0 -1
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LICENSE +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/_base.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/_example_models.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/claudius.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/claudiusbb.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/duplex.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/duplexbb.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/fault_trace/fault_trace.cpg +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/fault_trace/fault_trace.dbf +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/fault_trace/fault_trace.prj +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/fault_trace/fault_trace.shp +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/fault_trace/fault_trace.shx +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/bbox.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/contacts.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/fault_displacement.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/fault_edges.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/fault_locations.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/fault_orientations.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/stratigraphic_order.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/stratigraphic_orientations.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/geological_map_data/stratigraphic_thickness.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/intrusion.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/intrusionbb.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/onefoldbb.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/onefolddata.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/refolded_bb.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/refolded_fold.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datasets/data/tabular_intrusion.csv +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datatypes/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datatypes/_point.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datatypes/_structured_grid.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/datatypes/_surface.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/export/exporters.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/export/file_formats.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/export/geoh5.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/export/gocad.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/export/omf_wrapper.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_api.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_builders.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_cython/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_discrete_fold_interpolator.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_discrete_interpolator.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_geological_interpolator.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_interpolator_builder.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_interpolator_factory.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_operator.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_p2interpolator.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_surfe_wrapper.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_2d_base_unstructured.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_2d_p1_unstructured.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_2d_p2_unstructured.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_2d_structured_grid.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_2d_structured_tetra.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_3d_base_structured.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_3d_p2_tetra.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_3d_structured_tetra.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_3d_unstructured_tetra.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_aabb.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_base_support.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_face_table.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/supports/_support_factory.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/core/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/core/geological_model.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/_analytical_feature.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/_cross_product_geological_feature.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/_geological_feature.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/_projected_vector_feature.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/_region.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/_structural_frame.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/_unconformity_feature.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/builders/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/builders/_base_builder.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/builders/_folded_feature_builder.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/builders/_structural_frame_builder.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fault/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fault/_fault_function_feature.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/_fold.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/_fold_rotation_angle_feature.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/_foldframe.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/_svariogram.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/fold_function/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/fold_function/_base_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/fold_function/_fourier_series_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/fold_function/_lambda_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/features/fold/fold_function/_trigo_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/input/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/input/fault_network.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/input/map2loop_processor.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/input/process_data.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/input/project_file.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/intrusions/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/intrusions/geom_conceptual_models.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/intrusions/geometric_scaling_functions.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/intrusions/intrusion_builder.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/intrusions/intrusion_feature.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/intrusions/intrusion_frame_builder.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/modelling/intrusions/intrusion_support_functions.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/_transformation.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/colours.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/config.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/dtm_creator.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/exceptions.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/features.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/json_encoder.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/linalg.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/logging.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/typing.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/utils/utils.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/visualisation/__init__.py +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural.egg-info/SOURCES.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural.egg-info/dependency_links.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural.egg-info/requires.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural.egg-info/top_level.txt +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/README.md +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/pyproject.toml +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/setup.cfg +0 -0
- {loopstructural-1.6.12 → loopstructural-1.6.14}/setup.py +0 -0
|
@@ -281,6 +281,7 @@ class BoundingBox:
|
|
|
281
281
|
origin=origin,
|
|
282
282
|
maximum=maximum,
|
|
283
283
|
global_origin=self.global_origin,
|
|
284
|
+
nsteps=self.nsteps,
|
|
284
285
|
dimensions=self.dimensions,
|
|
285
286
|
)
|
|
286
287
|
|
|
@@ -387,7 +388,7 @@ class BoundingBox:
|
|
|
387
388
|
|
|
388
389
|
if not local:
|
|
389
390
|
coordinates = [
|
|
390
|
-
np.linspace(self.global_origin[i], self.global_maximum[i], nsteps[i])
|
|
391
|
+
np.linspace(self.global_origin[i]+self.origin[i], self.global_maximum[i], nsteps[i])
|
|
391
392
|
for i in range(self.dimensions)
|
|
392
393
|
]
|
|
393
394
|
coordinate_grid = np.meshgrid(*coordinates, indexing="ij")
|
|
@@ -83,8 +83,16 @@ from ..interpolators._p1interpolator import P1Interpolator
|
|
|
83
83
|
try:
|
|
84
84
|
from ..interpolators._surfe_wrapper import SurfeRBFInterpolator
|
|
85
85
|
except ImportError:
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
class SurfeRBFInterpolator(GeologicalInterpolator):
|
|
87
|
+
"""
|
|
88
|
+
Dummy class to handle the case where Surfe is not installed.
|
|
89
|
+
This will raise a warning when used.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
def __init__(self, *args, **kwargs):
|
|
93
|
+
raise ImportError(
|
|
94
|
+
"Surfe cannot be imported. Please install Surfe. pip install surfe/ conda install -c loop3d surfe"
|
|
95
|
+
)
|
|
88
96
|
interpolator_map = {
|
|
89
97
|
InterpolatorType.BASE: GeologicalInterpolator,
|
|
90
98
|
InterpolatorType.BASE_DISCRETE: DiscreteInterpolator,
|
|
@@ -454,22 +454,28 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
|
|
|
454
454
|
)
|
|
455
455
|
self.up_to_date = False
|
|
456
456
|
|
|
457
|
-
def add_regularisation(self, operator, w=0.1):
|
|
458
|
-
"""
|
|
459
457
|
|
|
460
|
-
Parameters
|
|
461
|
-
----------
|
|
462
|
-
operator
|
|
463
|
-
w
|
|
464
458
|
|
|
465
|
-
|
|
466
|
-
|
|
459
|
+
# def assemble_borders(self, operator, w, name='regularisation'):
|
|
460
|
+
# """
|
|
461
|
+
# Adds a constraint to the border of the model to force the value to be equal to the value at the border
|
|
467
462
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
463
|
+
# Parameters
|
|
464
|
+
# ----------
|
|
465
|
+
# operator : Operator
|
|
466
|
+
# operator to use for the regularisation
|
|
467
|
+
# w : double
|
|
468
|
+
# weight of the regularisation
|
|
469
|
+
|
|
470
|
+
# Returns
|
|
471
|
+
# -------
|
|
472
|
+
|
|
473
|
+
# """
|
|
474
|
+
# # First get the global indicies of the pairs of neighbours this should be an
|
|
475
|
+
# # Nx27 array for 3d and an Nx9 array for 2d
|
|
476
|
+
|
|
477
|
+
# global_indexes = self.support.neighbour_global_indexes()
|
|
471
478
|
|
|
472
|
-
# def assemble_borders(self, operator, w):
|
|
473
479
|
|
|
474
480
|
def assemble_inner(self, operator, w, name='regularisation'):
|
|
475
481
|
"""
|
{loopstructural-1.6.12 → loopstructural-1.6.14}/LoopStructural/interpolators/_p1interpolator.py
RENAMED
|
@@ -146,7 +146,7 @@ class P1Interpolator(DiscreteInterpolator):
|
|
|
146
146
|
self.reset()
|
|
147
147
|
for key in kwargs:
|
|
148
148
|
if "regularisation" in kwargs:
|
|
149
|
-
self.interpolation_weights["cgw"] =
|
|
149
|
+
self.interpolation_weights["cgw"] = kwargs["regularisation"]
|
|
150
150
|
self.up_to_date = False
|
|
151
151
|
self.interpolation_weights[key] = kwargs[key]
|
|
152
152
|
if self.interpolation_weights["cgw"] > 0.0:
|
|
@@ -437,8 +437,9 @@ class StructuredGrid(BaseStructuredSupport):
|
|
|
437
437
|
T[:, 2, 6] = (1 - local_coords[:, 0]) * local_coords[:, 1]
|
|
438
438
|
T[:, 2, 3] = -local_coords[:, 0] * local_coords[:, 1]
|
|
439
439
|
T[:, 2, 7] = local_coords[:, 0] * local_coords[:, 1]
|
|
440
|
-
T /= self.step_vector[0]
|
|
441
|
-
|
|
440
|
+
T[:, 0, :] /= self.step_vector[None, 0]
|
|
441
|
+
T[:, 1, :] /= self.step_vector[None, 1]
|
|
442
|
+
T[:, 2, :] /= self.step_vector[None, 2]
|
|
442
443
|
return vertices, T, elements, inside
|
|
443
444
|
|
|
444
445
|
def get_element_for_location(self, pos: np.ndarray):
|
|
@@ -22,6 +22,14 @@ from ..modelling.input import (
|
|
|
22
22
|
try:
|
|
23
23
|
from ..modelling.input.project_file import LoopProjectfileProcessor
|
|
24
24
|
except (LoopImportError, ImportError):
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
25
|
+
class LoopProjectfileProcessor(ProcessInputData):
|
|
26
|
+
"""
|
|
27
|
+
Dummy class to handle the case where LoopProjectFile is not installed.
|
|
28
|
+
This will raise a warning when used.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, *args, **kwargs):
|
|
32
|
+
raise LoopImportError(
|
|
33
|
+
"LoopProjectFile cannot be imported. Please install LoopProjectFile."
|
|
34
|
+
)
|
|
35
|
+
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geological features
|
|
3
|
+
"""
|
|
4
|
+
from LoopStructural.utils.maths import regular_tetraherdron_for_points, gradient_from_tetrahedron
|
|
5
|
+
from ...modelling.features import BaseFeature
|
|
6
|
+
from ...utils import getLogger
|
|
7
|
+
from ...modelling.features import FeatureType
|
|
8
|
+
import numpy as np
|
|
9
|
+
from typing import Callable, Optional
|
|
10
|
+
from ...utils import LoopValueError
|
|
11
|
+
|
|
12
|
+
logger = getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LambdaGeologicalFeature(BaseFeature):
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
function: Optional[Callable[[np.ndarray], np.ndarray]] = None,
|
|
19
|
+
name: str = "unnamed_lambda",
|
|
20
|
+
gradient_function: Optional[Callable[[np.ndarray], np.ndarray]] = None,
|
|
21
|
+
model=None,
|
|
22
|
+
regions: Optional[list] = None,
|
|
23
|
+
faults: Optional[list] = None,
|
|
24
|
+
builder=None,
|
|
25
|
+
):
|
|
26
|
+
"""A lambda geological feature is a wrapper for a geological
|
|
27
|
+
feature that has a function at the base. This can be then used
|
|
28
|
+
in place of a geological feature.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
function : _type_, optional
|
|
33
|
+
_description_, by default None
|
|
34
|
+
name : str, optional
|
|
35
|
+
_description_, by default "unnamed_lambda"
|
|
36
|
+
gradient_function : _type_, optional
|
|
37
|
+
_description_, by default None
|
|
38
|
+
model : _type_, optional
|
|
39
|
+
_description_, by default None
|
|
40
|
+
regions : list, optional
|
|
41
|
+
_description_, by default []
|
|
42
|
+
faults : list, optional
|
|
43
|
+
_description_, by default []
|
|
44
|
+
builder : _type_, optional
|
|
45
|
+
_description_, by default None
|
|
46
|
+
"""
|
|
47
|
+
BaseFeature.__init__(self, name, model, faults if faults is not None else [], regions if regions is not None else [], builder)
|
|
48
|
+
self.type = FeatureType.LAMBDA
|
|
49
|
+
self.function = function
|
|
50
|
+
self.gradient_function = gradient_function
|
|
51
|
+
self.regions = regions if regions is not None else []
|
|
52
|
+
|
|
53
|
+
def evaluate_value(self, pos: np.ndarray, ignore_regions=False) -> np.ndarray:
|
|
54
|
+
"""_summary_
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
xyz : np.ndarray
|
|
59
|
+
_description_
|
|
60
|
+
|
|
61
|
+
Returns
|
|
62
|
+
-------
|
|
63
|
+
np.ndarray
|
|
64
|
+
_description_
|
|
65
|
+
"""
|
|
66
|
+
v = np.zeros((pos.shape[0]))
|
|
67
|
+
v[:] = np.nan
|
|
68
|
+
|
|
69
|
+
mask = self._calculate_mask(pos, ignore_regions=ignore_regions)
|
|
70
|
+
pos = self._apply_faults(pos)
|
|
71
|
+
if self.function is not None:
|
|
72
|
+
|
|
73
|
+
v[mask] = self.function(pos[mask,:])
|
|
74
|
+
return v
|
|
75
|
+
|
|
76
|
+
def evaluate_gradient(self, pos: np.ndarray, ignore_regions=False,element_scale_parameter=None) -> np.ndarray:
|
|
77
|
+
"""_summary_
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
xyz : np.ndarray
|
|
82
|
+
_description_
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
np.ndarray
|
|
87
|
+
_description_
|
|
88
|
+
"""
|
|
89
|
+
if pos.shape[1] != 3:
|
|
90
|
+
raise LoopValueError("Need Nx3 array of xyz points to evaluate gradient")
|
|
91
|
+
logger.info(f'Calculating gradient for {self.name}')
|
|
92
|
+
if element_scale_parameter is None:
|
|
93
|
+
if self.model is not None:
|
|
94
|
+
element_scale_parameter = np.min(self.model.bounding_box.step_vector) / 10
|
|
95
|
+
else:
|
|
96
|
+
element_scale_parameter = 1
|
|
97
|
+
else:
|
|
98
|
+
try:
|
|
99
|
+
element_scale_parameter = float(element_scale_parameter)
|
|
100
|
+
except ValueError:
|
|
101
|
+
logger.error("element_scale_parameter must be a float")
|
|
102
|
+
element_scale_parameter = 1
|
|
103
|
+
v = np.zeros((pos.shape[0], 3))
|
|
104
|
+
v = np.zeros(pos.shape)
|
|
105
|
+
v[:] = np.nan
|
|
106
|
+
mask = self._calculate_mask(pos, ignore_regions=ignore_regions)
|
|
107
|
+
# evaluate the faults on the nodes of the faulted feature support
|
|
108
|
+
# then evaluate the gradient at these points
|
|
109
|
+
if len(self.faults) > 0:
|
|
110
|
+
# generate a regular tetrahedron for each point
|
|
111
|
+
# we will then move these points by the fault and then recalculate the gradient.
|
|
112
|
+
# this should work...
|
|
113
|
+
resolved = False
|
|
114
|
+
tetrahedron = regular_tetraherdron_for_points(pos, element_scale_parameter)
|
|
115
|
+
|
|
116
|
+
while resolved:
|
|
117
|
+
for f in self.faults:
|
|
118
|
+
v = (
|
|
119
|
+
f[0]
|
|
120
|
+
.evaluate_value(tetrahedron.reshape(-1, 3), fillnan='nearest')
|
|
121
|
+
.reshape(tetrahedron.shape[0], 4)
|
|
122
|
+
)
|
|
123
|
+
flag = np.logical_or(np.all(v > 0, axis=1), np.all(v < 0, axis=1))
|
|
124
|
+
if np.any(~flag):
|
|
125
|
+
logger.warning(
|
|
126
|
+
f"Points are too close to fault {f[0].name}. Refining the tetrahedron"
|
|
127
|
+
)
|
|
128
|
+
element_scale_parameter *= 0.5
|
|
129
|
+
tetrahedron = regular_tetraherdron_for_points(pos, element_scale_parameter)
|
|
130
|
+
|
|
131
|
+
resolved = True
|
|
132
|
+
|
|
133
|
+
tetrahedron_faulted = self._apply_faults(np.array(tetrahedron.reshape(-1, 3))).reshape(
|
|
134
|
+
tetrahedron.shape
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
values = self.function(tetrahedron_faulted.reshape(-1, 3)).reshape(
|
|
138
|
+
(-1, 4)
|
|
139
|
+
)
|
|
140
|
+
v[mask, :] = gradient_from_tetrahedron(tetrahedron[mask, :, :], values[mask])
|
|
141
|
+
|
|
142
|
+
return v
|
|
143
|
+
if self.gradient_function is None:
|
|
144
|
+
v[:, :] = np.nan
|
|
145
|
+
else:
|
|
146
|
+
v[:, :] = self.gradient_function(pos)
|
|
147
|
+
return v
|
|
148
|
+
|
|
149
|
+
def get_data(self, value_map: Optional[dict] = None):
|
|
150
|
+
return
|
|
151
|
+
|
|
152
|
+
def copy(self, name: Optional[str] = None):
|
|
153
|
+
return LambdaGeologicalFeature(
|
|
154
|
+
self.function,
|
|
155
|
+
name if name is not None else f'{self.name}_copy',
|
|
156
|
+
self.gradient_function,
|
|
157
|
+
self.model,
|
|
158
|
+
self.regions,
|
|
159
|
+
self.faults,
|
|
160
|
+
self.builder,
|
|
161
|
+
)
|