LoopStructural 1.0.3__zip → 1.0.71.dev0__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.
Files changed (119) hide show
  1. Miniconda/envs/loop/Lib/site-packages/LoopStructural/__init__.py +12 -7
  2. Miniconda/envs/loop/Lib/site-packages/LoopStructural/__pycache__/__init__.cpython-36.pyc +0 -0
  3. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/__init__.cpython-36.pyc +0 -0
  4. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/_base.cpython-36.pyc +0 -0
  5. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__init__.py +3 -0
  6. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/__init__.cpython-36.pyc +0 -0
  7. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/base_structured_3d_support.cpython-36.pyc +0 -0
  8. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_fold_interpolator.cpython-36.pyc +0 -0
  9. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_interpolator.cpython-36.pyc +0 -0
  10. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/finite_difference_interpolator.cpython-36.pyc +0 -0
  11. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/geological_interpolator.cpython-36.pyc +0 -0
  12. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/operator.cpython-36.pyc +0 -0
  13. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/piecewiselinear_interpolator.cpython-36.pyc +0 -0
  14. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_grid.cpython-36.pyc +0 -0
  15. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_tetra.cpython-36.pyc +0 -0
  16. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/surfe_wrapper.cpython-36.pyc +0 -0
  17. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/base_structured_3d_support.py +101 -0
  18. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__pycache__/__init__.cpython-36.pyc +0 -0
  19. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.c +4137 -2716
  20. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.cp36-win_amd64.pyd +0 -0
  21. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_fold_interpolator.py +56 -22
  22. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_interpolator.py +61 -28
  23. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/finite_difference_interpolator.py +71 -11
  24. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/geological_interpolator.py +22 -3
  25. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/operator.py +16 -1
  26. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py +150 -11
  27. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_grid.py +31 -69
  28. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_tetra.py +89 -45
  29. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/surfe_wrapper.py +7 -8
  30. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__pycache__/__init__.cpython-36.pyc +0 -0
  31. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/__init__.cpython-36.pyc +0 -0
  32. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model.cpython-36.pyc +0 -0
  33. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model_graph.cpython-36.pyc +0 -0
  34. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/stratigraphic_column.cpython-36.pyc +0 -0
  35. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model.py +515 -197
  36. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model_graph.py +881 -0
  37. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/stratigraphic_column.py +5 -0
  38. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__init__.py +1 -0
  39. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/__init__.cpython-36.pyc +0 -0
  40. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_builder.cpython-36.pyc +0 -0
  41. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function.cpython-36.pyc +0 -0
  42. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function_feature.cpython-36.pyc +0 -0
  43. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_segment.cpython-36.pyc +0 -0
  44. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_builder.py +127 -0
  45. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function.py +2 -1
  46. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function_feature.py +2 -1
  47. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_segment.py +30 -3
  48. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__init__.py +1 -0
  49. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/__init__.cpython-36.pyc +0 -0
  50. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/cross_product_geological_feature.cpython-36.pyc +0 -0
  51. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature.cpython-36.pyc +0 -0
  52. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature_builder.cpython-36.pyc +0 -0
  53. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/lambda_geological_feature.cpython-36.pyc +0 -0
  54. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/region_feature.cpython-36.pyc +0 -0
  55. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame.cpython-36.pyc +0 -0
  56. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame_builder.cpython-36.pyc +0 -0
  57. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/unconformity_feature.cpython-36.pyc +0 -0
  58. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/cross_product_geological_feature.py +18 -5
  59. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature.py +22 -49
  60. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature_builder.py +171 -47
  61. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/lambda_geological_feature.py +31 -0
  62. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/region_feature.py +3 -0
  63. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame.py +28 -11
  64. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame_builder.py +32 -22
  65. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/unconformity_feature.py +6 -1
  66. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/__init__.cpython-36.pyc +0 -0
  67. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold.cpython-36.pyc +0 -0
  68. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle.cpython-36.pyc +0 -0
  69. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle_feature.cpython-36.pyc +0 -0
  70. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/foldframe.cpython-36.pyc +0 -0
  71. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/svariogram.cpython-36.pyc +0 -0
  72. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold.py +13 -5
  73. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle.py +5 -4
  74. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle_feature.py +2 -1
  75. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/foldframe.py +7 -5
  76. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/svariogram.py +2 -1
  77. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__init__.py +5 -1
  78. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/__init__.cpython-36.pyc +0 -0
  79. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/bounding_box.cpython-36.pyc +0 -0
  80. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/exceptions.cpython-36.pyc +0 -0
  81. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/helper.cpython-36.pyc +0 -0
  82. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/logging.cpython-36.pyc +0 -0
  83. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/map2loop.cpython-36.pyc +0 -0
  84. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/regions.cpython-36.pyc +0 -0
  85. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/utils.cpython-36.pyc +0 -0
  86. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/bounding_box.py +21 -0
  87. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/exceptions.py +2 -1
  88. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/helper.py +10 -2
  89. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/logging.py +60 -0
  90. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/map2loop.py +128 -37
  91. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/regions.py +11 -0
  92. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/utils.py +40 -47
  93. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/__init__.cpython-36.pyc +0 -0
  94. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/map_viewer.cpython-36.pyc +0 -0
  95. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_plotter.cpython-36.pyc +0 -0
  96. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_visualisation.cpython-36.pyc +0 -0
  97. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/rotation_angle_plotter.cpython-36.pyc +0 -0
  98. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/sphinx_scraper.cpython-36.pyc +0 -0
  99. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/stratigraphic_column.cpython-36.pyc +0 -0
  100. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/map_viewer.py +236 -36
  101. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_plotter.py +2 -1
  102. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_visualisation.py +427 -79
  103. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/rotation_angle_plotter.py +29 -12
  104. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/stratigraphic_column.py +60 -0
  105. Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/PKG-INFO +1 -1
  106. Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/SOURCES.txt +10 -5
  107. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.71.dev0-py3.6.egg-info/requires.txt +8 -0
  108. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/__init__.cpython-36.pyc +0 -0
  109. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.3-py3.6.egg-info/requires.txt +0 -3
  110. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_faults.cpython-36.pyc +0 -0
  111. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_fold.cpython-36.pyc +0 -0
  112. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_interpolator.cpython-36.pyc +0 -0
  113. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_refolded.cpython-36.pyc +0 -0
  114. Miniconda/envs/loop/Lib/site-packages/tests/test_faults.py +0 -17
  115. Miniconda/envs/loop/Lib/site-packages/tests/test_fold.py +0 -57
  116. Miniconda/envs/loop/Lib/site-packages/tests/test_interpolator.py +0 -88
  117. Miniconda/envs/loop/Lib/site-packages/tests/test_refolded.py +0 -22
  118. /Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/dependency_links.txt +0 -0
  119. /Miniconda/envs/loop/Lib/site-packages/{LoopStructural-1.0.3-py3.6.egg-info → LoopStructural-1.0.71.dev0-py3.6.egg-info}/top_level.txt +0 -0
@@ -1,3 +1,6 @@
1
+ """
2
+ Piecewise linear interpolator using folds
3
+ """
1
4
  import logging
2
5
 
3
6
  import numpy as np
@@ -6,7 +9,8 @@ from LoopStructural.interpolators.cython.dsi_helper import fold_cg
6
9
  from LoopStructural.interpolators.piecewiselinear_interpolator import \
7
10
  PiecewiseLinearInterpolator
8
11
 
9
- logger = logging.getLogger(__name__)
12
+ from LoopStructural.utils import getLogger
13
+ logger = getLogger(__name__)
10
14
 
11
15
 
12
16
  class DiscreteFoldInterpolator(PiecewiseLinearInterpolator):
@@ -79,9 +83,9 @@ class DiscreteFoldInterpolator(PiecewiseLinearInterpolator):
79
83
  logger.error('updating fold, this should be done by accessing the fold attribute')
80
84
  self.fold = fold
81
85
 
82
- def add_fold_constraints(self, fold_orientation=10., fold_axis_w=10., fold_regularisation=.1,
86
+ def add_fold_constraints(self, fold_orientation=10., fold_axis_w=10., fold_regularisation=[.1,0.01,0.01],
83
87
  fold_normalisation=1.,
84
- fold_norm=1.):
88
+ fold_norm=1., step=2):
85
89
  """
86
90
 
87
91
  Parameters
@@ -90,12 +94,15 @@ class DiscreteFoldInterpolator(PiecewiseLinearInterpolator):
90
94
  weight for the fold direction/orientation in the least squares system
91
95
  fold_axis_w : double
92
96
  weight for the fold axis in the least squares system
93
- fold_regularisation : double
97
+ fold_regularisation : list
94
98
  weight for the fold regularisation in the least squares system
95
99
  fold_normalisation : double
96
100
  weight for the fold norm constraint in the least squares system
97
101
  fold_norm
98
102
  length of the interpolation norm in the least squares system
103
+ step: int
104
+ array step for adding constraints
105
+
99
106
 
100
107
  Returns
101
108
  -------
@@ -112,7 +119,8 @@ class DiscreteFoldInterpolator(PiecewiseLinearInterpolator):
112
119
  # calculate the fold geometry for the elements barycentre
113
120
  deformed_orientation, fold_axis, dgz = \
114
121
  self.fold.get_deformed_orientation(self.support.barycentre())
115
-
122
+ element_idx = np.arange(self.support.n_elements)
123
+ np.random.shuffle(element_idx)
116
124
  # calculate element volume for weighting
117
125
  vecs = nodes[:, 1:, :] - nodes[:, 0, None, :]
118
126
  vol = np.abs(np.linalg.det(vecs)) / 6
@@ -120,49 +128,75 @@ class DiscreteFoldInterpolator(PiecewiseLinearInterpolator):
120
128
  """
121
129
  dot product between vector in deformed ori plane = 0
122
130
  """
131
+ np.random.shuffle(element_idx)
132
+
123
133
  logger.info("Adding fold orientation constraint to %s w = %f"%(self.propertyname, fold_orientation))
124
- A = np.einsum('ij,ijk->ik', deformed_orientation, eg)
125
- A *= vol[:, None]
134
+ A = np.einsum('ij,ijk->ik', deformed_orientation[element_idx[::step],:], eg[element_idx[::step],:,:])
135
+ A *= vol[element_idx[::step], None]
126
136
  A *= fold_orientation
127
- B = np.zeros(self.support.n_elements)
128
- idc = self.support.get_elements()
129
- self.add_constraints_to_least_squares(A, B, idc)
137
+ B = np.zeros(A.shape[0])
138
+ idc = self.support.get_elements()[element_idx[::step],:]
139
+ self.add_constraints_to_least_squares(A, B, idc, name='fold orientation')
130
140
 
131
141
  if fold_axis_w is not None:
132
142
  """
133
143
  dot product between axis and gradient should be 0
134
144
  """
145
+ np.random.shuffle(element_idx)
146
+
135
147
  logger.info("Adding fold axis constraint to %s w = %f"%(self.propertyname,fold_axis_w))
136
- A = np.einsum('ij,ijk->ik', fold_axis, eg)
137
- A *= vol[:, None]
148
+ A = np.einsum('ij,ijk->ik', fold_axis[element_idx[::step],:], eg[element_idx[::step],:,:])
149
+ A *= vol[element_idx[::step], None]
138
150
  A *= fold_axis_w
139
- B = np.zeros(self.support.n_elements).tolist()
140
- self.add_constraints_to_least_squares(A, B, self.support.get_elements())
151
+ B = np.zeros(A.shape[0]).tolist()
152
+ idc = self.support.get_elements()[element_idx[::step],:]
153
+
154
+ self.add_constraints_to_least_squares(A, B, idc, name='fold axis')
141
155
 
142
156
  if fold_normalisation is not None:
143
157
  """
144
158
  specify scalar norm in X direction
145
159
  """
160
+ np.random.shuffle(element_idx)
161
+
146
162
  logger.info("Adding fold normalisation constraint to %s w = %f"%(self.propertyname,fold_normalisation))
147
- A = np.einsum('ij,ijk->ik', dgz, eg)
148
- A *= vol[:, None]
163
+ A = np.einsum('ij,ijk->ik', dgz[element_idx[::step],:], eg[element_idx[::step],:,:])
164
+ A *= vol[element_idx[::step], None]
149
165
  A *= fold_normalisation
150
- B = np.ones(self.support.n_elements)
166
+ B = np.ones(A.shape[0])
151
167
 
152
168
  if fold_norm is not None:
153
169
  B[:] = fold_norm
154
170
  B *= fold_normalisation
155
- B *= vol
156
- self.add_constraints_to_least_squares(A, B, self.support.get_elements())
171
+ B *= vol[element_idx[::step]]
172
+ idc = self.support.get_elements()[element_idx[::step],:]
173
+
174
+ self.add_constraints_to_least_squares(A, B, idc, name='fold normalisation')
157
175
 
158
176
  if fold_regularisation is not None:
159
177
  """
160
178
  fold constant gradient
161
179
  """
162
- logger.info("Adding fold regularisation constraint to %s w = %f"%(self.propertyname,fold_regularisation))
180
+ logger.info("Adding fold regularisation constraint to {} w = {} {} {}".format(self.propertyname,
181
+ fold_regularisation[0],fold_regularisation[1],fold_regularisation[1]))
182
+
163
183
  idc, c, ncons = fold_cg(eg, dgz, self.support.get_neighbours(), self.support.get_elements(), self.support.nodes)
164
184
  A = np.array(c[:ncons, :])
165
- A *= fold_regularisation
185
+ A *= fold_regularisation[0]
186
+ B = np.zeros(A.shape[0])
187
+ idc = np.array(idc[:ncons, :])
188
+ self.add_constraints_to_least_squares(A, B, idc, name='fold regularisation 1')
189
+
190
+ idc, c, ncons = fold_cg(eg, deformed_orientation, self.support.get_neighbours(), self.support.get_elements(), self.support.nodes)
191
+ A = np.array(c[:ncons, :])
192
+ A *= fold_regularisation[1]
193
+ B = np.zeros(A.shape[0])
194
+ idc = np.array(idc[:ncons, :])
195
+ self.add_constraints_to_least_squares(A, B, idc, name='fold regularisation 2')
196
+
197
+ idc, c, ncons = fold_cg(eg, fold_axis, self.support.get_neighbours(), self.support.get_elements(), self.support.nodes)
198
+ A = np.array(c[:ncons, :])
199
+ A *= fold_regularisation[2]
166
200
  B = np.zeros(A.shape[0])
167
201
  idc = np.array(idc[:ncons, :])
168
- self.add_constraints_to_least_squares(A, B, idc)
202
+ self.add_constraints_to_least_squares(A, B, idc, name='fold regularisation 3')
@@ -10,7 +10,8 @@ from scipy.sparse import linalg as sla
10
10
  from LoopStructural.interpolators.geological_interpolator import \
11
11
  GeologicalInterpolator
12
12
 
13
- logger = logging.getLogger(__name__)
13
+ from LoopStructural.utils import getLogger
14
+ logger = getLogger(__name__)
14
15
 
15
16
 
16
17
  class DiscreteInterpolator(GeologicalInterpolator):
@@ -30,12 +31,9 @@ class DiscreteInterpolator(GeologicalInterpolator):
30
31
  GeologicalInterpolator.__init__(self)
31
32
  self.B = []
32
33
  self.support = support
33
- self.region_function = None
34
- self.region = np.arange(0, support.n_nodes)
35
- self.region_map = np.zeros(support.n_nodes).astype(int)
34
+ self.region_function = lambda xyz : np.ones(xyz.shape[0],dtype=int)
36
35
  # self.region_map[self.region] = np.array(range(0,
37
36
  # len(self.region_map[self.region])))
38
- self.nx = len(self.support.nodes[self.region])
39
37
  self.shape = 'rectangular'
40
38
  if self.shape == 'square':
41
39
  self.B = np.zeros(self.nx)
@@ -51,7 +49,22 @@ class DiscreteInterpolator(GeologicalInterpolator):
51
49
  self.eq_const_c_ = 0
52
50
  self.constraints = {}
53
51
  self.interpolation_weights= {}
54
-
52
+ logger.info("Creating discrete interpolator with {} degrees of freedom".format(self.nx))
53
+
54
+ @property
55
+ def nx(self):
56
+ return len(self.support.nodes[self.region])
57
+
58
+ @property
59
+ def region(self):
60
+ return self.region_function(self.support.nodes)
61
+
62
+ @property
63
+ def region_map(self):
64
+ region_map = np.zeros(self.support.n_nodes).astype(int)
65
+ region_map[self.region] = np.array(
66
+ range(0, len(region_map[self.region])))
67
+ return region_map
55
68
  def set_property_name(self, propertyname):
56
69
  """
57
70
  Set the property name attribute, this is usually used to
@@ -83,12 +96,8 @@ class DiscreteInterpolator(GeologicalInterpolator):
83
96
  # evaluate the region function on the support to determine
84
97
  # which nodes are inside update region map and degrees of freedom
85
98
  self.region_function = region
86
- self.region = region(self.support.nodes)
87
- self.region_map = np.zeros(self.support.n_nodes).astype(int)
88
- self.region_map[self.region] = np.array(
89
- range(0, len(self.region_map[self.region])))
90
- self.nx = len(self.support.nodes[self.region])
91
-
99
+ logger.info("Interpolation now uses region and has {} degrees of freedom".format(self.nx))
100
+
92
101
  def set_interpolation_weights(self, weights):
93
102
  """
94
103
  Set the interpolation weights dictionary
@@ -147,21 +156,36 @@ class DiscreteInterpolator(GeologicalInterpolator):
147
156
  A = np.array(A)
148
157
  B = np.array(B)
149
158
  idc = np.array(idc)
150
- if np.any(np.isnan(idc)) or np.any(np.isnan(A)) or np.any(np.isnan(B)):
151
- logger.warning("Constraints contain nan not adding constraints: {}".format(name))
152
- return
153
159
  nr = A.shape[0]
160
+ #logger.debug('Adding constraints to interpolator: {} {} {}'.format(A.shape[0]))
161
+ # print(A.shape,B.shape,idc.shape)
162
+ if A.shape != idc.shape:
163
+ return
164
+
154
165
  if len(A.shape) > 2:
155
166
  nr = A.shape[0] * A.shape[1]
167
+ A = A.reshape((A.shape[0]*A.shape[1],A.shape[2]))
168
+ idc = idc.reshape((idc.shape[0]*idc.shape[1],idc.shape[2]))
169
+ # going to assume if any are nan they are all nan
170
+ mask = np.any(np.isnan(A),axis=1)
171
+ A[mask,:] = 0
172
+ if np.any(np.isnan(idc)) or np.any(np.isnan(A)) or np.any(np.isnan(B)):
173
+ logger.warning("Constraints contain nan not adding constraints: {}".format(name))
174
+ # return
175
+
156
176
  rows = np.arange(0, nr).astype(int)
157
177
  rows += self.c_
158
178
  constraint_ids = rows.copy()
159
179
 
160
- if name in self.constraints:
161
- self.constraints[name] = np.hstack([self.constraints[name],
162
- constraint_ids])
180
+ if name in self.constraints:
181
+
182
+ self.constraints[name]['A'] = np.vstack([self.constraints[name]['A'],A])
183
+ self.constraints[name]['B'] = np.hstack([self.constraints[name]['B'], B])
184
+ self.constraints[name]['idc'] = np.vstack([self.constraints[name]['idc'],
185
+ idc])
186
+
163
187
  if name not in self.constraints:
164
- self.constraints[name] = constraint_ids
188
+ self.constraints[name] = {'node_indexes':constraint_ids,'A':A,'B':B.flatten(),'idc':idc}
165
189
  rows = np.tile(rows, (A.shape[-1], 1)).T
166
190
 
167
191
  self.c_ += nr
@@ -176,7 +200,12 @@ class DiscreteInterpolator(GeologicalInterpolator):
176
200
  self.row.extend(rows[~mask].tolist())
177
201
  self.col.extend(idc[~mask].tolist())
178
202
  self.B.extend(B.tolist())
179
-
203
+
204
+ def calculate_residual_for_constraints(self):
205
+ residuals = {}
206
+ for constraint_name, constraint in self.constraints:
207
+ residuals[constraint_name] = np.einsum('ij,ij->i',constraint['A'],self.c[constraint['idc'].astype(int)]) - constraint['B'].flatten()
208
+ return residuals
180
209
  def remove_constraints_from_least_squares(self, name='undefined',
181
210
  constraint_ids=None):
182
211
  """
@@ -345,7 +374,8 @@ class DiscreteInterpolator(GeologicalInterpolator):
345
374
  """
346
375
 
347
376
  lsqrargs = {}
348
- # lsqrargs['tol'] = 1e-12
377
+ lsqrargs['tol'] = 1e-12
378
+ lsqrargs['atol'] = 0
349
379
  if 'iter_lim' in kwargs:
350
380
  logger.info("Using %i maximum iterations" % kwargs['iter_lim'])
351
381
  lsqrargs['iter_lim'] = kwargs['iter_lim']
@@ -427,7 +457,7 @@ class DiscreteInterpolator(GeologicalInterpolator):
427
457
  cgargs['M'] = precon(A)
428
458
  return sla.cg(A, B, **cgargs)[0][:self.nx]
429
459
 
430
- def _solve_pyamg(self, A, B):
460
+ def _solve_pyamg(self, A, B, tol=1e-12,x0=None,**kwargs):
431
461
  """
432
462
  Solve least squares system using pyamg algorithmic multigrid solver
433
463
 
@@ -441,7 +471,8 @@ class DiscreteInterpolator(GeologicalInterpolator):
441
471
 
442
472
  """
443
473
  import pyamg
444
- return pyamg.solve(A, B, verb=False)[:self.nx]
474
+ logger.info("Solving using pyamg: tol {}".format(tol))
475
+ return pyamg.solve(A, B, tol=tol, x0=x0, verb=False)[:self.nx]
445
476
 
446
477
  def _solve(self, solver='cg', **kwargs):
447
478
  """
@@ -462,6 +493,8 @@ class DiscreteInterpolator(GeologicalInterpolator):
462
493
  True if the interpolation is run
463
494
 
464
495
  """
496
+ logger.info("Solving interpolation for {}".format(self.propertyname))
497
+
465
498
  self.c = np.zeros(self.support.n_nodes)
466
499
  self.c[:] = np.nan
467
500
  damp = True
@@ -487,7 +520,7 @@ class DiscreteInterpolator(GeologicalInterpolator):
487
520
  if solver == 'pyamg':
488
521
  try:
489
522
  logger.info("Solving with pyamg solve")
490
- self.c[self.region] = self._solve_pyamg(A, B)
523
+ self.c[self.region] = self._solve_pyamg(A, B,**kwargs)
491
524
  except ImportError:
492
525
  logger.warn("Pyamg not installed using cg instead")
493
526
  self.c[self.region] = self._solve_cg(A, B)
@@ -497,12 +530,12 @@ class DiscreteInterpolator(GeologicalInterpolator):
497
530
  logger.warning("Using external solver")
498
531
  self.c[self.region] = kwargs['external'](A, B)[:self.nx]
499
532
  # check solution is not nan
500
- self.support.properties[self.propertyname] = self.c
533
+ # self.support.properties[self.propertyname] = self.c
501
534
  if np.all(self.c == np.nan):
502
535
  logger.warning("Solver not run, no scalar field")
503
536
  # if solution is all 0, probably didn't work
504
537
  if np.all(self.c[self.region] == 0):
505
- logger.warning("No solution, scalar field 0. Add more data.")
538
+ logger.warning("No solution, {} scalar field 0. Add more data.".format(self.propertyname))
506
539
 
507
540
  def update(self):
508
541
  """
@@ -530,7 +563,7 @@ class DiscreteInterpolator(GeologicalInterpolator):
530
563
 
531
564
  if evaluation_points[~mask, :].shape[0] > 0:
532
565
  evaluated[~mask] = self.support.evaluate_value(
533
- evaluation_points[~mask], self.propertyname)
566
+ evaluation_points[~mask], self.c)
534
567
  return evaluated
535
568
 
536
569
  def evaluate_gradient(self, evaluation_points):
@@ -547,5 +580,5 @@ class DiscreteInterpolator(GeologicalInterpolator):
547
580
  """
548
581
  if evaluation_points.shape[0] > 0:
549
582
  return self.support.evaluate_gradient(evaluation_points,
550
- self.propertyname)
583
+ self.c)
551
584
  return np.zeros((0, 3))
@@ -1,3 +1,6 @@
1
+ """
2
+ FiniteDifference interpolator
3
+ """
1
4
  import logging
2
5
 
3
6
  import numpy as np
@@ -6,7 +9,8 @@ from LoopStructural.utils.helper import get_vectors
6
9
  from .discrete_interpolator import DiscreteInterpolator
7
10
  from .operator import Operator
8
11
 
9
- logger = logging.getLogger(__name__)
12
+ from LoopStructural.utils import getLogger
13
+ logger = getLogger(__name__)
10
14
 
11
15
 
12
16
  class FiniteDifferenceInterpolator(DiscreteInterpolator):
@@ -38,7 +42,9 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
38
42
  'cpw': 1.,
39
43
  'gpw': 1.,
40
44
  'npw': 1.,
41
- 'tpw': 1.})
45
+ 'tpw': 1.,
46
+ 'ipw': 1.
47
+ })
42
48
 
43
49
  self.vol = grid.step_vector[0] * grid.step_vector[1] * \
44
50
  grid.step_vector[2]
@@ -69,7 +75,6 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
69
75
  -------
70
76
 
71
77
  """
72
-
73
78
  for key in kwargs:
74
79
  self.up_to_date = False
75
80
  if 'regularisation' in kwargs:
@@ -123,6 +128,9 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
123
128
  self.add_tangent_ctr_pts(
124
129
  np.sqrt(self.vol) * self.interpolation_weights['tpw']
125
130
  )
131
+ self.add_interface_ctr_pts(
132
+ np.sqrt(self.vol)*self.interpolation_weights['ipw']
133
+ )
126
134
 
127
135
  def copy(self):
128
136
  """
@@ -166,7 +174,58 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
166
174
 
167
175
  self.add_constraints_to_least_squares(a.T * w,
168
176
  points[inside, 3] * w,
169
- idc[inside, :])
177
+ idc[inside, :],
178
+ name='value')
179
+ def add_interface_ctr_pts(self, w=1.0): # for now weight all value points the same
180
+ """
181
+ Adds a constraint that defines all points with the same 'id' to be the same value
182
+ Sets all P1-P2 = 0 for all pairs of points
183
+
184
+ Parameters
185
+ ----------
186
+ w : double
187
+ weight
188
+
189
+ Returns
190
+ -------
191
+
192
+ """
193
+ # get elements for points
194
+ points = self.get_interface_constraints()
195
+ if points.shape[0] > 1:
196
+ node_idx, inside = self.support.position_to_cell_corners(
197
+ points[:, :3])
198
+ # print(points[inside,:].shape)
199
+
200
+ gi = np.zeros(self.support.n_nodes)
201
+ gi[:] = -1
202
+ gi[self.region] = np.arange(0, self.nx)
203
+ idc = np.zeros(node_idx.shape)
204
+ idc[:] = -1
205
+
206
+ idc[inside, :] = gi[node_idx[inside, :]]
207
+ inside = np.logical_and(~np.any(idc == -1, axis=1), inside)
208
+ a = self.support.position_to_dof_coefs(points[inside, :3]).T
209
+ # create oversided array for storing constraints
210
+ A = np.zeros((a.shape[0]*a.shape[0],a.shape[1]*2))
211
+ interface_idc = np.zeros((a.shape[0]*a.shape[0],a.shape[1]*2),dtype=int)
212
+ interface_idc[:] = -1
213
+ c_i = 0
214
+
215
+ for i in np.unique(points[np.logical_and(~np.isnan(points[:,3]),inside),3]):
216
+ mask = points[inside,3] == i
217
+ for p1 in range(points[inside][mask].shape[0]):
218
+ for p2 in range(p1+1,points[inside][mask].shape[0]):
219
+ A[c_i,:8] = a[mask][p1,:]
220
+ A[c_i,8:] -= a[mask][p2,:]
221
+ interface_idc[c_i,:8] = idc[inside,:][mask,:][p1,:]
222
+ interface_idc[c_i,8:] = idc[inside,:][mask,:][p2,:]
223
+ c_i+=1
224
+ outside = ~np.any(interface_idc == -1, axis=1)
225
+
226
+ self.add_constraints_to_least_squares(A[outside,:] * w,
227
+ np.zeros(A[outside,:].shape[0]),
228
+ interface_idc[outside, :], name='interface')
170
229
 
171
230
  def add_gradient_constraint(self, w=1.):
172
231
  """
@@ -203,9 +262,9 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
203
262
  A = np.einsum('ij,ijk->ik', strike_vector.T, T)
204
263
 
205
264
  B = np.zeros(points[inside, :].shape[0])
206
- self.add_constraints_to_least_squares(A * w, B, idc[inside, :])
265
+ self.add_constraints_to_least_squares(A * w, B, idc[inside, :], name='gradient')
207
266
  A = np.einsum('ij,ijk->ik', dip_vector.T, T)
208
- self.add_constraints_to_least_squares(A * w, B, idc[inside, :])
267
+ self.add_constraints_to_least_squares(A * w, B, idc[inside, :], name='gradient')
209
268
 
210
269
  def add_norm_constraint(self, w=1.):
211
270
  """
@@ -243,13 +302,13 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
243
302
  w /= 3
244
303
  self.add_constraints_to_least_squares(T[:, 0, :] * w,
245
304
  points[inside, 3] * w,
246
- idc[inside, :])
305
+ idc[inside, :], name='norm')
247
306
  self.add_constraints_to_least_squares(T[:, 1, :] * w,
248
307
  points[inside, 4] * w,
249
- idc[inside, :])
308
+ idc[inside, :], name='norm')
250
309
  self.add_constraints_to_least_squares(T[:, 2, :] * w,
251
310
  points[inside, 5] * w,
252
- idc[inside, :])
311
+ idc[inside, :], name='norm')
253
312
 
254
313
  def add_gradient_orthogonal_constraint(self, points, vector, w=1.0,
255
314
  B=0):
@@ -289,7 +348,7 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
289
348
  A = np.einsum('ij,ijk->ik', vector[inside, :3], T)
290
349
 
291
350
  B = np.zeros(points[inside, :].shape[0])
292
- self.add_constraints_to_least_squares(A * w, B, idc[inside, :])
351
+ self.add_constraints_to_least_squares(A * w, B, idc[inside, :], name='gradient orthogonal')
293
352
 
294
353
  def add_regularisation(self, operator, w=0.1):
295
354
  """
@@ -334,6 +393,7 @@ class FiniteDifferenceInterpolator(DiscreteInterpolator):
334
393
  B = np.zeros(global_indexes.shape[1])
335
394
  self.add_constraints_to_least_squares(a[inside, :] * w,
336
395
  B[inside],
337
- idc[inside, :]
396
+ idc[inside, :],
397
+ name='regularisation'
338
398
  )
339
399
  return
@@ -1,13 +1,20 @@
1
+ """
2
+ Base geological interpolator
3
+ """
1
4
  import logging
2
5
 
3
6
  import numpy as np
4
7
 
5
- logger = logging.getLogger(__name__)
8
+ from LoopStructural.utils import getLogger
9
+ logger = getLogger(__name__)
6
10
 
7
11
 
8
12
  class GeologicalInterpolator:
9
13
  """
10
-
14
+ Attributes
15
+ ----------
16
+ data : dict
17
+ a dictionary with np.arrays for gradient, value, normal, tangent data
11
18
  """
12
19
  def __init__(self):
13
20
  """
@@ -19,7 +26,8 @@ class GeologicalInterpolator:
19
26
  self.data = {'gradient': np.zeros((0,7)),
20
27
  'value' : np.zeros((0,5)),
21
28
  'normal': np.zeros((0,7)),
22
- 'tangent': np.zeros((0,7))
29
+ 'tangent': np.zeros((0,7)),
30
+ 'interface' : np.zeros((0,5))
23
31
  }
24
32
  self.n_g = 0
25
33
  self.n_i = 0
@@ -109,6 +117,9 @@ class GeologicalInterpolator:
109
117
  """
110
118
  self.data['tangent'] = points
111
119
 
120
+ def set_interface_constraints(self, points):
121
+ self.data['interface'] = points
122
+
112
123
  def get_value_constraints(self):
113
124
  """
114
125
 
@@ -147,6 +158,14 @@ class GeologicalInterpolator:
147
158
  """
148
159
  return self.data['normal']
149
160
 
161
+ def get_data_locations(self):
162
+ norm = self.get_norm_constraints()
163
+ grad = self.get_gradient_constraints()
164
+ val = self.get_value_constraints()
165
+ return np.vstack([norm[:,:3],grad[:,:3],val[:,:3]])
166
+
167
+ def get_interface_constraints(self):
168
+ return self.data['interface']
150
169
  def setup_interpolator(self, **kwargs):
151
170
  """
152
171
  Runs all of the required setting up stuff
@@ -1,8 +1,12 @@
1
+ """
2
+ Finite difference masks
3
+ """
1
4
  import logging
2
5
 
3
6
  import numpy as np
4
7
 
5
- logger = logging.getLogger(__name__)
8
+ from LoopStructural.utils import getLogger
9
+ logger = getLogger(__name__)
6
10
 
7
11
 
8
12
  class Operator(object):
@@ -44,3 +48,14 @@ class Operator(object):
44
48
  [0, 1, 0], # third plane
45
49
  [0, 0, 0]]]
46
50
  )
51
+
52
+ #Hessian is
53
+ # Dxx Dxy Dxz
54
+ # Dxy Dyy Dzy
55
+ # Dzx Dzy Dzz
56
+
57
+ #det of hessian
58
+ # Det_Hessian_operator =
59
+ # Dxx_mask.dot(Dyy_mask.dot(Dzz_mask)) - Dxx_mask.dot(Dyz_mask.dot(Dyz_mask) -
60
+ # Dxy_mask.dot(Dxy_mask.dot(Dzz_mask)) - Dxy_mask.dot(Dxz_mask.dot(Dyz_mask)) +
61
+ # Dxz_mask.dot(Dxy_mask.dot(Dyz_mask)) - Dxz_mask.dot(Dyy_mask.dot(Dxz_mask))