resqpy 4.16.11__py3-none-any.whl → 4.17.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.
@@ -120,6 +120,7 @@ class TriMesh(rqs.Mesh):
120
120
  self.origin = None
121
121
  else:
122
122
  self.origin = origin
123
+ self.t_type = np.int32 if self.is_big() else np.int64
123
124
 
124
125
  @classmethod
125
126
  def from_tri_mesh_and_z_values(cls,
@@ -302,7 +303,7 @@ class TriMesh(rqs.Mesh):
302
303
  def tri_nodes_for_tji(self, tji):
303
304
  """Return mesh node indices, shape (3, 2), for triangle tji (tj, ti)."""
304
305
  j, i = tji
305
- tn = np.zeros((3, 2), dtype = int)
306
+ tn = np.zeros((3, 2), dtype = self.t_type)
306
307
  j_odd = j % 2
307
308
  i2, i_odd = divmod(i, 2)
308
309
  assert 0 <= j < self.nj - 1 and 0 <= i < 2 * (self.ni - 1)
@@ -325,7 +326,7 @@ class TriMesh(rqs.Mesh):
325
326
  j = tji_array[..., 0]
326
327
  i = tji_array[..., 1]
327
328
  tn_shape = tuple(list(tji_array.shape[:-1]) + [3, 2])
328
- tn = np.zeros(tn_shape, dtype = int)
329
+ tn = np.zeros(tn_shape, dtype = self.t_type)
329
330
  j_odd = j % 2
330
331
  i2, i_odd = np.divmod(i, 2)
331
332
  mask = np.logical_or(np.logical_or(j < 0, j >= self.nj - 1), np.logical_or(i < 0, i >= 2 * (self.ni - 1)))
@@ -342,9 +343,9 @@ class TriMesh(rqs.Mesh):
342
343
 
343
344
  def all_tri_nodes(self):
344
345
  """Returns array of mesh node indices for all triangles, shape (nj - 1, 2 * (ni - 1), 3, 2)."""
345
- tna = np.zeros((self.nj - 1, 2 * (self.ni - 1), 3, 2), dtype = int)
346
+ tna = np.zeros((self.nj - 1, 2 * (self.ni - 1), 3, 2), dtype = self.t_type)
346
347
  # set mesh j indices
347
- tna[:, :, 0, 0] = np.expand_dims(np.arange(self.nj - 1, dtype = int), axis = -1)
348
+ tna[:, :, 0, 0] = np.expand_dims(np.arange(self.nj - 1, dtype = self.t_type), axis = -1)
348
349
  tna[1::2, ::2, 0, 0] += 1
349
350
  tna[::2, 1::2, 0, 0] += 1
350
351
  tna[:, :, 1, 0] = tna[:, :, 0, 0]
@@ -352,7 +353,7 @@ class TriMesh(rqs.Mesh):
352
353
  tna[1::2, ::2, 2, 0] -= 2
353
354
  tna[::2, 1::2, 2, 0] -= 2
354
355
  # set mesh i indices
355
- tna[:, ::2, 0, 1] = np.expand_dims(np.arange(self.ni - 1, dtype = int), axis = 0)
356
+ tna[:, ::2, 0, 1] = np.expand_dims(np.arange(self.ni - 1, dtype = self.t_type), axis = 0)
356
357
  tna[:, 1::2, 0, 1] = tna[:, ::2, 0, 1]
357
358
  tna[:, :, 1, 1] = tna[:, :, 0, 1] + 1
358
359
  tna[:, :, 2, 1] = tna[:, :, 0, 1]
@@ -362,7 +363,7 @@ class TriMesh(rqs.Mesh):
362
363
  def triangles_and_points(self):
363
364
  """Returns node indices and xyz points in form suitable for a Surface (triangulated set)."""
364
365
  tna = self.all_tri_nodes()
365
- composite_ji = tna[:, :, :, 0] * self.ni + tna[:, :, :, 1]
366
+ composite_ji = (tna[:, :, :, 0] * self.ni + tna[:, :, :, 1]).astype(self.t_type)
366
367
  return (composite_ji.reshape((-1, 3)), self.full_array_ref().reshape((-1, 3)))
367
368
 
368
369
  def tji_for_triangle_index(self, ti):
@@ -410,7 +411,7 @@ class TriMesh(rqs.Mesh):
410
411
  tp)
411
412
  tn_a[:, 1] *= 2 # node j
412
413
 
413
- return np.concatenate((tn_a, tn_b), axis = 0)
414
+ return np.concatenate((tn_a, tn_b), axis = 0).astype(self.t_type)
414
415
 
415
416
  def edge_zero_crossings(self, z_values = None):
416
417
  """Returns numpy list of points from edges where z values cross zero (or given value).
@@ -31,6 +31,7 @@ class TriangulatedPatch:
31
31
  self.ni = None # used to convert a triangle index back into a (j, i) pair when freshly built from mesh
32
32
  self.points = None
33
33
  self.crs_uuid = crs_uuid
34
+ self.t_type = np.int32 # gets set to int64 if number of points requires it
34
35
  if patch_node is not None:
35
36
  xml_patch_index = rqet.find_tag_int(patch_node, 'PatchIndex')
36
37
  assert xml_patch_index is not None
@@ -56,52 +57,61 @@ class TriangulatedPatch:
56
57
  crs_root = self.model.root_for_uuid(self.crs_uuid)
57
58
  return crs_root, self.crs_uuid
58
59
 
59
- def triangles_and_points(self):
60
+ def triangles_and_points(self, copy = False):
60
61
  """Returns arrays representing the patch.
61
62
 
62
- Returns:
63
+ arguments:
64
+ copy (bool, default False): if True, a copy of the arrays is returned; if False, the cached
65
+ arrays are returned
66
+
67
+ returns:
63
68
  Tuple (triangles, points):
64
69
 
65
70
  * triangles (int array of shape[:, 3]): integer indices into points array,
66
71
  being the nodes of the corners of the triangles
67
72
  * points (float array of shape[:, 3]): flat array of xyz points, indexed by triangles
68
73
  """
69
- if self.triangles is not None:
74
+ if self.triangles is None:
75
+
76
+ assert self.triangle_count is not None and self.node_count is not None
77
+
78
+ geometry_node = rqet.find_tag(self.node, 'Geometry')
79
+ assert geometry_node is not None
80
+ p_root = rqet.find_tag(geometry_node, 'Points')
81
+ assert p_root is not None, 'Points xml node not found for triangle patch'
82
+ assert rqet.node_type(p_root) == 'Point3dHdf5Array'
83
+ h5_key_pair = self.model.h5_uuid_and_path_for_node(p_root, tag = 'Coordinates')
84
+ if h5_key_pair is None:
85
+ return (None, None)
86
+ try:
87
+ self.model.h5_array_element(h5_key_pair,
88
+ cache_array = True,
89
+ object = self,
90
+ array_attribute = 'points',
91
+ dtype = 'float')
92
+ except Exception:
93
+ log.error('hdf5 points failure for triangle patch ' + str(self.patch_index))
94
+ raise
95
+ self._set_t_type()
96
+ triangles_node = rqet.find_tag(self.node, 'Triangles')
97
+ h5_key_pair = self.model.h5_uuid_and_path_for_node(triangles_node)
98
+ if h5_key_pair is None:
99
+ log.warning('No Triangles found in xml for patch index: ' + str(self.patch_index))
100
+ return (None, None)
101
+ try:
102
+ self.model.h5_array_element(h5_key_pair,
103
+ cache_array = True,
104
+ object = self,
105
+ array_attribute = 'triangles',
106
+ dtype = self.t_type)
107
+ except Exception:
108
+ log.error('hdf5 triangles failure for triangle patch ' + str(self.patch_index))
109
+ raise
110
+
111
+ if copy:
112
+ return (self.triangles.copy(), self.points.copy())
113
+ else:
70
114
  return (self.triangles, self.points)
71
- assert self.triangle_count is not None and self.node_count is not None
72
-
73
- geometry_node = rqet.find_tag(self.node, 'Geometry')
74
- assert geometry_node is not None
75
- p_root = rqet.find_tag(geometry_node, 'Points')
76
- assert p_root is not None, 'Points xml node not found for triangle patch'
77
- assert rqet.node_type(p_root) == 'Point3dHdf5Array'
78
- h5_key_pair = self.model.h5_uuid_and_path_for_node(p_root, tag = 'Coordinates')
79
- if h5_key_pair is None:
80
- return (None, None)
81
- try:
82
- self.model.h5_array_element(h5_key_pair,
83
- cache_array = True,
84
- object = self,
85
- array_attribute = 'points',
86
- dtype = 'float')
87
- except Exception:
88
- log.error('hdf5 points failure for triangle patch ' + str(self.patch_index))
89
- raise
90
- triangles_node = rqet.find_tag(self.node, 'Triangles')
91
- h5_key_pair = self.model.h5_uuid_and_path_for_node(triangles_node)
92
- if h5_key_pair is None:
93
- log.warning('No Triangles found in xml for patch index: ' + str(self.patch_index))
94
- return (None, None)
95
- try:
96
- self.model.h5_array_element(h5_key_pair,
97
- cache_array = True,
98
- object = self,
99
- array_attribute = 'triangles',
100
- dtype = 'int')
101
- except Exception:
102
- log.error('hdf5 triangles failure for triangle patch ' + str(self.patch_index))
103
- raise
104
- return (self.triangles, self.points)
105
115
 
106
116
  def set_to_trimmed_patch(self, larger_patch, xyz_box = None, xy_polygon = None, internal = False):
107
117
  """Populate this (empty) patch with triangles and points that overlap with a trimming volume.
@@ -147,7 +157,7 @@ class TriangulatedPatch:
147
157
  # find unique points used by those triangles
148
158
  p_keep = np.unique(large_t[t_in])
149
159
  # note new point index for each old point that is being kept
150
- p_map = np.full(len(points_in), -1, dtype = int)
160
+ p_map = np.full(len(points_in), -1, dtype = large_t.dtype)
151
161
  p_map[p_keep] = np.arange(len(p_keep))
152
162
  # copy those unique points into a trimmed points array
153
163
  points_trimmed = large_p[p_keep]
@@ -190,10 +200,10 @@ class TriangulatedPatch:
190
200
  # create pair of triangles
191
201
  if quad_triangles:
192
202
  self.triangle_count = 4
193
- self.triangles = np.array([[0, 2, 4], [2, 1, 4], [1, 3, 4], [3, 0, 4]], dtype = int)
203
+ self.triangles = np.array([[0, 2, 4], [2, 1, 4], [1, 3, 4], [3, 0, 4]], dtype = self.t_type)
194
204
  else:
195
205
  self.triangle_count = 2
196
- self.triangles = np.array([[0, 1, 2], [0, 3, 1]], dtype = int)
206
+ self.triangles = np.array([[0, 1, 2], [0, 3, 1]], dtype = self.t_type)
197
207
 
198
208
  def set_to_triangle(self, corners):
199
209
  """Populate this (empty) patch with a single triangle."""
@@ -202,12 +212,12 @@ class TriangulatedPatch:
202
212
  self.node_count = 3
203
213
  self.points = corners.copy()
204
214
  self.triangle_count = 1
205
- self.triangles = np.array([[0, 1, 2]], dtype = int)
215
+ self.triangles = np.array([[0, 1, 2]], dtype = self.t_type)
206
216
 
207
217
  def set_to_triangle_pair(self, corners):
208
218
  """Populate this (empty) patch with a pair of triangles."""
209
219
 
210
- self.set_from_triangles_and_points(np.array([[0, 1, 3], [0, 3, 2]], dtype = int), corners)
220
+ self.set_from_triangles_and_points(np.array([[0, 1, 3], [0, 3, 2]], dtype = self.t_type), corners)
211
221
 
212
222
  def set_from_triangles_and_points(self, triangles, points):
213
223
  """Populate this (empty) patch from triangle node indices and points from elsewhere."""
@@ -240,7 +250,7 @@ class TriangulatedPatch:
240
250
  self.node_count = (n + 1) * (n + 2) // 2
241
251
  self.points = np.empty((self.node_count, 3))
242
252
  self.triangle_count = n * n
243
- self.triangles = np.empty((self.triangle_count, 3), dtype = int)
253
+ self.triangles = np.empty((self.triangle_count, 3), dtype = self.t_type)
244
254
  self.points[0] = sail_point(centre, radius, azimuth, 0.0).copy()
245
255
  p = 0
246
256
  t = 0
@@ -282,11 +292,12 @@ class TriangulatedPatch:
282
292
  quad_centres[:, :] = 0.25 * (mesh_xyz[:-1, :-1, :] + mesh_xyz[:-1, 1:, :] + mesh_xyz[1:, :-1, :] +
283
293
  mesh_xyz[1:, 1:, :]).reshape((-1, 3))
284
294
  self.points = np.concatenate((mesh_xyz.copy().reshape((-1, 3)), quad_centres))
295
+ self._set_t_type()
285
296
  mesh_size = mesh_xyz.size // 3
286
297
  self.node_count = self.points.size // 3
287
298
  self.triangle_count = 4 * (mesh_shape[0] - 1) * (mesh_shape[1] - 1)
288
299
  self.quad_triangles = True
289
- triangles = np.empty((mesh_shape[0] - 1, mesh_shape[1] - 1, 4, 3), dtype = int) # flatten later
300
+ triangles = np.empty((mesh_shape[0] - 1, mesh_shape[1] - 1, 4, 3), dtype = self.t_type) # flatten later
290
301
  nic = ni - 1
291
302
  for j in range(mesh_shape[0] - 1):
292
303
  for i in range(nic):
@@ -298,10 +309,11 @@ class TriangulatedPatch:
298
309
  triangles[j, i, 3, 2] = j * ni + i
299
310
  else:
300
311
  self.points = mesh_xyz.copy().reshape((-1, 3))
312
+ self._set_t_type()
301
313
  self.node_count = mesh_shape[0] * mesh_shape[1]
302
314
  self.triangle_count = 2 * (mesh_shape[0] - 1) * (mesh_shape[1] - 1)
303
315
  self.quad_triangles = False
304
- triangles = np.empty((mesh_shape[0] - 1, mesh_shape[1] - 1, 2, 3), dtype = int) # flatten later
316
+ triangles = np.empty((mesh_shape[0] - 1, mesh_shape[1] - 1, 2, 3), dtype = self.t_type) # flatten later
305
317
  for j in range(mesh_shape[0] - 1):
306
318
  for i in range(mesh_shape[1] - 1):
307
319
  triangles[j, i, 0, 0] = j * ni + i
@@ -321,7 +333,7 @@ class TriangulatedPatch:
321
333
 
322
334
  indices = self.get_indices_from_sparse_meshxyz(mesh_xyz)
323
335
 
324
- triangles = np.zeros((2 * (mesh_shape[0] - 1) * (mesh_shape[1] - 1), 3), dtype = int) # truncate later
336
+ triangles = np.zeros((2 * (mesh_shape[0] - 1) * (mesh_shape[1] - 1), 3), dtype = self.t_type) # truncate later
325
337
  nt = 0
326
338
  for j in range(mesh_shape[0] - 1):
327
339
  for i in range(mesh_shape[1] - 1):
@@ -357,7 +369,7 @@ class TriangulatedPatch:
357
369
  else:
358
370
  raise Exception('code failure in sparse mesh processing')
359
371
  self.ni = None
360
- self.triangles = triangles[:nt, :]
372
+ self.triangles = triangles[:nt, :].copy()
361
373
  self.triangle_count = nt
362
374
 
363
375
  def get_indices_from_sparse_meshxyz(self, mesh_xyz):
@@ -373,6 +385,7 @@ class TriangulatedPatch:
373
385
  points[i] = mesh_xyz[non_nans[0][i], non_nans[1][i]]
374
386
  indices[non_nans[0][i], non_nans[1][i]] = i
375
387
  self.points = points[:len(non_nans[0]), :]
388
+ self._set_t_type()
376
389
  self.node_count = len(non_nans[0])
377
390
 
378
391
  return indices
@@ -389,11 +402,12 @@ class TriangulatedPatch:
389
402
  quad_centres = np.empty((nj, ni, 3))
390
403
  quad_centres[:, :, :] = 0.25 * np.sum(mesh_xyz, axis = (2, 3))
391
404
  self.points = np.concatenate((mesh_xyz.copy().reshape((-1, 3)), quad_centres.reshape((-1, 3))))
405
+ self._set_t_type()
392
406
  mesh_size = mesh_xyz.size // 3
393
407
  self.node_count = 5 * nj * ni
394
408
  self.triangle_count = 4 * nj * ni
395
409
  self.quad_triangles = True
396
- triangles = np.empty((nj, ni, 4, 3), dtype = int) # flatten later
410
+ triangles = np.empty((nj, ni, 4, 3), dtype = self.t_type) # flatten later
397
411
  for j in range(nj):
398
412
  for i in range(ni):
399
413
  base_p = 4 * (j * ni + i)
@@ -405,10 +419,11 @@ class TriangulatedPatch:
405
419
  triangles[j, i, 3, 2] = base_p
406
420
  else:
407
421
  self.points = mesh_xyz.copy().reshape((-1, 3))
422
+ self._set_t_type()
408
423
  self.node_count = 4 * nj * ni
409
424
  self.triangle_count = 2 * nj * ni
410
425
  self.quad_triangles = False
411
- triangles = np.empty((nj, ni, 2, 3), dtype = int) # flatten later
426
+ triangles = np.empty((nj, ni, 2, 3), dtype = self.t_type) # flatten later
412
427
  for j in range(nj):
413
428
  for i in range(ni):
414
429
  base_p = 4 * (j * ni + i)
@@ -469,7 +484,8 @@ class TriangulatedPatch:
469
484
  self.triangle_count = 12
470
485
  self.node_count = 8
471
486
  self.points = cp.copy().reshape((-1, 3))
472
- triangles = np.empty((3, 2, 2, 3), dtype = int) # flatten later
487
+ self._set_t_type()
488
+ triangles = np.empty((3, 2, 2, 3), dtype = self.t_type) # flatten later
473
489
  for axis in range(3):
474
490
  if axis == 0:
475
491
  ip1, ip2 = 2, 1
@@ -500,7 +516,8 @@ class TriangulatedPatch:
500
516
  quad_centres[2, 1, :] = 0.25 * np.sum(cp[:, :, 1, :], axis = (0, 1)) # I+
501
517
  self.node_count = 14
502
518
  self.points = np.concatenate((cp.copy().reshape((-1, 3)), quad_centres.reshape((-1, 3))))
503
- triangles = np.empty((3, 2, 4, 3), dtype = int) # flatten later
519
+ self._set_t_type()
520
+ triangles = np.empty((3, 2, 4, 3), dtype = self.t_type) # flatten later
504
521
  for axis in range(3):
505
522
  if axis == 0:
506
523
  ip1, ip2 = 2, 1
@@ -544,3 +561,6 @@ class TriangulatedPatch:
544
561
  _, _ = self.triangles_and_points() # ensure points are loaded
545
562
  z_values = self.points[:, 2].copy()
546
563
  self.points[:, 2] = ref_depth + scaling_factor * (z_values - ref_depth)
564
+
565
+ def _set_t_type(self):
566
+ self.t_type = np.int64 if len(self.points) > 2_147_483_648 else np.int32
@@ -136,6 +136,7 @@ class BlockedWell(BaseResqpy):
136
136
  self.wellbore_interpretation = None #: associated wellbore interpretation object
137
137
  self.wellbore_feature = None #: associated wellbore feature object
138
138
  self.well_name = None #: name of well to import from ascii file formats
139
+ self.cell_index_dtype = np.int32 #: set to int64 if any grid has more than 2^31 - 1 cells, otherwise int32
139
140
 
140
141
  self.cell_interval_map = None # maps from cell index to interval (ie. node) index; populated on demand
141
142
 
@@ -150,11 +151,11 @@ class BlockedWell(BaseResqpy):
150
151
  # this is the default as indicated on page 139 (but not p. 180) of the RESQML Usage Gude v2.0.1
151
152
  # also assumes K is generally increasing downwards
152
153
  # see DevOps backlog item 269001 discussion for more information
153
- # self.face_index_map = np.array([[0, 1], [4, 2], [5, 3]], dtype = int)
154
- self.face_index_map = np.array([[0, 1], [2, 4], [5, 3]], dtype = int) # order: top, base, J-, I+, J+, I-
154
+ # self.face_index_map = np.array([[0, 1], [4, 2], [5, 3]], dtype = np.int8)
155
+ self.face_index_map = np.array([[0, 1], [2, 4], [5, 3]], dtype = np.int8) # order: top, base, J-, I+, J+, I-
155
156
  # and the inverse, maps from 0..5 to (axis, p01)
156
- # self.face_index_inverse_map = np.array([[0, 0], [0, 1], [1, 1], [2, 1], [1, 0], [2, 0]], dtype = int)
157
- self.face_index_inverse_map = np.array([[0, 0], [0, 1], [1, 0], [2, 1], [1, 1], [2, 0]], dtype = int)
157
+ # self.face_index_inverse_map = np.array([[0, 0], [0, 1], [1, 1], [2, 1], [1, 0], [2, 0]], dtype = np.int8)
158
+ self.face_index_inverse_map = np.array([[0, 0], [0, 1], [1, 0], [2, 1], [1, 1], [2, 0]], dtype = np.int8)
158
159
  # note: the rework_face_pairs() method, below, overwrites the face indices based on I, J cell indices
159
160
 
160
161
  super().__init__(model = parent_model,
@@ -238,14 +239,14 @@ class BlockedWell(BaseResqpy):
238
239
 
239
240
  assert self.cell_count < self.node_count
240
241
 
241
- self.__find_ci_node_and_load_hdf5_array(node = node)
242
-
243
- self.__find_fi_node_and_load_hdf5_array(node)
244
-
245
242
  unique_grid_indices = self.__find_gi_node_and_load_hdf5_array(node = node)
246
243
 
247
244
  self.__find_grid_node(node = node, unique_grid_indices = unique_grid_indices)
248
245
 
246
+ self.__find_ci_node_and_load_hdf5_array(node = node)
247
+
248
+ self.__find_fi_node_and_load_hdf5_array(node)
249
+
249
250
  interp_uuid = rqet.find_nested_tags_text(node, ['RepresentedInterpretation', 'UUID'])
250
251
  if interp_uuid is None:
251
252
  self.wellbore_interpretation = None
@@ -273,7 +274,7 @@ class BlockedWell(BaseResqpy):
273
274
 
274
275
  ci_node = rqet.find_tag(node, 'CellIndices')
275
276
  assert ci_node is not None, 'blocked well cell indices hdf5 reference not found in xml'
276
- rqwu.load_hdf5_array(self, ci_node, 'cell_indices', dtype = int)
277
+ rqwu.load_hdf5_array(self, ci_node, 'cell_indices', dtype = self.cell_index_dtype)
277
278
  assert (self.cell_indices is not None and self.cell_indices.ndim == 1 and
278
279
  self.cell_indices.size == self.cell_count), 'mismatch in number of cell indices for blocked well'
279
280
  self.cellind_null = rqet.find_tag_int(ci_node, 'NullValue')
@@ -285,7 +286,7 @@ class BlockedWell(BaseResqpy):
285
286
 
286
287
  fi_node = rqet.find_tag(node, 'LocalFacePairPerCellIndices')
287
288
  assert fi_node is not None, 'blocked well face indices hdf5 reference not found in xml'
288
- rqwu.load_hdf5_array(self, fi_node, 'raw_face_indices', dtype = 'int')
289
+ rqwu.load_hdf5_array(self, fi_node, 'raw_face_indices', dtype = np.int8)
289
290
  assert self.raw_face_indices is not None, 'failed to load face indices for blocked well'
290
291
  assert self.raw_face_indices.size == 2 * self.cell_count, 'mismatch in number of cell faces for blocked well'
291
292
  if self.raw_face_indices.ndim > 1:
@@ -305,15 +306,14 @@ class BlockedWell(BaseResqpy):
305
306
 
306
307
  gi_node = rqet.find_tag(node, 'GridIndices')
307
308
  assert gi_node is not None, 'blocked well grid indices hdf5 reference not found in xml'
308
- rqwu.load_hdf5_array(self, gi_node, 'grid_indices', dtype = 'int')
309
+ rqwu.load_hdf5_array(self, gi_node, 'grid_indices', dtype = np.int32)
309
310
  # assert self.grid_indices is not None and self.grid_indices.ndim == 1 and self.grid_indices.size == self.node_count - 1
310
311
  # temporary code to handle blocked wells with incorrectly shaped grid indices wrt. nodes
311
312
  assert self.grid_indices is not None and self.grid_indices.ndim == 1
312
313
  if self.grid_indices.size != self.node_count - 1:
313
314
  if self.grid_indices.size == self.cell_count and self.node_count == 2 * self.cell_count:
314
315
  log.warning(f'handling node duplication or missing unblocked intervals in blocked well: {self.title}')
315
-
316
- expanded_grid_indices = np.full(self.node_count - 1, -1, dtype = int)
316
+ expanded_grid_indices = np.full(self.node_count - 1, -1, dtype = np.int32)
317
317
  expanded_grid_indices[::2] = self.grid_indices
318
318
  self.grid_indices = expanded_grid_indices
319
319
  else:
@@ -342,6 +342,8 @@ class BlockedWell(BaseResqpy):
342
342
  grid_uuid = rqet.uuid_for_part_root(grid_node)
343
343
  grid_obj = self.model.grid(uuid = grid_uuid, find_properties = False)
344
344
  self.grid_list.append(grid_obj)
345
+ if grid_obj.is_big():
346
+ self.cell_index_dtype = np.int64
345
347
 
346
348
  def extract_property_collection(self, refresh = False):
347
349
  """Returns a property collection for the blocked well."""
@@ -434,7 +436,7 @@ class BlockedWell(BaseResqpy):
434
436
  def _set_cell_interval_map(self):
435
437
  """Sets up an index mapping from blocked cell index to interval index, accounting for unblocked intervals."""
436
438
 
437
- self.cell_interval_map = np.zeros(self.cell_count, dtype = int)
439
+ self.cell_interval_map = np.zeros(self.cell_count, dtype = np.int32)
438
440
  ci = 0
439
441
  for ii in range(self.node_count - 1):
440
442
  if self.grid_indices[ii] < 0:
@@ -461,7 +463,7 @@ class BlockedWell(BaseResqpy):
461
463
  grid_for_cell_list = []
462
464
  grid_indices = self.compressed_grid_indices()
463
465
  assert len(grid_indices) == self.cell_count
464
- cell_indices = np.empty((self.cell_count, 3), dtype = int)
466
+ cell_indices = np.empty((self.cell_count, 3), dtype = np.int32)
465
467
  for cell_number in range(self.cell_count):
466
468
  grid = self.grid_list[grid_indices[cell_number]]
467
469
  grid_for_cell_list.append(grid)
@@ -493,7 +495,7 @@ class BlockedWell(BaseResqpy):
493
495
 
494
496
  if cells_kji0 is None or len(cells_kji0) == 0:
495
497
  return None
496
- well_box = np.empty((2, 3), dtype = int)
498
+ well_box = np.empty((2, 3), dtype = np.int32)
497
499
  well_box[0] = np.min(cells_kji0, axis = 0)
498
500
  well_box[1] = np.max(cells_kji0, axis = 0)
499
501
  return well_box
@@ -853,9 +855,9 @@ class BlockedWell(BaseResqpy):
853
855
  self.node_count = len(trajectory_mds)
854
856
  self.node_mds = np.array(trajectory_mds)
855
857
  self.cell_count = len(blocked_cells_kji0)
856
- self.grid_indices = np.array(blocked_intervals, dtype = int) # NB. only supporting one grid at the moment
857
- self.cell_indices = grid.natural_cell_indices(np.array(blocked_cells_kji0))
858
- self.face_pair_indices = np.array(blocked_face_pairs, dtype = int)
858
+ self.grid_indices = np.array(blocked_intervals, dtype = np.int32) # NB. only supporting one grid at the moment
859
+ self.cell_indices = grid.natural_cell_indices(np.array(blocked_cells_kji0)).astype(self.cell_index_dtype)
860
+ self.face_pair_indices = np.array(blocked_face_pairs, dtype = np.int8)
859
861
  self.grid_list = [grid]
860
862
 
861
863
  trajectory_points, trajectory_mds = BlockedWell.__add_tail_to_trajectory_if_necessary(
@@ -877,7 +879,7 @@ class BlockedWell(BaseResqpy):
877
879
  row = df.iloc[df_row]
878
880
  if pd.isna(row[0]) or pd.isna(row[1]) or pd.isna(row[2]):
879
881
  return None
880
- cell_kji0 = np.empty((3,), dtype = int)
882
+ cell_kji0 = np.empty((3,), dtype = np.int32)
881
883
  cell_kji0[:] = row[2], row[1], row[0]
882
884
  cell_kji0[:] -= 1
883
885
  return cell_kji0
@@ -1201,9 +1203,10 @@ class BlockedWell(BaseResqpy):
1201
1203
  self.node_count = len(trajectory_mds)
1202
1204
  self.node_mds = np.array(trajectory_mds)
1203
1205
  self.cell_count = len(blocked_cells_kji0)
1204
- self.grid_indices = np.array(blocked_intervals,
1205
- dtype = int) # NB. only supporting one grid at the moment
1206
- self.cell_indices = grid.natural_cell_indices(np.array(blocked_cells_kji0))
1206
+ # NB. only supporting one grid at the moment
1207
+ self.grid_indices = np.array(blocked_intervals, dtype = np.int32)
1208
+ self.cell_indices = grid.natural_cell_indices(np.array(blocked_cells_kji0)).astype(
1209
+ self.cell_index_dtype)
1207
1210
  self.face_pair_indices = np.array(blocked_face_pairs)
1208
1211
  self.grid_list = [grid]
1209
1212
 
@@ -1240,7 +1243,7 @@ class BlockedWell(BaseResqpy):
1240
1243
  words = line.split()
1241
1244
  assert len(words) >= 9, 'not enough items on data line in cell I/O file, minimum 9 expected'
1242
1245
  i1, j1, k1 = int(words[0]), int(words[1]), int(words[2])
1243
- cell_kji0 = np.array((k1 - 1, j1 - 1, i1 - 1), dtype = int)
1246
+ cell_kji0 = np.array((k1 - 1, j1 - 1, i1 - 1), dtype = np.int32)
1244
1247
  assert np.all(0 <= cell_kji0) and np.all(
1245
1248
  cell_kji0 < grid.extent_kji), 'cell I/O cell index not within grid extent'
1246
1249
  entry_xyz = np.array((float(words[3]), float(words[4]), float(words[5])))
@@ -1511,7 +1514,7 @@ class BlockedWell(BaseResqpy):
1511
1514
  for grid in self.grid_list:
1512
1515
  grid.cache_all_geometry_arrays()
1513
1516
 
1514
- k_face_check = np.zeros((2, 2), dtype = int)
1517
+ k_face_check = np.zeros((2, 2), dtype = np.int8)
1515
1518
  k_face_check[1, 1] = 1 # now represents entry, exit of K-, K+
1516
1519
  k_face_check_end = k_face_check.copy()
1517
1520
  k_face_check_end[1] = -1 # entry through K-, terminating (TD) within cell
@@ -448,7 +448,7 @@ class Trajectory(BaseResqpy):
448
448
  """Loads the trajectory object based on the centre points of a list of cells."""
449
449
 
450
450
  assert grid is not None, 'grid argument missing for trajectory initislisation from cell list'
451
- cell_kji0_list = np.array(cell_kji0_list, dtype = int)
451
+ cell_kji0_list = np.array(cell_kji0_list, dtype = np.int32)
452
452
  assert cell_kji0_list.ndim == 2 and cell_kji0_list.shape[1] == 3
453
453
  assert spline_mode in ['none', 'linear', 'square', 'cube']
454
454
 
@@ -483,7 +483,7 @@ class Trajectory(BaseResqpy):
483
483
  df = wellspec_dict[well_name]
484
484
  assert len(df) > 0, 'no rows of perforation data found in wellspec for well ' + well_name
485
485
 
486
- cell_kji0_list = np.empty((len(df), 3), dtype = int)
486
+ cell_kji0_list = np.empty((len(df), 3), dtype = np.int32)
487
487
  cell_kji0_list[:, 0] = df['L']
488
488
  cell_kji0_list[:, 1] = df['JW']
489
489
  cell_kji0_list[:, 2] = df['IW']
@@ -191,7 +191,7 @@ def add_blocked_well_properties_from_wellbore_frame(bw,
191
191
  wb_a = np.zeros(bw.cell_count, dtype = bool)
192
192
  length = np.zeros(bw.cell_count, dtype = float)
193
193
  pperf = np.zeros(bw.cell_count, dtype = float)
194
- dominant_wbf_interval = np.full(bw.cell_count, -1, dtype = int)
194
+ dominant_wbf_interval = np.full(bw.cell_count, -1, dtype = np.int32)
195
195
  ci = 0
196
196
  for wb_ii in range(bw.node_count - 1):
197
197
  if bw.grid_indices[wb_ii] < 0:
@@ -442,10 +442,10 @@ def add_logs_from_cellio(blockedwell, cellio):
442
442
  df = df.apply(pd.to_numeric)
443
443
  # Get the cell_indices from the grid for the given i/j/k
444
444
  df['cell_indices'] = grid.natural_cell_indices(
445
- np.array((df['k_index'] - 1, df['j_index'] - 1, df['i_index'] - 1), dtype = int).T)
445
+ np.array((df['k_index'] - 1, df['j_index'] - 1, df['i_index'] - 1), dtype = np.int32).T)
446
446
  df = df.drop(['i_index', 'j_index', 'k_index', 'x_in', 'y_in', 'z_in', 'x_out', 'y_out', 'z_out'], axis = 1)
447
- assert (df['cell_indices'] == blockedwell.cell_indices
448
- ).all(), 'Cell indices do not match between blocked well and log inputs'
447
+ assert (df['cell_indices'] == blockedwell.cell_indices).all(), \
448
+ 'Cell indices do not match between blocked well and log inputs'
449
449
 
450
450
  # Work out if the data columns are continuous, categorical or discrete
451
451
  type_dict = {}
@@ -468,11 +468,11 @@ def add_logs_from_cellio(blockedwell, cellio):
468
468
  if log not in ['cell_indices']:
469
469
  data_type = type_dict[log]
470
470
  if log == 'ZONES':
471
- data_type, dtype, null, discrete = 'discrete', int, -1, True
471
+ data_type, dtype, null, discrete = 'discrete', np.int32, -1, True
472
472
  elif data_type == 'continuous':
473
473
  dtype, null, discrete = float, np.nan, False
474
474
  else:
475
- dtype, null, discrete = int, -1, True
475
+ dtype, null, discrete = np.int32, -1, True
476
476
  if data_type == 'categorical':
477
477
  lookup_uuid = lookup_dict[log] # For categorical data, find or generate a StringLookupTable
478
478
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: resqpy
3
- Version: 4.16.11
3
+ Version: 4.17.1
4
4
  Summary: Python API for working with RESQML models
5
5
  Home-page: https://github.com/bp/resqpy
6
6
  License: MIT