turbx 1.0.2__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.
turbx/grid_metric.py ADDED
@@ -0,0 +1,272 @@
1
+ import timeit
2
+
3
+ import numpy as np
4
+ from tqdm import tqdm
5
+
6
+ from .gradient import gradient
7
+ from .utils import even_print
8
+
9
+ # ======================================================================
10
+
11
+ def get_metric_tensor_2d(x2d, y2d, acc=2, edge_stencil='full', **kwargs):
12
+ '''
13
+ Compute the grid metric tensor (inverse of grid Jacobian) for a 2D grid
14
+ -----
15
+ Computational Fluid Mechanics and Heat Transfer (2012) Pletcher, Tannehill, Anderson
16
+ p.266-270, 335-337, 652
17
+ '''
18
+
19
+ verbose = kwargs.get('verbose',False)
20
+ no_warn = kwargs.get('no_warn',False)
21
+
22
+ if not isinstance(x2d, np.ndarray):
23
+ raise ValueError('x2d should be of type np.ndarray')
24
+ if not isinstance(y2d, np.ndarray):
25
+ raise ValueError('y2d should be of type np.ndarray')
26
+
27
+ if (x2d.ndim!=2):
28
+ raise ValueError('x2d should have ndim=2 (xy)')
29
+ if (y2d.ndim!=2):
30
+ raise ValueError('y2d should have ndim=2 (xy)')
31
+
32
+ if not (x2d.shape==y2d.shape):
33
+ raise ValueError('x2d.shape!=y2d.shape')
34
+
35
+ nx,ny = x2d.shape
36
+
37
+ ## the 'computational' grid (unit Cartesian)
38
+ ## --> [x_comp,y_comp]= [ξ,η] = [q1,q2]
39
+ #x_comp = np.arange(nx, dtype=np.float64)
40
+ #y_comp = np.arange(ny, dtype=np.float64)
41
+ x_comp = 1.
42
+ y_comp = 1.
43
+
44
+ # === get Jacobian :: ∂(x,y)/∂(q1,q2)
45
+
46
+ t_start = timeit.default_timer()
47
+
48
+ dxdx = gradient(x2d, x_comp, axis=0, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
49
+ dydx = gradient(y2d, x_comp, axis=0, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
50
+ dxdy = gradient(x2d, y_comp, axis=1, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
51
+ dydy = gradient(y2d, y_comp, axis=1, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
52
+
53
+ J = np.stack((np.stack((dxdx, dydx), axis=2),
54
+ np.stack((dxdy, dydy), axis=2)), axis=3)
55
+
56
+ t_delta = timeit.default_timer() - t_start
57
+ if verbose: tqdm.write( even_print('get J','%0.3f [s]'%(t_delta,), s=True) )
58
+
59
+ # === get metric tensor M = J^-1 = ∂(q1,q2)/∂(x,y) = ∂(ξ,η)/∂(x,y)
60
+
61
+ if False: ## method 1
62
+
63
+ t_start = timeit.default_timer()
64
+
65
+ M = np.linalg.inv(J)
66
+
67
+ # M_bak = np.copy(M)
68
+ # M = np.zeros((nx,ny,2,2),dtype=np.float64)
69
+ # for i in range(nx):
70
+ # for j in range(ny):
71
+ # M[i,j,:,:] = sp.linalg.inv( J[i,j,:,:] )
72
+ # np.testing.assert_allclose(M_bak, M, atol=1e-12, rtol=1e-12)
73
+ # print('check passed')
74
+
75
+ t_delta = timeit.default_timer() - t_start
76
+ if verbose: tqdm.write( even_print('get M','%0.3f [s]'%(t_delta,), s=True) )
77
+
78
+ if True: ## method 2
79
+
80
+ if ('M' in locals()):
81
+ M_bak = np.copy(M)
82
+ M = None; del M
83
+
84
+ t_start = timeit.default_timer()
85
+
86
+ ## Jacobian determinant
87
+ Jac_det = dxdx*dydy - dydx*dxdy
88
+
89
+ # Jac_det_bak = np.copy(Jac_det)
90
+ # Jac_det = None; del Jac_det
91
+ # Jac_det = np.linalg.det(J)
92
+ # np.testing.assert_allclose(Jac_det, Jac_det_bak, atol=1e-14, rtol=1e-14)
93
+ # print('check passed')
94
+
95
+ M = np.zeros((nx,ny,2,2), dtype=np.float64)
96
+ M[:,:,0,0] = +dydy / Jac_det ## ξ_x
97
+ M[:,:,0,1] = -dxdy / Jac_det ## ξ_y
98
+ M[:,:,1,0] = -dydx / Jac_det ## η_x
99
+ M[:,:,1,1] = +dxdx / Jac_det ## η_y
100
+
101
+ t_delta = timeit.default_timer() - t_start
102
+ if verbose: tqdm.write( even_print('get M','%0.3f [s]'%(t_delta,), s=True) )
103
+
104
+ if ('M_bak' in locals()):
105
+ np.testing.assert_allclose(M[:,:,0,0], M_bak[:,:,0,0], atol=1e-14, rtol=1e-14)
106
+ print('check passed: ξ_x')
107
+ np.testing.assert_allclose(M[:,:,0,1], M_bak[:,:,0,1], atol=1e-14, rtol=1e-14)
108
+ print('check passed: ξ_y')
109
+ np.testing.assert_allclose(M[:,:,1,0], M_bak[:,:,1,0], atol=1e-14, rtol=1e-14)
110
+ print('check passed: η_x')
111
+ np.testing.assert_allclose(M[:,:,1,1], M_bak[:,:,1,1], atol=1e-14, rtol=1e-14)
112
+ print('check passed: η_y')
113
+ np.testing.assert_allclose(M, M_bak, atol=1e-14, rtol=1e-14)
114
+ print('check passed: M')
115
+
116
+ return M
117
+
118
+ def get_metric_tensor_3d(x3d, y3d, z3d, acc=2, edge_stencil='full', **kwargs):
119
+ '''
120
+ Compute the grid metric tensor (inverse of grid Jacobian) for a 3D grid
121
+ -----
122
+ Computational Fluid Mechanics and Heat Transfer (2012) Pletcher, Tannehill, Anderson
123
+ p.266-270, 335-337, 652
124
+ '''
125
+
126
+ verbose = kwargs.get('verbose',False)
127
+ no_warn = kwargs.get('no_warn',False)
128
+
129
+ if not isinstance(x3d, np.ndarray):
130
+ raise ValueError('x3d should be of type np.ndarray')
131
+ if not isinstance(y3d, np.ndarray):
132
+ raise ValueError('y3d should be of type np.ndarray')
133
+ if not isinstance(z3d, np.ndarray):
134
+ raise ValueError('z3d should be of type np.ndarray')
135
+
136
+ if (x3d.ndim!=3):
137
+ raise ValueError('x3d should have ndim=3 (xyz)')
138
+ if (y3d.ndim!=3):
139
+ raise ValueError('y3d should have ndim=3 (xyz)')
140
+ if (z3d.ndim!=3):
141
+ raise ValueError('z3d should have ndim=3 (xyz)')
142
+
143
+ if not (x3d.shape==y3d.shape):
144
+ raise ValueError('x3d.shape!=y3d.shape')
145
+ if not (y3d.shape==z3d.shape):
146
+ raise ValueError('y3d.shape!=z3d.shape')
147
+
148
+ nx,ny,nz = x3d.shape
149
+
150
+ ## the 'computational' grid (unit Cartesian)
151
+ ## --> [x_comp,y_comp,z_comp ]= [ξ,η,ζ] = [q1,q2,q3]
152
+ #x_comp = np.arange(nx, dtype=np.float64)
153
+ #y_comp = np.arange(ny, dtype=np.float64)
154
+ #z_comp = np.arange(nz, dtype=np.float64)
155
+ x_comp = 1.
156
+ y_comp = 1.
157
+ z_comp = 1.
158
+
159
+ # === get Jacobian :: ∂(x,y,z)/∂(q1,q2,q3)
160
+
161
+ t_start = timeit.default_timer()
162
+
163
+ dxdx = gradient(x3d, x_comp, axis=0, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
164
+ dydx = gradient(y3d, x_comp, axis=0, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
165
+ dzdx = gradient(z3d, x_comp, axis=0, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
166
+
167
+ dxdy = gradient(x3d, y_comp, axis=1, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
168
+ dydy = gradient(y3d, y_comp, axis=1, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
169
+ dzdy = gradient(z3d, y_comp, axis=1, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
170
+
171
+ dxdz = gradient(x3d, z_comp, axis=2, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
172
+ dydz = gradient(y3d, z_comp, axis=2, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
173
+ dzdz = gradient(z3d, z_comp, axis=2, d=1, acc=acc, edge_stencil=edge_stencil, no_warn=no_warn)
174
+
175
+ J = np.stack((np.stack((dxdx, dydx, dzdx), axis=3),
176
+ np.stack((dxdy, dydy, dzdy), axis=3),
177
+ np.stack((dxdz, dydz, dzdz), axis=3)), axis=4)
178
+
179
+ t_delta = timeit.default_timer() - t_start
180
+ if verbose: tqdm.write( even_print('get J','%0.3f [s]'%(t_delta,), s=True) )
181
+
182
+ # === get metric tensor M = J^-1 = ∂(q1,q2,q3)/∂(x,y,z) = ∂(ξ,η,ζ)/∂(x,y,z)
183
+
184
+ if False: ## method 1
185
+
186
+ t_start = timeit.default_timer()
187
+
188
+ M = np.linalg.inv(J)
189
+
190
+ # M_bak = np.copy(M)
191
+ # for i in range(nx):
192
+ # for j in range(ny):
193
+ # for k in range(nz):
194
+ # M[i,j,k,:,:] = sp.linalg.inv( J[i,j,k,:,:] )
195
+ # np.testing.assert_allclose(M_bak, M, atol=1e-12, rtol=1e-12)
196
+ # print('check passed')
197
+
198
+ t_delta = timeit.default_timer() - t_start
199
+ if verbose: tqdm.write( even_print('get M','%0.3f [s]'%(t_delta,), s=True) )
200
+
201
+ if True: ## method 2
202
+
203
+ if ('M' in locals()):
204
+ M_bak = np.copy(M)
205
+ M = None; del M
206
+
207
+ t_start = timeit.default_timer()
208
+
209
+ a = J[:,:,:,0,0]
210
+ b = J[:,:,:,0,1]
211
+ c = J[:,:,:,0,2]
212
+ d = J[:,:,:,1,0]
213
+ e = J[:,:,:,1,1]
214
+ f = J[:,:,:,1,2]
215
+ g = J[:,:,:,2,0]
216
+ h = J[:,:,:,2,1]
217
+ i = J[:,:,:,2,2]
218
+
219
+ # a = J[:,:,:,0,0]
220
+ # b = J[:,:,:,1,0]
221
+ # c = J[:,:,:,2,0]
222
+ # d = J[:,:,:,0,1]
223
+ # e = J[:,:,:,1,1]
224
+ # f = J[:,:,:,2,1]
225
+ # g = J[:,:,:,0,2]
226
+ # h = J[:,:,:,1,2]
227
+ # i = J[:,:,:,2,2]
228
+
229
+ Jac_det = ( + a*e*i
230
+ + b*f*g
231
+ + c*d*h
232
+ - c*e*g
233
+ - b*d*i
234
+ - a*f*h )
235
+
236
+ M = np.zeros((nx,ny,nz,3,3), dtype=np.float64)
237
+ M[:,:,:,0,0] = +( dydy * dzdz - dydz * dzdy ) / Jac_det ## ξ_x
238
+ M[:,:,:,0,1] = -( dxdy * dzdz - dxdz * dzdy ) / Jac_det ## ξ_y
239
+ M[:,:,:,0,2] = +( dxdy * dydz - dxdz * dydy ) / Jac_det ## ξ_z
240
+ M[:,:,:,1,0] = -( dydx * dzdz - dydz * dzdx ) / Jac_det ## η_x
241
+ M[:,:,:,1,1] = +( dxdx * dzdz - dxdz * dzdx ) / Jac_det ## η_y
242
+ M[:,:,:,1,2] = -( dxdx * dydz - dxdz * dydx ) / Jac_det ## η_z
243
+ M[:,:,:,2,0] = +( dydx * dzdy - dydy * dzdx ) / Jac_det ## ζ_x
244
+ M[:,:,:,2,1] = -( dxdx * dzdy - dxdy * dzdx ) / Jac_det ## ζ_y
245
+ M[:,:,:,2,2] = +( dxdx * dydy - dxdy * dydx ) / Jac_det ## ζ_z
246
+
247
+ t_delta = timeit.default_timer() - t_start
248
+ if verbose: tqdm.write( even_print('get M','%0.3f [s]'%(t_delta,), s=True) )
249
+
250
+ if ('M_bak' in locals()):
251
+ np.testing.assert_allclose(M[:,:,:,0,0], M_bak[:,:,:,0,0], atol=1e-14, rtol=1e-14)
252
+ print('check passed: ξ_x')
253
+ np.testing.assert_allclose(M[:,:,:,0,1], M_bak[:,:,:,0,1], atol=1e-14, rtol=1e-14)
254
+ print('check passed: ξ_y')
255
+ np.testing.assert_allclose(M[:,:,:,0,2], M_bak[:,:,:,0,2], atol=1e-14, rtol=1e-14)
256
+ print('check passed: ξ_z')
257
+ np.testing.assert_allclose(M[:,:,:,1,0], M_bak[:,:,:,1,0], atol=1e-14, rtol=1e-14)
258
+ print('check passed: η_x')
259
+ np.testing.assert_allclose(M[:,:,:,1,1], M_bak[:,:,:,1,1], atol=1e-14, rtol=1e-14)
260
+ print('check passed: η_y')
261
+ np.testing.assert_allclose(M[:,:,:,1,2], M_bak[:,:,:,1,2], atol=1e-14, rtol=1e-14)
262
+ print('check passed: η_z')
263
+ np.testing.assert_allclose(M[:,:,:,2,0], M_bak[:,:,:,2,0], atol=1e-14, rtol=1e-14)
264
+ print('check passed: ζ_x')
265
+ np.testing.assert_allclose(M[:,:,:,2,1], M_bak[:,:,:,2,1], atol=1e-14, rtol=1e-14)
266
+ print('check passed: ζ_y')
267
+ np.testing.assert_allclose(M[:,:,:,2,2], M_bak[:,:,:,2,2], atol=1e-14, rtol=1e-14)
268
+ print('check passed: ζ_z')
269
+ np.testing.assert_allclose(M, M_bak, atol=1e-14, rtol=1e-14)
270
+ print('check passed: M')
271
+
272
+ return M
turbx/h5.py ADDED
@@ -0,0 +1,236 @@
1
+ import sys
2
+
3
+ import h5py
4
+ import numpy as np
5
+ from tqdm import tqdm
6
+
7
+ # ======================================================================
8
+
9
+ def h5_chunk_sizer(nxi, **kwargs):
10
+ '''
11
+ Solve for HDF5 dataset chunk size.
12
+
13
+ Parameters:
14
+ ----------
15
+ nxi : iterable
16
+ The shape of the full HDF5 dataset.
17
+ constraint : iterable
18
+ Per-axis constraint. Each element can be:
19
+ - None → flexible
20
+ - int (>0) → fixed chunk size
21
+ - 'full' or -1 → chunk size equals axis size
22
+ - ('max', int) → chunk size must be ≤ int
23
+ '''
24
+
25
+ size_kb = kwargs.get('size_kb' , 2*1024 ) ## target chunk size in [KB] --> default = 2 [MB]
26
+ itemsize = kwargs.get('itemsize' , 4 ) ## dtype.itemsize --> default single precision i.e. 4 [B]
27
+ constraint = kwargs.get('constraint' , None ) ## iterable of nxi constraints --> int,None,'full'/-1
28
+ base = kwargs.get('base' , 2 ) ## axis chunk size = ceil[size/(<int>*base)] where <int> is incremented
29
+
30
+ ## if no constraint given, all axes are fully flexible
31
+ if constraint is None:
32
+ constraint = [ None for i in range(len(nxi)) ]
33
+
34
+ ## check inputs
35
+ if not hasattr(constraint, '__iter__') or len(nxi) != len(constraint):
36
+ raise ValueError('nxi and constraint must be iterable and the same length')
37
+ if not isinstance(base,int):
38
+ raise TypeError('base must be an integer')
39
+ if (base<1):
40
+ raise TypeError('base must be an integer')
41
+
42
+ # === increment divisor on largest axis, with divisor=<int>*base
43
+
44
+ nxi = list(nxi)
45
+ div = [ 1 for i in range(len(nxi)) ] ## divisor vector, initialize with int ones
46
+
47
+ ## list of axes indices which are 'flexible' ... this is updated dynamically in loop
48
+ i_flexible = [ i for i,c in enumerate(constraint) if c is None or isinstance(c,tuple) ]
49
+
50
+ while True:
51
+
52
+ div_last = list(div) ## make a copy
53
+ #print(f'div_last = {str(tuple(div_last))}')
54
+
55
+ chunks = []
56
+ for i in range(len(nxi)):
57
+
58
+ dim = nxi[i]
59
+
60
+ if (constraint[i] is None):
61
+ C = max( int(np.floor(dim/div[i])) , 1 ) ## divide by divisor
62
+ elif (constraint[i] == 'full') or (constraint[i] == -1):
63
+ C = dim ## chunk axis shape is == dset axis shape
64
+ elif isinstance(constraint[i], int) and (constraint[i]>0):
65
+ C = constraint[i] ## chunk axis shape is just the constraint
66
+ elif isinstance(constraint[i], tuple) and (constraint[i][0]=='max') and isinstance(constraint[i][1],int):
67
+ max_val = constraint[i][1]
68
+ C = min( max( int(np.floor(dim/div[i])) , 1 ) , max_val )
69
+ else:
70
+ raise ValueError(f'problem with constraint[{i:d}] = {str(constraint[i])}')
71
+ chunks.append(C)
72
+
73
+ #print(f'chunks = {str(tuple(chunks))}')
74
+
75
+ ## recalculate i_flexible
76
+ i_flexible = []
77
+ for i,c in enumerate(constraint):
78
+ if chunks[i] == 1: ## already at min, is not flexible
79
+ continue
80
+ if c is None:
81
+ i_flexible.append(i)
82
+ elif isinstance(c,tuple) and c[0]=='max':
83
+ if chunks[i] > 1:
84
+ i_flexible.append(i)
85
+
86
+ #print(f'i_flexible = {str(i_flexible)}')
87
+
88
+ ## there are no flexible axes --> exit loop
89
+ if len(i_flexible)==0:
90
+ break
91
+
92
+ ## the current size of a chunk
93
+ chunk_size_kb = np.prod(chunks)*itemsize / 1024.
94
+ #print(f'chunk size {chunk_size_kb:0.1f} [KB] / {np.prod(chunks)*itemsize:d} [B]')
95
+
96
+ if ( chunk_size_kb <= size_kb ): ## if chunk size is < target, then break
97
+ break
98
+ else: ## otherwise, increase the divisor of the greatest 'flexible' axis
99
+
100
+ ## get index of (flexible) axis with greatest size
101
+ aa = [ i for i,c in enumerate(chunks) if (i in i_flexible) ]
102
+ bb = [ c for i,c in enumerate(chunks) if (i in i_flexible) ]
103
+ i_gt = aa[np.argmax(bb)]
104
+
105
+ ## update divisor
106
+ div[i_gt] *= base
107
+
108
+ #print(f'div = {str(tuple(div))}')
109
+ #print('---')
110
+
111
+ ## check if in infinite loop (divisor not being updated)
112
+ if (div_last is not None) and (div == div_last):
113
+ raise ValueError(f'invalid parameters for h5_chunk_sizer() : constraint={str(constraint)}, size_kb={size_kb:d}, base={base:d}')
114
+
115
+ return tuple(chunks)
116
+
117
+ def h5_visititems_print_attrs(name, obj):
118
+ '''
119
+ callable for input to h5py.Group.visititems() to print names & attributes
120
+ '''
121
+ n_slashes = name.count('/')
122
+ shift = n_slashes*2*' '
123
+ item_name = name.split('/')[-1]
124
+
125
+ if isinstance(obj,h5py._hl.dataset.Dataset):
126
+ print(shift + item_name + ' --> shape=%s, dtype=%s'%( str(obj.shape), str(obj.dtype) ) )
127
+ else:
128
+ print(shift + item_name)
129
+
130
+ ## print attributes
131
+ for key, val in obj.attrs.items():
132
+ try:
133
+ print(shift + 2*' ' + f'{key} = {str(val)} --> dtype={str(val.dtype)}')
134
+ except AttributeError:
135
+ print(shift + 2*' ' + f'{key} = {str(val)} --> type={str(type(val).__name__)}')
136
+
137
+ def h5_print_contents(h5filehandle):
138
+ '''
139
+ Print file-level attributes and recursively print names & attributes of all groups and datasets.
140
+ '''
141
+
142
+ ## file-level attributes
143
+ for key, val in h5filehandle.attrs.items():
144
+ try:
145
+ print(f'{key} = {str(val)} --> dtype={str(val.dtype)}')
146
+ except AttributeError:
147
+ print(f'{key} = {str(val)} --> type={str(type(val).__name__)}')
148
+
149
+ def visitor(name, obj):
150
+ n_slashes = name.count('/')
151
+ shift = n_slashes * 2 * ' '
152
+ item_name = name.split('/')[-1]
153
+
154
+ if isinstance(obj, h5py._hl.dataset.Dataset):
155
+ print(shift + item_name + ' --> shape=%s, dtype=%s' % (str(obj.shape), str(obj.dtype)))
156
+ else:
157
+ print(shift + item_name)
158
+
159
+ for key, val in obj.attrs.items():
160
+ try:
161
+ print(shift + 2 * ' ' + f'{key} = {str(val)} --> dtype={str(val.dtype)}')
162
+ except AttributeError:
163
+ print(shift + 2 * ' ' + f'{key} = {str(val)} --> type={str(type(val).__name__)}')
164
+
165
+ # Use the visitor function with visititems
166
+ h5filehandle.visititems(visitor)
167
+
168
+ return
169
+
170
+ class h5_visit_container:
171
+ '''
172
+ callable for input to h5py.Group.visit() which stores dataset/group names
173
+ '''
174
+ def __init__(self):
175
+ self.names = []
176
+ def __call__(self, name):
177
+ if (name not in self.names):
178
+ self.names.append(name)
179
+
180
+ def h5_ds_force_allocate_chunks(ds, verbose=False, quick=False):
181
+ '''
182
+ Force allocation of all chunks in an ND dataset by writing real data
183
+ '''
184
+ if not isinstance(ds, h5py.Dataset):
185
+ raise TypeError('ds must be a h5py.Dataset object')
186
+
187
+ shape = ds.shape
188
+ dtype = ds.dtype
189
+ chunk_shape = ds.chunks
190
+ rng = np.random.default_rng(seed=1)
191
+
192
+ ## for contiguous datasets, fill the entire array
193
+ if chunk_shape is None:
194
+ #ds[...] = np.zeros(shape, dtype=dtype) ## might lead to optimizations under the hood
195
+ #ds[...] = rng.uniform(-1,+1,size=shape).astype(dtype)
196
+ ds[...] = rng.random(size=shape, dtype=dtype)
197
+ return
198
+
199
+ ## info needed for iterating through chunks
200
+ chunk_starts = [range(0, dim, cdim) for dim, cdim in zip(shape, chunk_shape)]
201
+ chunk_grid_shape = [len(r) for r in chunk_starts]
202
+ total_chunks = np.prod(chunk_grid_shape)
203
+
204
+ if verbose:
205
+ progress_bar = tqdm(
206
+ total=total_chunks,
207
+ ncols=100,
208
+ desc='allocate chunks',
209
+ leave=True,
210
+ file=sys.stdout,
211
+ mininterval=0.1,
212
+ smoothing=0.,
213
+ #bar_format="\033[B{l_bar}{bar}| {n}/{total} [{percentage:.1f}%] {elapsed}/{remaining}\033[A\n\b",
214
+ bar_format="{l_bar}{bar}| {n}/{total} [{percentage:.1f}%] {elapsed}/{remaining}",
215
+ ascii="░█",
216
+ colour='#FF6600',
217
+ )
218
+
219
+ for chunk_idx in np.ndindex(*chunk_grid_shape):
220
+ starts = [r[i] for r, i in zip(chunk_starts, chunk_idx)]
221
+
222
+ if quick: ## just write a single element to allocate the chunk
223
+ ds[tuple(starts)] = 0
224
+ else:
225
+ slices = tuple(
226
+ slice(start, min(start + size, dim))
227
+ for start, size, dim in zip(starts, chunk_shape, shape)
228
+ )
229
+ actual_shape = tuple(slc.stop - slc.start for slc in slices)
230
+ #ds[slices] = np.zeros(actual_shape, dtype=dtype) ## might lead to optimizations under the hood
231
+ #ds[slices] = rng.uniform(-1,+1,size=actual_shape).astype(dtype)
232
+ ds[slices] = rng.random(size=actual_shape, dtype=dtype)
233
+
234
+ if verbose: progress_bar.update()
235
+ if verbose: progress_bar.close()
236
+ return