LoopStructural 1.0.1__zip
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.
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/__init__.py +33 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__init__.py +12 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/_base.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/_base.py +65 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/claudius.csv +21049 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/claudiusbb.txt +2 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/duplex.csv +126 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/duplexbb.txt +2 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/intrusion.csv +1017 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/intrusionbb.txt +2 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/onefoldbb.txt +2 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/onefolddata.csv +2226 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/refolded_bb.txt +2 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/refolded_fold.csv +2126 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__init__.py +31 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_fold_interpolator.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_interpolator.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/finite_difference_interpolator.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/geological_interpolator.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/operator.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/piecewiselinear_interpolator.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_grid.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_tetra.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/surfe_wrapper.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__init__.py +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.c +27805 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.cp37-win_amd64.pyd +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_fold_interpolator.py +168 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_interpolator.py +551 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/finite_difference_interpolator.py +339 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/geological_interpolator.py +178 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/operator.py +46 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py +300 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_grid.py +460 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_tetra.py +637 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/surfe_wrapper.py +119 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__init__.py +46 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__init__.py +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model.py +1179 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__init__.py +3 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function_feature.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_segment.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function.py +187 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function_feature.py +75 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_segment.py +270 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__init__.py +7 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/cross_product_geological_feature.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature_builder.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/region_feature.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame_builder.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/unconformity_feature.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/cross_product_geological_feature.py +77 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature.py +276 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature_builder.py +289 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/region_feature.py +31 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame.py +116 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame_builder.py +179 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/unconformity_feature.py +69 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__init__.py +8 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle_feature.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/foldframe.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/svariogram.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold.py +135 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle.py +132 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle_feature.py +57 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/foldframe.py +191 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/svariogram.py +179 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__init__.py +14 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/exceptions.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/helper.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/map2loop.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/utils.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/exceptions.py +9 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/helper.py +373 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/map2loop.py +229 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/utils.py +76 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__init__.py +19 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/map_viewer.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_plotter.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_visualisation.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/rotation_angle_plotter.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/sphinx_scraper.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/map_viewer.py +122 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_plotter.py +16 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_visualisation.py +704 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/rotation_angle_plotter.py +66 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/sphinx_scraper.py +34 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/PKG-INFO +10 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/SOURCES.txt +60 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/dependency_links.txt +1 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/requires.txt +3 -0
- Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/top_level.txt +2 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__init__.py +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/__init__.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_faults.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_fold.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_interpolator.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_refolded.cpython-37.pyc +0 -0
- Miniconda/envs/loop/Lib/site-packages/tests/test_faults.py +17 -0
- Miniconda/envs/loop/Lib/site-packages/tests/test_fold.py +57 -0
- Miniconda/envs/loop/Lib/site-packages/tests/test_interpolator.py +88 -0
- Miniconda/envs/loop/Lib/site-packages/tests/test_refolded.py +22 -0
Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/finite_difference_interpolator.py
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from LoopStructural.utils.helper import get_vectors
|
|
6
|
+
from .discrete_interpolator import DiscreteInterpolator
|
|
7
|
+
from .operator import Operator
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class FiniteDifferenceInterpolator(DiscreteInterpolator):
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, grid):
|
|
18
|
+
"""
|
|
19
|
+
Finite difference interpolation on a regular cartesian grid
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
grid : StructuredGrid
|
|
24
|
+
"""
|
|
25
|
+
self.shape = 'rectangular'
|
|
26
|
+
DiscreteInterpolator.__init__(self, grid)
|
|
27
|
+
# default weights for the interpolation matrix are 1 in x,y,z and
|
|
28
|
+
# 1/
|
|
29
|
+
self.set_interpolation_weights({'dxy': .7,
|
|
30
|
+
'dyz': .7,
|
|
31
|
+
'dxz': .7,
|
|
32
|
+
'dxx': 1.,
|
|
33
|
+
'dyy': 1.,
|
|
34
|
+
'dzz': 1.,
|
|
35
|
+
'dx': 1.,
|
|
36
|
+
'dy': 1.,
|
|
37
|
+
'dz': 1.,
|
|
38
|
+
'cpw': 1.,
|
|
39
|
+
'gpw': 1.,
|
|
40
|
+
'npw': 1.,
|
|
41
|
+
'tpw': 1.})
|
|
42
|
+
|
|
43
|
+
self.vol = grid.step_vector[0] * grid.step_vector[1] * \
|
|
44
|
+
grid.step_vector[2]
|
|
45
|
+
|
|
46
|
+
def _setup_interpolator(self, **kwargs):
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
kwargs
|
|
52
|
+
possible kwargs are weights for the different masks and masks.
|
|
53
|
+
|
|
54
|
+
Notes
|
|
55
|
+
-----
|
|
56
|
+
Default masks are the second derivative in x,y,z direction and the second derivative of x wrt
|
|
57
|
+
y and y wrt z and z wrt x. Custom masks can be used by specifying the operator as a 3d numpy array
|
|
58
|
+
e.g. [ [ [ 0 0 0 ]
|
|
59
|
+
[ 0 1 0 ]
|
|
60
|
+
[ 0 0 0 ] ]
|
|
61
|
+
[ [ 1 1 1 ]
|
|
62
|
+
[ 1 1 1 ]
|
|
63
|
+
[ 1 1 1 ] ]
|
|
64
|
+
[ [ 0 0 0 ]
|
|
65
|
+
[ 0 1 0 ]
|
|
66
|
+
[ 0 0 0 ] ]
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
for key in kwargs:
|
|
74
|
+
self.up_to_date = False
|
|
75
|
+
if 'regularisation' in kwargs:
|
|
76
|
+
self.interpolation_weights['dxy'] = kwargs[
|
|
77
|
+
'regularisation'] * 0.7
|
|
78
|
+
self.interpolation_weights['dyz'] = kwargs[
|
|
79
|
+
'regularisation'] * 0.7
|
|
80
|
+
self.interpolation_weights['dxz'] = kwargs[
|
|
81
|
+
'regularisation'] * 0.7
|
|
82
|
+
self.interpolation_weights['dxx'] = kwargs[
|
|
83
|
+
'regularisation'] * 1.
|
|
84
|
+
self.interpolation_weights['dyy'] = kwargs[
|
|
85
|
+
'regularisation'] * 1.
|
|
86
|
+
self.interpolation_weights['dzz'] = kwargs[
|
|
87
|
+
'regularisation'] * 1.
|
|
88
|
+
self.interpolation_weights[key] = kwargs[key]
|
|
89
|
+
# if we want to define the operators manually
|
|
90
|
+
if 'operators' in kwargs:
|
|
91
|
+
for n, o in kwargs['operators'].items():
|
|
92
|
+
self.assemble_inner(o[0], o[1])
|
|
93
|
+
# otherwise just use defaults
|
|
94
|
+
if 'operators' not in kwargs:
|
|
95
|
+
operator = Operator.Dxy_mask
|
|
96
|
+
|
|
97
|
+
self.assemble_inner(operator, np.sqrt(2 * self.vol) *
|
|
98
|
+
self.interpolation_weights['dxy'])
|
|
99
|
+
operator = Operator.Dyz_mask
|
|
100
|
+
self.assemble_inner(operator, np.sqrt(2 * self.vol) *
|
|
101
|
+
self.interpolation_weights['dyz'])
|
|
102
|
+
operator = Operator.Dxz_mask
|
|
103
|
+
self.assemble_inner(operator, np.sqrt(2 * self.vol) *
|
|
104
|
+
self.interpolation_weights['dxz'])
|
|
105
|
+
operator = Operator.Dxx_mask
|
|
106
|
+
self.assemble_inner(operator,
|
|
107
|
+
np.sqrt(self.vol) * self.interpolation_weights[
|
|
108
|
+
'dxx'])
|
|
109
|
+
operator = Operator.Dyy_mask
|
|
110
|
+
self.assemble_inner(operator,
|
|
111
|
+
np.sqrt(self.vol) * self.interpolation_weights[
|
|
112
|
+
'dyy'])
|
|
113
|
+
operator = Operator.Dzz_mask
|
|
114
|
+
self.assemble_inner(operator,
|
|
115
|
+
np.sqrt(self.vol) * self.interpolation_weights[
|
|
116
|
+
'dzz'])
|
|
117
|
+
self.add_norm_constraint(
|
|
118
|
+
np.sqrt(self.vol) * self.interpolation_weights['npw'])
|
|
119
|
+
self.add_gradient_constraint(
|
|
120
|
+
np.sqrt(self.vol) * self.interpolation_weights['gpw'])
|
|
121
|
+
self.add_vaue_constraint(
|
|
122
|
+
np.sqrt(self.vol) * self.interpolation_weights['cpw'])
|
|
123
|
+
self.add_tangent_ctr_pts(
|
|
124
|
+
np.sqrt(self.vol) * self.interpolation_weights['tpw']
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def copy(self):
|
|
128
|
+
"""
|
|
129
|
+
Create a new identical interpolator
|
|
130
|
+
|
|
131
|
+
Returns
|
|
132
|
+
-------
|
|
133
|
+
returns a new empy interpolator from the same support
|
|
134
|
+
"""
|
|
135
|
+
return FiniteDifferenceInterpolator(self.support)
|
|
136
|
+
|
|
137
|
+
def add_vaue_constraint(self, w=1.):
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
Parameters
|
|
141
|
+
----------
|
|
142
|
+
w : double or numpy array
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
points = self.get_value_constraints()
|
|
150
|
+
# check that we have added some points
|
|
151
|
+
if points.shape[0] > 0:
|
|
152
|
+
node_idx, inside = self.support.position_to_cell_corners(
|
|
153
|
+
points[:, :3])
|
|
154
|
+
# print(points[inside,:].shape)
|
|
155
|
+
|
|
156
|
+
gi = np.zeros(self.support.n_nodes)
|
|
157
|
+
gi[:] = -1
|
|
158
|
+
gi[self.region] = np.arange(0, self.nx)
|
|
159
|
+
idc = np.zeros(node_idx.shape)
|
|
160
|
+
idc[:] = -1
|
|
161
|
+
|
|
162
|
+
idc[inside, :] = gi[node_idx[inside, :]]
|
|
163
|
+
inside = np.logical_and(~np.any(idc == -1, axis=1), inside)
|
|
164
|
+
a = self.support.position_to_dof_coefs(points[inside, :3])
|
|
165
|
+
# a*=w
|
|
166
|
+
|
|
167
|
+
self.add_constraints_to_least_squares(a.T * w,
|
|
168
|
+
points[inside, 3] * w,
|
|
169
|
+
idc[inside, :])
|
|
170
|
+
|
|
171
|
+
def add_gradient_constraint(self, w=1.):
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
Parameters
|
|
175
|
+
----------
|
|
176
|
+
w : double / numpy array
|
|
177
|
+
|
|
178
|
+
Returns
|
|
179
|
+
-------
|
|
180
|
+
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
points = self.get_gradient_constraints()
|
|
184
|
+
if points.shape[0] > 0:
|
|
185
|
+
# calculate unit vector for orientation data
|
|
186
|
+
# points[:,3:]/=np.linalg.norm(points[:,3:],axis=1)[:,None]
|
|
187
|
+
|
|
188
|
+
node_idx, inside = self.support.position_to_cell_corners(
|
|
189
|
+
points[:, :3])
|
|
190
|
+
# calculate unit vector for node gradients
|
|
191
|
+
# this means we are only constraining direction of grad not the
|
|
192
|
+
# magnitude
|
|
193
|
+
gi = np.zeros(self.support.n_nodes)
|
|
194
|
+
gi[:] = -1
|
|
195
|
+
gi[self.region] = np.arange(0, self.nx)
|
|
196
|
+
idc = np.zeros(node_idx.shape)
|
|
197
|
+
idc[:] = -1
|
|
198
|
+
idc[inside, :] = gi[node_idx[inside, :]]
|
|
199
|
+
inside = np.logical_and(~np.any(idc == -1, axis=1), inside)
|
|
200
|
+
|
|
201
|
+
T = self.support.calcul_T(points[inside, :3])
|
|
202
|
+
strike_vector, dip_vector = get_vectors(points[inside, 3:6])
|
|
203
|
+
A = np.einsum('ij,ijk->ik', strike_vector.T, T)
|
|
204
|
+
|
|
205
|
+
B = np.zeros(points[inside, :].shape[0])
|
|
206
|
+
# self.add_constraints_to_least_squares(A * w, B, idc[inside, :])
|
|
207
|
+
A += np.einsum('ij,ijk->ik', dip_vector.T, T)
|
|
208
|
+
self.add_constraints_to_least_squares(A * w, B, idc[inside, :])
|
|
209
|
+
|
|
210
|
+
def add_norm_constraint(self, w=1.):
|
|
211
|
+
"""
|
|
212
|
+
Add constraints to control the norm of the gradient of the scalar field
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
w : double
|
|
217
|
+
weighting of this constraint (double)
|
|
218
|
+
|
|
219
|
+
Returns
|
|
220
|
+
-------
|
|
221
|
+
|
|
222
|
+
"""
|
|
223
|
+
points = self.get_norm_constraints()
|
|
224
|
+
if points.shape[0] > 0:
|
|
225
|
+
# calculate unit vector for orientation data
|
|
226
|
+
# points[:,3:]/=np.linalg.norm(points[:,3:],axis=1)[:,None]
|
|
227
|
+
|
|
228
|
+
node_idx, inside = self.support.position_to_cell_corners(
|
|
229
|
+
points[:, :3])
|
|
230
|
+
gi = np.zeros(self.support.n_nodes)
|
|
231
|
+
gi[:] = -1
|
|
232
|
+
gi[self.region] = np.arange(0, self.nx)
|
|
233
|
+
idc = np.zeros(node_idx.shape)
|
|
234
|
+
idc[:] = -1
|
|
235
|
+
idc[inside, :] = gi[node_idx[inside, :]]
|
|
236
|
+
inside = np.logical_and(~np.any(idc == -1, axis=1), inside)
|
|
237
|
+
|
|
238
|
+
# calculate unit vector for node gradients
|
|
239
|
+
# this means we are only constraining direction of grad not the
|
|
240
|
+
# magnitude
|
|
241
|
+
T = self.support.calcul_T(points[inside, :3])
|
|
242
|
+
|
|
243
|
+
w /= 3
|
|
244
|
+
self.add_constraints_to_least_squares(T[:, 0, :] * w,
|
|
245
|
+
points[inside, 3] * w,
|
|
246
|
+
idc[inside, :])
|
|
247
|
+
self.add_constraints_to_least_squares(T[:, 1, :] * w,
|
|
248
|
+
points[inside, 4] * w,
|
|
249
|
+
idc[inside, :])
|
|
250
|
+
self.add_constraints_to_least_squares(T[:, 2, :] * w,
|
|
251
|
+
points[inside, 5] * w,
|
|
252
|
+
idc[inside, :])
|
|
253
|
+
|
|
254
|
+
def add_gradient_orthogonal_constraint(self, points, vector, w=1.0,
|
|
255
|
+
B=0):
|
|
256
|
+
"""
|
|
257
|
+
constraints scalar field to be orthogonal to a given vector
|
|
258
|
+
|
|
259
|
+
Parameters
|
|
260
|
+
----------
|
|
261
|
+
elements : np.array
|
|
262
|
+
normals : np.array
|
|
263
|
+
w : double
|
|
264
|
+
B : np.array
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
|
|
269
|
+
"""
|
|
270
|
+
if points.shape[0] > 0:
|
|
271
|
+
# calculate unit vector for orientation data
|
|
272
|
+
# points[:,3:]/=np.linalg.norm(points[:,3:],axis=1)[:,None]
|
|
273
|
+
|
|
274
|
+
node_idx, inside = self.support.position_to_cell_corners(
|
|
275
|
+
points[:, :3])
|
|
276
|
+
# calculate unit vector for node gradients
|
|
277
|
+
# this means we are only constraining direction of grad not the
|
|
278
|
+
# magnitude
|
|
279
|
+
gi = np.zeros(self.support.n_nodes)
|
|
280
|
+
gi[:] = -1
|
|
281
|
+
gi[self.region] = np.arange(0, self.nx)
|
|
282
|
+
idc = np.zeros(node_idx.shape)
|
|
283
|
+
idc[:] = -1
|
|
284
|
+
|
|
285
|
+
idc[inside, :] = gi[node_idx[inside, :]]
|
|
286
|
+
inside = np.logical_and(~np.any(idc == -1, axis=1), inside)
|
|
287
|
+
|
|
288
|
+
T = self.support.calcul_T(points[inside, :3])
|
|
289
|
+
A = np.einsum('ij,ijk->ik', vector[inside, :3], T)
|
|
290
|
+
|
|
291
|
+
B = np.zeros(points[inside, :].shape[0])
|
|
292
|
+
self.add_constraints_to_least_squares(A * w, B, idc[inside, :])
|
|
293
|
+
|
|
294
|
+
def add_regularisation(self, operator, w=0.1):
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
Parameters
|
|
298
|
+
----------
|
|
299
|
+
operator
|
|
300
|
+
w
|
|
301
|
+
|
|
302
|
+
Returns
|
|
303
|
+
-------
|
|
304
|
+
|
|
305
|
+
"""
|
|
306
|
+
self.assemble_inner(operator)
|
|
307
|
+
# self.assemble_borders()
|
|
308
|
+
|
|
309
|
+
def assemble_inner(self, operator, w):
|
|
310
|
+
"""
|
|
311
|
+
|
|
312
|
+
Parameters
|
|
313
|
+
----------
|
|
314
|
+
operator : Operator
|
|
315
|
+
w : double
|
|
316
|
+
|
|
317
|
+
Returns
|
|
318
|
+
-------
|
|
319
|
+
|
|
320
|
+
"""
|
|
321
|
+
# First get the global indicies of the pairs of neighbours this should be an
|
|
322
|
+
# Nx27 array for 3d and an Nx9 array for 2d
|
|
323
|
+
|
|
324
|
+
global_indexes = self.support.neighbour_global_indexes() # np.array([ii,jj]))
|
|
325
|
+
|
|
326
|
+
a = np.tile(operator.flatten(), (global_indexes.shape[1], 1))
|
|
327
|
+
idc = global_indexes.T
|
|
328
|
+
|
|
329
|
+
gi = np.zeros(self.support.n_nodes)
|
|
330
|
+
gi[:] = -1
|
|
331
|
+
gi[self.region] = np.arange(0, self.nx)
|
|
332
|
+
idc = gi[idc]
|
|
333
|
+
inside = ~np.any(idc == -1, axis=1)
|
|
334
|
+
B = np.zeros(global_indexes.shape[1])
|
|
335
|
+
self.add_constraints_to_least_squares(a[inside, :] * w,
|
|
336
|
+
B[inside],
|
|
337
|
+
idc[inside, :]
|
|
338
|
+
)
|
|
339
|
+
return
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GeologicalInterpolator:
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
def __init__(self):
|
|
13
|
+
"""
|
|
14
|
+
This class is the base class for a geological interpolator and contains all of the
|
|
15
|
+
main interface functions. Any class that is inheriting from this should be callable
|
|
16
|
+
by using any of these functions. This will enable interpolators to be interchanged.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
self.data = {'gradient': np.zeros((0,7)),
|
|
20
|
+
'value' : np.zeros((0,5)),
|
|
21
|
+
'normal': np.zeros((0,7)),
|
|
22
|
+
'tangent': np.zeros((0,7))
|
|
23
|
+
}
|
|
24
|
+
self.n_g = 0
|
|
25
|
+
self.n_i = 0
|
|
26
|
+
self.n_n = 0
|
|
27
|
+
self.n_t = 0
|
|
28
|
+
|
|
29
|
+
self.type = 'undefined'
|
|
30
|
+
self.up_to_date = False
|
|
31
|
+
self.constraints = []
|
|
32
|
+
self.propertyname = 'defaultproperty'
|
|
33
|
+
self.__str = 'Base Geological Interpolator'
|
|
34
|
+
|
|
35
|
+
def __str__(self):
|
|
36
|
+
|
|
37
|
+
return self.__str
|
|
38
|
+
|
|
39
|
+
def set_region(self,**kwargs):
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
def set_property_name(self, name):
|
|
43
|
+
"""
|
|
44
|
+
Set the name of the interpolated property
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
name : string
|
|
48
|
+
name of the property to be saved on a mesh
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
self.propertyname = name
|
|
55
|
+
|
|
56
|
+
def set_value_constraints(self, points):
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
points
|
|
62
|
+
|
|
63
|
+
Returns
|
|
64
|
+
-------
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
self.data['value'] = points
|
|
69
|
+
self.n_i = points.shape[0]
|
|
70
|
+
|
|
71
|
+
def set_gradient_constraints(self, points):
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
points
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
self.n_g = points.shape[0]
|
|
83
|
+
self.data['gradient'] = points
|
|
84
|
+
|
|
85
|
+
def set_normal_constraints(self, points):
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
points
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
|
|
95
|
+
"""
|
|
96
|
+
self.n_n = points.shape[0]
|
|
97
|
+
self.data['normal'] = points
|
|
98
|
+
|
|
99
|
+
def set_tangent_constraints(self, points):
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
points
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
|
|
109
|
+
"""
|
|
110
|
+
self.data['tangent'] = points
|
|
111
|
+
|
|
112
|
+
def get_value_constraints(self):
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
numpy array
|
|
118
|
+
"""
|
|
119
|
+
return self.data['value']
|
|
120
|
+
|
|
121
|
+
def get_gradient_constraints(self):
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
numpy array
|
|
127
|
+
"""
|
|
128
|
+
return self.data['gradient']
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def get_tangent_constraints(self):
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
numpy array
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
return self.data['tangent']
|
|
140
|
+
|
|
141
|
+
def get_norm_constraints(self):
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
numpy array
|
|
147
|
+
"""
|
|
148
|
+
return self.data['normal']
|
|
149
|
+
|
|
150
|
+
def setup_interpolator(self, **kwargs):
|
|
151
|
+
"""
|
|
152
|
+
Runs all of the required setting up stuff
|
|
153
|
+
"""
|
|
154
|
+
self._setup_interpolator(**kwargs)
|
|
155
|
+
|
|
156
|
+
def solve_system(self, **kwargs):
|
|
157
|
+
"""
|
|
158
|
+
Solves the interpolation equations
|
|
159
|
+
"""
|
|
160
|
+
self._solve(**kwargs)
|
|
161
|
+
self.up_to_date = True
|
|
162
|
+
|
|
163
|
+
def update(self):
|
|
164
|
+
return False
|
|
165
|
+
|
|
166
|
+
def reset(self):
|
|
167
|
+
"""
|
|
168
|
+
Removes all of the data from an interpolator
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
|
|
173
|
+
"""
|
|
174
|
+
self.n_g = 0
|
|
175
|
+
self.n_i = 0
|
|
176
|
+
self.n_n = 0
|
|
177
|
+
self.n_t = 0
|
|
178
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Operator(object):
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
z = np.zeros((3, 3))
|
|
13
|
+
Dx_mask = np.array([z, [
|
|
14
|
+
[0.0, 0.0, 0.0],
|
|
15
|
+
[-0.5, 0.0, 0.5],
|
|
16
|
+
[0.0, 0.0, 0.0]], z
|
|
17
|
+
])
|
|
18
|
+
Dy_mask = Dx_mask.swapaxes(1, 2)
|
|
19
|
+
Dz_mask = Dx_mask.swapaxes(0, 2)
|
|
20
|
+
|
|
21
|
+
Dxx_mask = np.array([z, [
|
|
22
|
+
[0, 0, 0],
|
|
23
|
+
[1, -2, 1],
|
|
24
|
+
[0, 0, 0]], z])
|
|
25
|
+
Dyy_mask = Dxx_mask.swapaxes(1, 2)
|
|
26
|
+
Dzz_mask = Dxx_mask.swapaxes(0, 2)
|
|
27
|
+
|
|
28
|
+
Dxy_mask = np.array([z, [
|
|
29
|
+
[-0.25, 0, 0.25],
|
|
30
|
+
[0, 0, 0],
|
|
31
|
+
[0.25, 0, -0.25]
|
|
32
|
+
], z])
|
|
33
|
+
Dxz_mask = Dxy_mask.swapaxes(0, 1)
|
|
34
|
+
Dyz_mask = Dxy_mask.swapaxes(0, 2)
|
|
35
|
+
|
|
36
|
+
# from https://en.wikipedia.org/wiki/Discrete_Laplace_operator
|
|
37
|
+
Lapacian = np.array([[[0, 0, 0],
|
|
38
|
+
[0, 1, 0], # first plane
|
|
39
|
+
[0, 0, 0]]
|
|
40
|
+
, [[0, 1, 0],
|
|
41
|
+
[1, -6, 1], # second plane
|
|
42
|
+
[0, 1, 0]],
|
|
43
|
+
[[0, 0, 0],
|
|
44
|
+
[0, 1, 0], # third plane
|
|
45
|
+
[0, 0, 0]]]
|
|
46
|
+
)
|