LoopStructural 1.6.11__tar.gz → 1.6.13__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.11 → loopstructural-1.6.13}/LoopStructural/datatypes/_bounding_box.py +2 -4
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datatypes/_point.py +2 -2
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_finite_difference_interpolator.py +18 -3
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_3d_base_structured.py +3 -3
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_3d_structured_tetra.py +3 -3
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_3d_unstructured_tetra.py +3 -3
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_face_table.py +3 -3
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/core/geological_model.py +7 -7
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/_base_geological_feature.py +1 -1
- loopstructural-1.6.13/LoopStructural/modelling/features/_lambda_geological_feature.py +161 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/builders/_fault_builder.py +131 -144
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fault/_fault_function.py +18 -24
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fault/_fault_segment.py +12 -6
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/input/process_data.py +6 -6
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/_surface.py +1 -1
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/regions.py +45 -41
- loopstructural-1.6.13/LoopStructural/version.py +1 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural.egg-info/PKG-INFO +1 -1
- {loopstructural-1.6.11 → loopstructural-1.6.13}/PKG-INFO +1 -1
- loopstructural-1.6.11/LoopStructural/modelling/features/_lambda_geological_feature.py +0 -103
- loopstructural-1.6.11/LoopStructural/version.py +0 -1
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LICENSE +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/_base.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/_example_models.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/claudius.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/claudiusbb.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/duplex.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/duplexbb.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/fault_trace/fault_trace.cpg +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/fault_trace/fault_trace.dbf +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/fault_trace/fault_trace.prj +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/fault_trace/fault_trace.shp +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/fault_trace/fault_trace.shx +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/bbox.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/contacts.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/fault_displacement.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/fault_edges.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/fault_locations.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/fault_orientations.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/stratigraphic_order.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/stratigraphic_orientations.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/geological_map_data/stratigraphic_thickness.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/intrusion.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/intrusionbb.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/onefoldbb.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/onefolddata.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/refolded_bb.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/refolded_fold.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datasets/data/tabular_intrusion.csv +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datatypes/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datatypes/_structured_grid.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/datatypes/_surface.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/export/exporters.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/export/file_formats.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/export/geoh5.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/export/gocad.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/export/omf_wrapper.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_api.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_builders.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_cython/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_discrete_fold_interpolator.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_discrete_interpolator.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_geological_interpolator.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_interpolator_builder.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_interpolator_factory.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_operator.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_p1interpolator.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_p2interpolator.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/_surfe_wrapper.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_2d_base_unstructured.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_2d_p1_unstructured.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_2d_p2_unstructured.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_2d_structured_grid.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_2d_structured_tetra.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_3d_p2_tetra.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_3d_structured_grid.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_aabb.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_base_support.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_support_factory.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/core/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/_analytical_feature.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/_cross_product_geological_feature.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/_geological_feature.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/_projected_vector_feature.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/_region.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/_structural_frame.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/_unconformity_feature.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/builders/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/builders/_base_builder.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/builders/_folded_feature_builder.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/builders/_geological_feature_builder.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/builders/_structural_frame_builder.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fault/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fault/_fault_function_feature.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/_fold.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/_fold_rotation_angle_feature.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/_foldframe.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/_svariogram.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/fold_function/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/fold_function/_base_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/fold_function/_fourier_series_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/fold_function/_lambda_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/features/fold/fold_function/_trigo_fold_rotation_angle.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/input/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/input/fault_network.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/input/map2loop_processor.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/input/project_file.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/intrusions/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/intrusions/geom_conceptual_models.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/intrusions/geometric_scaling_functions.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/intrusions/intrusion_builder.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/intrusions/intrusion_feature.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/intrusions/intrusion_frame_builder.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/intrusions/intrusion_support_functions.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/_transformation.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/colours.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/config.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/dtm_creator.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/exceptions.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/features.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/helper.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/json_encoder.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/linalg.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/logging.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/maths.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/typing.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/utils/utils.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/visualisation/__init__.py +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural.egg-info/SOURCES.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural.egg-info/dependency_links.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural.egg-info/requires.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural.egg-info/top_level.txt +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/README.md +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/pyproject.toml +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/setup.cfg +0 -0
- {loopstructural-1.6.11 → loopstructural-1.6.13}/setup.py +0 -0
|
@@ -326,9 +326,7 @@ class BoundingBox:
|
|
|
326
326
|
if iy == -1:
|
|
327
327
|
return self.origin[ix]
|
|
328
328
|
|
|
329
|
-
return self.bb[
|
|
330
|
-
ix,
|
|
331
|
-
]
|
|
329
|
+
return self.bb[ix,]
|
|
332
330
|
|
|
333
331
|
def __getitem__(self, name):
|
|
334
332
|
if isinstance(name, str):
|
|
@@ -389,7 +387,7 @@ class BoundingBox:
|
|
|
389
387
|
|
|
390
388
|
if not local:
|
|
391
389
|
coordinates = [
|
|
392
|
-
np.linspace(self.global_origin[i], self.global_maximum[i], nsteps[i])
|
|
390
|
+
np.linspace(self.global_origin[i]+self.origin[i], self.global_maximum[i], nsteps[i])
|
|
393
391
|
for i in range(self.dimensions)
|
|
394
392
|
]
|
|
395
393
|
coordinate_grid = np.meshgrid(*coordinates, indexing="ij")
|
|
@@ -147,8 +147,8 @@ class VectorPoints:
|
|
|
147
147
|
else:
|
|
148
148
|
norm = np.linalg.norm(vectors, axis=1)
|
|
149
149
|
vectors[norm > 0, :] /= norm[norm > 0][:, None]
|
|
150
|
-
norm = norm[norm > 0] / norm[norm > 0].max()
|
|
151
|
-
vectors *= norm[
|
|
150
|
+
norm[norm > 0] = norm[norm > 0] / norm[norm > 0].max()
|
|
151
|
+
vectors[norm > 0, :] *= norm[norm > 0, None]
|
|
152
152
|
if scale_function is not None:
|
|
153
153
|
# vectors /= np.linalg.norm(vectors, axis=1)[:, None]
|
|
154
154
|
vectors *= scale_function(self.locations)[:, None]
|
|
@@ -272,7 +272,12 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
|
|
|
272
272
|
idc[inside, :] = gi[node_idx[inside, :]]
|
|
273
273
|
inside = np.logical_and(~np.any(idc == -1, axis=1), inside)
|
|
274
274
|
|
|
275
|
-
(
|
|
275
|
+
(
|
|
276
|
+
vertices,
|
|
277
|
+
T,
|
|
278
|
+
elements,
|
|
279
|
+
inside_,
|
|
280
|
+
) = self.support.get_element_gradient_for_location(
|
|
276
281
|
points[inside, : self.support.dimension]
|
|
277
282
|
)
|
|
278
283
|
# normalise constraint vector and scale element matrix by this
|
|
@@ -335,7 +340,12 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
|
|
|
335
340
|
# calculate unit vector for node gradients
|
|
336
341
|
# this means we are only constraining direction of grad not the
|
|
337
342
|
# magnitude
|
|
338
|
-
(
|
|
343
|
+
(
|
|
344
|
+
vertices,
|
|
345
|
+
T,
|
|
346
|
+
elements,
|
|
347
|
+
inside_,
|
|
348
|
+
) = self.support.get_element_gradient_for_location(
|
|
339
349
|
points[inside, : self.support.dimension]
|
|
340
350
|
)
|
|
341
351
|
# T*=np.product(self.support.step_vector)
|
|
@@ -422,7 +432,12 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
|
|
|
422
432
|
vectors[norm > 0, :] /= norm[norm > 0, None]
|
|
423
433
|
|
|
424
434
|
# normalise element vector to unit vector for dot product
|
|
425
|
-
(
|
|
435
|
+
(
|
|
436
|
+
vertices,
|
|
437
|
+
T,
|
|
438
|
+
elements,
|
|
439
|
+
inside_,
|
|
440
|
+
) = self.support.get_element_gradient_for_location(
|
|
426
441
|
points[inside, : self.support.dimension]
|
|
427
442
|
)
|
|
428
443
|
T[norm > 0, :, :] /= norm[norm > 0, None, None]
|
|
@@ -162,9 +162,9 @@ class BaseStructuredSupport(BaseSupport):
|
|
|
162
162
|
length = self.maximum - origin
|
|
163
163
|
length /= self.step_vector
|
|
164
164
|
self._nsteps = np.ceil(length).astype(np.int64)
|
|
165
|
-
self._nsteps[
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
self._nsteps[self._nsteps == 0] = (
|
|
166
|
+
3 # need to have a minimum of 3 elements to apply the finite difference mask
|
|
167
|
+
)
|
|
168
168
|
if np.any(~(self._nsteps > 0)):
|
|
169
169
|
logger.error(
|
|
170
170
|
f"Cannot resize the interpolation support. The proposed number of steps is {self._nsteps}, these must be all > 0"
|
|
@@ -166,9 +166,9 @@ class TetMesh(BaseStructuredSupport):
|
|
|
166
166
|
shared_face_index[:] = -1
|
|
167
167
|
shared_face_index[row.reshape(-1, 3)[:, 0], :] = col.reshape(-1, 3)
|
|
168
168
|
|
|
169
|
-
self.shared_elements[
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
self.shared_elements[np.arange(self.shared_element_relationships.shape[0]), :] = (
|
|
170
|
+
shared_face_index
|
|
171
|
+
)
|
|
172
172
|
# resize
|
|
173
173
|
self.shared_elements = self.shared_elements[: len(self.shared_element_relationships), :]
|
|
174
174
|
|
|
@@ -173,9 +173,9 @@ class UnStructuredTetMesh(BaseSupport):
|
|
|
173
173
|
shared_face_index[:] = -1
|
|
174
174
|
shared_face_index[row.reshape(-1, 3)[:, 0], :] = col.reshape(-1, 3)
|
|
175
175
|
|
|
176
|
-
self.shared_elements[
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
self.shared_elements[np.arange(self.shared_element_relationships.shape[0]), :] = (
|
|
177
|
+
shared_face_index
|
|
178
|
+
)
|
|
179
179
|
# resize
|
|
180
180
|
self.shared_elements = self.shared_elements[: len(self.shared_element_relationships), :]
|
|
181
181
|
# flag = np.zeros(self.elements.shape[0])
|
{loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/interpolators/supports/_face_table.py
RENAMED
|
@@ -63,8 +63,8 @@ def _init_face_table(grid):
|
|
|
63
63
|
shared_face_index = np.zeros((shared_faces.shape[0], grid.dimension), dtype=int)
|
|
64
64
|
shared_face_index[:] = -1
|
|
65
65
|
shared_face_index[row.reshape(-1, grid.dimension)[:, 0], :] = col.reshape(-1, grid.dimension)
|
|
66
|
-
grid._shared_elements[
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
grid._shared_elements[np.arange(grid.shared_element_relationships.shape[0]), :] = (
|
|
67
|
+
shared_face_index
|
|
68
|
+
)
|
|
69
69
|
# resize
|
|
70
70
|
grid._shared_elements = grid.shared_elements[: len(grid.shared_element_relationships), :]
|
{loopstructural-1.6.11 → loopstructural-1.6.13}/LoopStructural/modelling/core/geological_model.py
RENAMED
|
@@ -598,12 +598,10 @@ class GeologicalModel:
|
|
|
598
598
|
* self._data.loc[mask, "polarity"].to_numpy()[:, None]
|
|
599
599
|
)
|
|
600
600
|
self._data.drop(["strike", "dip"], axis=1, inplace=True)
|
|
601
|
-
self._data[
|
|
602
|
-
[
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
].astype(
|
|
606
|
-
float
|
|
601
|
+
self._data[['X', 'Y', 'Z', 'val', 'nx', 'ny', 'nz', 'gx', 'gy', 'gz', 'tx', 'ty', 'tz']] = (
|
|
602
|
+
self._data[
|
|
603
|
+
['X', 'Y', 'Z', 'val', 'nx', 'ny', 'nz', 'gx', 'gy', 'gz', 'tx', 'ty', 'tz']
|
|
604
|
+
].astype(float)
|
|
607
605
|
)
|
|
608
606
|
|
|
609
607
|
def set_model_data(self, data):
|
|
@@ -1805,7 +1803,9 @@ class GeologicalModel:
|
|
|
1805
1803
|
values.to_list(),
|
|
1806
1804
|
self.bounding_box,
|
|
1807
1805
|
name=names.loc[values.index].to_list(),
|
|
1808
|
-
colours=unit_table.loc[unit_table['feature_name'] == u, 'colour'].tolist()[
|
|
1806
|
+
colours=unit_table.loc[unit_table['feature_name'] == u, 'colour'].tolist()[
|
|
1807
|
+
1:
|
|
1808
|
+
], # we don't isosurface basement, no value
|
|
1809
1809
|
)
|
|
1810
1810
|
)
|
|
1811
1811
|
|
|
@@ -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
|
+
)
|