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.
@@ -0,0 +1,336 @@
1
+ import os
2
+ import timeit
3
+
4
+ import numpy as np
5
+ import scipy as sp
6
+
7
+ from .bl import calc_bl_integral_quantities_1d, calc_d99_1d, calc_profile_edge_1d
8
+ from .gradient import gradient
9
+ from .utils import even_print, format_time_string
10
+
11
+ # ======================================================================
12
+
13
+ def _add_mean_dimensional_data_xpln(self, **kwargs):
14
+ '''
15
+ Get dimensionalized mean data for [x] plane
16
+ --> save to existing RGD file with fsubtype=mean
17
+ - assumes volume which is thin in [x] direction
18
+ - an RGD which is the output of rgd.get_mean() should be opened here
19
+ - NOT parallel!!
20
+ '''
21
+
22
+ verbose = kwargs.get('verbose',True)
23
+ epsilon = kwargs.get('epsilon',5e-5)
24
+ acc = kwargs.get('acc',6)
25
+ edge_stencil = kwargs.get('edge_stencil','full')
26
+
27
+ if (self.rank==0):
28
+ verbose = True
29
+ else:
30
+ verbose = False
31
+
32
+ if verbose: print('\n'+'rgd.add_mean_dimensional_data_xpln()'+'\n'+72*'-')
33
+ t_start_func = timeit.default_timer()
34
+
35
+ ## this func is not parallel
36
+ if self.usingmpi:
37
+ raise NotImplementedError('rgd.add_mean_dimensional_data_xpln() is not a parallel function')
38
+
39
+ ## 'r' and 'w' open modes are not allowed
40
+ if not (self.open_mode=='a') or (self.open_mode=='r+'):
41
+ raise ValueError(f'open mode is {self.open_mode}')
42
+
43
+ ## assert that this is a mean flow file ( i.e. output from rgd.get_mean() )
44
+ if (self.fsubtype!='mean'):
45
+ print(self.fsubtype)
46
+ raise ValueError
47
+
48
+ ## get size of infile
49
+ fsize = os.path.getsize(self.fname)/1024**3
50
+ if verbose: even_print(os.path.basename(self.fname),'%0.1f [GB]'%fsize)
51
+ if verbose: even_print('nx','%i'%self.nx)
52
+ if verbose: even_print('ny','%i'%self.ny)
53
+ if verbose: even_print('nz','%i'%self.nz)
54
+ if verbose: even_print('nt','%i'%self.nt)
55
+ if verbose: even_print('ngp','%0.1f [M]'%(self.ngp/1e6,))
56
+ if verbose: print(72*'-')
57
+
58
+ ## read in 1D coordinate arrays, then dimensionalize [m]
59
+ x = np.copy( self['dims/x'][()] * self.lchar )
60
+ y = np.copy( self['dims/y'][()] * self.lchar )
61
+ z = np.copy( self['dims/z'][()] * self.lchar )
62
+
63
+ if (x.ndim!=1):
64
+ raise ValueError
65
+ if (y.ndim!=1):
66
+ raise ValueError
67
+ if (z.ndim!=1):
68
+ raise ValueError
69
+
70
+ ## check if constant Δz (calculate Δz+ later)
71
+ dz0 = np.diff(z)[0]
72
+ if not np.all(np.isclose(np.diff(z), dz0, rtol=1e-7)):
73
+ raise NotImplementedError
74
+
75
+ ## check if mean rgd has attr 'dt'
76
+ if ('dt' in self.attrs.keys()):
77
+ dt = self.attrs['dt']
78
+ if (dt is not None):
79
+ dt *= self.tchar
80
+ else:
81
+ raise ValueError
82
+
83
+ if verbose: even_print('Δt/tchar','%0.8f'%(dt/self.tchar))
84
+ if verbose: even_print('Δt','%0.3e [s]'%(dt,))
85
+ if verbose: even_print('duration/tchar','%0.1f'%(self.duration_avg,))
86
+ if verbose: even_print('duration','%0.3e [s]'%(self.duration_avg*self.tchar,))
87
+ if verbose: print(72*'-')
88
+
89
+ ## re-dimensionalize
90
+ u = np.copy( self.U_inf * self['data/u'][()].T )
91
+ v = np.copy( self.U_inf * self['data/v'][()].T )
92
+ w = np.copy( self.U_inf * self['data/w'][()].T )
93
+ rho = np.copy( self.rho_inf * self['data/rho'][()].T )
94
+ p = np.copy( (self.rho_inf * self.U_inf**2) * self['data/p'][()].T )
95
+ T = np.copy( self.T_inf * self['data/T'][()].T )
96
+
97
+ # mu1 = np.copy( self.C_Suth * T**(3/2) / (T + self.S_Suth) )
98
+ # mu2 = np.copy( self.mu_Suth_ref * ( T / self.T_Suth_ref )**(3/2) * ((self.T_Suth_ref+self.S_Suth)/(T+self.S_Suth)) )
99
+ # np.testing.assert_allclose(mu1, mu2, rtol=2e-7, atol=2e-7)
100
+ # mu = np.copy(mu2)
101
+
102
+ mu = np.copy( self.C_Suth * T**(3/2) / (T + self.S_Suth) )
103
+ nu = np.copy( mu / rho )
104
+
105
+ # === average in [x,z] --> leave 1D [y]
106
+
107
+ u = np.squeeze( np.mean( u , axis=(0,2), dtype=np.float64) )
108
+ v = np.squeeze( np.mean( v , axis=(0,2), dtype=np.float64) )
109
+ w = np.squeeze( np.mean( w , axis=(0,2), dtype=np.float64) )
110
+ rho = np.squeeze( np.mean( rho , axis=(0,2), dtype=np.float64) )
111
+ p = np.squeeze( np.mean( p , axis=(0,2), dtype=np.float64) )
112
+ T = np.squeeze( np.mean( T , axis=(0,2), dtype=np.float64) )
113
+ mu = np.squeeze( np.mean( mu , axis=(0,2), dtype=np.float64) )
114
+ nu = np.squeeze( np.mean( nu , axis=(0,2), dtype=np.float64) )
115
+
116
+ # ## determine finite difference order / size of central stencil based on [nx]
117
+ # if (nx<3):
118
+ # raise ValueError('dx[] not possible because nx<3')
119
+ # elif (nx>=3) and (nx<5):
120
+ # acc = 2
121
+ # elif (nx>=5) and (nx<7):
122
+ # acc = 4
123
+ # elif (nx>=7):
124
+ # acc = 6
125
+ # else:
126
+ # raise ValueError('this should never happen')
127
+
128
+ if verbose: even_print('acc','%i'%acc)
129
+ if verbose: even_print('edge_stencil',edge_stencil)
130
+ if verbose: print(72*'-')
131
+
132
+ ## get [y] gradients --> size [y]
133
+ ddy_u = gradient(u , y, axis=0, acc=acc, edge_stencil=edge_stencil, d=1)
134
+ ddy_v = gradient(v , y, axis=0, acc=acc, edge_stencil=edge_stencil, d=1)
135
+ ddy_T = gradient(T , y, axis=0, acc=acc, edge_stencil=edge_stencil, d=1)
136
+ ddy_p = gradient(p , y, axis=0, acc=acc, edge_stencil=edge_stencil, d=1)
137
+ ddy_rho = gradient(rho , y, axis=0, acc=acc, edge_stencil=edge_stencil, d=1)
138
+
139
+ ## wall quantities
140
+ ddy_u_wall = float( ddy_u[0] )
141
+ ddy_T_wall = float( ddy_T[0] )
142
+ rho_wall = float( rho[0] )
143
+ nu_wall = float( nu[0] )
144
+ mu_wall = float( mu[0] )
145
+ T_wall = float( T[0] )
146
+ tau_wall = mu_wall * ddy_u_wall
147
+
148
+ u_tau = np.sqrt( tau_wall / rho_wall ) ## uτ
149
+ sc_u_in = u_tau
150
+ sc_l_in = nu_wall / u_tau ## δν
151
+ sc_t_in = nu_wall / u_tau**2 ## tν
152
+ np.testing.assert_allclose(sc_t_in, sc_l_in/sc_u_in, rtol=1e-14, atol=1e-14)
153
+
154
+ if verbose: even_print('ρw',f'{rho_wall:0.5f} [kg/m³]')
155
+ if verbose: even_print('Tw',f'{T_wall:0.2f} [K]')
156
+ if verbose: even_print('μw',f'{mu_wall:0.5E} [kg/(m·s)]')
157
+ if verbose: even_print('νw',f'{nu_wall:0.5E} [m²/s]')
158
+ if verbose: even_print('uτ',f'{u_tau:0.5E} [m/s]')
159
+ if verbose: even_print('τw',f'{tau_wall:0.5E} [Pa]')
160
+ if verbose: even_print('δν',f'{sc_l_in:0.5E} [m]')
161
+ if verbose: even_print('tν',f'{sc_t_in:0.5E} [s]')
162
+ if verbose: even_print('(du/dy)_w',f'{ddy_u_wall:0.3E} [1/s]')
163
+ if verbose: even_print('(dT/dy)_w',f'{ddy_T_wall:0.3E} [K/m]')
164
+ if verbose: print(72*'-')
165
+
166
+ ongrid = True ## snap to [y] index
167
+
168
+ ddy_u_plus = np.copy( ddy_u / (u_tau/sc_l_in) ) ## du+/dy+ = (du/dy)/(uτ/δν) = (du/dy)/(uτ^2/νw)
169
+
170
+ ## get edge --> where |du+/dy+|<ϵ
171
+ y_edge = calc_profile_edge_1d(
172
+ y=y, ## dimensional
173
+ ddy_u=ddy_u_plus,
174
+ ongrid=ongrid,
175
+ epsilon=epsilon,
176
+ acc=acc,
177
+ edge_stencil=edge_stencil,
178
+ interp_kind='cubic',
179
+ )
180
+
181
+ j_edge = np.abs( y - y_edge ).argmin()
182
+ if not np.isclose(y[j_edge], y_edge, rtol=1e-14):
183
+ raise ValueError
184
+
185
+ if verbose: even_print('ϵ',f'{epsilon:0.5E}')
186
+ if verbose: even_print('j_edge',f'{j_edge:d}')
187
+ if verbose: even_print('(du+/dy+)_edge',f'{ddy_u_plus[j_edge]:0.5E}')
188
+ if verbose: even_print('y_edge',f'{y_edge:0.5E} [m]')
189
+ if verbose: even_print('y+_edge',f'{y_edge/sc_l_in:0.3f}')
190
+
191
+ aa = (y_edge-y.min())/(y.max()-y.min())
192
+ if verbose: even_print('(y_edge-ymin)/(ymax-ymin)',f'{aa:0.3f}')
193
+
194
+ # ===
195
+
196
+ u_edge = u[j_edge]
197
+ #v_edge = v[j_edge]
198
+ #w_edge = w[j_edge]
199
+ T_edge = T[j_edge]
200
+ rho_edge = rho[j_edge]
201
+ mu_edge = mu[j_edge]
202
+ nu_edge = nu[j_edge]
203
+
204
+ ## δ99
205
+ d99 = calc_d99_1d(
206
+ y=y,
207
+ u=u,
208
+ y_edge=y_edge,
209
+ u_edge=u_edge,
210
+ rtol=1e-3,
211
+ interp_kind='cubic',
212
+ )
213
+
214
+ # ## grid-snapped δ99 --> not used
215
+ # j99 = np.abs( y - d99 ).argmin()
216
+ # d99g = y[j99]
217
+
218
+ u_99 = float( sp.interpolate.interp1d(y, u, kind='cubic', bounds_error=True)(d99) )
219
+
220
+ ## outer scales
221
+ sc_l_out = d99
222
+ sc_u_out = u_99
223
+ sc_t_out = d99/u_99
224
+ np.testing.assert_allclose(sc_t_out, sc_l_out/sc_u_out, rtol=1e-14, atol=1e-14)
225
+
226
+ t_meas = self.duration_avg * (self.lchar / self.U_inf)
227
+ t_eddy = t_meas / ( d99 / u_tau )
228
+
229
+ ## get BL integral quantities
230
+ dd = calc_bl_integral_quantities_1d(
231
+ y=y,
232
+ u=u,
233
+ rho=rho,
234
+ u_tau=u_tau,
235
+ d99=d99,
236
+ y_edge=y_edge,
237
+ rho_edge=rho_edge,
238
+ nu_edge=nu_edge,
239
+ u_edge=u_edge,
240
+ nu_wall=nu_wall,
241
+ )
242
+
243
+ # === add to file
244
+
245
+ gn = 'data_dim'
246
+
247
+ ## if group already exists in file, delete it entirely
248
+ if (gn in self):
249
+ del self[gn]
250
+
251
+ ## 1D
252
+
253
+ self.create_dataset(f'{gn}/u' , data=u , chunks=None)
254
+ self.create_dataset(f'{gn}/rho' , data=rho , chunks=None)
255
+
256
+ self.create_dataset(f'{gn}/ddy_u' , data=ddy_u , chunks=None)
257
+ self.create_dataset(f'{gn}/ddy_v' , data=ddy_v , chunks=None)
258
+ self.create_dataset(f'{gn}/ddy_T' , data=ddy_T , chunks=None)
259
+ self.create_dataset(f'{gn}/ddy_p' , data=ddy_p , chunks=None)
260
+ self.create_dataset(f'{gn}/ddy_rho' , data=ddy_rho , chunks=None)
261
+
262
+ self.create_dataset(f'{gn}/z1d' , data=z , chunks=None)
263
+ self.create_dataset(f'{gn}/z' , data=z , chunks=None)
264
+
265
+ ## 0D
266
+
267
+ self.create_dataset(f'{gn}/dz0' , data=dz0 , chunks=None)
268
+ self.create_dataset(f'{gn}/dt' , data=dt , chunks=None)
269
+
270
+ self.create_dataset(f'{gn}/y_edge' , data=y_edge , chunks=None)
271
+ self.create_dataset(f'{gn}/d99' , data=d99 , chunks=None)
272
+ self.create_dataset(f'{gn}/u_99' , data=u_99 , chunks=None)
273
+
274
+ self.create_dataset(f'{gn}/u_edge' , data=u_edge , chunks=None)
275
+ self.create_dataset(f'{gn}/rho_edge' , data=rho_edge , chunks=None)
276
+ self.create_dataset(f'{gn}/mu_edge' , data=mu_edge , chunks=None)
277
+ self.create_dataset(f'{gn}/nu_edge' , data=nu_edge , chunks=None)
278
+ self.create_dataset(f'{gn}/T_edge' , data=T_edge , chunks=None)
279
+
280
+ self.create_dataset(f'{gn}/u_tau' , data=u_tau , chunks=None)
281
+
282
+ self.create_dataset(f'{gn}/ddy_u_wall' , data=ddy_u_wall , chunks=None )
283
+ self.create_dataset(f'{gn}/ddy_T_wall' , data=ddy_T_wall , chunks=None )
284
+ self.create_dataset(f'{gn}/rho_wall' , data=rho_wall , chunks=None )
285
+ self.create_dataset(f'{gn}/nu_wall' , data=nu_wall , chunks=None )
286
+ self.create_dataset(f'{gn}/mu_wall' , data=mu_wall , chunks=None )
287
+ self.create_dataset(f'{gn}/T_wall' , data=T_wall , chunks=None )
288
+ self.create_dataset(f'{gn}/tau_wall' , data=tau_wall , chunks=None )
289
+ #self.create_dataset(f'{gn}/q_wall' , data=q_wall , chunks=None )
290
+
291
+ self.create_dataset(f'{gn}/sc_u_in' , data=sc_u_in , chunks=None)
292
+ self.create_dataset(f'{gn}/sc_l_in' , data=sc_l_in , chunks=None)
293
+ self.create_dataset(f'{gn}/sc_t_in' , data=sc_t_in , chunks=None)
294
+ self.create_dataset(f'{gn}/sc_u_out' , data=sc_u_out , chunks=None)
295
+ self.create_dataset(f'{gn}/sc_l_out' , data=sc_l_out , chunks=None)
296
+ self.create_dataset(f'{gn}/sc_t_out' , data=sc_t_out , chunks=None)
297
+
298
+ ## add integrated quantities (all 0D)
299
+ for key,val in dd.items():
300
+ self.create_dataset(f'{gn}/{key}', data=val, chunks=None)
301
+
302
+ ## report
303
+ if verbose:
304
+ print(72*'-')
305
+ even_print('Reτ' , '%0.1f'%dd['Re_tau'] )
306
+ even_print('Reθ' , '%0.1f'%dd['Re_theta'] )
307
+ even_print('θ' , '%0.5E [m]'%dd['theta_cmp'] )
308
+ even_print('δ*' , '%0.5E [m]'%dd['dstar_cmp'] )
309
+ even_print('H12' , '%0.5f'%dd['H12'] )
310
+ even_print('δ99' , '%0.5E [m]'%d99 )
311
+ even_print('θ/δ99' , '%0.5f'%(dd['theta_cmp']/d99) )
312
+ even_print('δ*/δ99' , '%0.5f'%(dd['dstar_cmp']/d99) )
313
+
314
+ even_print('uτ' , f'{u_tau:0.5E} [m/s]' )
315
+ even_print('νw' , f'{nu_wall:0.5E} [m²/s]' )
316
+ even_print('τw' , f'{tau_wall:0.5E} [Pa]' )
317
+
318
+ even_print('τw/q_inf' , '%0.5E'%(tau_wall/(self.rho_inf*self.U_inf**2)) )
319
+ even_print('cf = 2·τw/(ρe·ue²)' , '%0.5E'%(2*tau_wall/(rho_edge*u_edge**2)) )
320
+ even_print('t_meas' , '%0.5E [s]'%t_meas )
321
+ even_print('t_meas/tchar' , '%0.1f'%(t_meas/self.tchar) )
322
+ even_print('t_eddy = t_meas/(δ99/uτ)' , '%0.2f'%t_eddy )
323
+ even_print('t_meas/(δ99/u_99)' , '%0.2f'%(t_meas/(d99/u_99)) )
324
+ even_print('t_meas/(20·δ99/u_99)' , '%0.2f'%(t_meas/(20*d99/u_99)) )
325
+ print(72*'-')
326
+ even_print('sc_u_in = uτ' , '%0.5E [m/s]'%(sc_u_in,) )
327
+ even_print('sc_l_in = δν = νw/uτ' , '%0.5E [m]'%(sc_l_in,) )
328
+ even_print('sc_t_in = tν = νw/uτ²' , '%0.5E [s]'%(sc_t_in,) )
329
+ even_print('sc_u_out = u_99' , '%0.5E [m/s]'%(sc_u_out,) )
330
+ even_print('sc_l_out = δ99' , '%0.5E [m]'%(sc_l_out,) )
331
+ even_print('sc_t_out = δ99/u_99' , '%0.5E [s]'%(sc_t_out,) )
332
+
333
+ if verbose: print(72*'-')
334
+ if verbose: print('total time : rgd.add_mean_dimensional_data_xpln() : %s'%format_time_string((timeit.default_timer() - t_start_func)))
335
+ if verbose: print(72*'-')
336
+ return