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.

Files changed (129) hide show
  1. LoopStructural/__init__.py +52 -0
  2. LoopStructural/datasets/__init__.py +23 -0
  3. LoopStructural/datasets/_base.py +301 -0
  4. LoopStructural/datasets/_example_models.py +10 -0
  5. LoopStructural/datasets/data/claudius.csv +21049 -0
  6. LoopStructural/datasets/data/claudiusbb.txt +2 -0
  7. LoopStructural/datasets/data/duplex.csv +126 -0
  8. LoopStructural/datasets/data/duplexbb.txt +2 -0
  9. LoopStructural/datasets/data/fault_trace/fault_trace.cpg +1 -0
  10. LoopStructural/datasets/data/fault_trace/fault_trace.dbf +0 -0
  11. LoopStructural/datasets/data/fault_trace/fault_trace.prj +1 -0
  12. LoopStructural/datasets/data/fault_trace/fault_trace.shp +0 -0
  13. LoopStructural/datasets/data/fault_trace/fault_trace.shx +0 -0
  14. LoopStructural/datasets/data/geological_map_data/bbox.csv +2 -0
  15. LoopStructural/datasets/data/geological_map_data/contacts.csv +657 -0
  16. LoopStructural/datasets/data/geological_map_data/fault_displacement.csv +7 -0
  17. LoopStructural/datasets/data/geological_map_data/fault_edges.txt +2 -0
  18. LoopStructural/datasets/data/geological_map_data/fault_locations.csv +79 -0
  19. LoopStructural/datasets/data/geological_map_data/fault_orientations.csv +19 -0
  20. LoopStructural/datasets/data/geological_map_data/stratigraphic_order.csv +13 -0
  21. LoopStructural/datasets/data/geological_map_data/stratigraphic_orientations.csv +207 -0
  22. LoopStructural/datasets/data/geological_map_data/stratigraphic_thickness.csv +13 -0
  23. LoopStructural/datasets/data/intrusion.csv +1017 -0
  24. LoopStructural/datasets/data/intrusionbb.txt +2 -0
  25. LoopStructural/datasets/data/onefoldbb.txt +2 -0
  26. LoopStructural/datasets/data/onefolddata.csv +2226 -0
  27. LoopStructural/datasets/data/refolded_bb.txt +2 -0
  28. LoopStructural/datasets/data/refolded_fold.csv +205 -0
  29. LoopStructural/datasets/data/tabular_intrusion.csv +23 -0
  30. LoopStructural/datatypes/__init__.py +4 -0
  31. LoopStructural/datatypes/_bounding_box.py +422 -0
  32. LoopStructural/datatypes/_point.py +166 -0
  33. LoopStructural/datatypes/_structured_grid.py +94 -0
  34. LoopStructural/datatypes/_surface.py +184 -0
  35. LoopStructural/export/exporters.py +554 -0
  36. LoopStructural/export/file_formats.py +15 -0
  37. LoopStructural/export/geoh5.py +100 -0
  38. LoopStructural/export/gocad.py +126 -0
  39. LoopStructural/export/omf_wrapper.py +88 -0
  40. LoopStructural/interpolators/__init__.py +105 -0
  41. LoopStructural/interpolators/_api.py +143 -0
  42. LoopStructural/interpolators/_builders.py +149 -0
  43. LoopStructural/interpolators/_cython/__init__.py +0 -0
  44. LoopStructural/interpolators/_discrete_fold_interpolator.py +183 -0
  45. LoopStructural/interpolators/_discrete_interpolator.py +692 -0
  46. LoopStructural/interpolators/_finite_difference_interpolator.py +470 -0
  47. LoopStructural/interpolators/_geological_interpolator.py +380 -0
  48. LoopStructural/interpolators/_interpolator_factory.py +89 -0
  49. LoopStructural/interpolators/_non_linear_discrete_interpolator.py +0 -0
  50. LoopStructural/interpolators/_operator.py +38 -0
  51. LoopStructural/interpolators/_p1interpolator.py +228 -0
  52. LoopStructural/interpolators/_p2interpolator.py +277 -0
  53. LoopStructural/interpolators/_surfe_wrapper.py +174 -0
  54. LoopStructural/interpolators/supports/_2d_base_unstructured.py +340 -0
  55. LoopStructural/interpolators/supports/_2d_p1_unstructured.py +68 -0
  56. LoopStructural/interpolators/supports/_2d_p2_unstructured.py +288 -0
  57. LoopStructural/interpolators/supports/_2d_structured_grid.py +462 -0
  58. LoopStructural/interpolators/supports/_2d_structured_tetra.py +0 -0
  59. LoopStructural/interpolators/supports/_3d_base_structured.py +467 -0
  60. LoopStructural/interpolators/supports/_3d_p2_tetra.py +331 -0
  61. LoopStructural/interpolators/supports/_3d_structured_grid.py +470 -0
  62. LoopStructural/interpolators/supports/_3d_structured_tetra.py +746 -0
  63. LoopStructural/interpolators/supports/_3d_unstructured_tetra.py +637 -0
  64. LoopStructural/interpolators/supports/__init__.py +55 -0
  65. LoopStructural/interpolators/supports/_aabb.py +77 -0
  66. LoopStructural/interpolators/supports/_base_support.py +114 -0
  67. LoopStructural/interpolators/supports/_face_table.py +70 -0
  68. LoopStructural/interpolators/supports/_support_factory.py +32 -0
  69. LoopStructural/modelling/__init__.py +29 -0
  70. LoopStructural/modelling/core/__init__.py +0 -0
  71. LoopStructural/modelling/core/geological_model.py +1867 -0
  72. LoopStructural/modelling/features/__init__.py +32 -0
  73. LoopStructural/modelling/features/_analytical_feature.py +79 -0
  74. LoopStructural/modelling/features/_base_geological_feature.py +364 -0
  75. LoopStructural/modelling/features/_cross_product_geological_feature.py +100 -0
  76. LoopStructural/modelling/features/_geological_feature.py +288 -0
  77. LoopStructural/modelling/features/_lambda_geological_feature.py +93 -0
  78. LoopStructural/modelling/features/_region.py +18 -0
  79. LoopStructural/modelling/features/_structural_frame.py +186 -0
  80. LoopStructural/modelling/features/_unconformity_feature.py +83 -0
  81. LoopStructural/modelling/features/builders/__init__.py +5 -0
  82. LoopStructural/modelling/features/builders/_base_builder.py +111 -0
  83. LoopStructural/modelling/features/builders/_fault_builder.py +590 -0
  84. LoopStructural/modelling/features/builders/_folded_feature_builder.py +129 -0
  85. LoopStructural/modelling/features/builders/_geological_feature_builder.py +543 -0
  86. LoopStructural/modelling/features/builders/_structural_frame_builder.py +237 -0
  87. LoopStructural/modelling/features/fault/__init__.py +3 -0
  88. LoopStructural/modelling/features/fault/_fault_function.py +444 -0
  89. LoopStructural/modelling/features/fault/_fault_function_feature.py +82 -0
  90. LoopStructural/modelling/features/fault/_fault_segment.py +505 -0
  91. LoopStructural/modelling/features/fold/__init__.py +9 -0
  92. LoopStructural/modelling/features/fold/_fold.py +167 -0
  93. LoopStructural/modelling/features/fold/_fold_rotation_angle.py +149 -0
  94. LoopStructural/modelling/features/fold/_fold_rotation_angle_feature.py +67 -0
  95. LoopStructural/modelling/features/fold/_foldframe.py +194 -0
  96. LoopStructural/modelling/features/fold/_svariogram.py +188 -0
  97. LoopStructural/modelling/input/__init__.py +2 -0
  98. LoopStructural/modelling/input/fault_network.py +80 -0
  99. LoopStructural/modelling/input/map2loop_processor.py +165 -0
  100. LoopStructural/modelling/input/process_data.py +650 -0
  101. LoopStructural/modelling/input/project_file.py +84 -0
  102. LoopStructural/modelling/intrusions/__init__.py +25 -0
  103. LoopStructural/modelling/intrusions/geom_conceptual_models.py +142 -0
  104. LoopStructural/modelling/intrusions/geometric_scaling_functions.py +123 -0
  105. LoopStructural/modelling/intrusions/intrusion_builder.py +672 -0
  106. LoopStructural/modelling/intrusions/intrusion_feature.py +410 -0
  107. LoopStructural/modelling/intrusions/intrusion_frame_builder.py +971 -0
  108. LoopStructural/modelling/intrusions/intrusion_support_functions.py +460 -0
  109. LoopStructural/utils/__init__.py +38 -0
  110. LoopStructural/utils/_surface.py +143 -0
  111. LoopStructural/utils/_transformation.py +76 -0
  112. LoopStructural/utils/config.py +18 -0
  113. LoopStructural/utils/dtm_creator.py +17 -0
  114. LoopStructural/utils/exceptions.py +31 -0
  115. LoopStructural/utils/helper.py +292 -0
  116. LoopStructural/utils/json_encoder.py +18 -0
  117. LoopStructural/utils/linalg.py +8 -0
  118. LoopStructural/utils/logging.py +79 -0
  119. LoopStructural/utils/maths.py +245 -0
  120. LoopStructural/utils/regions.py +103 -0
  121. LoopStructural/utils/typing.py +7 -0
  122. LoopStructural/utils/utils.py +68 -0
  123. LoopStructural/version.py +1 -0
  124. LoopStructural/visualisation/__init__.py +11 -0
  125. LoopStructural-1.6.1.dist-info/LICENSE +21 -0
  126. LoopStructural-1.6.1.dist-info/METADATA +81 -0
  127. LoopStructural-1.6.1.dist-info/RECORD +129 -0
  128. LoopStructural-1.6.1.dist-info/WHEEL +5 -0
  129. 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
+ }