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
3
+ """
1
4
  import logging
2
5
 
3
6
  import numpy as np
@@ -6,7 +9,8 @@ from LoopStructural.interpolators.discrete_interpolator import \
6
9
  DiscreteInterpolator
7
10
  from LoopStructural.utils.helper import get_vectors
8
11
 
9
- logger = logging.getLogger(__name__)
12
+ from LoopStructural.utils import getLogger
13
+ logger = getLogger(__name__)
10
14
 
11
15
 
12
16
  class PiecewiseLinearInterpolator(DiscreteInterpolator):
@@ -29,11 +33,10 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
29
33
  DiscreteInterpolator.__init__(self, mesh)
30
34
  # whether to assemble a rectangular matrix or a square matrix
31
35
  self.interpolator_type = 'PLI'
32
- self.nx = len(self.support.nodes[self.region])
33
36
  self.support = mesh
34
37
 
35
- self.set_interpolation_weights({'cgw': 0.1, 'cpw': 1., 'npw': 1.,
36
- 'gpw': 1., 'tpw': 1.})
38
+ self.interpolation_weights = {'cgw': 0.1, 'cpw': 1., 'npw': 1.,
39
+ 'gpw': 1., 'tpw': 1., 'ipw': 1.}
37
40
  self.__str = 'Piecewise Linear Interpolator with %i unknowns. \n' % \
38
41
  self.nx
39
42
 
@@ -69,7 +72,10 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
69
72
  self.interpolation_weights[key] = kwargs[key]
70
73
  if self.interpolation_weights['cgw'] > 0.:
71
74
  self.up_to_date = False
72
- self.add_constant_gradient(self.interpolation_weights['cgw'])
75
+ self.add_constant_gradient(self.interpolation_weights['cgw'],
76
+ direction_feature=kwargs.get('direction_feature',None),
77
+ direction_vector=kwargs.get('direction_vector',None)
78
+ )
73
79
  logger.info("Using constant gradient regularisation w = %f"
74
80
  %self.interpolation_weights['cgw'])
75
81
  logger.info("Added %i gradient constraints, %i normal constraints,"
@@ -80,8 +86,11 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
80
86
  self.add_norm_ctr_pts(self.interpolation_weights['npw'])
81
87
  self.add_ctr_pts(self.interpolation_weights['cpw'])
82
88
  self.add_tangent_ctr_pts(self.interpolation_weights['tpw'])
83
-
84
- def add_constant_gradient(self, w=0.1):
89
+ self.add_interface_ctr_pts(self.interpolation_weights['ipw'])
90
+ if 'constant_norm' in kwargs:
91
+ self.add_constant_norm(w=kwargs['constant_norm'])
92
+
93
+ def add_constant_gradient(self, w= 0.1, direction_vector=None, direction_feature=None):
85
94
  """
86
95
  Add the constant gradient regularisation to the system
87
96
 
@@ -93,8 +102,17 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
93
102
  -------
94
103
 
95
104
  """
105
+ if direction_feature is not None:
106
+ print('dir fe')
107
+ direction_vector = direction_feature.evaluate_gradient(self.support.barycentre())
108
+ if direction_vector is not None:
109
+ if direction_vector.shape[0] == 1:
110
+ # if using a constant direction, tile array so it works for cg calc
111
+ direction_vector = np.tile(direction_vector,(self.support.barycentre().shape[0],1))
112
+
113
+
96
114
  # iterate over all elements
97
- A, idc, B = self.support.get_constant_gradient(region=self.region)
115
+ A, idc, B = self.support.get_constant_gradient(region=self.region,direction=direction_vector)
98
116
  A = np.array(A)
99
117
  B = np.array(B)
100
118
  idc = np.array(idc)
@@ -111,6 +129,79 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
111
129
  name='regularisation')
112
130
  return
113
131
 
132
+ def add_direction_constant_gradient(self, w= 0.1, direction_vector=None, direction_feature=None):
133
+ """
134
+ Add the constant gradient regularisation to the system where regularisation is projected
135
+ on a vector
136
+
137
+ Parameters
138
+ ----------
139
+ w (double) - weighting of the cg parameter
140
+ direction_vector
141
+ direction_feature
142
+
143
+ Returns
144
+ -------
145
+
146
+ """
147
+ if direction_feature:
148
+ print('dir fe')
149
+ direction_vector = direction_feature.evaluate_gradient(self.support.barycentre())
150
+ if direction_vector:
151
+ if direction_vector.shape[0] == 1:
152
+ # if using a constant direction, tile array so it works for cg calc
153
+ direction_vector = np.tile(direction_vector,(self.support.barycentre().shape[0],1))
154
+
155
+
156
+ # iterate over all elements
157
+ A, idc, B = self.support.get_constant_gradient(region=self.region,direction=direction_vector)
158
+ A = np.array(A)
159
+ B = np.array(B)
160
+ idc = np.array(idc)
161
+
162
+ gi = np.zeros(self.support.n_nodes)
163
+ gi[:] = -1
164
+ gi[self.region] = np.arange(0, self.nx)
165
+ idc = gi[idc]
166
+ outside = ~np.any(idc == -1, axis=1)
167
+
168
+ # w/=A.shape[0]
169
+ self.add_constraints_to_least_squares(A[outside, :] * w,
170
+ B[outside] * w, idc[outside, :],
171
+ name='directional regularisation')
172
+ return
173
+
174
+
175
+ def add_constant_norm(self, w=0.1):
176
+ """
177
+ Add the constant gradient regularisation to the system
178
+
179
+ Parameters
180
+ ----------
181
+ w (double) - weighting of the cg parameter
182
+
183
+ Returns
184
+ -------
185
+
186
+ """
187
+ # iterate over all elements
188
+ A, idc, B = self.support.get_constant_norm(region=self.region)
189
+ A = np.array(A)
190
+ B = np.array(B)
191
+ idc = np.array(idc)
192
+
193
+ gi = np.zeros(self.support.n_nodes)
194
+ gi[:] = -1
195
+ gi[self.region] = np.arange(0, self.nx)
196
+ idc = gi[idc]
197
+ outside = ~np.any(idc == -1, axis=1)
198
+
199
+ # w/=A.shape[0]
200
+ self.add_constraints_to_least_squares(A[outside, :] * w,
201
+ B[outside] * w, idc[outside, :],
202
+ name='norm_regularisation')
203
+ return
204
+
114
205
  def add_gradient_ctr_pts(self, w=1.0):
115
206
  """
116
207
  Adds gradient constraints to the least squares system with a weight
@@ -131,6 +222,7 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
131
222
  requires at least two other
132
223
  value constraints OR a norm constraint for the interpolant to solve.
133
224
  """
225
+
134
226
  points = self.get_gradient_constraints()
135
227
  if points.shape[0] > 0:
136
228
  vertices, element_gradients, tetras, inside = self.support.get_tetra_gradient_for_location(points[:,:3])
@@ -226,7 +318,8 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
226
318
 
227
319
  Parameters
228
320
  ----------
229
- w
321
+ w : double
322
+ weight
230
323
 
231
324
  Returns
232
325
  -------
@@ -255,6 +348,51 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
255
348
  points[inside,:][outside, 3] * w * vol[outside],
256
349
  idc[outside, :], name='value')
257
350
 
351
+ def add_interface_ctr_pts(self, w=1.0): # for now weight all value points the same
352
+ """
353
+ Adds a constraint that defines all points with the same 'id' to be the same value
354
+ Sets all P1-P2 = 0 for all pairs of points
355
+
356
+ Parameters
357
+ ----------
358
+ w : double
359
+ weight
360
+
361
+ Returns
362
+ -------
363
+
364
+ """
365
+
366
+ # get elements for points
367
+ points = self.get_interface_constraints()
368
+ if points.shape[0] > 1:
369
+ vertices, c, tetras, inside = self.support.get_tetra_for_location(points[:,:3])
370
+ # calculate volume of tetras
371
+ vecs = vertices[inside, 1:, :] - vertices[inside, 0, None, :]
372
+ vol = np.abs(np.linalg.det(vecs)) / 6
373
+ A = c[inside]
374
+ A *= vol[:,None]
375
+ idc = tetras[inside,:]
376
+ for id in np.unique(points[np.logical_and(~np.isnan(points[:,3]),inside),3]):
377
+ mask = points[inside,3] == id
378
+ interface_A = A[None,mask,:] - A[mask,None,:]
379
+ interface_A = np.sum(interface_A,axis=0)
380
+ # interface_A = interface_A.reshape((interface_A.shape[0]*interface_A.shape[0],A.shape[1]))
381
+ interface_idc = idc[mask,:]
382
+
383
+ # now map the index from global to region create array size of mesh
384
+ # initialise as np.nan, then map points inside region to 0->nx
385
+ gi = np.zeros(self.support.n_nodes).astype(int)
386
+ gi[:] = -1
387
+
388
+ gi[self.region] = np.arange(0, self.nx)
389
+ interface_idc = gi[interface_idc]
390
+ # interface_idc = np.tile(interface_idc,(interface_idc.shape[0],1)).reshape(interface_A.shape)#flatten()
391
+ outside = ~np.any(interface_idc == -1, axis=1)
392
+ self.add_constraints_to_least_squares(interface_A[outside,:] * w,
393
+ np.zeros(interface_A[outside,:].shape[0]),
394
+ interface_idc[outside, :], name='interface')
395
+
258
396
  def add_gradient_orthogonal_constraint(self, points, vector, w=1.0,
259
397
  B=0):
260
398
  """
@@ -275,6 +413,7 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
275
413
  vertices, element_gradients, tetras, inside = self.support.get_tetra_gradient_for_location(points[:,:3])
276
414
  #e, inside = self.support.elements_for_array(points[:, :3])
277
415
  #nodes = self.support.nodes[self.support.elements[e]]
416
+ vector /= np.linalg.norm(vector,axis=1)[:,None]
278
417
  vecs = vertices[:, 1:, :] - vertices[:, 0, None, :]
279
418
  vol = np.abs(np.linalg.det(vecs)) # / 6
280
419
  # d_t = self.support.get_elements_gradients(e)
@@ -290,9 +429,9 @@ class PiecewiseLinearInterpolator(DiscreteInterpolator):
290
429
  gi[self.region] = np.arange(0, self.nx).astype(int)
291
430
  w /= 3
292
431
  idc = gi[tetras]
293
- B = np.zeros(idc.shape[0])
432
+ B = np.zeros(idc.shape[0])+B
294
433
  outside = ~np.any(idc == -1, axis=1)
295
434
  self.add_constraints_to_least_squares(A[outside, :] * w,
296
- B[outside], idc[outside, :])
435
+ B[outside], idc[outside, :], name='gradient_orthogonal')
297
436
 
298
437
 
@@ -1,11 +1,19 @@
1
+ """
2
+ Cartesian grid for fold interpolator
3
+
4
+ """
1
5
  import logging
2
6
 
3
7
  import numpy as np
4
8
 
5
- logger = logging.getLogger(__name__)
9
+ from .base_structured_3d_support import BaseStructuredSupport
10
+
6
11
 
12
+ from LoopStructural.utils import getLogger
13
+ logger = getLogger(__name__)
7
14
 
8
- class StructuredGrid:
15
+
16
+ class StructuredGrid(BaseStructuredSupport):
9
17
  """
10
18
 
11
19
  """
@@ -13,7 +21,7 @@ class StructuredGrid:
13
21
  origin=np.zeros(3),
14
22
  nsteps=np.array([10, 10, 10]),
15
23
  step_vector=np.ones(3),
16
- maximum=None
24
+ name=None
17
25
  ):
18
26
  """
19
27
 
@@ -22,69 +30,15 @@ class StructuredGrid:
22
30
  origin - 3d list or numpy array
23
31
  nsteps - 3d list or numpy array of ints
24
32
  step_vector - 3d list or numpy array of int
25
- maximum
26
33
  """
27
-
28
- self.nsteps = np.array(nsteps)
29
- self.step_vector = np.array(step_vector)
30
- self.origin = np.array(origin)
31
- # self.nsteps+=1
32
- self.n_nodes = self.nsteps[0] * self.nsteps[1] * self.nsteps[2]
33
- # self.nsteps-=1
34
- self.dim = 3
35
- self.nsteps_cells = self.nsteps - 1
36
- self.n_cell_x = self.nsteps[0] - 1
37
- self.n_cell_y = self.nsteps[1] - 1
38
- self.n_cell_z = self.nsteps[2] - 1
39
- self.properties = {}
40
- self.n_elements = self.n_cell_x * self.n_cell_y * self.n_cell_z
41
-
42
- # calculate the node positions using numpy (this should probably not
43
- # be stored as it defeats
44
- # the purpose of a structured grid
45
-
46
- # self.barycentre = self.cell_centres(np.arange(self.n_elements))
47
-
34
+ BaseStructuredSupport.__init__(self,origin,nsteps,step_vector)
48
35
  self.regions = {}
49
36
  self.regions['everywhere'] = np.ones(self.n_nodes).astype(bool)
50
-
51
- @property
52
- def nodes(self):
53
- max = self.origin + self.nsteps_cells * self.step_vector
54
- x = np.linspace(self.origin[0], max[0], self.nsteps[0])
55
- y = np.linspace(self.origin[1], max[1], self.nsteps[1])
56
- z = np.linspace(self.origin[2], max[2], self.nsteps[2])
57
- xx, yy, zz = np.meshgrid(x, y, z, indexing='ij')
58
- return np.array([xx.flatten(order='F'), yy.flatten(order='F'),
59
- zz.flatten(order='F')]).T
37
+ self.name = name
60
38
 
61
39
  def barycentre(self):
62
40
  return self.cell_centres(np.arange(self.n_elements))
63
41
 
64
- def print_geometry(self):
65
- print('Origin: %f %f %f' % (
66
- self.origin[0], self.origin[1], self.origin[2]))
67
- print('Cell size: %f %f %f' % (
68
- self.step_vector[0], self.step_vector[1], self.step_vector[2]))
69
- max = self.origin + self.nsteps_cells * self.step_vector
70
- print('Max extent: %f %f %f' % (max[0], max[1], max[2]))
71
-
72
- def update_property(self, propertyname, values):
73
- """[summary]
74
-
75
- [extended_summary]
76
-
77
- Parameters
78
- ----------
79
- propertyname : [type]
80
- [description]
81
- values : [type]
82
- [description]
83
- """
84
- if values.shape[0] == self.n_nodes:
85
- self.properties[propertyname] = values
86
- if values.shape[0] == self.n_elements:
87
- self.cell_properties[propertyname] = values
88
42
 
89
43
  def cell_centres(self, global_index):
90
44
  """[summary]
@@ -293,10 +247,10 @@ class StructuredGrid:
293
247
  1, 1, 1, 1, 1, 1, 1, 1, 1]
294
248
  ])
295
249
  neighbours = indexes[:, None, :] + mask[:, :, None]
296
- return neighbours[0, :, :] + self.nsteps[0, None, None] * neighbours[1,
250
+ return(neighbours[0, :, :] + self.nsteps[0, None, None] * neighbours[1,
297
251
  :, :] + \
298
252
  self.nsteps[0, None, None] * self.nsteps[
299
- 1, None, None] * neighbours[2, :, :]
253
+ 1, None, None] * neighbours[2, :, :]).astype(np.int64)
300
254
 
301
255
  def cell_corner_indexes(self, x_cell_index, y_cell_index, z_cell_index):
302
256
  """
@@ -363,7 +317,7 @@ class StructuredGrid:
363
317
  globalidx[~inside] = -1
364
318
  return globalidx, inside
365
319
 
366
- def evaluate_value(self, evaluation_points, property_name):
320
+ def evaluate_value(self, evaluation_points, property_array):
367
321
  """
368
322
  Evaluate the value of of the property at the locations.
369
323
  Trilinear interpolation dot corner values
@@ -377,28 +331,36 @@ class StructuredGrid:
377
331
  -------
378
332
 
379
333
  """
334
+ if property_array.shape[0] != self.n_nodes:
335
+ logger.error("Property array does not match grid")
336
+ raise BaseException
380
337
  idc, inside = self.position_to_cell_corners(evaluation_points)
381
338
  v = np.zeros(idc.shape)
382
339
  v[:, :] = np.nan
383
340
 
384
341
  v[inside, :] = self.position_to_dof_coefs(
385
342
  evaluation_points[inside, :]).T
386
- v[inside, :] *= self.properties[property_name][idc[inside, :]]
343
+
344
+ v[inside, :] *= property_array[idc[inside, :]]
345
+
387
346
  return np.sum(v, axis=1)
388
347
 
389
- def evaluate_gradient(self, evaluation_points, property_name):
348
+ def evaluate_gradient(self, evaluation_points, property_array):
349
+ if property_array.shape[0] != self.n_nodes:
350
+ logger.error("Property array does not match grid")
351
+ raise BaseException
390
352
  idc, inside = self.position_to_cell_corners(evaluation_points)
391
353
  T = np.zeros((idc.shape[0], 3, 8))
392
354
  T[inside, :, :] = self.calcul_T(evaluation_points[inside, :])
393
355
  # indices = np.array([self.position_to_cell_index(evaluation_points)])
394
356
  # idc = self.global_indicies(indices.swapaxes(0,1))
395
357
  # print(idc)
396
- T[inside, 0, :] *= self.properties[property_name][idc[inside, :]]
397
- T[inside, 1, :] *= self.properties[property_name][idc[inside, :]]
398
- T[inside, 2, :] *= self.properties[property_name][idc[inside, :]]
358
+ T[inside, 0, :] *= property_array[idc[inside, :]]
359
+ T[inside, 1, :] *= property_array[idc[inside, :]]
360
+ T[inside, 2, :] *= property_array[idc[inside, :]]
399
361
  return np.array(
400
- [np.sum(T[:, 0, :], axis=1) / 8, np.sum(T[:, 1, :], axis=1) / 8,
401
- np.sum(T[:, 2, :], axis=1) / 8]).T
362
+ [np.sum(T[:, 0, :], axis=1), np.sum(T[:, 1, :], axis=1) ,
363
+ np.sum(T[:, 2, :], axis=1) ]).T
402
364
 
403
365
  def calcul_T(self, pos):
404
366
  """
@@ -1,9 +1,13 @@
1
+ """
2
+ Tetmesh based on cartesian grid for piecewise linear interpolation
3
+ """
1
4
  import logging
2
5
 
3
6
  import numpy as np
4
- from LoopStructural.interpolators.cython.dsi_helper import cg
7
+ from LoopStructural.interpolators.cython.dsi_helper import cg, constant_norm, fold_cg
5
8
 
6
- logger = logging.getLogger(__name__)
9
+ from LoopStructural.utils import getLogger
10
+ logger = getLogger(__name__)
7
11
 
8
12
  class TetMesh:
9
13
  """
@@ -13,13 +17,14 @@ class TetMesh:
13
17
  self.origin = np.array(origin)
14
18
  self.step_vector = np.array(step_vector)
15
19
  self.nsteps = np.array(nsteps)
20
+ self.n_nodes = self.nsteps[0]*self.nsteps[1]*self.nsteps[2]
21
+
16
22
  self.nsteps_cells = self.nsteps - 1
17
23
  self.n_cell_x = self.nsteps[0] - 1
18
24
  self.n_cell_y = self.nsteps[1] - 1
19
25
  self.n_cell_z = self.nsteps[2] - 1
20
26
  self.n_cells = self.n_cell_x * self.n_cell_y * self.n_cell_z
21
- self.n_nodes = self.nsteps[0]*self.nsteps[1]*self.nsteps[2]
22
-
27
+ self.maximum = origin+self.nsteps*self.step_vector
23
28
  self.tetra_mask_even = np.array([
24
29
  [7,1,2,4],
25
30
  [6,2,4,7],
@@ -36,8 +41,6 @@ class TetMesh:
36
41
  [1,0,3,5]
37
42
  ])
38
43
  self.ntetra = self.n_cells * 5
39
- self.properties = {}
40
- self.property_gradients = {}
41
44
  self.n_elements = self.ntetra
42
45
  self.cg = None
43
46
 
@@ -80,11 +83,7 @@ class TetMesh:
80
83
  axis=1) / 4.
81
84
  return barycentre
82
85
 
83
- def update_property(self, name, value):
84
-
85
- self.properties[name] = value
86
-
87
- def evaluate_value(self, pos, prop):
86
+ def evaluate_value(self, pos, property_array):
88
87
  """
89
88
  Evaluate value of interpolant
90
89
 
@@ -102,10 +101,10 @@ class TetMesh:
102
101
  values = np.zeros(pos.shape[0])
103
102
  values[:] = np.nan
104
103
  vertices, c, tetras, inside = self.get_tetra_for_location(pos)
105
- values[inside] = np.sum(c[inside,:]*self.properties[prop][tetras[inside,:]],axis=1)
104
+ values[inside] = np.sum(c[inside,:]*property_array[tetras[inside,:]],axis=1)
106
105
  return values
107
106
 
108
- def evaluate_gradient(self, pos, prop):
107
+ def evaluate_gradient(self, pos, property_array):
109
108
  """
110
109
  Evaluate the gradient of an interpolant at the locations
111
110
 
@@ -124,13 +123,20 @@ class TetMesh:
124
123
  values = np.zeros(pos.shape)
125
124
  values[:] = np.nan
126
125
  vertices, element_gradients, tetras, inside = self.get_tetra_gradient_for_location(pos)
127
- vertex_vals = self.properties[prop][tetras]
128
126
  #grads = np.zeros(tetras.shape)
129
- values[inside,:] = (element_gradients[inside,:,:]*vertex_vals[inside, None, :]).sum(2)
127
+ values[inside,:] = (element_gradients[inside,:,:]*property_array[tetras[inside,None,:]]).sum(2)
130
128
  length = np.sum(values[inside,:],axis=1)
131
- values[inside,:] /= length[:,None]
129
+ # values[inside,:] /= length[:,None]
132
130
  return values
133
131
 
132
+ def inside(self, pos):
133
+ inside = np.ones(pos.shape[0]).astype(bool)
134
+ for i in range(3):
135
+ inside *= pos[:, i] > self.origin[None, i]
136
+ inside *= pos[:, i] < self.origin[None, i] + \
137
+ self.step_vector[None, i] * self.nsteps_cells[None, i]
138
+ return inside
139
+
134
140
  def get_tetra_for_location(self, pos):
135
141
  """
136
142
  Determine the tetrahedron from a numpy array of points
@@ -146,11 +152,13 @@ class TetMesh:
146
152
 
147
153
  """
148
154
  pos = np.array(pos)
155
+ inside = self.inside(pos)
149
156
  # initialise array for tetrahedron vertices
150
157
  vertices = np.zeros((5, 4, pos.shape[0], 3))
151
158
  vertices[:] = np.nan
152
159
  # get cell indexes
153
160
  c_xi, c_yi, c_zi = self.position_to_cell_index(pos)
161
+
154
162
  # determine if using +ve or -ve mask
155
163
  even_mask = (c_xi + c_yi + c_zi) % 2 == 0
156
164
  # get cell corners
@@ -188,15 +196,18 @@ class TetMesh:
188
196
  # if all coords are +ve then point is inside cell
189
197
  mask = np.all(c > 0, axis=2)
190
198
 
191
- inside = np.any(mask,axis=1)
199
+ inside = np.logical_and(inside,np.any(mask,axis=1))
192
200
  # get cell corners
193
201
  xi, yi, zi = self.cell_corner_indexes(c_xi, c_yi, c_zi)
194
-
195
202
  #create mask to see which cells are even
196
203
  even_mask = (c_xi + c_yi + c_zi) % 2 == 0
197
204
  # create global node index list
198
- gi = xi + yi * self.nsteps[0] + zi * self.nsteps[0] * self.nsteps[1]
205
+ # print('nsteps',self.nsteps, 'nsteps_cells', self.nsteps_cells)
206
+ # print('x',np.min(c_xi),np.max(c_xi),np.min(xi),np.max(xi))
207
+ # print('y',np.min(c_yi),np.max(c_yi),np.min(yi),np.max(yi))
208
+ # print('z',np.min(c_zi),np.max(c_zi),np.min(zi),np.max(zi))
199
209
 
210
+ gi = xi + yi * self.nsteps[0] + zi * self.nsteps[0] * self.nsteps[1]
200
211
  # container for tetras
201
212
  tetras = np.zeros((xi.shape[0], 5, 4)).astype(int)
202
213
 
@@ -207,7 +218,6 @@ class TetMesh:
207
218
  vertices_return[:] = np.nan
208
219
  # set all masks not inside to False
209
220
  mask[~inside,:] = False
210
- #print(mask.shape,inside.shape,vertices.shape,vertices_return.shape,vertices[mask,:,:].shape)
211
221
  vertices_return[inside,:,:] = vertices[mask,:,:]#[mask,:,:]#[inside,:,:]
212
222
  c_return = np.zeros((pos.shape[0],4))
213
223
  c_return[:] = np.nan
@@ -217,7 +227,7 @@ class TetMesh:
217
227
  tetra_return[inside,:] = tetras[mask,:]
218
228
  return vertices_return, c_return, tetra_return, inside
219
229
 
220
- def get_constant_gradient(self, region):
230
+ def get_constant_gradient(self, region, direction=None):
221
231
  """
222
232
  Get the constant gradient for the specified nodes
223
233
 
@@ -230,6 +240,34 @@ class TetMesh:
230
240
  -------
231
241
 
232
242
  """
243
+ """
244
+ Add the constant gradient regularisation to the system
245
+
246
+ Parameters
247
+ ----------
248
+ w (double) - weighting of the cg parameter
249
+
250
+ Returns
251
+ -------
252
+
253
+ """
254
+ if direction is not None:
255
+ print('using cg direction')
256
+ logger.info("Running constant gradient")
257
+ elements_gradients = self.get_element_gradients(np.arange(self.ntetra))
258
+ if elements_gradients.shape[0] != direction.shape[0]:
259
+ logger.error('Cannot add directional CG, vector field is not the correct length')
260
+ return
261
+ region = region.astype('int64')
262
+
263
+ neighbours = self.get_neighbours()
264
+ elements = self.get_elements()
265
+ idc, c, ncons = fold_cg(elements_gradients, direction, neighbours.astype('int64'), elements.astype('int64'), self.nodes)
266
+
267
+ idc = np.array(idc[:ncons, :])
268
+ c = np.array(c[:ncons, :])
269
+ B = np.zeros(c.shape[0])
270
+ return c, idc, B
233
271
  if self.cg is None:
234
272
  logger.info("Running constant gradient")
235
273
  elements_gradients = self.get_element_gradients(np.arange(self.ntetra))
@@ -245,7 +283,34 @@ class TetMesh:
245
283
  B = np.zeros(c.shape[0])
246
284
  self.cg = (c,idc,B)
247
285
  return self.cg[0], self.cg[1], self.cg[2]
286
+ def get_constant_norm(self, region):
287
+ """
288
+ Get the constant gradient for the specified nodes
289
+
290
+ Parameters
291
+ ----------
292
+ region : np.array(dtype=bool)
293
+ mask of nodes to calculate cg for
294
+
295
+ Returns
296
+ -------
297
+
298
+ """
299
+
300
+ logger.info("Running constant gradient")
301
+ elements_gradients = self.get_element_gradients(np.arange(self.ntetra))
302
+ region = region.astype('int64')
303
+
304
+ neighbours = self.get_neighbours()
305
+ elements = self.get_elements()
306
+ idc, c, ncons = constant_norm(elements_gradients, neighbours.astype('int64'), elements.astype('int64'), self.nodes,
307
+ region.astype('int64'))
248
308
 
309
+ idc = np.array(idc[:ncons, :])
310
+ c = np.array(c[:ncons, :])
311
+ B = np.zeros(c.shape[0])
312
+
313
+ return c,idc,B
249
314
  def get_elements(self):
250
315
  """
251
316
  Get a numpy array of all of the elements in the mesh
@@ -346,12 +411,9 @@ class TetMesh:
346
411
  vertices, bc, tetras, inside = self.get_tetra_for_location(pos)
347
412
  ps = vertices
348
413
  m = np.array(
349
- [[(ps[:, 1, 0] - ps[:, 0, 0]), (ps[:, 1, 1] - ps[:, 0, 1]),
350
- (ps[:, 1, 2] - ps[:, 0, 2])],
351
- [(ps[:, 2, 0] - ps[:, 0, 0]), (ps[:, 2, 1] - ps[:, 0, 1]),
352
- (ps[:, 2, 2] - ps[:, 0, 2])],
353
- [(ps[:, 3, 0] - ps[:, 0, 0]), (ps[:, 3, 1] - ps[:, 0, 1]),
354
- (ps[:, 3, 2] - ps[:, 0, 2])]])
414
+ [[(ps[:, 1, 0] - ps[:, 0, 0]), (ps[:, 1, 1] - ps[:, 0, 1]),(ps[:, 1, 2] - ps[:, 0, 2])],
415
+ [(ps[:, 2, 0] - ps[:, 0, 0]), (ps[:, 2, 1] - ps[:, 0, 1]),(ps[:, 2, 2] - ps[:, 0, 2])],
416
+ [(ps[:, 3, 0] - ps[:, 0, 0]), (ps[:, 3, 1] - ps[:, 0, 1]),(ps[:, 3, 2] - ps[:, 0, 2])]])
355
417
  I = np.array(
356
418
  [[-1., 1., 0., 0.],
357
419
  [-1., 0., 1., 0.],
@@ -363,25 +425,7 @@ class TetMesh:
363
425
  element_gradients = element_gradients @ I
364
426
  return vertices, element_gradients, tetras, inside
365
427
 
366
- def inside(self, pos):
367
- """
368
- Check if a point is inside the structured grid
369
-
370
- Parameters
371
- ----------
372
- pos
373
-
374
- Returns
375
- -------
376
428
 
377
- """
378
- # check whether point is inside box
379
- inside = np.ones(pos.shape[0]).astype(bool)
380
- for i in range(3):
381
- inside *= pos[:, i] > self.origin[None, i]
382
- inside *= pos[:, i] < self.origin[None, i] + \
383
- self.step_vector[None, i] * self.nsteps_cells[None, i]
384
- return inside
385
429
 
386
430
  def global_node_indicies(self, indexes):
387
431
  """