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/__init__.py +52 -0
- turbx/bl.py +620 -0
- turbx/blasius.py +64 -0
- turbx/cli.py +19 -0
- turbx/composite_profile.py +243 -0
- turbx/confidence_interval.py +64 -0
- turbx/eas3.py +420 -0
- turbx/eas4.py +567 -0
- turbx/fig_ax_constructor.py +52 -0
- turbx/freestream_parameters.py +268 -0
- turbx/gradient.py +391 -0
- turbx/grid_metric.py +272 -0
- turbx/h5.py +236 -0
- turbx/mvp.py +385 -0
- turbx/rgd.py +2693 -0
- turbx/rgd_mean.py +523 -0
- turbx/rgd_testing.py +354 -0
- turbx/rgd_xpln_ccor.py +701 -0
- turbx/rgd_xpln_coh.py +992 -0
- turbx/rgd_xpln_mean_dim.py +336 -0
- turbx/rgd_xpln_spectrum.py +940 -0
- turbx/rgd_xpln_stats.py +738 -0
- turbx/rgd_xpln_turb_budget.py +1193 -0
- turbx/set_mpl_env.py +85 -0
- turbx/signal.py +277 -0
- turbx/spd.py +1206 -0
- turbx/spd_wall_ccor.py +629 -0
- turbx/spd_wall_ci.py +406 -0
- turbx/spd_wall_import.py +676 -0
- turbx/spd_wall_spectrum.py +638 -0
- turbx/spd_wall_stats.py +618 -0
- turbx/utils.py +84 -0
- turbx/ztmd.py +2224 -0
- turbx/ztmd_analysis.py +2337 -0
- turbx/ztmd_loader.py +56 -0
- turbx-1.0.2.dist-info/LICENSE +21 -0
- turbx-1.0.2.dist-info/METADATA +120 -0
- turbx-1.0.2.dist-info/RECORD +41 -0
- turbx-1.0.2.dist-info/WHEEL +5 -0
- turbx-1.0.2.dist-info/entry_points.txt +2 -0
- turbx-1.0.2.dist-info/top_level.txt +1 -0
turbx/spd_wall_ccor.py
ADDED
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import timeit
|
|
4
|
+
from pathlib import Path, PurePosixPath
|
|
5
|
+
|
|
6
|
+
import h5py
|
|
7
|
+
import numpy as np
|
|
8
|
+
import scipy as sp
|
|
9
|
+
from tqdm import tqdm
|
|
10
|
+
|
|
11
|
+
from .h5 import h5_print_contents
|
|
12
|
+
from .signal import ccor, get_overlapping_window_size, get_overlapping_windows
|
|
13
|
+
from .utils import even_print, format_time_string
|
|
14
|
+
|
|
15
|
+
# ======================================================================
|
|
16
|
+
|
|
17
|
+
def _calc_ccor_wall(self, **kwargs):
|
|
18
|
+
'''
|
|
19
|
+
Calculate cross-correlation [z,t] at every [x]
|
|
20
|
+
- designed for analyzing unsteady, pre-computed wall quantities ([y] plane)
|
|
21
|
+
'''
|
|
22
|
+
|
|
23
|
+
if (self.rank==0):
|
|
24
|
+
verbose = True
|
|
25
|
+
else:
|
|
26
|
+
verbose = False
|
|
27
|
+
|
|
28
|
+
if verbose: print('\n'+'spd.calc_ccor_wall()'+'\n'+72*'-')
|
|
29
|
+
t_start_func = timeit.default_timer()
|
|
30
|
+
|
|
31
|
+
if not self.usingmpi:
|
|
32
|
+
raise NotImplementedError('function is not implemented for non-MPI usage')
|
|
33
|
+
|
|
34
|
+
h5py_is_mpi_build = h5py.h5.get_config().mpi
|
|
35
|
+
if not h5py_is_mpi_build:
|
|
36
|
+
if verbose: print('h5py was not compiled for parallel usage! exiting.')
|
|
37
|
+
sys.exit(1)
|
|
38
|
+
|
|
39
|
+
ri = kwargs.get('ri',1)
|
|
40
|
+
rj = kwargs.get('rj',1)
|
|
41
|
+
rt = kwargs.get('rt',1)
|
|
42
|
+
|
|
43
|
+
fn_h5_out = kwargs.get('fn_h5_out',None) ## filename for output HDF5 (.h5) file
|
|
44
|
+
overlap_fac_nom = kwargs.get('overlap_fac_nom',0.50) ## nominal windows overlap factor
|
|
45
|
+
n_win = kwargs.get('n_win',8) ## number of segment windows for [t] ccor calc
|
|
46
|
+
|
|
47
|
+
## check data distribution
|
|
48
|
+
if (rj!=1):
|
|
49
|
+
raise AssertionError('rj!=1')
|
|
50
|
+
if (rt!=1):
|
|
51
|
+
raise AssertionError('rt!=1')
|
|
52
|
+
if (ri*rj*rt != self.n_ranks):
|
|
53
|
+
raise AssertionError('ri*rj*rt != self.n_ranks')
|
|
54
|
+
if (ri>self.ni):
|
|
55
|
+
raise AssertionError('ri>self.ni')
|
|
56
|
+
if (self.ni%ri!=0):
|
|
57
|
+
raise AssertionError('ni currently needs to be divisible by the n ranks')
|
|
58
|
+
|
|
59
|
+
## distribute data over [i]/[x]
|
|
60
|
+
ril_ = np.array_split(np.arange(self.ni,dtype=np.int64),min(ri,self.ni))
|
|
61
|
+
ril = [[b[0],b[-1]+1] for b in ril_ ]
|
|
62
|
+
ri1,ri2 = ril[self.rank]
|
|
63
|
+
nir = ri2 - ri1
|
|
64
|
+
|
|
65
|
+
## output filename : HDF5 (.h5)
|
|
66
|
+
if (fn_h5_out is None): ## automatically determine name
|
|
67
|
+
fname_path = os.path.dirname(self.fname)
|
|
68
|
+
fname_base = os.path.basename(self.fname)
|
|
69
|
+
fname_root, fname_ext = os.path.splitext(fname_base)
|
|
70
|
+
#fname_root = re.findall(r'io\S+_mpi_[0-9]+', fname_root)[0]
|
|
71
|
+
fn_h5_out_base = fname_root+'_ccor.h5'
|
|
72
|
+
fn_h5_out = str(PurePosixPath(fname_path, fn_h5_out_base))
|
|
73
|
+
if (Path(fn_h5_out).suffix != '.h5'):
|
|
74
|
+
raise ValueError(f"fn_h5_out='{str(fn_h5_out)}' must end in .h5")
|
|
75
|
+
if os.path.isfile(fn_h5_out):
|
|
76
|
+
if (fn_h5_out == self.fname):
|
|
77
|
+
raise ValueError(f"fn_h5_out='{str(fn_h5_out)}' cannot be same as input filename.")
|
|
78
|
+
|
|
79
|
+
if verbose: even_print( 'fn_h5' , self.fname )
|
|
80
|
+
if verbose: even_print( 'fn_h5_out' , fn_h5_out )
|
|
81
|
+
if verbose: print(72*'-')
|
|
82
|
+
self.comm.Barrier()
|
|
83
|
+
|
|
84
|
+
# ===
|
|
85
|
+
|
|
86
|
+
## the data dictionary to be written to .h5 later
|
|
87
|
+
data = {}
|
|
88
|
+
|
|
89
|
+
## freestream data
|
|
90
|
+
#lchar = self.lchar ; data['lchar'] = self.lchar
|
|
91
|
+
U_inf = self.U_inf ; data['U_inf'] = self.U_inf
|
|
92
|
+
rho_inf = self.rho_inf ; data['rho_inf'] = self.rho_inf
|
|
93
|
+
T_inf = self.T_inf ; data['T_inf'] = self.T_inf
|
|
94
|
+
#mu_inf = self.mu_inf ; data['mu_inf'] = self.mu_inf
|
|
95
|
+
data['p_inf'] = self.p_inf
|
|
96
|
+
data['Ma'] = self.Ma
|
|
97
|
+
data['Pr'] = self.Pr
|
|
98
|
+
|
|
99
|
+
## read in 1D coordinate arrays & re-dimensionalize
|
|
100
|
+
x = np.copy( self['dims/x'][()] * self.lchar )
|
|
101
|
+
z = np.copy( self['dims/z'][()] * self.lchar )
|
|
102
|
+
t = np.copy( self['dims/t'][()] * self.tchar )
|
|
103
|
+
data['x'] = x
|
|
104
|
+
data['z'] = z
|
|
105
|
+
data['t'] = t
|
|
106
|
+
|
|
107
|
+
nx = self.ni
|
|
108
|
+
ni = self.ni
|
|
109
|
+
nz = self.nj
|
|
110
|
+
nj = self.nj
|
|
111
|
+
data['ni'] = ni
|
|
112
|
+
data['nx'] = nx
|
|
113
|
+
data['nj'] = nj
|
|
114
|
+
data['nz'] = nz
|
|
115
|
+
|
|
116
|
+
nt = self.nt
|
|
117
|
+
data['nt'] = nt
|
|
118
|
+
|
|
119
|
+
## assert constant Δz
|
|
120
|
+
dz0 = np.diff(z)[0]
|
|
121
|
+
if not np.all(np.isclose(np.diff(z), dz0, rtol=1e-6)):
|
|
122
|
+
raise NotImplementedError('Δz not constant')
|
|
123
|
+
|
|
124
|
+
## get Δt, dimensional [s]
|
|
125
|
+
if hasattr(self,'dt'):
|
|
126
|
+
dt = self.dt * self.tchar
|
|
127
|
+
np.testing.assert_allclose(dt, t[1]-t[0], rtol=1e-12, atol=1e-12)
|
|
128
|
+
else:
|
|
129
|
+
dt = t[1] - t[0] ## already dimensional
|
|
130
|
+
|
|
131
|
+
if hasattr(self,'duration'):
|
|
132
|
+
t_meas = self.duration * self.tchar
|
|
133
|
+
np.testing.assert_allclose(t_meas, t.max()-t.min(), rtol=1e-12, atol=1e-12)
|
|
134
|
+
else:
|
|
135
|
+
t_meas = t[-1] - t[0] ## already dimensional
|
|
136
|
+
self.duration = t_meas / self.tchar ## non-dimensionalize for attribute
|
|
137
|
+
|
|
138
|
+
zrange = z.max() - z.min()
|
|
139
|
+
|
|
140
|
+
data['t'] = t
|
|
141
|
+
data['dt'] = dt
|
|
142
|
+
data['dz'] = dz0
|
|
143
|
+
data['zrange'] = zrange
|
|
144
|
+
|
|
145
|
+
if verbose: even_print( 'Δt/tchar' , f'{dt/self.tchar:0.8f}' )
|
|
146
|
+
if verbose: even_print( 'Δt' , f'{dt:0.3e} [s]' )
|
|
147
|
+
if verbose: even_print( 'duration/tchar' , f'{self.duration:0.1f}' )
|
|
148
|
+
if verbose: even_print( 'duration' , f'{self.duration*self.tchar:0.3e} [s]' )
|
|
149
|
+
if verbose: print(72*'-')
|
|
150
|
+
|
|
151
|
+
## report
|
|
152
|
+
if verbose:
|
|
153
|
+
even_print('Δt' , f'{dt :0.5e} [s]' )
|
|
154
|
+
even_print('t_meas' , f'{t_meas:0.5e} [s]' )
|
|
155
|
+
even_print('Δz' , f'{dz0 :0.5e} [m]' )
|
|
156
|
+
even_print('zrange' , f'{zrange:0.5e} [m]' )
|
|
157
|
+
print(72*'-')
|
|
158
|
+
|
|
159
|
+
win_len, overlap = get_overlapping_window_size(nt, n_win, overlap_fac_nom)
|
|
160
|
+
overlap_fac = overlap / win_len
|
|
161
|
+
tw, n_win, n_pad = get_overlapping_windows(t, win_len, overlap)
|
|
162
|
+
t_meas_per_win = (win_len-1)*dt
|
|
163
|
+
data['win_len'] = win_len
|
|
164
|
+
data['overlap_fac'] = overlap_fac
|
|
165
|
+
data['overlap'] = overlap
|
|
166
|
+
data['n_win'] = n_win
|
|
167
|
+
data['t_meas_per_win'] = t_meas_per_win
|
|
168
|
+
|
|
169
|
+
if verbose:
|
|
170
|
+
even_print('overlap_fac (nominal)' , f'{overlap_fac_nom:0.5f}' )
|
|
171
|
+
even_print('n_win' , f'{n_win:d}' )
|
|
172
|
+
even_print('win_len' , f'{win_len:d}' )
|
|
173
|
+
even_print('overlap' , f'{overlap:d}' )
|
|
174
|
+
even_print('overlap_fac' , f'{overlap_fac:0.5f}' )
|
|
175
|
+
even_print('n_pad' , f'{n_pad:d}' )
|
|
176
|
+
#even_print('t_win/(δ99/uτ)' , '%0.3f [-]'%t_eddy_per_win )
|
|
177
|
+
print(72*'-')
|
|
178
|
+
|
|
179
|
+
## get lags [t]
|
|
180
|
+
#lags_t,_ = ccor( np.ones(nt,dtype=np.float32), np.ones(nt,dtype=np.float32), get_lags=True )
|
|
181
|
+
lags_t,_ = ccor( np.ones(win_len,dtype=np.float32), np.ones(win_len,dtype=np.float32), get_lags=True )
|
|
182
|
+
#n_lags_t_ = nt*2-1
|
|
183
|
+
n_lags_t_ = win_len*2-1
|
|
184
|
+
n_lags_t = lags_t.shape[0]
|
|
185
|
+
if (n_lags_t!=n_lags_t_):
|
|
186
|
+
raise AssertionError('check lags [t]')
|
|
187
|
+
|
|
188
|
+
data['lags_t'] = lags_t
|
|
189
|
+
data['n_lags_t'] = n_lags_t
|
|
190
|
+
|
|
191
|
+
if verbose:
|
|
192
|
+
even_print('n lags (Δt)' , '%i'%(n_lags_t,))
|
|
193
|
+
|
|
194
|
+
## get lags [z]
|
|
195
|
+
lags_z,_ = ccor( np.ones(nz,dtype=np.float32) , np.ones(nz,dtype=np.float32), get_lags=True )
|
|
196
|
+
n_lags_z_ = nz*2-1
|
|
197
|
+
n_lags_z = lags_z.shape[0]
|
|
198
|
+
if (n_lags_z!=n_lags_z_):
|
|
199
|
+
raise AssertionError('check lags [z]')
|
|
200
|
+
|
|
201
|
+
data['lags_z'] = lags_z
|
|
202
|
+
data['n_lags_z'] = n_lags_z
|
|
203
|
+
|
|
204
|
+
if verbose:
|
|
205
|
+
even_print('n lags (Δz)' , '%i'%(n_lags_z,))
|
|
206
|
+
|
|
207
|
+
# ==============================================================
|
|
208
|
+
# prepare buffers, etc.
|
|
209
|
+
# ==============================================================
|
|
210
|
+
|
|
211
|
+
do_density_weighting = False ## deactivated for now... would need implementation
|
|
212
|
+
|
|
213
|
+
## cross-correlation pairs
|
|
214
|
+
## [ str:var1, str:var2 ]
|
|
215
|
+
ccor_combis = [
|
|
216
|
+
|
|
217
|
+
[ 'u_tau' , 'u_tau' ], ## [ uτ , uτ ] --> ccor[ uτ′ , uτ′ ]
|
|
218
|
+
[ 'v_tau' , 'v_tau' ], ## [ vτ , vτ ] --> ccor[ vτ′ , vτ′ ]
|
|
219
|
+
[ 'w_tau' , 'w_tau' ], ## [ wτ , wτ ] --> ccor[ wτ′ , wτ′ ]
|
|
220
|
+
|
|
221
|
+
#[ 'u_tau' , 'v_tau' ], ## [ uτ , vτ ] --> ccor[ uτ′ , vτ′ ]
|
|
222
|
+
#[ 'u_tau' , 'w_tau' ], ## [ uτ , wτ ] --> ccor[ uτ′ , wτ′ ]
|
|
223
|
+
#[ 'v_tau' , 'w_tau' ], ## [ vτ , wτ ] --> ccor[ vτ′ , wτ′ ]
|
|
224
|
+
|
|
225
|
+
[ 'tau_uy' , 'tau_uy' ], ## [ τuy , τuy ] --> ccor[ τuy′ , τuy′ ]
|
|
226
|
+
[ 'tau_vy' , 'tau_vy' ], ## [ τvy , τvy ] --> ccor[ τvy′ , τvy′ ]
|
|
227
|
+
[ 'tau_wy' , 'tau_wy' ], ## [ τwy , τwy ] --> ccor[ τwy′ , τwy′ ]
|
|
228
|
+
|
|
229
|
+
#[ 'tau_uy' , 'tau_vy' ], ## [ τuy , τvy ] --> ccor[ τuy′ , τvy′ ]
|
|
230
|
+
#[ 'tau_uy' , 'tau_wy' ], ## [ τuy , τwy ] --> ccor[ τuy′ , τwy′ ]
|
|
231
|
+
#[ 'tau_vy' , 'tau_wy' ], ## [ τvy , τwy ] --> ccor[ τvy′ , τwy′ ]
|
|
232
|
+
|
|
233
|
+
[ 'p' , 'p' ], ## [p,p] --> ccor[ p′ , p′ ]
|
|
234
|
+
[ 'T' , 'T' ], ## [T,T] --> ccor[ T′ , T′ ]
|
|
235
|
+
[ 'rho' , 'rho' ], ## [ρ,ρ] --> ccor[ ρ′ , ρ′ ]
|
|
236
|
+
|
|
237
|
+
[ 'u_tau' , 'p' ], ## [uτ,p] --> ccor[ uτ′ , p′ ]
|
|
238
|
+
[ 'tau_uy' , 'p' ], ## [τuy,p] --> ccor[ τuy′ , p′ ]
|
|
239
|
+
|
|
240
|
+
]
|
|
241
|
+
|
|
242
|
+
## generate cross-correlation scalar names
|
|
243
|
+
scalars = []
|
|
244
|
+
for ccor_combi in ccor_combis:
|
|
245
|
+
#s1,s2,do_density_weighting = ccor_combi
|
|
246
|
+
s1,s2 = ccor_combi
|
|
247
|
+
if do_density_weighting:
|
|
248
|
+
raise NotImplementedError
|
|
249
|
+
else:
|
|
250
|
+
scalars.append(f"{s1.replace('_','')}I_{s2.replace('_','')}I")
|
|
251
|
+
|
|
252
|
+
scalars_dtypes = [ np.dtype(np.float64) for s in scalars ]
|
|
253
|
+
|
|
254
|
+
## generate AVG scalar names
|
|
255
|
+
scalars_Re_avg = []
|
|
256
|
+
#scalars_Fv_avg = []
|
|
257
|
+
for ccor_combi in ccor_combis:
|
|
258
|
+
#s1,s2,do_density_weighting = ccor_combi
|
|
259
|
+
s1,s2 = ccor_combi
|
|
260
|
+
if do_density_weighting and ('rho' not in scalars_Re_avg):
|
|
261
|
+
scalars_Re_avg.append('rho')
|
|
262
|
+
if do_density_weighting:
|
|
263
|
+
#if (s1 not in scalars_Fv_avg):
|
|
264
|
+
# scalars_Fv_avg.append(s1)
|
|
265
|
+
#if (s2 not in scalars_Fv_avg):
|
|
266
|
+
# scalars_Fv_avg.append(s2)
|
|
267
|
+
raise NotImplementedError
|
|
268
|
+
else:
|
|
269
|
+
if (s1 not in scalars_Re_avg):
|
|
270
|
+
scalars_Re_avg.append(s1)
|
|
271
|
+
if (s2 not in scalars_Re_avg):
|
|
272
|
+
scalars_Re_avg.append(s2)
|
|
273
|
+
|
|
274
|
+
## numpy formatted arrays: buffers for PSD & other data (rank-local)
|
|
275
|
+
Rz = np.zeros(shape=(nir, n_lags_z ) , dtype={'names':scalars, 'formats':scalars_dtypes})
|
|
276
|
+
Rt = np.zeros(shape=(nir, n_lags_t ) , dtype={'names':scalars, 'formats':scalars_dtypes})
|
|
277
|
+
covariance = np.zeros(shape=(nir, ) , dtype={'names':scalars, 'formats':scalars_dtypes})
|
|
278
|
+
avg_Re = np.zeros(shape=(nir, ) , dtype={'names':scalars_Re_avg, 'formats':[ np.dtype(np.float64) for s in scalars_Re_avg ]})
|
|
279
|
+
#avg_Fv = np.zeros(shape=(nir, ) , dtype={'names':scalars_Fv_avg, 'formats':[ np.dtype(np.float64) for s in scalars_Fv_avg ]})
|
|
280
|
+
|
|
281
|
+
if verbose:
|
|
282
|
+
even_print('n cross-correlation scalar combinations' , '%i'%(len(ccor_combis),))
|
|
283
|
+
print(72*'-')
|
|
284
|
+
|
|
285
|
+
## window for [z] -- rectangular because [z] is assumed periodic already
|
|
286
|
+
window_z = np.ones(nz,dtype=np.float64)
|
|
287
|
+
mean_sq_win_z = np.mean(window_z**2)
|
|
288
|
+
if verbose:
|
|
289
|
+
even_print('mean(window_z**2)', '%0.5f'%(mean_sq_win_z,))
|
|
290
|
+
|
|
291
|
+
## window function for [t]
|
|
292
|
+
window_type = None
|
|
293
|
+
if (window_type=='tukey'):
|
|
294
|
+
window_t = sp.signal.windows.tukey(win_len,alpha=0.5,sym=False) ## α=0:rectangular, α=1:Hann
|
|
295
|
+
elif (window_type=='hann'):
|
|
296
|
+
window_t = sp.signal.windows.hann(win_len,sym=False)
|
|
297
|
+
elif (window_type is None):
|
|
298
|
+
window_t = np.ones(win_len, dtype=np.float64)
|
|
299
|
+
else:
|
|
300
|
+
raise ValueError
|
|
301
|
+
|
|
302
|
+
if verbose:
|
|
303
|
+
even_print('window type [t]', '\'%s\''%str(window_type))
|
|
304
|
+
|
|
305
|
+
## Not needed for normalization for cross-correlation
|
|
306
|
+
## ... but report anyway
|
|
307
|
+
mean_sq_win_t = np.mean(window_t**2)
|
|
308
|
+
if verbose:
|
|
309
|
+
even_print('mean(window_t**2)', '%0.5f'%(mean_sq_win_t,))
|
|
310
|
+
|
|
311
|
+
# ==============================================================
|
|
312
|
+
# Main loop
|
|
313
|
+
# ==============================================================
|
|
314
|
+
|
|
315
|
+
if verbose:
|
|
316
|
+
progress_bar = tqdm(
|
|
317
|
+
total=len(ccor_combis)*nir,
|
|
318
|
+
ncols=100,
|
|
319
|
+
desc='ccor',
|
|
320
|
+
leave=True,
|
|
321
|
+
file=sys.stdout,
|
|
322
|
+
mininterval=0.1,
|
|
323
|
+
smoothing=0.,
|
|
324
|
+
#bar_format="\033[B{l_bar}{bar}| {n}/{total} [{percentage:.1f}%] {elapsed}/{remaining}\033[A\n\b",
|
|
325
|
+
bar_format="{l_bar}{bar}| {n}/{total} [{percentage:.1f}%] {elapsed}/{remaining}",
|
|
326
|
+
ascii="░█",
|
|
327
|
+
colour='#FF6600',
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
for cci,cc in enumerate(ccor_combis): ## ccor pairs
|
|
331
|
+
|
|
332
|
+
if verbose: tqdm.write(72*'-')
|
|
333
|
+
|
|
334
|
+
scalar_L, scalar_R = cc
|
|
335
|
+
|
|
336
|
+
msg = f'ccor[{scalar_L}′,{scalar_R}′]'
|
|
337
|
+
if verbose:
|
|
338
|
+
tqdm.write(even_print('computing',msg,s=True,))
|
|
339
|
+
|
|
340
|
+
dset_L = self[f'data/{scalar_L}']
|
|
341
|
+
dset_R = self[f'data/{scalar_R}']
|
|
342
|
+
data_gb_1x = self.n_ranks * 1 * self.nj * self.nt * dset_L.dtype.itemsize / 1024**3
|
|
343
|
+
|
|
344
|
+
scalar = scalars[cci]
|
|
345
|
+
|
|
346
|
+
## assert scalar name
|
|
347
|
+
scalar_ = f"{scalar_L.replace('_','')}I_{scalar_R.replace('_','')}I"
|
|
348
|
+
if (scalar != scalar_):
|
|
349
|
+
raise ValueError
|
|
350
|
+
|
|
351
|
+
## assert scalar name
|
|
352
|
+
if do_density_weighting:
|
|
353
|
+
#if (f'r{scalar_L}II_r{scalar_R}II' != scalar ):
|
|
354
|
+
# raise ValueError
|
|
355
|
+
raise NotImplementedError
|
|
356
|
+
else:
|
|
357
|
+
if (f"{scalar_L.replace('_','')}I_{scalar_R.replace('_','')}I" != scalar ):
|
|
358
|
+
raise ValueError
|
|
359
|
+
|
|
360
|
+
## [x] loop --> each rank works on part of global [x]/[i] range
|
|
361
|
+
for ii in range(ri1,ri2):
|
|
362
|
+
|
|
363
|
+
iii = ii - ri1 ## [x] index local
|
|
364
|
+
|
|
365
|
+
data_L = np.zeros( (nz,nt) , dtype=np.float64 )
|
|
366
|
+
data_R = np.zeros( (nz,nt) , dtype=np.float64 )
|
|
367
|
+
|
|
368
|
+
self.comm.Barrier()
|
|
369
|
+
t_start = timeit.default_timer()
|
|
370
|
+
|
|
371
|
+
## read data L
|
|
372
|
+
n_scalars_read = 1 ## initialize
|
|
373
|
+
scalar_str = scalar_L ## initialize
|
|
374
|
+
with dset_L.collective:
|
|
375
|
+
data_L[:,:] = np.copy( dset_L[ii,:,:] ).astype(np.float64)
|
|
376
|
+
self.comm.Barrier()
|
|
377
|
+
|
|
378
|
+
## read data R (if != data L)
|
|
379
|
+
if (scalar_L==scalar_R):
|
|
380
|
+
data_R[:,:] = np.copy( data_L )
|
|
381
|
+
else:
|
|
382
|
+
n_scalars_read += 1
|
|
383
|
+
scalar_str += f',{scalar_R}'
|
|
384
|
+
with dset_R.collective:
|
|
385
|
+
data_R[:,:] = np.copy( dset_R[ii,:,:] ).astype(np.float64)
|
|
386
|
+
self.comm.Barrier()
|
|
387
|
+
|
|
388
|
+
self.comm.Barrier()
|
|
389
|
+
t_delta = timeit.default_timer() - t_start
|
|
390
|
+
data_gb = data_gb_1x * n_scalars_read
|
|
391
|
+
|
|
392
|
+
if verbose:
|
|
393
|
+
tqdm.write(even_print(f'read: {scalar_str}', f'{data_gb:0.3f} [GB] {t_delta:0.3f} [s] {data_gb/t_delta:0.3f} [GB/s]', s=True))
|
|
394
|
+
|
|
395
|
+
## data_L and data_R shape should be (nz,nt)
|
|
396
|
+
if ( data_L.shape != (nz,nt) ) or ( data_R.shape != (nz,nt) ):
|
|
397
|
+
print(f'rank {self.rank:d}: shape violation')
|
|
398
|
+
self.comm.Abort(1)
|
|
399
|
+
|
|
400
|
+
# === redimensionalize
|
|
401
|
+
|
|
402
|
+
if scalar_L in ['tau_uy','tau_vy','tau_wy',]:
|
|
403
|
+
data_L *= rho_inf * U_inf**2
|
|
404
|
+
elif scalar_L in ['u_tau','v_tau','w_tau',]:
|
|
405
|
+
data_L *= U_inf
|
|
406
|
+
elif scalar_L in ['p',]:
|
|
407
|
+
data_L *= rho_inf * U_inf**2
|
|
408
|
+
elif scalar_L in ['T',]:
|
|
409
|
+
data_L *= T_inf
|
|
410
|
+
elif scalar_L in ['rho',]:
|
|
411
|
+
data_L *= rho_inf
|
|
412
|
+
else:
|
|
413
|
+
raise ValueError
|
|
414
|
+
|
|
415
|
+
if scalar_R in ['tau_uy','tau_vy','tau_wy',]:
|
|
416
|
+
data_R *= rho_inf * U_inf**2
|
|
417
|
+
elif scalar_R in ['u_tau','v_tau','w_tau',]:
|
|
418
|
+
data_R *= U_inf
|
|
419
|
+
elif scalar_R in ['p',]:
|
|
420
|
+
data_R *= rho_inf * U_inf**2
|
|
421
|
+
elif scalar_R in ['T',]:
|
|
422
|
+
data_R *= T_inf
|
|
423
|
+
elif scalar_R in ['rho',]:
|
|
424
|
+
data_R *= rho_inf
|
|
425
|
+
else:
|
|
426
|
+
raise ValueError
|
|
427
|
+
|
|
428
|
+
## data_L and data_R shape should be (nz,nt)
|
|
429
|
+
if ( data_L.shape != (nz,nt) ) or ( data_R.shape != (nz,nt) ):
|
|
430
|
+
print(f'rank {self.rank:d}: shape violation')
|
|
431
|
+
self.comm.Abort(1)
|
|
432
|
+
|
|
433
|
+
# === compute mean-removed data
|
|
434
|
+
|
|
435
|
+
## avg(□) or avg(ρ·□)/avg(ρ) in [t]
|
|
436
|
+
if do_density_weighting:
|
|
437
|
+
#rho_avg = np.mean( rho , axis=-1, dtype=np.float64, keepdims=True)
|
|
438
|
+
#data_L_avg = np.mean( rho*data_L , axis=-1, dtype=np.float64, keepdims=True)
|
|
439
|
+
#data_L_avg /= rho_avg
|
|
440
|
+
#data_R_avg = np.mean( rho*data_R , axis=-1, dtype=np.float64, keepdims=True)
|
|
441
|
+
#data_R_avg /= rho_avg
|
|
442
|
+
raise NotImplementedError
|
|
443
|
+
else:
|
|
444
|
+
data_L_avg = np.mean( data_L , axis=-1, dtype=np.float64, keepdims=True) ## (nz,1)
|
|
445
|
+
data_R_avg = np.mean( data_R , axis=-1, dtype=np.float64, keepdims=True) ## (nz,1)
|
|
446
|
+
|
|
447
|
+
## data_L_avg and data_R_avg shape should be (nz,1)
|
|
448
|
+
if ( data_L_avg.shape != (nz,1) ) or ( data_R_avg.shape != (nz,1) ):
|
|
449
|
+
print(f'rank {self.rank:d}: shape violation')
|
|
450
|
+
self.comm.Abort(1)
|
|
451
|
+
|
|
452
|
+
## Reynolds prime □′ or Favre prime □″ --> shape (nz,nt)
|
|
453
|
+
data_L -= data_L_avg
|
|
454
|
+
data_R -= data_R_avg
|
|
455
|
+
|
|
456
|
+
## data_L and data_R shape should be (nz,nt)
|
|
457
|
+
if ( data_L.shape != (nz,nt) ) or ( data_R.shape != (nz,nt) ):
|
|
458
|
+
print(f'rank {self.rank:d}: shape violation')
|
|
459
|
+
self.comm.Abort(1)
|
|
460
|
+
|
|
461
|
+
## assert stationarity / definition averaging
|
|
462
|
+
## avg(□′)==0 or avg(ρ·□″)==0
|
|
463
|
+
if do_density_weighting:
|
|
464
|
+
#a_ = np.mean(rho*data_L, axis=-1, dtype=np.float64, keepdims=True)
|
|
465
|
+
#b_ = np.mean(rho*data_R, axis=-1, dtype=np.float64, keepdims=True)
|
|
466
|
+
raise NotImplementedError
|
|
467
|
+
else:
|
|
468
|
+
a_ = np.mean(data_L, axis=-1, dtype=np.float64, keepdims=True) ## average in [t] --> (nz,1)
|
|
469
|
+
b_ = np.mean(data_R, axis=-1, dtype=np.float64, keepdims=True)
|
|
470
|
+
if not np.allclose( a_, np.zeros_like(a_), atol=1e-6 ) or not np.allclose( b_, np.zeros_like(b_), atol=1e-6 ):
|
|
471
|
+
print(f'rank {self.rank:d}: avg(□′)!=0 or avg(ρ·□″)!=0')
|
|
472
|
+
self.comm.Abort(1)
|
|
473
|
+
|
|
474
|
+
## covariance: <□′□′>
|
|
475
|
+
if do_density_weighting:
|
|
476
|
+
#covariance_ = np.mean( rho*data_L * rho*data_R , axis=-1 , dtype=np.float64, keepdims=True)
|
|
477
|
+
raise NotImplementedError
|
|
478
|
+
else:
|
|
479
|
+
covariance_ = np.mean( data_L*data_R , axis=-1 , dtype=np.float64, keepdims=True) ## average in [t] --> (nz,1)
|
|
480
|
+
|
|
481
|
+
if ( covariance_.shape != (nz,1) ):
|
|
482
|
+
print(f'rank {self.rank:d}: shape violation')
|
|
483
|
+
self.comm.Abort(1)
|
|
484
|
+
|
|
485
|
+
## write this chunk/scalar's covariance to covariance buffer
|
|
486
|
+
## avg over [z,t] --> np.float64()
|
|
487
|
+
covariance[scalar][iii] = np.mean( covariance_ , axis=(0,1) , dtype=np.float64)
|
|
488
|
+
|
|
489
|
+
## write (rank-local) 1D [x] average
|
|
490
|
+
if do_density_weighting:
|
|
491
|
+
#avg_Fv[scalar_L][iii] = np.mean( data_L_avg , axis=(0,1) , dtype=np.float64) )
|
|
492
|
+
#avg_Fv[scalar_R][iii] = np.mean( data_R_avg , axis=(0,1) , dtype=np.float64) )
|
|
493
|
+
#avg_Re['rho'][iii] = np.mean( rho_avg , axis=(0,1) , dtype=np.float64) )
|
|
494
|
+
raise ValueError
|
|
495
|
+
else:
|
|
496
|
+
avg_Re[scalar_L][iii] = np.mean( data_L_avg , axis=(0,1) , dtype=np.float64)
|
|
497
|
+
avg_Re[scalar_R][iii] = np.mean( data_R_avg , axis=(0,1) , dtype=np.float64)
|
|
498
|
+
|
|
499
|
+
# ===============================================================================
|
|
500
|
+
# At this point you have 4D [x,y,z,t] □′ data
|
|
501
|
+
# ===============================================================================
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
## do [z] cross-correlation for every [t]
|
|
505
|
+
Rz_buf = np.zeros((nt,n_lags_z), dtype=np.float64)
|
|
506
|
+
for ti in range(nt):
|
|
507
|
+
uL = np.copy( data_L[:,ti] )
|
|
508
|
+
uR = np.copy( data_R[:,ti] )
|
|
509
|
+
Rz_buf[ti,:] = ccor(uL,uR)
|
|
510
|
+
|
|
511
|
+
Rz[scalar][iii,:] = np.mean(Rz_buf, axis=0, dtype=np.float64) ## mean across [t] --> (n_lags_z,)
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
## ## do [t] cross-correlation for every [z]
|
|
515
|
+
## Rt_buf = np.zeros((nz,n_lags_t), dtype=np.float64)
|
|
516
|
+
## for zi in range(nz):
|
|
517
|
+
## uL = np.copy( data_L[zi,:] )
|
|
518
|
+
## uR = np.copy( data_R[zi,:] )
|
|
519
|
+
## Rt_buf[zi,:] = ccor(uL,uR)
|
|
520
|
+
##
|
|
521
|
+
## Rt[scalar][iii,:] = np.mean(Rt_buf, axis=0, dtype=np.float64) ## mean across [z] --> (n_lags_t,)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
## do [t] cross-correlation for every [z]
|
|
525
|
+
Rt_buf = np.zeros((nz,n_lags_t), dtype=np.float64)
|
|
526
|
+
for zi in range(nz):
|
|
527
|
+
uL = np.copy( data_L[zi,:] )
|
|
528
|
+
uR = np.copy( data_R[zi,:] )
|
|
529
|
+
#Rt_buf[zi,:] = ccor(uL,uR)
|
|
530
|
+
|
|
531
|
+
uL_, nw, n_pad = get_overlapping_windows(uL, win_len, overlap)
|
|
532
|
+
uR_, nw, n_pad = get_overlapping_windows(uR, win_len, overlap)
|
|
533
|
+
|
|
534
|
+
## Per-segment buffer
|
|
535
|
+
Rt_buf_win = np.zeros((nw,n_lags_t), dtype=np.float64)
|
|
536
|
+
for wi in range(nw):
|
|
537
|
+
A1 = np.copy( uL_[wi,:] * window_t )
|
|
538
|
+
A2 = np.copy( uR_[wi,:] * window_t )
|
|
539
|
+
Rt_buf_win[wi,:] = ccor(A1,A2)
|
|
540
|
+
Rt_buf[zi,:] = np.mean(Rt_buf_win, axis=0, dtype=np.float64) ## mean across windows --> (n_lags_t,)
|
|
541
|
+
|
|
542
|
+
Rt[scalar][iii,:] = np.mean(Rt_buf, axis=0, dtype=np.float64) ## mean across [z] --> (n_lags_t,)
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
self.comm.Barrier() ## [x] loop ('ii' within this rank's range)
|
|
546
|
+
if verbose: progress_bar.update()
|
|
547
|
+
|
|
548
|
+
#break ## DEBUG
|
|
549
|
+
#break ## DEBUG
|
|
550
|
+
|
|
551
|
+
self.comm.Barrier()
|
|
552
|
+
if verbose:
|
|
553
|
+
progress_bar.close()
|
|
554
|
+
print(72*'-')
|
|
555
|
+
|
|
556
|
+
# ==============================================================
|
|
557
|
+
# Write HDF5 (.h5) file
|
|
558
|
+
# ==============================================================
|
|
559
|
+
|
|
560
|
+
## Overwrite outfile!
|
|
561
|
+
## - first, open on rank 0 and to write attributes and initialize datasets
|
|
562
|
+
if (self.rank==0):
|
|
563
|
+
with h5py.File(fn_h5_out, 'w') as hfw:
|
|
564
|
+
|
|
565
|
+
## write floats,ints as top-level attributes
|
|
566
|
+
for key,val in data.items():
|
|
567
|
+
if isinstance(data[key], (int,np.int32,np.int64)):
|
|
568
|
+
hfw.attrs[key] = val
|
|
569
|
+
elif isinstance(data[key], (float,np.float32,np.float64)):
|
|
570
|
+
hfw.attrs[key] = val
|
|
571
|
+
elif isinstance(data[key], np.ndarray):
|
|
572
|
+
pass
|
|
573
|
+
else:
|
|
574
|
+
print(f'key {key} is type {str(type(data[key]))}')
|
|
575
|
+
self.comm.Abort(1)
|
|
576
|
+
|
|
577
|
+
## write numpy arrays
|
|
578
|
+
hfw.create_dataset( 'dims/x' , data=x ) ## [m]
|
|
579
|
+
hfw.create_dataset( 'dims/z' , data=z ) ## [m]
|
|
580
|
+
hfw.create_dataset( 'dims/t' , data=t ) ## [s]
|
|
581
|
+
hfw.create_dataset( 'dims/lags_z' , data=lags_z )
|
|
582
|
+
hfw.create_dataset( 'dims/lags_t' , data=lags_t )
|
|
583
|
+
|
|
584
|
+
## initialize datasets : covariance,Rz,Rt
|
|
585
|
+
for scalar in scalars:
|
|
586
|
+
hfw.create_dataset( f'covariance/{scalar}' , shape=(nx,) , dtype=np.float64 , chunks=None , data=np.full((nx,),0.,np.float64) )
|
|
587
|
+
hfw.create_dataset( f'Rz/{scalar}' , shape=(nx,n_lags_z) , dtype=np.float64 , chunks=(1,n_lags_z) , data=np.full((nx,n_lags_z),0.,np.float64) )
|
|
588
|
+
hfw.create_dataset( f'Rt/{scalar}' , shape=(nx,n_lags_t) , dtype=np.float64 , chunks=(1,n_lags_t) , data=np.full((nx,n_lags_t),0.,np.float64) )
|
|
589
|
+
|
|
590
|
+
## initialize datasets : 1D [x] mean
|
|
591
|
+
for scalar in avg_Re.dtype.names:
|
|
592
|
+
hfw.create_dataset( f'avg/Re/{scalar}', shape=(nx,), dtype=np.float64, chunks=None, data=np.full((nx,),0.,np.float64) )
|
|
593
|
+
|
|
594
|
+
self.comm.Barrier()
|
|
595
|
+
|
|
596
|
+
## re-open in parallel for data writes
|
|
597
|
+
with h5py.File(fn_h5_out, 'a', driver='mpio', comm=self.comm) as hfw:
|
|
598
|
+
|
|
599
|
+
## collectively write covariance,Rz,Rt
|
|
600
|
+
for scalar in scalars:
|
|
601
|
+
dset = hfw[f'covariance/{scalar}']
|
|
602
|
+
with dset.collective:
|
|
603
|
+
dset[ri1:ri2] = covariance[scalar][:]
|
|
604
|
+
dset = hfw[f'Rz/{scalar}']
|
|
605
|
+
with dset.collective:
|
|
606
|
+
dset[ri1:ri2,:] = Rz[scalar][:,:]
|
|
607
|
+
dset = hfw[f'Rt/{scalar}']
|
|
608
|
+
with dset.collective:
|
|
609
|
+
dset[ri1:ri2,:] = Rt[scalar][:,:]
|
|
610
|
+
|
|
611
|
+
## collectively write 1D [z] avgs
|
|
612
|
+
for scalar in avg_Re.dtype.names:
|
|
613
|
+
dset = hfw[f'avg/Re/{scalar}']
|
|
614
|
+
with dset.collective:
|
|
615
|
+
dset[ri1:ri2] = avg_Re[scalar][:]
|
|
616
|
+
|
|
617
|
+
## report file contents
|
|
618
|
+
self.comm.Barrier()
|
|
619
|
+
if (self.rank==0):
|
|
620
|
+
even_print( os.path.basename(fn_h5_out) , f'{(os.path.getsize(fn_h5_out)/1024**2):0.1f} [MB]' )
|
|
621
|
+
print(72*'-')
|
|
622
|
+
with h5py.File(fn_h5_out,'r') as hfr:
|
|
623
|
+
h5_print_contents(hfr)
|
|
624
|
+
self.comm.Barrier()
|
|
625
|
+
|
|
626
|
+
if verbose: print(72*'-')
|
|
627
|
+
if verbose: print('total time : spd.calc_ccor_wall() : %s'%format_time_string((timeit.default_timer() - t_start_func)))
|
|
628
|
+
if verbose: print(72*'-')
|
|
629
|
+
return
|