LoopStructural 1.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of LoopStructural might be problematic. Click here for more details.
- LoopStructural/__init__.py +52 -0
- LoopStructural/datasets/__init__.py +23 -0
- LoopStructural/datasets/_base.py +301 -0
- LoopStructural/datasets/_example_models.py +10 -0
- LoopStructural/datasets/data/claudius.csv +21049 -0
- LoopStructural/datasets/data/claudiusbb.txt +2 -0
- LoopStructural/datasets/data/duplex.csv +126 -0
- LoopStructural/datasets/data/duplexbb.txt +2 -0
- LoopStructural/datasets/data/fault_trace/fault_trace.cpg +1 -0
- LoopStructural/datasets/data/fault_trace/fault_trace.dbf +0 -0
- LoopStructural/datasets/data/fault_trace/fault_trace.prj +1 -0
- LoopStructural/datasets/data/fault_trace/fault_trace.shp +0 -0
- LoopStructural/datasets/data/fault_trace/fault_trace.shx +0 -0
- LoopStructural/datasets/data/geological_map_data/bbox.csv +2 -0
- LoopStructural/datasets/data/geological_map_data/contacts.csv +657 -0
- LoopStructural/datasets/data/geological_map_data/fault_displacement.csv +7 -0
- LoopStructural/datasets/data/geological_map_data/fault_edges.txt +2 -0
- LoopStructural/datasets/data/geological_map_data/fault_locations.csv +79 -0
- LoopStructural/datasets/data/geological_map_data/fault_orientations.csv +19 -0
- LoopStructural/datasets/data/geological_map_data/stratigraphic_order.csv +13 -0
- LoopStructural/datasets/data/geological_map_data/stratigraphic_orientations.csv +207 -0
- LoopStructural/datasets/data/geological_map_data/stratigraphic_thickness.csv +13 -0
- LoopStructural/datasets/data/intrusion.csv +1017 -0
- LoopStructural/datasets/data/intrusionbb.txt +2 -0
- LoopStructural/datasets/data/onefoldbb.txt +2 -0
- LoopStructural/datasets/data/onefolddata.csv +2226 -0
- LoopStructural/datasets/data/refolded_bb.txt +2 -0
- LoopStructural/datasets/data/refolded_fold.csv +205 -0
- LoopStructural/datasets/data/tabular_intrusion.csv +23 -0
- LoopStructural/datatypes/__init__.py +4 -0
- LoopStructural/datatypes/_bounding_box.py +422 -0
- LoopStructural/datatypes/_point.py +166 -0
- LoopStructural/datatypes/_structured_grid.py +94 -0
- LoopStructural/datatypes/_surface.py +184 -0
- LoopStructural/export/exporters.py +554 -0
- LoopStructural/export/file_formats.py +15 -0
- LoopStructural/export/geoh5.py +100 -0
- LoopStructural/export/gocad.py +126 -0
- LoopStructural/export/omf_wrapper.py +88 -0
- LoopStructural/interpolators/__init__.py +105 -0
- LoopStructural/interpolators/_api.py +143 -0
- LoopStructural/interpolators/_builders.py +149 -0
- LoopStructural/interpolators/_cython/__init__.py +0 -0
- LoopStructural/interpolators/_discrete_fold_interpolator.py +183 -0
- LoopStructural/interpolators/_discrete_interpolator.py +692 -0
- LoopStructural/interpolators/_finite_difference_interpolator.py +470 -0
- LoopStructural/interpolators/_geological_interpolator.py +380 -0
- LoopStructural/interpolators/_interpolator_factory.py +89 -0
- LoopStructural/interpolators/_non_linear_discrete_interpolator.py +0 -0
- LoopStructural/interpolators/_operator.py +38 -0
- LoopStructural/interpolators/_p1interpolator.py +228 -0
- LoopStructural/interpolators/_p2interpolator.py +277 -0
- LoopStructural/interpolators/_surfe_wrapper.py +174 -0
- LoopStructural/interpolators/supports/_2d_base_unstructured.py +340 -0
- LoopStructural/interpolators/supports/_2d_p1_unstructured.py +68 -0
- LoopStructural/interpolators/supports/_2d_p2_unstructured.py +288 -0
- LoopStructural/interpolators/supports/_2d_structured_grid.py +462 -0
- LoopStructural/interpolators/supports/_2d_structured_tetra.py +0 -0
- LoopStructural/interpolators/supports/_3d_base_structured.py +467 -0
- LoopStructural/interpolators/supports/_3d_p2_tetra.py +331 -0
- LoopStructural/interpolators/supports/_3d_structured_grid.py +470 -0
- LoopStructural/interpolators/supports/_3d_structured_tetra.py +746 -0
- LoopStructural/interpolators/supports/_3d_unstructured_tetra.py +637 -0
- LoopStructural/interpolators/supports/__init__.py +55 -0
- LoopStructural/interpolators/supports/_aabb.py +77 -0
- LoopStructural/interpolators/supports/_base_support.py +114 -0
- LoopStructural/interpolators/supports/_face_table.py +70 -0
- LoopStructural/interpolators/supports/_support_factory.py +32 -0
- LoopStructural/modelling/__init__.py +29 -0
- LoopStructural/modelling/core/__init__.py +0 -0
- LoopStructural/modelling/core/geological_model.py +1867 -0
- LoopStructural/modelling/features/__init__.py +32 -0
- LoopStructural/modelling/features/_analytical_feature.py +79 -0
- LoopStructural/modelling/features/_base_geological_feature.py +364 -0
- LoopStructural/modelling/features/_cross_product_geological_feature.py +100 -0
- LoopStructural/modelling/features/_geological_feature.py +288 -0
- LoopStructural/modelling/features/_lambda_geological_feature.py +93 -0
- LoopStructural/modelling/features/_region.py +18 -0
- LoopStructural/modelling/features/_structural_frame.py +186 -0
- LoopStructural/modelling/features/_unconformity_feature.py +83 -0
- LoopStructural/modelling/features/builders/__init__.py +5 -0
- LoopStructural/modelling/features/builders/_base_builder.py +111 -0
- LoopStructural/modelling/features/builders/_fault_builder.py +590 -0
- LoopStructural/modelling/features/builders/_folded_feature_builder.py +129 -0
- LoopStructural/modelling/features/builders/_geological_feature_builder.py +543 -0
- LoopStructural/modelling/features/builders/_structural_frame_builder.py +237 -0
- LoopStructural/modelling/features/fault/__init__.py +3 -0
- LoopStructural/modelling/features/fault/_fault_function.py +444 -0
- LoopStructural/modelling/features/fault/_fault_function_feature.py +82 -0
- LoopStructural/modelling/features/fault/_fault_segment.py +505 -0
- LoopStructural/modelling/features/fold/__init__.py +9 -0
- LoopStructural/modelling/features/fold/_fold.py +167 -0
- LoopStructural/modelling/features/fold/_fold_rotation_angle.py +149 -0
- LoopStructural/modelling/features/fold/_fold_rotation_angle_feature.py +67 -0
- LoopStructural/modelling/features/fold/_foldframe.py +194 -0
- LoopStructural/modelling/features/fold/_svariogram.py +188 -0
- LoopStructural/modelling/input/__init__.py +2 -0
- LoopStructural/modelling/input/fault_network.py +80 -0
- LoopStructural/modelling/input/map2loop_processor.py +165 -0
- LoopStructural/modelling/input/process_data.py +650 -0
- LoopStructural/modelling/input/project_file.py +84 -0
- LoopStructural/modelling/intrusions/__init__.py +25 -0
- LoopStructural/modelling/intrusions/geom_conceptual_models.py +142 -0
- LoopStructural/modelling/intrusions/geometric_scaling_functions.py +123 -0
- LoopStructural/modelling/intrusions/intrusion_builder.py +672 -0
- LoopStructural/modelling/intrusions/intrusion_feature.py +410 -0
- LoopStructural/modelling/intrusions/intrusion_frame_builder.py +971 -0
- LoopStructural/modelling/intrusions/intrusion_support_functions.py +460 -0
- LoopStructural/utils/__init__.py +38 -0
- LoopStructural/utils/_surface.py +143 -0
- LoopStructural/utils/_transformation.py +76 -0
- LoopStructural/utils/config.py +18 -0
- LoopStructural/utils/dtm_creator.py +17 -0
- LoopStructural/utils/exceptions.py +31 -0
- LoopStructural/utils/helper.py +292 -0
- LoopStructural/utils/json_encoder.py +18 -0
- LoopStructural/utils/linalg.py +8 -0
- LoopStructural/utils/logging.py +79 -0
- LoopStructural/utils/maths.py +245 -0
- LoopStructural/utils/regions.py +103 -0
- LoopStructural/utils/typing.py +7 -0
- LoopStructural/utils/utils.py +68 -0
- LoopStructural/version.py +1 -0
- LoopStructural/visualisation/__init__.py +11 -0
- LoopStructural-1.6.1.dist-info/LICENSE +21 -0
- LoopStructural-1.6.1.dist-info/METADATA +81 -0
- LoopStructural-1.6.1.dist-info/RECORD +129 -0
- LoopStructural-1.6.1.dist-info/WHEEL +5 -0
- LoopStructural-1.6.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cartesian grid for fold interpolator
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from ._3d_base_structured import BaseStructuredSupport
|
|
9
|
+
|
|
10
|
+
from . import SupportType
|
|
11
|
+
|
|
12
|
+
from LoopStructural.utils import getLogger
|
|
13
|
+
|
|
14
|
+
logger = getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class StructuredGrid(BaseStructuredSupport):
|
|
18
|
+
""" """
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
origin=np.zeros(3),
|
|
23
|
+
nsteps=np.array([10, 10, 10]),
|
|
24
|
+
step_vector=np.ones(3),
|
|
25
|
+
rotation_xy=None,
|
|
26
|
+
):
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
origin - 3d list or numpy array
|
|
32
|
+
nsteps - 3d list or numpy array of ints
|
|
33
|
+
step_vector - 3d list or numpy array of int
|
|
34
|
+
"""
|
|
35
|
+
BaseStructuredSupport.__init__(self, origin, nsteps, step_vector, rotation_xy=rotation_xy)
|
|
36
|
+
self.type = SupportType.StructuredGrid
|
|
37
|
+
self.regions = {}
|
|
38
|
+
self.regions["everywhere"] = np.ones(self.n_nodes).astype(bool)
|
|
39
|
+
|
|
40
|
+
def onGeometryChange(self):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def barycentre(self):
|
|
45
|
+
return self.cell_centres(np.arange(self.n_elements))
|
|
46
|
+
|
|
47
|
+
def cell_centres(self, global_index):
|
|
48
|
+
"""get the centre of specified cells
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
global_index : array/list
|
|
54
|
+
container of integer global indexes to cells
|
|
55
|
+
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
numpy array
|
|
59
|
+
Nx3 array of cell centres
|
|
60
|
+
"""
|
|
61
|
+
cell_indexes = self.global_index_to_cell_index(global_index)
|
|
62
|
+
return (
|
|
63
|
+
self.origin[None, :]
|
|
64
|
+
+ self.step_vector[None, :] * (cell_indexes)
|
|
65
|
+
+ self.step_vector[None, :] * 0.5
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def trilinear(self, local_coords):
|
|
69
|
+
"""
|
|
70
|
+
returns the trilinear interpolation for the local coordinates
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
x - double, array of doubles
|
|
74
|
+
y - double, array of doubles
|
|
75
|
+
z - double, array of doubles
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
array of interpolation coefficients
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
interpolant = np.zeros((local_coords.shape[0], 8), dtype=np.float64)
|
|
83
|
+
# interpolant[:,0] = (1 - local_coords[:, 0])* (1 - local_coords[:, 1])* (1 - local_coords[:, 2])
|
|
84
|
+
# interpolant[:,1] = local_coords[:, 0]* (1 - local_coords[:, 1])* (1 - local_coords[:, 2])
|
|
85
|
+
# interpolant[:,2] = (1 - local_coords[:, 0])* local_coords[:, 1]* (1 - local_coords[:, 2])
|
|
86
|
+
# interpolant[:,3] = (1 - local_coords[:, 0])* (1 - local_coords[:, 1])* local_coords[:, 2]
|
|
87
|
+
# interpolant[:,4] = local_coords[:, 0] * (1 - local_coords[:, 1]) * local_coords[:, 2]
|
|
88
|
+
# interpolant[:,5] = (1 - local_coords[:, 0]) * local_coords[:, 1] * local_coords[:, 2]
|
|
89
|
+
# interpolant[:,6] = local_coords[:, 0] * local_coords[:, 1] * (1 - local_coords[:, 2])
|
|
90
|
+
# interpolant[:,7] = local_coords[:, 0] * local_coords[:, 1] * local_coords[:, 2]
|
|
91
|
+
interpolant[:, 0] = (
|
|
92
|
+
(1 - local_coords[:, 0]) * (1 - local_coords[:, 1]) * (1 - local_coords[:, 2])
|
|
93
|
+
)
|
|
94
|
+
interpolant[:, 1] = local_coords[:, 0] * (1 - local_coords[:, 1]) * (1 - local_coords[:, 2])
|
|
95
|
+
interpolant[:, 2] = (1 - local_coords[:, 0]) * local_coords[:, 1] * (1 - local_coords[:, 2])
|
|
96
|
+
interpolant[:, 4] = (1 - local_coords[:, 0]) * (1 - local_coords[:, 1]) * local_coords[:, 2]
|
|
97
|
+
interpolant[:, 5] = local_coords[:, 0] * (1 - local_coords[:, 1]) * local_coords[:, 2]
|
|
98
|
+
interpolant[:, 6] = (1 - local_coords[:, 0]) * local_coords[:, 1] * local_coords[:, 2]
|
|
99
|
+
interpolant[:, 3] = local_coords[:, 0] * local_coords[:, 1] * (1 - local_coords[:, 2])
|
|
100
|
+
interpolant[:, 7] = local_coords[:, 0] * local_coords[:, 1] * local_coords[:, 2]
|
|
101
|
+
return interpolant
|
|
102
|
+
|
|
103
|
+
def position_to_local_coordinates(self, pos):
|
|
104
|
+
"""
|
|
105
|
+
Convert from global to local coordinates within a cel
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
pos - array of positions inside
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
localx, localy, localz
|
|
113
|
+
|
|
114
|
+
"""
|
|
115
|
+
# TODO check if inside mesh
|
|
116
|
+
# pos = self.rotate(pos)
|
|
117
|
+
# calculate local coordinates for positions
|
|
118
|
+
local_coords = np.zeros(pos.shape)
|
|
119
|
+
local_coords[:, 0] = (
|
|
120
|
+
(pos[:, 0] - self.origin[None, 0]) % self.step_vector[None, 0]
|
|
121
|
+
) / self.step_vector[None, 0]
|
|
122
|
+
local_coords[:, 1] = (
|
|
123
|
+
(pos[:, 1] - self.origin[None, 1]) % self.step_vector[None, 1]
|
|
124
|
+
) / self.step_vector[None, 1]
|
|
125
|
+
local_coords[:, 2] = (
|
|
126
|
+
(pos[:, 2] - self.origin[None, 2]) % self.step_vector[None, 2]
|
|
127
|
+
) / self.step_vector[None, 2]
|
|
128
|
+
return local_coords
|
|
129
|
+
|
|
130
|
+
def position_to_dof_coefs(self, pos):
|
|
131
|
+
"""
|
|
132
|
+
global posotion to interpolation coefficients
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
pos
|
|
136
|
+
|
|
137
|
+
Returns
|
|
138
|
+
-------
|
|
139
|
+
|
|
140
|
+
"""
|
|
141
|
+
local_coords = self.position_to_local_coordinates(pos)
|
|
142
|
+
weights = self.trilinear(local_coords)
|
|
143
|
+
return weights
|
|
144
|
+
|
|
145
|
+
def neighbour_global_indexes(self, mask=None, **kwargs):
|
|
146
|
+
"""
|
|
147
|
+
Get neighbour indexes
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
kwargs - indexes array specifying the cells to return neighbours
|
|
152
|
+
|
|
153
|
+
Returns
|
|
154
|
+
-------
|
|
155
|
+
|
|
156
|
+
"""
|
|
157
|
+
indexes = None
|
|
158
|
+
if "indexes" in kwargs:
|
|
159
|
+
indexes = kwargs["indexes"]
|
|
160
|
+
if "indexes" not in kwargs:
|
|
161
|
+
indexes = np.array(
|
|
162
|
+
np.meshgrid(
|
|
163
|
+
np.arange(1, self.nsteps[0] - 1),
|
|
164
|
+
np.arange(1, self.nsteps[1] - 1),
|
|
165
|
+
np.arange(1, self.nsteps[2] - 1),
|
|
166
|
+
)
|
|
167
|
+
).reshape((3, -1))
|
|
168
|
+
# indexes = np.array(indexes).T
|
|
169
|
+
if indexes.ndim != 2:
|
|
170
|
+
return
|
|
171
|
+
# determine which neighbours to return default is diagonals included.
|
|
172
|
+
if mask is None:
|
|
173
|
+
mask = np.array(
|
|
174
|
+
[
|
|
175
|
+
[
|
|
176
|
+
-1,
|
|
177
|
+
0,
|
|
178
|
+
1,
|
|
179
|
+
-1,
|
|
180
|
+
0,
|
|
181
|
+
1,
|
|
182
|
+
-1,
|
|
183
|
+
0,
|
|
184
|
+
1,
|
|
185
|
+
-1,
|
|
186
|
+
0,
|
|
187
|
+
1,
|
|
188
|
+
-1,
|
|
189
|
+
0,
|
|
190
|
+
1,
|
|
191
|
+
-1,
|
|
192
|
+
0,
|
|
193
|
+
1,
|
|
194
|
+
-1,
|
|
195
|
+
0,
|
|
196
|
+
1,
|
|
197
|
+
-1,
|
|
198
|
+
0,
|
|
199
|
+
1,
|
|
200
|
+
-1,
|
|
201
|
+
0,
|
|
202
|
+
1,
|
|
203
|
+
],
|
|
204
|
+
[
|
|
205
|
+
-1,
|
|
206
|
+
-1,
|
|
207
|
+
-1,
|
|
208
|
+
0,
|
|
209
|
+
0,
|
|
210
|
+
0,
|
|
211
|
+
1,
|
|
212
|
+
1,
|
|
213
|
+
1,
|
|
214
|
+
-1,
|
|
215
|
+
-1,
|
|
216
|
+
-1,
|
|
217
|
+
0,
|
|
218
|
+
0,
|
|
219
|
+
0,
|
|
220
|
+
1,
|
|
221
|
+
1,
|
|
222
|
+
1,
|
|
223
|
+
-1,
|
|
224
|
+
-1,
|
|
225
|
+
-1,
|
|
226
|
+
0,
|
|
227
|
+
0,
|
|
228
|
+
0,
|
|
229
|
+
1,
|
|
230
|
+
1,
|
|
231
|
+
1,
|
|
232
|
+
],
|
|
233
|
+
[
|
|
234
|
+
-1,
|
|
235
|
+
-1,
|
|
236
|
+
-1,
|
|
237
|
+
-1,
|
|
238
|
+
-1,
|
|
239
|
+
-1,
|
|
240
|
+
-1,
|
|
241
|
+
-1,
|
|
242
|
+
-1,
|
|
243
|
+
0,
|
|
244
|
+
0,
|
|
245
|
+
0,
|
|
246
|
+
0,
|
|
247
|
+
0,
|
|
248
|
+
0,
|
|
249
|
+
0,
|
|
250
|
+
0,
|
|
251
|
+
0,
|
|
252
|
+
1,
|
|
253
|
+
1,
|
|
254
|
+
1,
|
|
255
|
+
1,
|
|
256
|
+
1,
|
|
257
|
+
1,
|
|
258
|
+
1,
|
|
259
|
+
1,
|
|
260
|
+
1,
|
|
261
|
+
],
|
|
262
|
+
]
|
|
263
|
+
)
|
|
264
|
+
neighbours = indexes[:, None, :] + mask[:, :, None]
|
|
265
|
+
return (
|
|
266
|
+
neighbours[0, :, :]
|
|
267
|
+
+ self.nsteps[0, None, None] * neighbours[1, :, :]
|
|
268
|
+
+ self.nsteps[0, None, None] * self.nsteps[1, None, None] * neighbours[2, :, :]
|
|
269
|
+
).astype(np.int64)
|
|
270
|
+
|
|
271
|
+
def evaluate_value(self, evaluation_points, property_array):
|
|
272
|
+
"""
|
|
273
|
+
Evaluate the value of of the property at the locations.
|
|
274
|
+
Trilinear interpolation dot corner values
|
|
275
|
+
|
|
276
|
+
Parameters
|
|
277
|
+
----------
|
|
278
|
+
evaluation_points np array of locations
|
|
279
|
+
property_name string of property name
|
|
280
|
+
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
|
|
284
|
+
"""
|
|
285
|
+
if property_array.shape[0] != self.n_nodes:
|
|
286
|
+
logger.error("Property array does not match grid")
|
|
287
|
+
raise ValueError(
|
|
288
|
+
"cannot assign {} vlaues to array of shape {}".format(
|
|
289
|
+
property_array.shape[0], self.n_nodes
|
|
290
|
+
)
|
|
291
|
+
)
|
|
292
|
+
idc, inside = self.position_to_cell_corners(evaluation_points)
|
|
293
|
+
# print(idc[inside,:], self.n_nodes,inside)
|
|
294
|
+
|
|
295
|
+
if idc.shape[0] != inside.shape[0]:
|
|
296
|
+
raise ValueError("index does not match number of nodes")
|
|
297
|
+
v = np.zeros(idc.shape)
|
|
298
|
+
v[:, :] = np.nan
|
|
299
|
+
v[inside, :] = self.position_to_dof_coefs(evaluation_points[inside, :])
|
|
300
|
+
v[inside, :] *= property_array[idc[inside, :]]
|
|
301
|
+
return np.sum(v, axis=1)
|
|
302
|
+
|
|
303
|
+
def evaluate_gradient(self, evaluation_points, property_array) -> np.ndarray:
|
|
304
|
+
"""Evaluate the gradient at a location given node values
|
|
305
|
+
|
|
306
|
+
Parameters
|
|
307
|
+
----------
|
|
308
|
+
evaluation_points : np.array((N,3))
|
|
309
|
+
locations
|
|
310
|
+
property_array : np.array((self.nx))
|
|
311
|
+
value node, has to be the same length as the number of nodes
|
|
312
|
+
|
|
313
|
+
Returns
|
|
314
|
+
-------
|
|
315
|
+
np.array((N,3),dtype=float)
|
|
316
|
+
gradient of the implicit function at the locations
|
|
317
|
+
|
|
318
|
+
Raises
|
|
319
|
+
------
|
|
320
|
+
ValueError
|
|
321
|
+
if the array is not the same shape as the number of nodes
|
|
322
|
+
|
|
323
|
+
Notes
|
|
324
|
+
-----
|
|
325
|
+
The implicit function gradient is not normalised, to convert to
|
|
326
|
+
a unit vector normalise using vector/=np.linalg.norm(vector,axis=1)[:,None]
|
|
327
|
+
"""
|
|
328
|
+
if property_array.shape[0] != self.n_nodes:
|
|
329
|
+
logger.error("Property array does not match grid")
|
|
330
|
+
raise ValueError(
|
|
331
|
+
"cannot assign {} vlaues to array of shape {}".format(
|
|
332
|
+
property_array.shape[0], self.n_nodes
|
|
333
|
+
)
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
idc, inside = self.position_to_cell_corners(evaluation_points)
|
|
337
|
+
T = np.zeros((idc.shape[0], 3, 8))
|
|
338
|
+
T[inside, :, :] = self.get_element_gradient_for_location(evaluation_points[inside, :])[1]
|
|
339
|
+
# indices = np.array([self.position_to_cell_index(evaluation_points)])
|
|
340
|
+
# idc = self.global_indicies(indices.swapaxes(0,1))
|
|
341
|
+
# print(idc)
|
|
342
|
+
if np.max(idc[inside, :]) > property_array.shape[0]:
|
|
343
|
+
cix, ciy, ciz = self.position_to_cell_index(evaluation_points)
|
|
344
|
+
if not np.all(cix[inside] < self.nsteps_cells[0]):
|
|
345
|
+
print(
|
|
346
|
+
evaluation_points[inside, :][cix[inside] < self.nsteps_cells[0], 0],
|
|
347
|
+
self.origin[0],
|
|
348
|
+
self.maximum[0],
|
|
349
|
+
)
|
|
350
|
+
if not np.all(ciy[inside] < self.nsteps_cells[1]):
|
|
351
|
+
print(
|
|
352
|
+
evaluation_points[inside, :][ciy[inside] < self.nsteps_cells[1], 1],
|
|
353
|
+
self.origin[1],
|
|
354
|
+
self.maximum[1],
|
|
355
|
+
)
|
|
356
|
+
if not np.all(ciz[inside] < self.nsteps_cells[2]):
|
|
357
|
+
print(ciz[inside], self.nsteps_cells[2])
|
|
358
|
+
print(self.step_vector, self.nsteps_cells, self.nsteps)
|
|
359
|
+
print(
|
|
360
|
+
evaluation_points[inside, :][~(ciz[inside] < self.nsteps_cells[2]), 2],
|
|
361
|
+
self.origin[2],
|
|
362
|
+
self.maximum[2],
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
raise ValueError("index does not match number of nodes")
|
|
366
|
+
T[inside, 0, :] *= property_array[idc[inside, :]]
|
|
367
|
+
T[inside, 1, :] *= property_array[idc[inside, :]]
|
|
368
|
+
T[inside, 2, :] *= property_array[idc[inside, :]]
|
|
369
|
+
return np.array(
|
|
370
|
+
[
|
|
371
|
+
np.sum(T[:, 0, :], axis=1),
|
|
372
|
+
np.sum(T[:, 1, :], axis=1),
|
|
373
|
+
np.sum(T[:, 2, :], axis=1),
|
|
374
|
+
]
|
|
375
|
+
).T
|
|
376
|
+
|
|
377
|
+
def get_element_gradient_for_location(self, pos: np.ndarray):
|
|
378
|
+
"""
|
|
379
|
+
Get the gradient of the element at the locations.
|
|
380
|
+
|
|
381
|
+
Parameters
|
|
382
|
+
----------
|
|
383
|
+
pos : np.array((N,3),dtype=float)
|
|
384
|
+
locations
|
|
385
|
+
|
|
386
|
+
Returns
|
|
387
|
+
-------
|
|
388
|
+
vertices, gradient, element, inside
|
|
389
|
+
[description]
|
|
390
|
+
"""
|
|
391
|
+
# 6_ _ _ _ 8
|
|
392
|
+
# /| /|
|
|
393
|
+
# 4 /_| 5/ |
|
|
394
|
+
# | 2|_ _|_| 7
|
|
395
|
+
# | / | /
|
|
396
|
+
# |/_ _ _|/
|
|
397
|
+
# 0 1
|
|
398
|
+
#
|
|
399
|
+
# xindex, yindex, zindex = self.position_to_cell_index(pos)
|
|
400
|
+
# cellx, celly, cellz = self.cell_corner_indexes(xindex, yindex,zindex)
|
|
401
|
+
# x, y, z = self.node_indexes_to_position(cellx, celly, cellz)
|
|
402
|
+
pos = np.asarray(pos)
|
|
403
|
+
T = np.zeros((pos.shape[0], 3, 8))
|
|
404
|
+
local_coords = self.position_to_local_coordinates(pos)
|
|
405
|
+
vertices, inside = self.position_to_cell_vertices(pos)
|
|
406
|
+
elements, inside = self.position_to_cell_index(pos)
|
|
407
|
+
elements = self.global_cell_indices(elements)
|
|
408
|
+
|
|
409
|
+
T[:, 0, 0] = (1 - local_coords[:, 2]) * (local_coords[:, 1] - 1) # v000
|
|
410
|
+
T[:, 0, 1] = (1 - local_coords[:, 1]) * (1 - local_coords[:, 2])
|
|
411
|
+
T[:, 0, 2] = -local_coords[:, 1] * (1 - local_coords[:, 2])
|
|
412
|
+
T[:, 0, 4] = -(1 - local_coords[:, 1]) * local_coords[:, 2]
|
|
413
|
+
T[:, 0, 5] = (1 - local_coords[:, 1]) * local_coords[:, 2]
|
|
414
|
+
T[:, 0, 6] = -local_coords[:, 1] * local_coords[:, 2]
|
|
415
|
+
T[:, 0, 3] = local_coords[:, 1] * (1 - local_coords[:, 2])
|
|
416
|
+
T[:, 0, 7] = local_coords[:, 1] * local_coords[:, 2]
|
|
417
|
+
|
|
418
|
+
T[:, 1, 0] = (local_coords[:, 0] - 1) * (1 - local_coords[:, 2])
|
|
419
|
+
T[:, 1, 1] = -local_coords[:, 0] * (1 - local_coords[:, 2])
|
|
420
|
+
T[:, 1, 2] = (1 - local_coords[:, 0]) * (1 - local_coords[:, 2])
|
|
421
|
+
T[:, 1, 4] = -(1 - local_coords[:, 0]) * local_coords[:, 2]
|
|
422
|
+
T[:, 1, 5] = -local_coords[:, 0] * local_coords[:, 2]
|
|
423
|
+
T[:, 1, 6] = (1 - local_coords[:, 0]) * local_coords[:, 2]
|
|
424
|
+
T[:, 1, 3] = local_coords[:, 0] * (1 - local_coords[:, 2])
|
|
425
|
+
T[:, 1, 7] = local_coords[:, 0] * local_coords[:, 2]
|
|
426
|
+
|
|
427
|
+
T[:, 2, 0] = -(1 - local_coords[:, 0]) * (1 - local_coords[:, 1])
|
|
428
|
+
T[:, 2, 1] = -local_coords[:, 0] * (1 - local_coords[:, 1])
|
|
429
|
+
T[:, 2, 2] = -(1 - local_coords[:, 0]) * local_coords[:, 1]
|
|
430
|
+
T[:, 2, 4] = (1 - local_coords[:, 0]) * (1 - local_coords[:, 1])
|
|
431
|
+
T[:, 2, 5] = local_coords[:, 0] * (1 - local_coords[:, 1])
|
|
432
|
+
T[:, 2, 6] = (1 - local_coords[:, 0]) * local_coords[:, 1]
|
|
433
|
+
T[:, 2, 3] = -local_coords[:, 0] * local_coords[:, 1]
|
|
434
|
+
T[:, 2, 7] = local_coords[:, 0] * local_coords[:, 1]
|
|
435
|
+
T /= self.step_vector[0]
|
|
436
|
+
|
|
437
|
+
return vertices, T, elements, inside
|
|
438
|
+
|
|
439
|
+
def get_element_for_location(self, pos: np.ndarray):
|
|
440
|
+
"""Calculate the shape function of elements
|
|
441
|
+
for a location
|
|
442
|
+
|
|
443
|
+
Parameters
|
|
444
|
+
----------
|
|
445
|
+
pos : np.array((N,3))
|
|
446
|
+
location of points to calculate the shape function
|
|
447
|
+
|
|
448
|
+
Returns
|
|
449
|
+
-------
|
|
450
|
+
[type]
|
|
451
|
+
[description]
|
|
452
|
+
"""
|
|
453
|
+
vertices, inside = self.position_to_cell_vertices(pos)
|
|
454
|
+
vertices = np.array(vertices)
|
|
455
|
+
# print("ver", vertices.shape)
|
|
456
|
+
# vertices = vertices.reshape((vertices.shape[1], 8, 3))
|
|
457
|
+
elements, inside = self.position_to_cell_corners(pos)
|
|
458
|
+
elements, inside = self.position_to_cell_index(pos)
|
|
459
|
+
elements = self.global_cell_indices(elements)
|
|
460
|
+
a = self.position_to_dof_coefs(pos)
|
|
461
|
+
return vertices, a, elements, inside
|
|
462
|
+
|
|
463
|
+
def get_elements(self):
|
|
464
|
+
return
|
|
465
|
+
|
|
466
|
+
def to_dict(self):
|
|
467
|
+
return {
|
|
468
|
+
"type": self.type.numerator,
|
|
469
|
+
**super().to_dict(),
|
|
470
|
+
}
|