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.

Files changed (119) hide show
  1. Miniconda/envs/loop/Lib/site-packages/LoopStructural/__init__.py +33 -0
  2. Miniconda/envs/loop/Lib/site-packages/LoopStructural/__pycache__/__init__.cpython-37.pyc +0 -0
  3. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__init__.py +12 -0
  4. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/__init__.cpython-37.pyc +0 -0
  5. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/__pycache__/_base.cpython-37.pyc +0 -0
  6. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/_base.py +65 -0
  7. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/claudius.csv +21049 -0
  8. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/claudiusbb.txt +2 -0
  9. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/duplex.csv +126 -0
  10. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/duplexbb.txt +2 -0
  11. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/intrusion.csv +1017 -0
  12. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/intrusionbb.txt +2 -0
  13. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/onefoldbb.txt +2 -0
  14. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/onefolddata.csv +2226 -0
  15. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/refolded_bb.txt +2 -0
  16. Miniconda/envs/loop/Lib/site-packages/LoopStructural/datasets/data/refolded_fold.csv +2126 -0
  17. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__init__.py +31 -0
  18. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/__init__.cpython-37.pyc +0 -0
  19. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_fold_interpolator.cpython-37.pyc +0 -0
  20. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/discrete_interpolator.cpython-37.pyc +0 -0
  21. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/finite_difference_interpolator.cpython-37.pyc +0 -0
  22. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/geological_interpolator.cpython-37.pyc +0 -0
  23. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/operator.cpython-37.pyc +0 -0
  24. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/piecewiselinear_interpolator.cpython-37.pyc +0 -0
  25. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_grid.cpython-37.pyc +0 -0
  26. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/structured_tetra.cpython-37.pyc +0 -0
  27. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/__pycache__/surfe_wrapper.cpython-37.pyc +0 -0
  28. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__init__.py +0 -0
  29. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/__pycache__/__init__.cpython-37.pyc +0 -0
  30. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.c +27805 -0
  31. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/cython/dsi_helper.cp37-win_amd64.pyd +0 -0
  32. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_fold_interpolator.py +168 -0
  33. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/discrete_interpolator.py +551 -0
  34. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/finite_difference_interpolator.py +339 -0
  35. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/geological_interpolator.py +178 -0
  36. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/operator.py +46 -0
  37. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/piecewiselinear_interpolator.py +300 -0
  38. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_grid.py +460 -0
  39. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/structured_tetra.py +637 -0
  40. Miniconda/envs/loop/Lib/site-packages/LoopStructural/interpolators/surfe_wrapper.py +119 -0
  41. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__init__.py +46 -0
  42. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/__pycache__/__init__.cpython-37.pyc +0 -0
  43. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__init__.py +0 -0
  44. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/__init__.cpython-37.pyc +0 -0
  45. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/__pycache__/geological_model.cpython-37.pyc +0 -0
  46. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/core/geological_model.py +1179 -0
  47. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__init__.py +3 -0
  48. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/__init__.cpython-37.pyc +0 -0
  49. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function.cpython-37.pyc +0 -0
  50. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_function_feature.cpython-37.pyc +0 -0
  51. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/__pycache__/fault_segment.cpython-37.pyc +0 -0
  52. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function.py +187 -0
  53. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_function_feature.py +75 -0
  54. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fault/fault_segment.py +270 -0
  55. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__init__.py +7 -0
  56. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/__init__.cpython-37.pyc +0 -0
  57. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/cross_product_geological_feature.cpython-37.pyc +0 -0
  58. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature.cpython-37.pyc +0 -0
  59. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/geological_feature_builder.cpython-37.pyc +0 -0
  60. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/region_feature.cpython-37.pyc +0 -0
  61. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame.cpython-37.pyc +0 -0
  62. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/structural_frame_builder.cpython-37.pyc +0 -0
  63. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/__pycache__/unconformity_feature.cpython-37.pyc +0 -0
  64. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/cross_product_geological_feature.py +77 -0
  65. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature.py +276 -0
  66. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/geological_feature_builder.py +289 -0
  67. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/region_feature.py +31 -0
  68. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame.py +116 -0
  69. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/structural_frame_builder.py +179 -0
  70. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/features/unconformity_feature.py +69 -0
  71. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__init__.py +8 -0
  72. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/__init__.cpython-37.pyc +0 -0
  73. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold.cpython-37.pyc +0 -0
  74. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle.cpython-37.pyc +0 -0
  75. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/fold_rotation_angle_feature.cpython-37.pyc +0 -0
  76. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/foldframe.cpython-37.pyc +0 -0
  77. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/__pycache__/svariogram.cpython-37.pyc +0 -0
  78. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold.py +135 -0
  79. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle.py +132 -0
  80. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/fold_rotation_angle_feature.py +57 -0
  81. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/foldframe.py +191 -0
  82. Miniconda/envs/loop/Lib/site-packages/LoopStructural/modelling/fold/svariogram.py +179 -0
  83. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__init__.py +14 -0
  84. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/__init__.cpython-37.pyc +0 -0
  85. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/exceptions.cpython-37.pyc +0 -0
  86. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/helper.cpython-37.pyc +0 -0
  87. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/map2loop.cpython-37.pyc +0 -0
  88. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/__pycache__/utils.cpython-37.pyc +0 -0
  89. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/exceptions.py +9 -0
  90. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/helper.py +373 -0
  91. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/map2loop.py +229 -0
  92. Miniconda/envs/loop/Lib/site-packages/LoopStructural/utils/utils.py +76 -0
  93. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__init__.py +19 -0
  94. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/__init__.cpython-37.pyc +0 -0
  95. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/map_viewer.cpython-37.pyc +0 -0
  96. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_plotter.cpython-37.pyc +0 -0
  97. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/model_visualisation.cpython-37.pyc +0 -0
  98. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/rotation_angle_plotter.cpython-37.pyc +0 -0
  99. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/__pycache__/sphinx_scraper.cpython-37.pyc +0 -0
  100. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/map_viewer.py +122 -0
  101. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_plotter.py +16 -0
  102. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/model_visualisation.py +704 -0
  103. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/rotation_angle_plotter.py +66 -0
  104. Miniconda/envs/loop/Lib/site-packages/LoopStructural/visualisation/sphinx_scraper.py +34 -0
  105. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/PKG-INFO +10 -0
  106. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/SOURCES.txt +60 -0
  107. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/dependency_links.txt +1 -0
  108. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/requires.txt +3 -0
  109. Miniconda/envs/loop/Lib/site-packages/LoopStructural-1.0.1-py3.7.egg-info/top_level.txt +2 -0
  110. Miniconda/envs/loop/Lib/site-packages/tests/__init__.py +0 -0
  111. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/__init__.cpython-37.pyc +0 -0
  112. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_faults.cpython-37.pyc +0 -0
  113. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_fold.cpython-37.pyc +0 -0
  114. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_interpolator.cpython-37.pyc +0 -0
  115. Miniconda/envs/loop/Lib/site-packages/tests/__pycache__/test_refolded.cpython-37.pyc +0 -0
  116. Miniconda/envs/loop/Lib/site-packages/tests/test_faults.py +17 -0
  117. Miniconda/envs/loop/Lib/site-packages/tests/test_fold.py +57 -0
  118. Miniconda/envs/loop/Lib/site-packages/tests/test_interpolator.py +88 -0
  119. Miniconda/envs/loop/Lib/site-packages/tests/test_refolded.py +22 -0
@@ -0,0 +1,551 @@
1
+ """
2
+ Discrete interpolator base for least squares
3
+ """
4
+ import logging
5
+
6
+ import numpy as np
7
+ from scipy.sparse import coo_matrix, bmat, eye
8
+ from scipy.sparse import linalg as sla
9
+
10
+ from LoopStructural.interpolators.geological_interpolator import \
11
+ GeologicalInterpolator
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class DiscreteInterpolator(GeologicalInterpolator):
17
+ """
18
+
19
+ """
20
+ def __init__(self, support):
21
+ """
22
+ Base class for a discrete interpolator e.g. piecewise linear or finite difference which is
23
+ any interpolator that solves the system using least squares approximation
24
+
25
+ Parameters
26
+ ----------
27
+ support
28
+ A discrete mesh with, nodes, elements, etc
29
+ """
30
+ GeologicalInterpolator.__init__(self)
31
+ self.B = []
32
+ 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)
36
+ # self.region_map[self.region] = np.array(range(0,
37
+ # len(self.region_map[self.region])))
38
+ self.nx = len(self.support.nodes[self.region])
39
+ self.shape = 'rectangular'
40
+ if self.shape == 'square':
41
+ self.B = np.zeros(self.nx)
42
+ self.c_ = 0
43
+ self.A = [] # sparse matrix storage coo format
44
+ self.col = []
45
+ self.row = [] # sparse matrix storage
46
+ self.solver = None
47
+ self.eq_const_C = []
48
+ self.eq_const_row = []
49
+ self.eq_const_col = []
50
+ self.eq_const_d = []
51
+ self.eq_const_c_ = 0
52
+ self.constraints = {}
53
+ self.interpolation_weights= {}
54
+
55
+ def set_property_name(self, propertyname):
56
+ """
57
+ Set the property name attribute, this is usually used to
58
+ save the property on the support
59
+
60
+ Parameters
61
+ ----------
62
+ propertyname
63
+
64
+ Returns
65
+ -------
66
+
67
+ """
68
+ self.propertyname = propertyname
69
+
70
+ def set_region(self, region=None):
71
+ """
72
+ Set the region of the support the interpolator is working on
73
+
74
+ Parameters
75
+ ----------
76
+ region - function(position)
77
+ return true when in region, false when out
78
+
79
+ Returns
80
+ -------
81
+
82
+ """
83
+ # evaluate the region function on the support to determine
84
+ # which nodes are inside update region map and degrees of freedom
85
+ 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
+
92
+ def set_interpolation_weights(self, weights):
93
+ """
94
+ Set the interpolation weights dictionary
95
+
96
+ Parameters
97
+ ----------
98
+ weights - dictionary
99
+ Entry of new weights to assign to self.interpolation_weights
100
+
101
+ Returns
102
+ -------
103
+
104
+ """
105
+ for key in weights:
106
+ self.up_to_date = False
107
+ self.interpolation_weights[key] = weights[key]
108
+
109
+ def reset(self):
110
+ """
111
+ Reset the interpolation constraints
112
+
113
+ """
114
+ logger.debug("Resetting interpolation constraints")
115
+ self.c_ = 0
116
+ self.A = [] # sparse matrix storage coo format
117
+ self.col = []
118
+ self.row = [] # sparse matrix storage
119
+ self.eq_const_C = []
120
+ self.eq_const_row = []
121
+ self.eq_const_col = []
122
+ self.eq_const_d = []
123
+ self.eq_const_c_ = 0
124
+ self.B = []
125
+ self.n_constraints = 0
126
+
127
+ def add_constraints_to_least_squares(self, A, B, idc, name='undefined'):
128
+ """
129
+ Adds constraints to the least squares system. Automatically works
130
+ out the row
131
+ index given the shape of the input arrays
132
+
133
+ Parameters
134
+ ----------
135
+ A : numpy array / list
136
+ RxC numpy array of constraints where C is number of columns,R rows
137
+ B : numpy array /list
138
+ B values array length R
139
+ idc : numpy array/list
140
+ RxC column index
141
+
142
+ Returns
143
+ -------
144
+ list of constraint ids
145
+
146
+ """
147
+ A = np.array(A)
148
+ B = np.array(B)
149
+ 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")
152
+ return
153
+ nr = A.shape[0]
154
+ if len(A.shape) > 2:
155
+ nr = A.shape[0] * A.shape[1]
156
+ rows = np.arange(0, nr).astype(int)
157
+ rows += self.c_
158
+ constraint_ids = rows.copy()
159
+
160
+ if name in self.constraints:
161
+ self.constraints[name] = np.hstack([self.constraints[name],
162
+ constraint_ids])
163
+ if name not in self.constraints:
164
+ self.constraints[name] = constraint_ids
165
+ rows = np.tile(rows, (A.shape[-1], 1)).T
166
+
167
+ self.c_ += nr
168
+ if self.shape == 'rectangular':
169
+ # don't add operator where it is = 0 to the sparse matrix!
170
+ A = A.flatten()
171
+ rows = rows.flatten()
172
+ idc = idc.flatten()
173
+ B = B.flatten()
174
+ mask = A == 0
175
+ self.A.extend(A[~mask].tolist())
176
+ self.row.extend(rows[~mask].tolist())
177
+ self.col.extend(idc[~mask].tolist())
178
+ self.B.extend(B.tolist())
179
+
180
+ def remove_constraints_from_least_squares(self, name='undefined',
181
+ constraint_ids=None):
182
+ """
183
+ Remove constraints from the least squares system using the constraint ids
184
+ which corresponds to the rows in the interpolation matrix.
185
+
186
+ Parameters
187
+ ----------
188
+ constraint_ids : np.array(dtype=int)
189
+ id of constraints to remove
190
+
191
+ Returns
192
+ -------
193
+
194
+ """
195
+
196
+ if constraint_ids is None:
197
+ constraint_ids = self.constraints[name]
198
+ print("Removing {} {} constraints from least squares".format(len(constraint_ids), name))
199
+ A = np.array(self.A)
200
+ B = np.array(self.B)
201
+ col = np.array(self.col)
202
+ row = np.array(self.row)
203
+ mask = np.any((row[:,None] == constraint_ids[None,:]) == True,
204
+ axis=1)
205
+ # np.any((numbers[:, None] == np.array([0, 10, 30])[None, :]) == True,
206
+ # axis=1)
207
+ bmask = np.ones(B.shape,dtype=bool)
208
+ bmask[constraint_ids] = 0
209
+ self.A = A[~mask].tolist()
210
+ self.B = B[bmask]
211
+ self.col = col[~mask].tolist()
212
+ rowmax = np.max(row[mask])
213
+ rowrange = rowmax-np.min(row[mask])
214
+ # row[np.logical_and(~mask,row>rowmax)] -= rowrange
215
+ return row[~mask]
216
+
217
+ def add_equality_constraints(self, node_idx, values):
218
+ """
219
+ Adds hard constraints to the least squares system. For now this just
220
+ sets
221
+ the node values to be fixed using a lagrangian.
222
+
223
+ Parameters
224
+ ----------
225
+ node_idx : numpy array/list
226
+ int array of node indexes
227
+ values : numpy array/list
228
+ array of node values
229
+
230
+ Returns
231
+ -------
232
+
233
+ """
234
+ # map from mesh node index to region node index
235
+ gi = np.zeros(self.support.n_nodes)
236
+ gi[:] = -1
237
+ gi[self.region] = np.arange(0, self.nx)
238
+ idc = gi[node_idx]
239
+ outside = ~(idc == -1)
240
+
241
+ self.eq_const_C.extend(np.ones(idc[outside].shape[0]).tolist())
242
+ self.eq_const_col.extend(idc[outside].tolist())
243
+ self.eq_const_row.extend((np.arange(0, idc[outside].shape[0])))
244
+ self.eq_const_d.extend(values[outside].tolist())
245
+ self.eq_const_c_ += idc[outside].shape[0]
246
+
247
+ def add_tangent_ctr_pts(self, w=1.0):
248
+ """
249
+
250
+ Parameters
251
+ ----------
252
+ w : double
253
+
254
+
255
+ Returns
256
+ -------
257
+
258
+ """
259
+ points = self.get_tangent_constraints()
260
+ if points.shape[0] > 1:
261
+ self.add_gradient_orthogonal_constraint(points[:,:3],points[:,3:6],w)
262
+
263
+ def build_matrix(self, square=True, damp=True):
264
+ """
265
+ Assemble constraints into interpolation matrix. Adds equaltiy
266
+ constraints
267
+ using lagrange modifiers if necessary
268
+
269
+ Parameters
270
+ ----------
271
+ damp: bool
272
+ Flag whether damping should be added to the diagonal of the matrix
273
+ Returns
274
+ -------
275
+ Interpolation matrix and B
276
+ """
277
+
278
+ logger.info("Interpolation matrix is %i x %i"%(self.c_,self.nx))
279
+ cols = np.array(self.col)
280
+ A = coo_matrix((np.array(self.A), (np.array(self.row), \
281
+ cols)), shape=(self.c_, self.nx),
282
+ dtype=float) # .tocsr()
283
+ B = np.array(self.B)
284
+ if not square:
285
+ logger.info("Using rectangular matrix, equality constraints are not used")
286
+ return A, B
287
+ AAT = A.T.dot(A)
288
+ BT = A.T.dot(B)
289
+ # add a small number to the matrix diagonal to smooth the results
290
+ # can help speed up solving, but might also introduce some errors
291
+
292
+ if self.eq_const_c_ > 0:
293
+ logger.info("Equality block is %i x %i"%(self.eq_const_c_,self.nx))
294
+ # solving constrained least squares using
295
+ # | ATA CT | |c| = b
296
+ # | C 0 | |y| d
297
+ # where A is the interpoaltion matrix
298
+ # C is the equality constraint matrix
299
+ # b is the interpolation constraints to be honoured
300
+ # in a least squares sense
301
+ # and d are the equality constraints
302
+ # c are the node values and y are the
303
+ # lagrange multipliers#
304
+ C = coo_matrix(
305
+ (np.array(self.eq_const_C), (np.array(self.eq_const_row),
306
+ np.array(self.eq_const_col))),
307
+ shape=(self.eq_const_c_, self.nx))
308
+ d = np.array(self.eq_const_d)
309
+ AAT = bmat([[AAT, C.T], [C, None]])
310
+ BT = np.hstack([BT, d])
311
+ if damp:
312
+ logger.info("Adding eps to matrix diagonal")
313
+ AAT += eye(AAT.shape[0]) * np.finfo('float').eps
314
+ return AAT, BT
315
+
316
+ def _solve_lu(self, A, B):
317
+ """
318
+ Call scipy LU decomoposition
319
+
320
+ Parameters
321
+ ----------
322
+ A : scipy square sparse matrix
323
+ B : numpy vector
324
+
325
+ Returns
326
+ -------
327
+
328
+ """
329
+ lu = sla.splu(A.tocsc())
330
+ sol = lu.solve(B)
331
+ return sol[:self.nx]
332
+
333
+ def _solve_lsqr(self, A, B, **kwargs):
334
+ """
335
+ Call scipy lsqr
336
+
337
+ Parameters
338
+ ----------
339
+ A : rectangular sparse matrix
340
+ B : vector
341
+
342
+ Returns
343
+ -------
344
+
345
+ """
346
+
347
+ lsqrargs = {}
348
+ # lsqrargs['tol'] = 1e-12
349
+ if 'iter_lim' in kwargs:
350
+ logger.info("Using %i maximum iterations" % kwargs['iter_lim'])
351
+ lsqrargs['iter_lim'] = kwargs['iter_lim']
352
+ if 'damp' in kwargs:
353
+ logger.info("Using damping coefficient")
354
+ lsqrargs['damp'] = kwargs['damp']
355
+ if 'atol' in kwargs:
356
+ logger.info('Using a tolerance of %f' % kwargs['atol'])
357
+ lsqrargs['atol'] = kwargs['atol']
358
+ if 'btol' in kwargs:
359
+ logger.info('Using btol of %f' % kwargs['btol'])
360
+ lsqrargs['btol'] = kwargs['btol']
361
+ if 'show' in kwargs:
362
+ lsqrargs['show'] = kwargs['show']
363
+ if 'conlim' in kwargs:
364
+ lsqrargs['conlim'] = kwargs['conlim']
365
+ return sla.lsqr(A,B, **lsqrargs)[0]
366
+
367
+ def _solve_chol(self, A, B):
368
+ """
369
+ Call suitesparse cholmod through scikitsparse
370
+ LINUX ONLY!
371
+
372
+ Parameters
373
+ ----------
374
+ A : scipy.sparse.matrix
375
+ square sparse matrix
376
+ B : numpy array
377
+ RHS of equation
378
+
379
+ Returns
380
+ -------
381
+
382
+ """
383
+ try:
384
+ from sksparse.cholmod import cholesky
385
+ factor = cholesky(A.tocsc())
386
+ return factor(B)[:self.nx]
387
+ except ImportError:
388
+ logger.warning("Scikit Sparse not installed try using cg instead")
389
+ return False
390
+
391
+ def _solve_cg(self, A, B, precon=None, **kwargs):
392
+ """
393
+ Call scipy conjugate gradient
394
+
395
+ Parameters
396
+ ----------
397
+ A : scipy.sparse.matrix
398
+ square sparse matrix
399
+ B : numpy vector
400
+ precon : scipy.sparse.matrix
401
+ a preconditioner for the conjugate gradient system
402
+ kwargs
403
+ kwargs to pass to scipy solve e.g. atol, btol, callback etc
404
+
405
+ Returns
406
+ -------
407
+ numpy array
408
+ """
409
+ cgargs = {}
410
+ cgargs['tol'] = 1e-12
411
+ cgargs['atol'] = 0
412
+ if 'maxiter' in kwargs:
413
+ logger.info("Using %i maximum iterations"%kwargs['maxiter'])
414
+ cgargs['maxiter'] = kwargs['maxiter']
415
+ if 'x0' in kwargs:
416
+ logger.info("Using starting guess")
417
+ cgargs['x0'] = kwargs['x0']
418
+ if 'tol' in kwargs:
419
+ logger.info('Using tolerance of %f'%kwargs['tol'])
420
+ cgargs['tol'] = kwargs['tol']
421
+ if 'atol' in kwargs:
422
+ logger.info('Using atol of %f'%kwargs['atol'])
423
+ cgargs['atol'] = kwargs['atol']
424
+ if 'callback' in kwargs:
425
+ cgargs['callback'] = kwargs['callback']
426
+ if precon is not None:
427
+ cgargs['M'] = precon(A)
428
+ return sla.cg(A, B, **cgargs)[0][:self.nx]
429
+
430
+ def _solve_pyamg(self, A, B):
431
+ """
432
+ Solve least squares system using pyamg algorithmic multigrid solver
433
+
434
+ Parameters
435
+ ----------
436
+ A : scipy.sparse.matrix
437
+ B : numpy array
438
+
439
+ Returns
440
+ -------
441
+
442
+ """
443
+ import pyamg
444
+ return pyamg.solve(A, B, verb=False)[:self.nx]
445
+
446
+ def _solve(self, solver='cg', **kwargs):
447
+ """
448
+ Main entry point to run the solver and update the node value
449
+ attribute for the
450
+ discreteinterpolator class
451
+
452
+ Parameters
453
+ ----------
454
+ solver : string
455
+ solver e.g. cg, lu, chol, custom
456
+ kwargs
457
+ kwargs for solver e.g. maxiter, preconditioner etc, damping for
458
+
459
+ Returns
460
+ -------
461
+ bool
462
+ True if the interpolation is run
463
+
464
+ """
465
+ self.c = np.zeros(self.support.n_nodes)
466
+ self.c[:] = np.nan
467
+ damp = True
468
+ if 'damp' in kwargs:
469
+ damp = kwargs['damp']
470
+ if solver == 'lu':
471
+ logger.info("Forcing matrix damping for LU")
472
+ damp = True
473
+ if solver == 'lsqr':
474
+ A, B = self.build_matrix(False)
475
+ else:
476
+ A, B = self.build_matrix(damp=damp)
477
+
478
+ # run the chosen solver
479
+ if solver == 'cg':
480
+ logger.info("Solving using conjugate gradient")
481
+ self.c[self.region] = self._solve_cg(A, B, **kwargs)
482
+ if solver == 'chol':
483
+ self.c[self.region] = self._solve_chol(A, B)
484
+ if solver == 'lu':
485
+ logger.info("Solving using scipy LU")
486
+ self.c[self.region] = self._solve_lu(A, B)
487
+ if solver == 'pyamg':
488
+ try:
489
+ logger.info("Solving with pyamg solve")
490
+ self.c[self.region] = self._solve_pyamg(A, B)
491
+ except ImportError:
492
+ logger.warn("Pyamg not installed using cg instead")
493
+ self.c[self.region] = self._solve_cg(A, B)
494
+ if solver == 'lsqr':
495
+ self.c[self.region] = self._solve_lsqr(A, B, **kwargs)
496
+ if solver == 'external':
497
+ logger.warning("Using external solver")
498
+ self.c[self.region] = kwargs['external'](A, B)[:self.nx]
499
+ # check solution is not nan
500
+ self.support.properties[self.propertyname] = self.c
501
+ if np.all(self.c == np.nan):
502
+ logger.warning("Solver not run, no scalar field")
503
+ # if solution is all 0, probably didn't work
504
+ if np.all(self.c[self.region] == 0):
505
+ logger.warning("No solution, scalar field 0. Add more data.")
506
+
507
+ def update(self):
508
+ """
509
+ Check if the solver is up to date, if not rerun interpolation using
510
+ the previously used solver. If the interpolation has not been run
511
+ before it will
512
+ return False
513
+
514
+ Returns
515
+ -------
516
+ bool
517
+
518
+ """
519
+ if self.solver is None:
520
+ logging.debug("Cannot rerun interpolator")
521
+ return False
522
+ if not self.up_to_date:
523
+ self.setup_interpolator()
524
+ return self._solve(self.solver)
525
+
526
+ def evaluate_value(self, evaluation_points):
527
+ evaluation_points = np.array(evaluation_points)
528
+ evaluated = np.zeros(evaluation_points.shape[0])
529
+ mask = np.any(evaluation_points == np.nan, axis=1)
530
+
531
+ if evaluation_points[~mask, :].shape[0] > 0:
532
+ evaluated[~mask] = self.support.evaluate_value(
533
+ evaluation_points[~mask], self.propertyname)
534
+ return evaluated
535
+
536
+ def evaluate_gradient(self, evaluation_points):
537
+ """
538
+ Evaluate the gradient of the scalar field at the evaluation points
539
+ Parameters
540
+ ----------
541
+ evaluation_points : np.array
542
+ xyz locations to evaluate the gradient
543
+
544
+ Returns
545
+ -------
546
+
547
+ """
548
+ if evaluation_points.shape[0] > 0:
549
+ return self.support.evaluate_gradient(evaluation_points,
550
+ self.propertyname)
551
+ return np.zeros((0, 3))