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
|
@@ -0,0 +1,1193 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import sys
|
|
4
|
+
import timeit
|
|
5
|
+
from pathlib import PurePosixPath
|
|
6
|
+
|
|
7
|
+
import h5py
|
|
8
|
+
import numpy as np
|
|
9
|
+
import psutil
|
|
10
|
+
from mpi4py import MPI
|
|
11
|
+
from tqdm import tqdm
|
|
12
|
+
|
|
13
|
+
#from .rgd import rgd ## no!
|
|
14
|
+
from .gradient import gradient
|
|
15
|
+
from .h5 import h5_chunk_sizer, h5_print_contents
|
|
16
|
+
from .utils import even_print, format_time_string
|
|
17
|
+
|
|
18
|
+
# ======================================================================
|
|
19
|
+
|
|
20
|
+
def _calc_turb_budget_xpln(self, **kwargs):
|
|
21
|
+
'''
|
|
22
|
+
calculate budget of turbulent kinetic energy (k)
|
|
23
|
+
-----
|
|
24
|
+
- dimensional [SI]
|
|
25
|
+
- designed for analyzing unsteady, thin planes in [x]
|
|
26
|
+
-----
|
|
27
|
+
SI units of terms are [kg/(m·s³)] or [kg m^-1 s^-3]
|
|
28
|
+
normalize with
|
|
29
|
+
* ν / u**4 / ρ --> *[ kg^-1 m s^3]
|
|
30
|
+
or
|
|
31
|
+
/ ( u**4 * ρ / ν ) --> /[kg m^-1 s^-3]
|
|
32
|
+
-----
|
|
33
|
+
Pirozzoli Grasso Gatski (2004)
|
|
34
|
+
Direct numerical simulation and analysis of a spatially evolving supersonic turbulent boundary layer at M=2.25
|
|
35
|
+
https://doi.org/10.1063/1.1637604
|
|
36
|
+
-----
|
|
37
|
+
Gaurini Moser Shariff Wray (2000)
|
|
38
|
+
Direct numerical simulation of a supersonic turbulent boundary layer at Mach 2.5
|
|
39
|
+
https://doi.org/10.1017/S0022112000008466
|
|
40
|
+
'''
|
|
41
|
+
|
|
42
|
+
rgd_meta = type(self) ## workaround for using rgd()
|
|
43
|
+
|
|
44
|
+
if (self.rank==0):
|
|
45
|
+
verbose = True
|
|
46
|
+
else:
|
|
47
|
+
verbose = False
|
|
48
|
+
|
|
49
|
+
if verbose: print('\n'+'rgd.calc_turb_budget_xpln()'+'\n'+72*'-')
|
|
50
|
+
t_start_func = timeit.default_timer()
|
|
51
|
+
|
|
52
|
+
if (self.fsubtype!='unsteady'):
|
|
53
|
+
raise RuntimeError(f"file subtype must be 'unsteady' but is '{str(self.fsubtype)}'")
|
|
54
|
+
|
|
55
|
+
if not self.usingmpi:
|
|
56
|
+
raise ValueError('rgd.calc_turb_budget_xpln() currently only works in MPI mode')
|
|
57
|
+
|
|
58
|
+
rx = kwargs.get('rx',1)
|
|
59
|
+
ry = kwargs.get('ry',1)
|
|
60
|
+
rz = kwargs.get('rz',1)
|
|
61
|
+
rt = kwargs.get('rt',1)
|
|
62
|
+
|
|
63
|
+
## number of subdivisions per rank [t] range
|
|
64
|
+
ct = kwargs.get( 'ct' , int((self.nt//self.n_ranks)//4) )
|
|
65
|
+
if not isinstance(ct,int) or (ct<1):
|
|
66
|
+
raise TypeError('ct should be a positive non-zero int')
|
|
67
|
+
|
|
68
|
+
# st = kwargs.get('st',1)
|
|
69
|
+
# if not isinstance(st,int) or (st<1):
|
|
70
|
+
# raise TypeError('st should be a positive non-zero int')
|
|
71
|
+
# if (self.nt%st!=0):
|
|
72
|
+
# raise ValueError('nt not divisible by st')
|
|
73
|
+
|
|
74
|
+
force = kwargs.get('force',False)
|
|
75
|
+
|
|
76
|
+
fn_h5_mean = kwargs.get('fn_h5_mean',None)
|
|
77
|
+
fn_h5_out = kwargs.get('fn_h5_out',None)
|
|
78
|
+
|
|
79
|
+
save_unsteady = kwargs.get('save_unsteady',False)
|
|
80
|
+
fn_h5_out_unsteady = kwargs.get('fn_h5_out_unsteady',None)
|
|
81
|
+
|
|
82
|
+
acc = kwargs.get('acc', 6)
|
|
83
|
+
edge_stencil = kwargs.get('edge_stencil', 'half')
|
|
84
|
+
|
|
85
|
+
chunk_kb = kwargs.get('chunk_kb',4*1024) ## h5 chunk size: default 4 [MB]
|
|
86
|
+
chunk_constraint = kwargs.get('chunk_constraint',(1,None,None,None)) ## the 'constraint' parameter for sizing h5 chunks
|
|
87
|
+
chunk_base = kwargs.get('chunk_base',2)
|
|
88
|
+
|
|
89
|
+
## only distribute data in [t]
|
|
90
|
+
if (rx!=1):
|
|
91
|
+
raise AssertionError('rx!=1')
|
|
92
|
+
if (ry!=1):
|
|
93
|
+
raise AssertionError('ry!=1')
|
|
94
|
+
if (rz!=1):
|
|
95
|
+
raise AssertionError('rz!=1')
|
|
96
|
+
|
|
97
|
+
if not isinstance(rt,int) or (rt<1):
|
|
98
|
+
raise ValueError('rt should be a positive non-zero int')
|
|
99
|
+
|
|
100
|
+
if (rx*ry*rz*rt != self.n_ranks):
|
|
101
|
+
raise AssertionError('rx*ry*rz*rt != self.n_ranks')
|
|
102
|
+
if (rx>self.nx):
|
|
103
|
+
raise AssertionError('rx>self.nx')
|
|
104
|
+
if (ry>self.ny):
|
|
105
|
+
raise AssertionError('ry>self.ny')
|
|
106
|
+
if (rz>self.nz):
|
|
107
|
+
raise AssertionError('rz>self.nz')
|
|
108
|
+
if (rt>self.nt):
|
|
109
|
+
raise AssertionError('rt>self.nt')
|
|
110
|
+
|
|
111
|
+
# ===
|
|
112
|
+
|
|
113
|
+
rtl_ = np.array_split(np.arange(self.nt,dtype=np.int64),rt)
|
|
114
|
+
rtl = [[b[0],b[-1]+1] for b in rtl_ ]
|
|
115
|
+
rt1,rt2 = rtl[self.rank]
|
|
116
|
+
ntr = rt2 - rt1
|
|
117
|
+
|
|
118
|
+
if (ntr<1):
|
|
119
|
+
print(f'rank {self.rank:d} ntr < 1')
|
|
120
|
+
self.comm.Abort(1)
|
|
121
|
+
if (ntr<ct):
|
|
122
|
+
print(f'rank {self.rank:d} ntr < ct')
|
|
123
|
+
self.comm.Abort(1)
|
|
124
|
+
|
|
125
|
+
## [t] sub chunk range --> ctl = list of ranges in rt1:rt2
|
|
126
|
+
ctl_ = np.array_split( np.arange(rt1,rt2) , ct )
|
|
127
|
+
ctl = [[b[0],b[-1]+1] for b in ctl_ ]
|
|
128
|
+
|
|
129
|
+
## check that no sub ranges are <=1
|
|
130
|
+
for a_ in [ ctl_[1]-ctl_[0] for ctl_ in ctl ]:
|
|
131
|
+
if (a_ <= 1):
|
|
132
|
+
#raise ValueError
|
|
133
|
+
print(f'rank {self.rank:d} has [t] a chunk subrange <= 1')
|
|
134
|
+
self.comm.Abort(1)
|
|
135
|
+
|
|
136
|
+
## the average sub [t] chunk size on this rank
|
|
137
|
+
#avg_ntc = np.mean( [ ctl_[1]-ctl_[0] for ctl_ in ctl ] )
|
|
138
|
+
#min_ntc = min( [ ctl_[1]-ctl_[0] for ctl_ in ctl ] )
|
|
139
|
+
#max_ntc = max( [ ctl_[1]-ctl_[0] for ctl_ in ctl ] )
|
|
140
|
+
|
|
141
|
+
## get all ntcs
|
|
142
|
+
my_ntcs = [ ctl_[1]-ctl_[0] for ctl_ in ctl ]
|
|
143
|
+
G = self.comm.gather([ self.rank , my_ntcs ], root=0)
|
|
144
|
+
G = self.comm.bcast(G, root=0)
|
|
145
|
+
|
|
146
|
+
allntcs = []
|
|
147
|
+
for G_ in G:
|
|
148
|
+
allntcs += G_[1]
|
|
149
|
+
allntcs = np.array( allntcs , dtype=np.int64 )
|
|
150
|
+
|
|
151
|
+
avg_ntc = np.mean( allntcs , dtype=np.float64 )
|
|
152
|
+
min_ntc = allntcs.min()
|
|
153
|
+
max_ntc = allntcs.max()
|
|
154
|
+
|
|
155
|
+
if 1: ## check that [t] sub-chunk ranges are correct
|
|
156
|
+
|
|
157
|
+
mytimeindices = []
|
|
158
|
+
for ctl_ in ctl:
|
|
159
|
+
ct1, ct2 = ctl_
|
|
160
|
+
mytimeindices += [ ti_ for ti_ in self.ti[ct1:ct2] ]
|
|
161
|
+
|
|
162
|
+
G = self.comm.gather([ self.rank , mytimeindices ], root=0)
|
|
163
|
+
G = self.comm.bcast(G, root=0)
|
|
164
|
+
|
|
165
|
+
alltimeindices = []
|
|
166
|
+
for G_ in G:
|
|
167
|
+
alltimeindices += G_[1]
|
|
168
|
+
alltimeindices = np.array( sorted(alltimeindices), dtype=np.int64 )
|
|
169
|
+
|
|
170
|
+
if not np.array_equal( alltimeindices , self.ti ):
|
|
171
|
+
raise AssertionError
|
|
172
|
+
if not np.array_equal( alltimeindices , np.arange(self.nt, dtype=np.int64) ):
|
|
173
|
+
raise AssertionError
|
|
174
|
+
|
|
175
|
+
self.comm.Barrier()
|
|
176
|
+
|
|
177
|
+
## mean file name (for reading)
|
|
178
|
+
if (fn_h5_mean is None):
|
|
179
|
+
fname_path = os.path.dirname(self.fname)
|
|
180
|
+
fname_base = os.path.basename(self.fname)
|
|
181
|
+
fname_root, fname_ext = os.path.splitext(fname_base)
|
|
182
|
+
fname_mean_h5_base = fname_root+'_mean.h5'
|
|
183
|
+
#fn_h5_mean = os.path.join(fname_path, fname_mean_h5_base)
|
|
184
|
+
fn_h5_mean = str(PurePosixPath(fname_path, fname_mean_h5_base))
|
|
185
|
+
#fn_h5_mean = Path(fname_path, fname_mean_h5_base)
|
|
186
|
+
|
|
187
|
+
if not os.path.isfile(fn_h5_mean):
|
|
188
|
+
raise FileNotFoundError('%s not found!'%fn_h5_mean)
|
|
189
|
+
|
|
190
|
+
## turb_budget .h5 file name (for writing) --> AVERAGED
|
|
191
|
+
if (fn_h5_out is None):
|
|
192
|
+
fname_path = os.path.dirname(self.fname)
|
|
193
|
+
fname_base = os.path.basename(self.fname)
|
|
194
|
+
fname_root, fname_ext = os.path.splitext(fname_base)
|
|
195
|
+
fname_root = re.findall(r'io\S+_mpi_[0-9]+', fname_root)[0]
|
|
196
|
+
fn_h5_out_base = fname_root+'_turb_budget.h5'
|
|
197
|
+
fn_h5_out = str(PurePosixPath(fname_path, fn_h5_out_base))
|
|
198
|
+
|
|
199
|
+
if os.path.isfile(fn_h5_out) and (force is False):
|
|
200
|
+
raise ValueError(f'{fn_h5_out} already present & force=False')
|
|
201
|
+
|
|
202
|
+
## turb_budget .h5 file name (for writing) --> UNSTEADY
|
|
203
|
+
if save_unsteady:
|
|
204
|
+
if (fn_h5_out_unsteady is None):
|
|
205
|
+
fname_path = os.path.dirname(self.fname)
|
|
206
|
+
fname_base = os.path.basename(self.fname)
|
|
207
|
+
fname_root, fname_ext = os.path.splitext(fname_base)
|
|
208
|
+
fname_root = re.findall(r'io\S+_mpi_[0-9]+', fname_root)[0]
|
|
209
|
+
fn_h5_out_unsteady_base = fname_root+'_turb_budget_unsteady.h5'
|
|
210
|
+
fn_h5_out_unsteady = str(PurePosixPath(fname_path, fn_h5_out_unsteady_base))
|
|
211
|
+
|
|
212
|
+
if os.path.isfile(fn_h5_out_unsteady) and (force is False):
|
|
213
|
+
raise ValueError(f'{fn_h5_out_unsteady} already present & force=False')
|
|
214
|
+
|
|
215
|
+
if verbose: even_print('fn_h5' , self.fname )
|
|
216
|
+
if verbose: even_print('fn_h5_mean' , fn_h5_mean )
|
|
217
|
+
if verbose: even_print('fn_h5_out' , fn_h5_out )
|
|
218
|
+
if verbose: print(72*'-')
|
|
219
|
+
if verbose: even_print('save unsteady' , str(save_unsteady) )
|
|
220
|
+
if verbose and save_unsteady:
|
|
221
|
+
even_print('unsteady file' , fn_h5_out_unsteady )
|
|
222
|
+
if verbose: print(72*'-')
|
|
223
|
+
|
|
224
|
+
# ===
|
|
225
|
+
|
|
226
|
+
if verbose: even_print('nx' , f'{self.nx:d}' )
|
|
227
|
+
if verbose: even_print('ny' , f'{self.ny:d}' )
|
|
228
|
+
if verbose: even_print('nz' , f'{self.nz:d}' )
|
|
229
|
+
if verbose: even_print('nt' , f'{self.nt:d}' )
|
|
230
|
+
if verbose: print(72*'-')
|
|
231
|
+
if verbose: even_print('rt' , f'{rt:d}' )
|
|
232
|
+
if verbose: even_print('ct' , f'{ct:d}' )
|
|
233
|
+
#if verbose: even_print('st' , f'{st:d}' )
|
|
234
|
+
if verbose: even_print('ntr' , f'{ntr:d}' )
|
|
235
|
+
if verbose: even_print('avg [t] chunk nt' , f'{avg_ntc:0.6f}' )
|
|
236
|
+
if verbose: even_print('min [t] chunk nt' , f'{min_ntc:d}' )
|
|
237
|
+
if verbose: even_print('max [t] chunk nt' , f'{max_ntc:d}' )
|
|
238
|
+
if verbose: print(72*'-')
|
|
239
|
+
|
|
240
|
+
# === init outfiles
|
|
241
|
+
|
|
242
|
+
#if verbose: print(72*'*')
|
|
243
|
+
if verbose: print(fn_h5_out)
|
|
244
|
+
if verbose: print(len(fn_h5_out)*'-')
|
|
245
|
+
|
|
246
|
+
## initialize file: turbulent kinetic energy budget, AVERAGED
|
|
247
|
+
#with rgd(fn_h5_out, 'w', force=force, driver='mpio', comm=self.comm) as f1:
|
|
248
|
+
with rgd_meta(fn_h5_out, 'w', force=force, driver='mpio', comm=self.comm) as f1:
|
|
249
|
+
|
|
250
|
+
f1.init_from_rgd(self.fname, t_info=False)
|
|
251
|
+
|
|
252
|
+
## set some top-level attributes
|
|
253
|
+
#f1.attrs['duration_avg'] = duration_avg ## duration of mean
|
|
254
|
+
f1.attrs['duration_avg'] = self.t[-1] - self.t[0]
|
|
255
|
+
#f1_mean.attrs['duration_avg'] = self.duration
|
|
256
|
+
f1.attrs['dt'] = self.t[1] - self.t[0]
|
|
257
|
+
#f1.attrs['fclass'] = 'rgd'
|
|
258
|
+
f1.attrs['fsubtype'] = 'mean'
|
|
259
|
+
|
|
260
|
+
shape = (1,f1.nz,f1.ny,f1.nx)
|
|
261
|
+
chunks = h5_chunk_sizer(nxi=shape, constraint=chunk_constraint, size_kb=chunk_kb, base=chunk_base, itemsize=8)
|
|
262
|
+
|
|
263
|
+
data_gb = 8 * 1 * f1.nz*f1.ny*f1.nx / 1024**3
|
|
264
|
+
|
|
265
|
+
for dss in ['production','dissipation','transport','diffusion','p_dilatation','p_diffusion']:
|
|
266
|
+
|
|
267
|
+
if verbose:
|
|
268
|
+
even_print('initializing data/%s'%(dss,),'%0.1f [GB]'%(data_gb,))
|
|
269
|
+
|
|
270
|
+
dset = f1.create_dataset(
|
|
271
|
+
f'data/{dss}',
|
|
272
|
+
shape=shape,
|
|
273
|
+
dtype=np.float64,
|
|
274
|
+
chunks=chunks,
|
|
275
|
+
#data=np.full(shape,0.,np.float64),
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
chunk_kb_ = np.prod(dset.chunks) * dset.dtype.itemsize / 1024. ## actual
|
|
279
|
+
if verbose:
|
|
280
|
+
even_print('chunk shape (t,z,y,x)','%s'%str(dset.chunks))
|
|
281
|
+
even_print('chunk size','%i [KB]'%int(round(chunk_kb_)))
|
|
282
|
+
|
|
283
|
+
# === replace dims/t array --> take last time of series
|
|
284
|
+
if ('dims/t' in f1):
|
|
285
|
+
del f1['dims/t']
|
|
286
|
+
f1.create_dataset('dims/t', data=np.array([self.t[-1]],dtype=np.float64), )
|
|
287
|
+
|
|
288
|
+
if hasattr(f1, 'duration_avg'):
|
|
289
|
+
if verbose: even_print('duration_avg', '%0.2f'%f1.duration_avg)
|
|
290
|
+
|
|
291
|
+
if verbose: print(72*'-')
|
|
292
|
+
|
|
293
|
+
## initialize file: turbulent kinetic energy budget, UNSTEADY
|
|
294
|
+
if save_unsteady:
|
|
295
|
+
|
|
296
|
+
if verbose: print(fn_h5_out_unsteady)
|
|
297
|
+
if verbose: print(len(str(fn_h5_out_unsteady))*'-')
|
|
298
|
+
|
|
299
|
+
#with rgd(fn_h5_out_unsteady, 'w', force=force, driver='mpio', comm=self.comm) as f1:
|
|
300
|
+
with rgd_meta(fn_h5_out_unsteady, 'w', force=force, driver='mpio', comm=self.comm) as f1:
|
|
301
|
+
|
|
302
|
+
f1.init_from_rgd(self.fname, t_info=True)
|
|
303
|
+
|
|
304
|
+
## set some top-level attributes
|
|
305
|
+
#f1.attrs['duration_avg'] = duration_avg ## duration of mean
|
|
306
|
+
f1.attrs['duration_avg'] = self.t[-1] - self.t[0]
|
|
307
|
+
#f1_mean.attrs['duration_avg'] = self.duration
|
|
308
|
+
f1.attrs['dt'] = self.t[1] - self.t[0]
|
|
309
|
+
#f1.attrs['fclass'] = 'rgd'
|
|
310
|
+
f1.attrs['fsubtype'] = 'unsteady'
|
|
311
|
+
|
|
312
|
+
shape = (self.nt,f1.nz,f1.ny,f1.nx)
|
|
313
|
+
#chunks = h5_chunk_sizer(nxi=shape, constraint=chunk_constraint, size_kb=chunk_kb, base=chunk_base, itemsize=4)
|
|
314
|
+
chunks = self['data/u'].chunks ## use chunk pattern of this file
|
|
315
|
+
|
|
316
|
+
data_gb = 4*self.nt*f1.nz*f1.ny*f1.nx / 1024**3
|
|
317
|
+
|
|
318
|
+
for dss in ['production','dissipation','transport','diffusion']: #,'p_dilatation','p_diffusion']:
|
|
319
|
+
|
|
320
|
+
if verbose:
|
|
321
|
+
even_print('initializing data/%s'%(dss,),'%0.1f [GB]'%(data_gb,))
|
|
322
|
+
|
|
323
|
+
dset = f1.create_dataset(
|
|
324
|
+
f'data/{dss}',
|
|
325
|
+
shape=shape,
|
|
326
|
+
dtype=np.float32,
|
|
327
|
+
chunks=chunks,
|
|
328
|
+
#data=np.full(shape,0.,np.float32),
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
chunk_kb_ = np.prod(dset.chunks) * dset.dtype.itemsize / 1024. ## actual
|
|
332
|
+
if verbose:
|
|
333
|
+
even_print('chunk shape (t,z,y,x)','%s'%str(dset.chunks))
|
|
334
|
+
even_print('chunk size','%i [KB]'%int(round(chunk_kb_)))
|
|
335
|
+
|
|
336
|
+
if verbose: print(72*'-')
|
|
337
|
+
|
|
338
|
+
self.comm.Barrier()
|
|
339
|
+
|
|
340
|
+
# ===
|
|
341
|
+
|
|
342
|
+
## OPEN the mean file... make sure to close later!
|
|
343
|
+
#hf_mean = rgd(fn_h5_mean, 'r', driver='mpio', comm=self.comm)
|
|
344
|
+
hf_mean = rgd_meta(fn_h5_mean, 'r', driver='mpio', comm=self.comm)
|
|
345
|
+
|
|
346
|
+
## verify contents of the mean file
|
|
347
|
+
np.testing.assert_allclose( hf_mean.x , self.x , atol=1e-12, rtol=1e-12 )
|
|
348
|
+
np.testing.assert_allclose( hf_mean.y , self.y , atol=1e-12, rtol=1e-12 )
|
|
349
|
+
np.testing.assert_allclose( hf_mean.z , self.z , atol=1e-12, rtol=1e-12 )
|
|
350
|
+
np.testing.assert_allclose( hf_mean.lchar , self.lchar , atol=1e-12, rtol=1e-12 )
|
|
351
|
+
np.testing.assert_allclose( hf_mean.U_inf , self.U_inf , atol=1e-12, rtol=1e-12 )
|
|
352
|
+
np.testing.assert_allclose( hf_mean.T_inf , self.T_inf , atol=1e-12, rtol=1e-12 )
|
|
353
|
+
np.testing.assert_allclose( hf_mean.rho_inf , self.rho_inf , atol=1e-12, rtol=1e-12 )
|
|
354
|
+
if (hf_mean.fsubtype!='mean'):
|
|
355
|
+
raise ValueError
|
|
356
|
+
|
|
357
|
+
# ===
|
|
358
|
+
|
|
359
|
+
data = {} ## dict to be output to .dat file
|
|
360
|
+
|
|
361
|
+
if ('data_dim' not in hf_mean):
|
|
362
|
+
raise ValueError('group data_dim not present')
|
|
363
|
+
|
|
364
|
+
## put all data from 'data_dim' into the dictionary data which will be pickled at the end
|
|
365
|
+
for dsn in hf_mean['data_dim'].keys():
|
|
366
|
+
d_ = np.copy( hf_mean[f'data_dim/{dsn}'][()] )
|
|
367
|
+
if (d_.ndim == 0):
|
|
368
|
+
d_ = float(d_)
|
|
369
|
+
data[dsn] = d_
|
|
370
|
+
|
|
371
|
+
## 1D
|
|
372
|
+
#rho_avg = np.copy( hf_mean['data_dim/rho'][()] )
|
|
373
|
+
#u_avg = np.copy( hf_mean['data_dim/u'][()] )
|
|
374
|
+
#v_avg = np.copy( hf_mean['data_dim/v'][()] )
|
|
375
|
+
#w_avg = np.copy( hf_mean['data_dim/w'][()] )
|
|
376
|
+
#T_avg = np.copy( hf_mean['data_dim/T'][()] )
|
|
377
|
+
#p_avg = np.copy( hf_mean['data_dim/p'][()] )
|
|
378
|
+
|
|
379
|
+
## 0D
|
|
380
|
+
u_tau = float( hf_mean['data_dim/u_tau'][()] )
|
|
381
|
+
nu_wall = float( hf_mean['data_dim/nu_wall'][()] )
|
|
382
|
+
rho_wall = float( hf_mean['data_dim/rho_wall'][()] )
|
|
383
|
+
#T_wall = float( hf_mean['data_dim/T_wall'][()] )
|
|
384
|
+
d99 = float( hf_mean['data_dim/d99'][()] )
|
|
385
|
+
u_99 = float( hf_mean['data_dim/u_99'][()] )
|
|
386
|
+
Re_tau = float( hf_mean['data_dim/Re_tau'][()] )
|
|
387
|
+
Re_theta = float( hf_mean['data_dim/Re_theta'][()] )
|
|
388
|
+
#sc_u_in = float( hf_mean['data_dim/sc_u_in'][()] )
|
|
389
|
+
sc_l_in = float( hf_mean['data_dim/sc_l_in'][()] )
|
|
390
|
+
sc_t_in = float( hf_mean['data_dim/sc_t_in'][()] )
|
|
391
|
+
#sc_u_out = float( hf_mean['data_dim/sc_u_out'][()] )
|
|
392
|
+
#sc_l_out = float( hf_mean['data_dim/sc_l_out'][()] )
|
|
393
|
+
#sc_t_out = float( hf_mean['data_dim/sc_t_out'][()] )
|
|
394
|
+
|
|
395
|
+
## 0D scalars
|
|
396
|
+
lchar = self.lchar ; data['lchar'] = lchar
|
|
397
|
+
U_inf = self.U_inf ; data['U_inf'] = U_inf
|
|
398
|
+
rho_inf = self.rho_inf ; data['rho_inf'] = rho_inf
|
|
399
|
+
T_inf = self.T_inf ; data['T_inf'] = T_inf
|
|
400
|
+
|
|
401
|
+
#data['M_inf'] = self.M_inf
|
|
402
|
+
data['Ma'] = self.Ma
|
|
403
|
+
data['Pr'] = self.Pr
|
|
404
|
+
|
|
405
|
+
## read in 1D coordinate arrays & re-dimensionalize
|
|
406
|
+
x = np.copy( self['dims/x'][()] * self.lchar )
|
|
407
|
+
y = np.copy( self['dims/y'][()] * self.lchar )
|
|
408
|
+
z = np.copy( self['dims/z'][()] * self.lchar )
|
|
409
|
+
t = np.copy( self['dims/t'][()] * self.tchar )
|
|
410
|
+
|
|
411
|
+
## dimensional [s]
|
|
412
|
+
dt = self.dt * self.tchar
|
|
413
|
+
np.testing.assert_allclose(dt, t[1]-t[0], rtol=1e-14, atol=1e-14)
|
|
414
|
+
|
|
415
|
+
t_meas = self.duration * self.tchar
|
|
416
|
+
np.testing.assert_allclose(t_meas, t.max()-t.min(), rtol=1e-14, atol=1e-14)
|
|
417
|
+
|
|
418
|
+
t_eddy = t_meas / ( d99 / u_tau )
|
|
419
|
+
|
|
420
|
+
## check if constant Δz (calculate Δz+ later)
|
|
421
|
+
dz0 = np.diff(z)[0]
|
|
422
|
+
if not np.all(np.isclose(np.diff(z), dz0, rtol=1e-7)):
|
|
423
|
+
raise NotImplementedError
|
|
424
|
+
np.testing.assert_allclose(dz0, z[1]-z[0], rtol=1e-14, atol=1e-14)
|
|
425
|
+
|
|
426
|
+
zrange = z.max() - z.min()
|
|
427
|
+
np.testing.assert_allclose(zrange, z[-1]-z[0], rtol=1e-14, atol=1e-14)
|
|
428
|
+
|
|
429
|
+
nx = self.nx ; data['nx'] = nx
|
|
430
|
+
ny = self.ny ; data['ny'] = ny
|
|
431
|
+
nz = self.nz ; data['nz'] = nz
|
|
432
|
+
nt = self.nt ; data['nt'] = nt
|
|
433
|
+
|
|
434
|
+
## add data to dict that gets output
|
|
435
|
+
data['x'] = x
|
|
436
|
+
data['y'] = y
|
|
437
|
+
data['z'] = z
|
|
438
|
+
data['t'] = t
|
|
439
|
+
data['t_meas'] = t_meas
|
|
440
|
+
data['dt'] = dt
|
|
441
|
+
data['dz0'] = dz0
|
|
442
|
+
data['zrange'] = zrange
|
|
443
|
+
|
|
444
|
+
if verbose: even_print('Δt/tchar','%0.8f'%(dt/self.tchar))
|
|
445
|
+
if verbose: even_print('Δt','%0.3e [s]'%(dt,))
|
|
446
|
+
if verbose: even_print('duration/tchar','%0.1f'%(self.duration,))
|
|
447
|
+
if verbose: even_print('duration','%0.3e [s]'%(self.duration*self.tchar,))
|
|
448
|
+
if verbose: print(72*'-')
|
|
449
|
+
|
|
450
|
+
## report
|
|
451
|
+
if verbose:
|
|
452
|
+
even_print('dt' , f'{dt :0.5e} [s]' )
|
|
453
|
+
even_print('t_meas' , f'{t_meas :0.5e} [s]' )
|
|
454
|
+
even_print('dz0' , f'{dz0 :0.5e} [m]' )
|
|
455
|
+
even_print('zrange' , f'{zrange :0.5e} [m]' )
|
|
456
|
+
print(72*'-')
|
|
457
|
+
|
|
458
|
+
## report
|
|
459
|
+
if verbose:
|
|
460
|
+
even_print( 'Reτ' , f'{Re_tau:0.1f}' )
|
|
461
|
+
even_print( 'Reθ' , f'{Re_theta:0.1f}' )
|
|
462
|
+
even_print( 'δ99' , f'{d99:0.5e} [m]' )
|
|
463
|
+
even_print( 'δν=(ν_wall/u_τ)' , f'{sc_l_in:0.5e} [m]' )
|
|
464
|
+
even_print( 'U_inf' , f'{self.U_inf:0.3f} [m/s]' )
|
|
465
|
+
even_print( 'uτ' , f'{u_tau:0.3f} [m/s]' )
|
|
466
|
+
even_print( 'ν_wall' , f'{nu_wall:0.5e} [m²/s]' )
|
|
467
|
+
even_print( 'ρ_wall' , f'{rho_wall:0.6f} [kg/m³]' )
|
|
468
|
+
even_print( 'Δz+' , f'{dz0/sc_l_in:0.3f}' )
|
|
469
|
+
even_print( 'zrange/δ99' , f'{zrange/d99:0.3f}' )
|
|
470
|
+
even_print( 'Δt+' , f'{dt/sc_t_in:0.3f}' )
|
|
471
|
+
print(72*'-')
|
|
472
|
+
|
|
473
|
+
## report
|
|
474
|
+
if verbose:
|
|
475
|
+
even_print('t_meas/(δ99/u_τ) = t_eddy' , '%0.2f'%t_eddy)
|
|
476
|
+
even_print('t_meas/(δ99/u99)' , '%0.2f'%(t_meas/(d99/u_99)))
|
|
477
|
+
even_print('t_meas/(20·δ99/u99)' , '%0.2f'%(t_meas/(20*d99/u_99)))
|
|
478
|
+
print(72*'-')
|
|
479
|
+
|
|
480
|
+
# ===
|
|
481
|
+
|
|
482
|
+
## copy AVG [u,v,w] into memory... DIMENSIONAL
|
|
483
|
+
u_re = np.copy( U_inf * hf_mean['data/u'][0,:,:,:].T ).astype(np.float64)
|
|
484
|
+
v_re = np.copy( U_inf * hf_mean['data/v'][0,:,:,:].T ).astype(np.float64)
|
|
485
|
+
w_re = np.copy( U_inf * hf_mean['data/w'][0,:,:,:].T ).astype(np.float64)
|
|
486
|
+
u_fv = np.copy( U_inf * hf_mean['data/u_fv'][0,:,:,:].T ).astype(np.float64)
|
|
487
|
+
v_fv = np.copy( U_inf * hf_mean['data/v_fv'][0,:,:,:].T ).astype(np.float64)
|
|
488
|
+
w_fv = np.copy( U_inf * hf_mean['data/w_fv'][0,:,:,:].T ).astype(np.float64)
|
|
489
|
+
|
|
490
|
+
p_re = np.copy( rho_inf * U_inf**2 * hf_mean['data/p'][0,:,:,:].T ).astype(np.float64)
|
|
491
|
+
|
|
492
|
+
## get Reynolds avg strain tensor elements
|
|
493
|
+
#dudx_re = gradient( u=u_re , x=x , axis=0 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
494
|
+
#dudy_re = gradient( u=u_re , x=y , axis=1 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
495
|
+
#dudz_re = gradient( u=u_re , x=z , axis=2 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
496
|
+
#dvdx_re = gradient( u=v_re , x=x , axis=0 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
497
|
+
#dvdy_re = gradient( u=v_re , x=y , axis=1 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
498
|
+
#dvdz_re = gradient( u=v_re , x=z , axis=2 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
499
|
+
#dwdx_re = gradient( u=w_re , x=x , axis=0 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
500
|
+
#dwdy_re = gradient( u=w_re , x=y , axis=1 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
501
|
+
#dwdz_re = gradient( u=w_re , x=z , axis=2 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
502
|
+
|
|
503
|
+
## get Favre avg strain tensor elements
|
|
504
|
+
dudx_fv = gradient( u=u_fv , x=x , axis=0 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
505
|
+
dudy_fv = gradient( u=u_fv , x=y , axis=1 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
506
|
+
dudz_fv = gradient( u=u_fv , x=z , axis=2 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
507
|
+
dvdx_fv = gradient( u=v_fv , x=x , axis=0 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
508
|
+
dvdy_fv = gradient( u=v_fv , x=y , axis=1 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
509
|
+
dvdz_fv = gradient( u=v_fv , x=z , axis=2 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
510
|
+
dwdx_fv = gradient( u=w_fv , x=x , axis=0 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
511
|
+
dwdy_fv = gradient( u=w_fv , x=y , axis=1 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
512
|
+
dwdz_fv = gradient( u=w_fv , x=z , axis=2 , acc=acc , edge_stencil=edge_stencil )[:,:,:,np.newaxis]
|
|
513
|
+
|
|
514
|
+
## accumulators for per-timestep sum, at end gets multiplied by (1/nt) to get average
|
|
515
|
+
unsteady_production_sum = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
516
|
+
unsteady_dissipation_sum = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
517
|
+
unsteady_transport_sum = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
518
|
+
unsteady_diffusion_sum = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
519
|
+
unsteady_p_diffusion_sum = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
520
|
+
unsteady_p_dilatation_sum = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
521
|
+
|
|
522
|
+
# ==============================================================
|
|
523
|
+
# check memory
|
|
524
|
+
# ==============================================================
|
|
525
|
+
|
|
526
|
+
hostname = MPI.Get_processor_name()
|
|
527
|
+
mem_free_gb = psutil.virtual_memory().free / 1024**3
|
|
528
|
+
G = self.comm.gather([ self.rank , hostname , mem_free_gb ], root=0)
|
|
529
|
+
G = self.comm.bcast(G, root=0)
|
|
530
|
+
|
|
531
|
+
## multiple ranks per node
|
|
532
|
+
host_mem = {}
|
|
533
|
+
for rank, host, mem in G:
|
|
534
|
+
if (host not in host_mem) or (mem < host_mem[host]):
|
|
535
|
+
host_mem[host] = mem
|
|
536
|
+
total_free = sum(host_mem.values())
|
|
537
|
+
|
|
538
|
+
if verbose:
|
|
539
|
+
for key,value in host_mem.items():
|
|
540
|
+
even_print(f'RAM free {key}', f'{int(np.floor(value)):d} [GB]')
|
|
541
|
+
print(72*'-')
|
|
542
|
+
even_print('RAM free (local,min)', f'{int(np.floor(min(host_mem.values()))):d} [GB]')
|
|
543
|
+
even_print('RAM free (global)', f'{int(np.floor(total_free)):d} [GB]')
|
|
544
|
+
|
|
545
|
+
shape_read = ( nx, ny, nz, max_ntc ) ## local
|
|
546
|
+
if verbose: even_print('read shape (local,max)', f'[{nx:d},{ny:d},{nz:d},{max_ntc:d}]')
|
|
547
|
+
data_gb = np.dtype(np.float64).itemsize * np.prod(shape_read) / 1024**3
|
|
548
|
+
if verbose: even_print('read size (local)', f'{data_gb:0.2f} [GB]')
|
|
549
|
+
if verbose: even_print('read size (global)', f'{int(np.ceil(data_gb*rt)):d} [GB]')
|
|
550
|
+
|
|
551
|
+
fac = 65
|
|
552
|
+
if verbose: even_print(f'read size (global) ×{fac:d}', f'{int(np.ceil(data_gb*rt*fac)):d} [GB]')
|
|
553
|
+
ram_usage_est = data_gb*rt*fac/total_free
|
|
554
|
+
if verbose: even_print('RAM usage estimate', f'{100*ram_usage_est:0.1f} [%]')
|
|
555
|
+
|
|
556
|
+
self.comm.Barrier()
|
|
557
|
+
if (ram_usage_est>0.90):
|
|
558
|
+
print('RAM consumption might be too high. exiting.')
|
|
559
|
+
self.comm.Abort(1)
|
|
560
|
+
|
|
561
|
+
if verbose:
|
|
562
|
+
print(72*'-')
|
|
563
|
+
|
|
564
|
+
# ==============================================================
|
|
565
|
+
# main loop
|
|
566
|
+
# ==============================================================
|
|
567
|
+
|
|
568
|
+
if verbose:
|
|
569
|
+
progress_bar = tqdm(
|
|
570
|
+
total=ct,
|
|
571
|
+
ncols=100,
|
|
572
|
+
desc='turb budget',
|
|
573
|
+
leave=True,
|
|
574
|
+
file=sys.stdout,
|
|
575
|
+
mininterval=0.1,
|
|
576
|
+
smoothing=0.,
|
|
577
|
+
#bar_format="\033[B{l_bar}{bar}| {n}/{total} [{percentage:.1f}%] {elapsed}/{remaining}\033[A\n\b",
|
|
578
|
+
bar_format="{l_bar}{bar}| {n}/{total} [{percentage:.1f}%] {elapsed}/{remaining}",
|
|
579
|
+
ascii="░█",
|
|
580
|
+
colour='#FF6600',
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
ct_counter=0
|
|
584
|
+
for ctl_ in ctl:
|
|
585
|
+
ct_counter += 1
|
|
586
|
+
ct1, ct2 = ctl_
|
|
587
|
+
ntc = ct2 - ct1
|
|
588
|
+
|
|
589
|
+
G = self.comm.gather([ self.rank , ntc ], root=0)
|
|
590
|
+
G = self.comm.bcast(G, root=0)
|
|
591
|
+
ntc_global = sum( [ g[1] for g in G ] )
|
|
592
|
+
|
|
593
|
+
if (ct>1):
|
|
594
|
+
if verbose:
|
|
595
|
+
mesg = f'[t] sub chunk {ct_counter:d}/{ct:d}'
|
|
596
|
+
tqdm.write( mesg )
|
|
597
|
+
tqdm.write( '-'*len(mesg) )
|
|
598
|
+
tqdm.write( even_print('nt in chunk', f'{ntc_global:d}', s=True) )
|
|
599
|
+
|
|
600
|
+
# === read unsteady data
|
|
601
|
+
|
|
602
|
+
ss1 = ['u','v','w','T','rho','p']
|
|
603
|
+
ss2 = ['uI','vI','wI', 'uII','vII','wII', 'pI'] ## 'TI','rhoI'
|
|
604
|
+
|
|
605
|
+
## data buffer
|
|
606
|
+
formats = [ np.float64 for s in ss1+ss2 ]
|
|
607
|
+
shape = (nx,ny,nz,ntc)
|
|
608
|
+
dd = np.zeros(shape=shape, dtype={'names':ss1+ss2, 'formats':formats}, order='C')
|
|
609
|
+
|
|
610
|
+
## read DIMLESS u,v,w,T,rho,p
|
|
611
|
+
for ss in ss1:
|
|
612
|
+
dset = self['data/%s'%ss]
|
|
613
|
+
self.comm.Barrier()
|
|
614
|
+
t_start = timeit.default_timer()
|
|
615
|
+
with dset.collective:
|
|
616
|
+
dd[ss] = dset[ct1:ct2,:,:,:].T
|
|
617
|
+
self.comm.Barrier()
|
|
618
|
+
t_delta = timeit.default_timer() - t_start
|
|
619
|
+
data_gb = dset.dtype.itemsize * nx*ny*nz * ntc_global / 1024**3
|
|
620
|
+
if verbose:
|
|
621
|
+
tqdm.write( even_print('read: %s'%ss, '%0.3f [GB] %0.3f [s] %0.3f [GB/s]'%(data_gb,t_delta,(data_gb/t_delta)), s=True) )
|
|
622
|
+
|
|
623
|
+
## re-dimensionalize unsteady data
|
|
624
|
+
dd['u'][:,:,:,:] *= U_inf
|
|
625
|
+
dd['v'][:,:,:,:] *= U_inf
|
|
626
|
+
dd['w'][:,:,:,:] *= U_inf
|
|
627
|
+
dd['T'][:,:,:,:] *= T_inf
|
|
628
|
+
dd['rho'][:,:,:,:] *= rho_inf
|
|
629
|
+
dd['p'][:,:,:,:] *= ( rho_inf * U_inf**2 )
|
|
630
|
+
|
|
631
|
+
## calculate DIMENSIONAL primes
|
|
632
|
+
dd['uI'][:,:,:,:] = dd['u'] - u_re[:,:,:,np.newaxis]
|
|
633
|
+
dd['vI'][:,:,:,:] = dd['v'] - v_re[:,:,:,np.newaxis]
|
|
634
|
+
dd['wI'][:,:,:,:] = dd['w'] - w_re[:,:,:,np.newaxis]
|
|
635
|
+
dd['uII'][:,:,:,:] = dd['u'] - u_fv[:,:,:,np.newaxis]
|
|
636
|
+
dd['vII'][:,:,:,:] = dd['v'] - v_fv[:,:,:,np.newaxis]
|
|
637
|
+
dd['wII'][:,:,:,:] = dd['w'] - w_fv[:,:,:,np.newaxis]
|
|
638
|
+
dd['pI'][:,:,:,:] = dd['p'] - p_re[:,:,:,np.newaxis]
|
|
639
|
+
|
|
640
|
+
if verbose: tqdm.write(72*'-')
|
|
641
|
+
|
|
642
|
+
data_gb = dd.nbytes / 1024**3
|
|
643
|
+
if verbose:
|
|
644
|
+
tqdm.write(even_print('unsteady data (rank)', f'{data_gb:0.1f} [GB]', s=True))
|
|
645
|
+
|
|
646
|
+
# === make VIEWS of the numpy structured array for convenience
|
|
647
|
+
|
|
648
|
+
#u = dd['u'][:,:,:,:]
|
|
649
|
+
#v = dd['v'][:,:,:,:]
|
|
650
|
+
#w = dd['w'][:,:,:,:]
|
|
651
|
+
T = dd['T'][:,:,:,:]
|
|
652
|
+
#p = dd['p'][:,:,:,:]
|
|
653
|
+
rho = dd['rho'][:,:,:,:]
|
|
654
|
+
|
|
655
|
+
uI = dd['uI'][:,:,:,:]
|
|
656
|
+
vI = dd['vI'][:,:,:,:]
|
|
657
|
+
wI = dd['wI'][:,:,:,:]
|
|
658
|
+
uII = dd['uII'][:,:,:,:]
|
|
659
|
+
vII = dd['vII'][:,:,:,:]
|
|
660
|
+
wII = dd['wII'][:,:,:,:]
|
|
661
|
+
pI = dd['pI'][:,:,:,:]
|
|
662
|
+
|
|
663
|
+
mu = np.copy( self.C_Suth * T**(3/2) / (T + self.S_Suth) )
|
|
664
|
+
#nu = np.copy( mu / rho )
|
|
665
|
+
|
|
666
|
+
# dd = None ; del dd
|
|
667
|
+
|
|
668
|
+
self.comm.Barrier()
|
|
669
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
670
|
+
if verbose:
|
|
671
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
672
|
+
|
|
673
|
+
# === get gradients
|
|
674
|
+
|
|
675
|
+
t_start = timeit.default_timer() ## rank 0 only
|
|
676
|
+
|
|
677
|
+
#dudx = gradient(u, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
678
|
+
#dudy = gradient(u, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
679
|
+
#dudz = gradient(u, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
680
|
+
#dvdx = gradient(v, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
681
|
+
#dvdy = gradient(v, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
682
|
+
#dvdz = gradient(v, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
683
|
+
#dwdx = gradient(w, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
684
|
+
#dwdy = gradient(w, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
685
|
+
#dwdz = gradient(w, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
686
|
+
|
|
687
|
+
duIdx = gradient(uI, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
688
|
+
duIdy = gradient(uI, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
689
|
+
duIdz = gradient(uI, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
690
|
+
dvIdx = gradient(vI, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
691
|
+
dvIdy = gradient(vI, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
692
|
+
dvIdz = gradient(vI, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
693
|
+
dwIdx = gradient(wI, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
694
|
+
dwIdy = gradient(wI, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
695
|
+
dwIdz = gradient(wI, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
696
|
+
|
|
697
|
+
duIIdx = gradient(uII, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
698
|
+
duIIdy = gradient(uII, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
699
|
+
duIIdz = gradient(uII, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
700
|
+
dvIIdx = gradient(vII, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
701
|
+
dvIIdy = gradient(vII, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
702
|
+
dvIIdz = gradient(vII, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
703
|
+
dwIIdx = gradient(wII, x, acc=acc, edge_stencil=edge_stencil, axis=0)
|
|
704
|
+
dwIIdy = gradient(wII, y, acc=acc, edge_stencil=edge_stencil, axis=1)
|
|
705
|
+
dwIIdz = gradient(wII, z, acc=acc, edge_stencil=edge_stencil, axis=2)
|
|
706
|
+
|
|
707
|
+
t_delta = timeit.default_timer() - t_start ## rank 0 only
|
|
708
|
+
|
|
709
|
+
if verbose:
|
|
710
|
+
tqdm.write(even_print('get gradients', format_time_string(t_delta), s=True))
|
|
711
|
+
|
|
712
|
+
self.comm.Barrier()
|
|
713
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
714
|
+
if verbose:
|
|
715
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
716
|
+
|
|
717
|
+
# === stack velocities into vectors and mean-removed strains into tensors
|
|
718
|
+
|
|
719
|
+
t_start = timeit.default_timer()
|
|
720
|
+
|
|
721
|
+
uI_i = np.stack(( uI , vI , wI ), axis=-1)
|
|
722
|
+
uII_i = np.stack(( uII , vII , wII ), axis=-1)
|
|
723
|
+
|
|
724
|
+
duIdx_ij = np.stack((np.stack((duIdx, duIdy, duIdz), axis=4),
|
|
725
|
+
np.stack((dvIdx, dvIdy, dvIdz), axis=4),
|
|
726
|
+
np.stack((dwIdx, dwIdy, dwIdz), axis=4)), axis=5)
|
|
727
|
+
|
|
728
|
+
duIIdx_ij = np.stack((np.stack((duIIdx, duIIdy, duIIdz), axis=4),
|
|
729
|
+
np.stack((dvIIdx, dvIIdy, dvIIdz), axis=4),
|
|
730
|
+
np.stack((dwIIdx, dwIIdy, dwIIdz), axis=4)), axis=5)
|
|
731
|
+
|
|
732
|
+
t_delta = timeit.default_timer() - t_start
|
|
733
|
+
if verbose:
|
|
734
|
+
tqdm.write(even_print('tensor stacking',format_time_string(t_delta), s=True))
|
|
735
|
+
|
|
736
|
+
self.comm.Barrier()
|
|
737
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
738
|
+
if verbose:
|
|
739
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
740
|
+
|
|
741
|
+
# === production : P
|
|
742
|
+
if True:
|
|
743
|
+
|
|
744
|
+
if verbose: tqdm.write(72*'-')
|
|
745
|
+
t_start = timeit.default_timer()
|
|
746
|
+
|
|
747
|
+
r_uII_uII = rho*uII*uII
|
|
748
|
+
r_uII_vII = rho*uII*vII
|
|
749
|
+
r_uII_wII = rho*uII*wII
|
|
750
|
+
|
|
751
|
+
r_vII_uII = rho*vII*uII
|
|
752
|
+
r_vII_vII = rho*vII*vII
|
|
753
|
+
r_vII_wII = rho*vII*wII
|
|
754
|
+
|
|
755
|
+
r_wII_uII = rho*wII*uII
|
|
756
|
+
r_wII_vII = rho*wII*vII
|
|
757
|
+
r_wII_wII = rho*wII*wII
|
|
758
|
+
|
|
759
|
+
## unsteady_production_ = - ( r_uII_uII * dudx_fv + r_uII_vII * dudy_fv + r_uII_wII * dudz_fv \
|
|
760
|
+
## + r_uII_vII * dvdx_fv + r_vII_vII * dvdy_fv + r_vII_wII * dvdz_fv \
|
|
761
|
+
## + r_uII_wII * dwdx_fv + r_vII_wII * dwdy_fv + r_wII_wII * dwdz_fv )
|
|
762
|
+
|
|
763
|
+
r_uIIuII_ij = np.stack((np.stack((r_uII_uII, r_uII_vII, r_uII_wII), axis=4),
|
|
764
|
+
np.stack((r_vII_uII, r_vII_vII, r_vII_wII), axis=4),
|
|
765
|
+
np.stack((r_wII_uII, r_wII_vII, r_wII_wII), axis=4)), axis=5)
|
|
766
|
+
|
|
767
|
+
dudx_fv_ij = np.stack((np.stack((dudx_fv, dudy_fv, dudz_fv), axis=4),
|
|
768
|
+
np.stack((dvdx_fv, dvdy_fv, dvdz_fv), axis=4),
|
|
769
|
+
np.stack((dwdx_fv, dwdy_fv, dwdz_fv), axis=4)), axis=5)
|
|
770
|
+
|
|
771
|
+
unsteady_production = -1*np.einsum('xyztij,xyztij->xyzt', r_uIIuII_ij, dudx_fv_ij)
|
|
772
|
+
|
|
773
|
+
## np.testing.assert_allclose(unsteady_production, unsteady_production_, atol=20000)
|
|
774
|
+
## print('check passed : np.einsum()')
|
|
775
|
+
|
|
776
|
+
t_delta = timeit.default_timer() - t_start
|
|
777
|
+
if verbose:
|
|
778
|
+
tqdm.write(even_print('calc production', format_time_string(t_delta), s=True))
|
|
779
|
+
|
|
780
|
+
self.comm.Barrier()
|
|
781
|
+
|
|
782
|
+
if save_unsteady: ## write 4D unsteady production
|
|
783
|
+
|
|
784
|
+
## technically this is an estimate
|
|
785
|
+
data_gb = self.n_ranks * np.prod(unsteady_production.shape) * unsteady_production.dtype.itemsize / 1024**3
|
|
786
|
+
|
|
787
|
+
#with rgd(fn_h5_out_unsteady, 'a', driver='mpio', comm=self.comm) as f1:
|
|
788
|
+
with rgd_meta(fn_h5_out_unsteady, 'a', driver='mpio', comm=self.comm) as f1:
|
|
789
|
+
dset = f1['data/production']
|
|
790
|
+
self.comm.Barrier()
|
|
791
|
+
t_start = timeit.default_timer()
|
|
792
|
+
with dset.collective:
|
|
793
|
+
dset[ct1:ct2,:,:,:] = unsteady_production.T
|
|
794
|
+
self.comm.Barrier()
|
|
795
|
+
t_delta = timeit.default_timer() - t_start
|
|
796
|
+
if verbose:
|
|
797
|
+
tqdm.write(even_print('write: production', '%0.2f [GB] %0.2f [s] %0.3f [GB/s]'%(data_gb,t_delta,(data_gb/t_delta)), s=True))
|
|
798
|
+
|
|
799
|
+
## combine sums across ranks for this [t] chunk
|
|
800
|
+
unsteady_production_sum_i = np.sum(unsteady_production, axis=3, keepdims=True, dtype=np.float64)
|
|
801
|
+
unsteady_production_sum_buf = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
802
|
+
self.comm.Reduce(
|
|
803
|
+
[unsteady_production_sum_i, MPI.DOUBLE],
|
|
804
|
+
[unsteady_production_sum_buf, MPI.DOUBLE],
|
|
805
|
+
op=MPI.SUM,
|
|
806
|
+
root=0,
|
|
807
|
+
)
|
|
808
|
+
|
|
809
|
+
## add aggregated sum (across ranks) to the total accumulator
|
|
810
|
+
unsteady_production_sum += unsteady_production_sum_buf
|
|
811
|
+
|
|
812
|
+
# === release mem
|
|
813
|
+
r_uII_uII = None; del r_uII_uII
|
|
814
|
+
r_uII_vII = None; del r_uII_vII
|
|
815
|
+
r_uII_wII = None; del r_uII_wII
|
|
816
|
+
r_vII_uII = None; del r_vII_uII
|
|
817
|
+
r_vII_vII = None; del r_vII_vII
|
|
818
|
+
r_vII_wII = None; del r_vII_wII
|
|
819
|
+
r_wII_uII = None; del r_wII_uII
|
|
820
|
+
r_wII_vII = None; del r_wII_vII
|
|
821
|
+
r_wII_wII = None; del r_wII_wII
|
|
822
|
+
r_uIIuII_ij = None; del r_uIIuII_ij
|
|
823
|
+
dudx_fv_ij = None; del dudx_fv_ij
|
|
824
|
+
unsteady_production = None; del unsteady_production
|
|
825
|
+
|
|
826
|
+
self.comm.Barrier()
|
|
827
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
828
|
+
if verbose:
|
|
829
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
830
|
+
|
|
831
|
+
# === dissipation : ε
|
|
832
|
+
if True:
|
|
833
|
+
|
|
834
|
+
if verbose: tqdm.write(72*'-')
|
|
835
|
+
t_start = timeit.default_timer()
|
|
836
|
+
|
|
837
|
+
duIIdx_ij_duIdx_ij = np.einsum('xyztij,xyztij->xyzt', duIIdx_ij, duIdx_ij)
|
|
838
|
+
duIIdx_ij_duIdx_ji = np.einsum('xyztij,xyztji->xyzt', duIIdx_ij, duIdx_ij)
|
|
839
|
+
|
|
840
|
+
## # === from pp_turbulent_budget.F90
|
|
841
|
+
## unsteady_dissipation_ = mu * ( (duIdx + duIdx) * duIIdx + (duIdy + dvIdx) * duIIdy + (duIdz + dwIdx) * duIIdz \
|
|
842
|
+
## + (dvIdx + duIdy) * dvIIdx + (dvIdy + dvIdy) * dvIIdy + (dvIdz + dwIdy) * dvIIdz \
|
|
843
|
+
## + (dwIdx + duIdz) * dwIIdx + (dwIdy + dvIdz) * dwIIdy + (dwIdz + dwIdz) * dwIIdz )
|
|
844
|
+
|
|
845
|
+
unsteady_dissipation = mu*(duIIdx_ij_duIdx_ij + duIIdx_ij_duIdx_ji)
|
|
846
|
+
|
|
847
|
+
## np.testing.assert_allclose(unsteady_dissipation, unsteady_dissipation_, rtol=1e-4)
|
|
848
|
+
## print('check passed : np.einsum() : dissipation')
|
|
849
|
+
|
|
850
|
+
t_delta = timeit.default_timer() - t_start
|
|
851
|
+
if verbose:
|
|
852
|
+
tqdm.write(even_print('calc dissipation', format_time_string(t_delta),s=True))
|
|
853
|
+
|
|
854
|
+
self.comm.Barrier()
|
|
855
|
+
|
|
856
|
+
if save_unsteady: ## write 4D unsteady dissipation
|
|
857
|
+
|
|
858
|
+
## technically this is an estimate
|
|
859
|
+
data_gb = self.n_ranks * np.prod(unsteady_dissipation.shape) * unsteady_dissipation.dtype.itemsize / 1024**3
|
|
860
|
+
|
|
861
|
+
#with rgd(fn_h5_out_unsteady, 'a', driver='mpio', comm=self.comm) as f1:
|
|
862
|
+
with rgd_meta(fn_h5_out_unsteady, 'a', driver='mpio', comm=self.comm) as f1:
|
|
863
|
+
dset = f1['data/dissipation']
|
|
864
|
+
self.comm.Barrier()
|
|
865
|
+
t_start = timeit.default_timer()
|
|
866
|
+
with dset.collective:
|
|
867
|
+
dset[ct1:ct2,:,:,:] = unsteady_dissipation.T
|
|
868
|
+
self.comm.Barrier()
|
|
869
|
+
t_delta = timeit.default_timer() - t_start
|
|
870
|
+
if verbose:
|
|
871
|
+
tqdm.write(even_print('write: dissipation', '%0.2f [GB] %0.2f [s] %0.3f [GB/s]'%(data_gb,t_delta,(data_gb/t_delta)), s=True))
|
|
872
|
+
|
|
873
|
+
## combine sums across ranks for this [t] chunk
|
|
874
|
+
unsteady_dissipation_sum_i = np.sum(unsteady_dissipation, axis=3, keepdims=True, dtype=np.float64)
|
|
875
|
+
unsteady_dissipation_sum_buf = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
876
|
+
self.comm.Reduce(
|
|
877
|
+
[unsteady_dissipation_sum_i, MPI.DOUBLE],
|
|
878
|
+
[unsteady_dissipation_sum_buf, MPI.DOUBLE],
|
|
879
|
+
op=MPI.SUM,
|
|
880
|
+
root=0,
|
|
881
|
+
)
|
|
882
|
+
|
|
883
|
+
## add aggregated sum (across ranks) to the total accumulator
|
|
884
|
+
unsteady_dissipation_sum += unsteady_dissipation_sum_buf
|
|
885
|
+
|
|
886
|
+
## release mem
|
|
887
|
+
duIIdx_ij_duIdx_ij = None; del duIIdx_ij_duIdx_ij
|
|
888
|
+
duIIdx_ij_duIdx_ji = None; del duIIdx_ij_duIdx_ji
|
|
889
|
+
unsteady_dissipation = None; del unsteady_dissipation
|
|
890
|
+
|
|
891
|
+
self.comm.Barrier()
|
|
892
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
893
|
+
if verbose:
|
|
894
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
895
|
+
|
|
896
|
+
# === transport : T
|
|
897
|
+
if True:
|
|
898
|
+
|
|
899
|
+
if verbose: tqdm.write(72*'-')
|
|
900
|
+
t_start = timeit.default_timer()
|
|
901
|
+
|
|
902
|
+
## triple correlation
|
|
903
|
+
tc = np.einsum('xyzt,xyzti,xyzti,xyztj->xyztj', rho, uII_i, uII_i, uII_i)
|
|
904
|
+
|
|
905
|
+
#tc_ddx = np.gradient(tc, x, axis=0, edge_order=2)
|
|
906
|
+
#tc_ddy = np.gradient(tc, y, axis=1, edge_order=2)
|
|
907
|
+
#tc_ddz = np.gradient(tc, z, axis=2, edge_order=2)
|
|
908
|
+
|
|
909
|
+
tc_ddx = gradient(tc, x, axis=0, acc=acc, edge_stencil=edge_stencil)
|
|
910
|
+
tc_ddy = gradient(tc, y, axis=1, acc=acc, edge_stencil=edge_stencil)
|
|
911
|
+
tc_ddz = gradient(tc, z, axis=2, acc=acc, edge_stencil=edge_stencil)
|
|
912
|
+
|
|
913
|
+
unsteady_transport = -0.5*(tc_ddx[:,:,:,:,0] + tc_ddy[:,:,:,:,1] + tc_ddz[:,:,:,:,2])
|
|
914
|
+
|
|
915
|
+
t_delta = timeit.default_timer() - t_start
|
|
916
|
+
if verbose:
|
|
917
|
+
tqdm.write(even_print('calc transport', format_time_string(t_delta),s=True))
|
|
918
|
+
|
|
919
|
+
self.comm.Barrier()
|
|
920
|
+
|
|
921
|
+
if save_unsteady: ## write 4D unsteady transport
|
|
922
|
+
|
|
923
|
+
## technically this is an estimate
|
|
924
|
+
data_gb = self.n_ranks * np.prod(unsteady_transport.shape) * unsteady_transport.dtype.itemsize / 1024**3
|
|
925
|
+
|
|
926
|
+
#with rgd(fn_h5_out_unsteady, 'a', driver='mpio', comm=self.comm) as f1:
|
|
927
|
+
with rgd_meta(fn_h5_out_unsteady, 'a', driver='mpio', comm=self.comm) as f1:
|
|
928
|
+
dset = f1['data/transport']
|
|
929
|
+
self.comm.Barrier()
|
|
930
|
+
t_start = timeit.default_timer()
|
|
931
|
+
with dset.collective:
|
|
932
|
+
dset[ct1:ct2,:,:,:] = unsteady_transport.T
|
|
933
|
+
self.comm.Barrier()
|
|
934
|
+
t_delta = timeit.default_timer() - t_start
|
|
935
|
+
if verbose:
|
|
936
|
+
tqdm.write(even_print('write: transport', '%0.2f [GB] %0.2f [s] %0.3f [GB/s]'%(data_gb,t_delta,(data_gb/t_delta)), s=True))
|
|
937
|
+
|
|
938
|
+
## combine sums across ranks for this [t] chunk
|
|
939
|
+
unsteady_transport_sum_i = np.sum(unsteady_transport, axis=3, keepdims=True, dtype=np.float64)
|
|
940
|
+
unsteady_transport_sum_buf = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
941
|
+
self.comm.Reduce(
|
|
942
|
+
[unsteady_transport_sum_i, MPI.DOUBLE],
|
|
943
|
+
[unsteady_transport_sum_buf, MPI.DOUBLE],
|
|
944
|
+
op=MPI.SUM,
|
|
945
|
+
root=0,
|
|
946
|
+
)
|
|
947
|
+
|
|
948
|
+
## add aggregated sum (across ranks) to the total accumulator
|
|
949
|
+
unsteady_transport_sum += unsteady_transport_sum_buf
|
|
950
|
+
|
|
951
|
+
## release mem
|
|
952
|
+
tc = None; del tc
|
|
953
|
+
tc_ddx = None; del tc_ddx
|
|
954
|
+
tc_ddy = None; del tc_ddy
|
|
955
|
+
tc_ddz = None; del tc_ddz
|
|
956
|
+
unsteady_transport = None; del unsteady_transport
|
|
957
|
+
|
|
958
|
+
self.comm.Barrier()
|
|
959
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
960
|
+
if verbose:
|
|
961
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
962
|
+
|
|
963
|
+
# === viscous diffusion : D
|
|
964
|
+
if True:
|
|
965
|
+
|
|
966
|
+
if verbose: tqdm.write(72*'-')
|
|
967
|
+
t_start = timeit.default_timer()
|
|
968
|
+
|
|
969
|
+
omega_ij = duIdx_ij + np.transpose(duIdx_ij, axes=(0,1,2,3,5,4))
|
|
970
|
+
|
|
971
|
+
if False:
|
|
972
|
+
|
|
973
|
+
omega_ij_2 = np.stack((np.stack(((duIdx+duIdx), (dvIdx+duIdy), (dwIdx+duIdz)), axis=4),
|
|
974
|
+
np.stack(((duIdy+dvIdx), (dvIdy+dvIdy), (dwIdy+dvIdz)), axis=4),
|
|
975
|
+
np.stack(((duIdz+dwIdx), (dvIdz+dwIdy), (dwIdz+dwIdz)), axis=4)), axis=5)
|
|
976
|
+
|
|
977
|
+
np.testing.assert_allclose(omega_ij, omega_ij_2, rtol=1e-8)
|
|
978
|
+
|
|
979
|
+
if verbose:
|
|
980
|
+
print('check passed : omega_ij')
|
|
981
|
+
|
|
982
|
+
A = np.einsum('xyzt,xyzti,xyztij->xyztj', mu, uI_i, omega_ij)
|
|
983
|
+
|
|
984
|
+
A_ddx = gradient(A[:,:,:,:,0], x, axis=0, acc=acc, edge_stencil=edge_stencil)
|
|
985
|
+
A_ddy = gradient(A[:,:,:,:,1], y, axis=1, acc=acc, edge_stencil=edge_stencil)
|
|
986
|
+
A_ddz = gradient(A[:,:,:,:,2], z, axis=2, acc=acc, edge_stencil=edge_stencil)
|
|
987
|
+
|
|
988
|
+
unsteady_diffusion = A_ddx + A_ddy + A_ddz
|
|
989
|
+
|
|
990
|
+
t_delta = timeit.default_timer() - t_start
|
|
991
|
+
if verbose:
|
|
992
|
+
tqdm.write(even_print('calc diffusion', format_time_string(t_delta),s=True))
|
|
993
|
+
|
|
994
|
+
self.comm.Barrier()
|
|
995
|
+
|
|
996
|
+
if save_unsteady: ## write 4D unsteady diffusion
|
|
997
|
+
|
|
998
|
+
## technically this is an estimate
|
|
999
|
+
data_gb = self.n_ranks * np.prod(unsteady_diffusion.shape) * unsteady_diffusion.dtype.itemsize / 1024**3
|
|
1000
|
+
|
|
1001
|
+
#with rgd(fn_h5_out_unsteady, 'a', driver='mpio', comm=self.comm) as f1:
|
|
1002
|
+
with rgd_meta(fn_h5_out_unsteady, 'a', driver='mpio', comm=self.comm) as f1:
|
|
1003
|
+
dset = f1['data/diffusion']
|
|
1004
|
+
self.comm.Barrier()
|
|
1005
|
+
t_start = timeit.default_timer()
|
|
1006
|
+
with dset.collective:
|
|
1007
|
+
dset[ct1:ct2,:,:,:] = unsteady_diffusion.T
|
|
1008
|
+
self.comm.Barrier()
|
|
1009
|
+
t_delta = timeit.default_timer() - t_start
|
|
1010
|
+
if verbose:
|
|
1011
|
+
tqdm.write(even_print('write: diffusion', '%0.2f [GB] %0.2f [s] %0.3f [GB/s]'%(data_gb,t_delta,(data_gb/t_delta)), s=True))
|
|
1012
|
+
|
|
1013
|
+
## combine sums across ranks for this [t] chunk
|
|
1014
|
+
unsteady_diffusion_sum_i = np.sum(unsteady_diffusion, axis=3, keepdims=True, dtype=np.float64)
|
|
1015
|
+
unsteady_diffusion_sum_buf = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
1016
|
+
self.comm.Reduce(
|
|
1017
|
+
[unsteady_diffusion_sum_i, MPI.DOUBLE],
|
|
1018
|
+
[unsteady_diffusion_sum_buf, MPI.DOUBLE],
|
|
1019
|
+
op=MPI.SUM,
|
|
1020
|
+
root=0,
|
|
1021
|
+
)
|
|
1022
|
+
|
|
1023
|
+
## add aggregated sum (across ranks) to the total accumulator
|
|
1024
|
+
unsteady_diffusion_sum += unsteady_diffusion_sum_buf
|
|
1025
|
+
|
|
1026
|
+
## release mem
|
|
1027
|
+
omega_ij = None; del omega_ij
|
|
1028
|
+
A = None; del A
|
|
1029
|
+
A_ddx = None; del A_ddx
|
|
1030
|
+
A_ddy = None; del A_ddy
|
|
1031
|
+
A_ddz = None; del A_ddz
|
|
1032
|
+
unsteady_diffusion = None; del unsteady_diffusion
|
|
1033
|
+
|
|
1034
|
+
self.comm.Barrier()
|
|
1035
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
1036
|
+
if verbose:
|
|
1037
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
1038
|
+
|
|
1039
|
+
# === pressure diffusion
|
|
1040
|
+
if True:
|
|
1041
|
+
|
|
1042
|
+
if verbose: tqdm.write(72*'-')
|
|
1043
|
+
t_start = timeit.default_timer()
|
|
1044
|
+
|
|
1045
|
+
A = np.einsum('xyzti,xyzt->xyzti', uII_i, pI)
|
|
1046
|
+
|
|
1047
|
+
#A_ddx = np.gradient(A[:,:,:,:,0], x, axis=0, edge_order=2)
|
|
1048
|
+
#A_ddy = np.gradient(A[:,:,:,:,1], y, axis=1, edge_order=2)
|
|
1049
|
+
#A_ddz = np.gradient(A[:,:,:,:,2], z, axis=2, edge_order=2)
|
|
1050
|
+
|
|
1051
|
+
A_ddx = gradient(A[:,:,:,:,0], x, axis=0, acc=acc, edge_stencil=edge_stencil)
|
|
1052
|
+
A_ddy = gradient(A[:,:,:,:,1], y, axis=1, acc=acc, edge_stencil=edge_stencil)
|
|
1053
|
+
A_ddz = gradient(A[:,:,:,:,2], z, axis=2, acc=acc, edge_stencil=edge_stencil)
|
|
1054
|
+
|
|
1055
|
+
unsteady_p_diffusion = A_ddx + A_ddy + A_ddz
|
|
1056
|
+
|
|
1057
|
+
t_delta = timeit.default_timer() - t_start
|
|
1058
|
+
if verbose:
|
|
1059
|
+
tqdm.write(even_print('calc p_diffusion', format_time_string(t_delta),s=True))
|
|
1060
|
+
|
|
1061
|
+
self.comm.Barrier()
|
|
1062
|
+
|
|
1063
|
+
## combine sums across ranks for this [t] chunk
|
|
1064
|
+
unsteady_p_diffusion_sum_i = np.sum(unsteady_p_diffusion, axis=3, keepdims=True, dtype=np.float64)
|
|
1065
|
+
unsteady_p_diffusion_sum_buf = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
1066
|
+
self.comm.Reduce(
|
|
1067
|
+
[unsteady_p_diffusion_sum_i, MPI.DOUBLE],
|
|
1068
|
+
[unsteady_p_diffusion_sum_buf, MPI.DOUBLE],
|
|
1069
|
+
op=MPI.SUM,
|
|
1070
|
+
root=0,
|
|
1071
|
+
)
|
|
1072
|
+
|
|
1073
|
+
## add aggregated sum (across ranks) to the total accumulator
|
|
1074
|
+
unsteady_p_diffusion_sum += unsteady_p_diffusion_sum_buf
|
|
1075
|
+
|
|
1076
|
+
# === release mem
|
|
1077
|
+
A = None; del A
|
|
1078
|
+
A_ddx = None; del A_ddx
|
|
1079
|
+
A_ddy = None; del A_ddy
|
|
1080
|
+
A_ddz = None; del A_ddz
|
|
1081
|
+
unsteady_p_diffusion = None; del unsteady_p_diffusion
|
|
1082
|
+
|
|
1083
|
+
self.comm.Barrier()
|
|
1084
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
1085
|
+
if verbose:
|
|
1086
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
1087
|
+
|
|
1088
|
+
# === pressure dilatation
|
|
1089
|
+
if True:
|
|
1090
|
+
|
|
1091
|
+
if verbose: tqdm.write(72*'-')
|
|
1092
|
+
t_start = timeit.default_timer()
|
|
1093
|
+
|
|
1094
|
+
# A = np.einsum('xyzt,xyzti->xyzti', pI, uII_i)
|
|
1095
|
+
# A_ddx = np.gradient(A[:,:,:,:,0], x, axis=0, edge_order=2)
|
|
1096
|
+
# A_ddy = np.gradient(A[:,:,:,:,1], y, axis=1, edge_order=2)
|
|
1097
|
+
# A_ddz = np.gradient(A[:,:,:,:,2], z, axis=2, edge_order=2)
|
|
1098
|
+
# unsteady_p_dilatation = A_ddx + A_ddy + A_ddz
|
|
1099
|
+
|
|
1100
|
+
unsteady_p_dilatation = pI * ( duIIdx + dvIIdy + dwIIdz )
|
|
1101
|
+
|
|
1102
|
+
t_delta = timeit.default_timer() - t_start
|
|
1103
|
+
if verbose:
|
|
1104
|
+
tqdm.write(even_print('calc p_dilatation', format_time_string(t_delta),s=True))
|
|
1105
|
+
|
|
1106
|
+
self.comm.Barrier()
|
|
1107
|
+
|
|
1108
|
+
## combine sums across ranks for this [t] chunk
|
|
1109
|
+
unsteady_p_dilatation_sum_i = np.sum(unsteady_p_dilatation, axis=3, keepdims=True, dtype=np.float64)
|
|
1110
|
+
unsteady_p_dilatation_sum_buf = np.zeros((nx,ny,nz,1), dtype=np.float64, order='C')
|
|
1111
|
+
self.comm.Reduce(
|
|
1112
|
+
[unsteady_p_dilatation_sum_i, MPI.DOUBLE],
|
|
1113
|
+
[unsteady_p_dilatation_sum_buf, MPI.DOUBLE],
|
|
1114
|
+
op=MPI.SUM,
|
|
1115
|
+
root=0,
|
|
1116
|
+
)
|
|
1117
|
+
|
|
1118
|
+
## add aggregated sum (across ranks) to the total accumulator
|
|
1119
|
+
unsteady_p_dilatation_sum += unsteady_p_dilatation_sum_buf
|
|
1120
|
+
|
|
1121
|
+
## release mem
|
|
1122
|
+
unsteady_p_dilatation = None
|
|
1123
|
+
del unsteady_p_dilatation
|
|
1124
|
+
|
|
1125
|
+
self.comm.Barrier()
|
|
1126
|
+
mem_free_gb = psutil.virtual_memory().free/1024**3
|
|
1127
|
+
if verbose:
|
|
1128
|
+
tqdm.write(even_print('mem free', f'{mem_free_gb:0.1f} [GB]', s=True))
|
|
1129
|
+
|
|
1130
|
+
if verbose:
|
|
1131
|
+
progress_bar.update()
|
|
1132
|
+
tqdm.write(72*'-')
|
|
1133
|
+
|
|
1134
|
+
#break ## debug
|
|
1135
|
+
|
|
1136
|
+
if verbose: progress_bar.close()
|
|
1137
|
+
if verbose: print(72*'-')
|
|
1138
|
+
|
|
1139
|
+
## CLOSE the files that were opened
|
|
1140
|
+
hf_mean.close()
|
|
1141
|
+
|
|
1142
|
+
# ==============================================================
|
|
1143
|
+
# multiply accumulators by (1/n) to get [t] avg
|
|
1144
|
+
# ==============================================================
|
|
1145
|
+
|
|
1146
|
+
if (self.rank==0):
|
|
1147
|
+
production = np.copy( ((1/nt) * unsteady_production_sum ) )
|
|
1148
|
+
dissipation = np.copy( ((1/nt) * unsteady_dissipation_sum ) )
|
|
1149
|
+
transport = np.copy( ((1/nt) * unsteady_transport_sum ) )
|
|
1150
|
+
diffusion = np.copy( ((1/nt) * unsteady_diffusion_sum ) )
|
|
1151
|
+
p_diffusion = np.copy( ((1/nt) * unsteady_p_diffusion_sum ) )
|
|
1152
|
+
p_dilatation = np.copy( ((1/nt) * unsteady_p_dilatation_sum ) )
|
|
1153
|
+
self.comm.Barrier()
|
|
1154
|
+
|
|
1155
|
+
# === write to HDF5
|
|
1156
|
+
|
|
1157
|
+
if self.rank==0:
|
|
1158
|
+
#with rgd(fn_h5_out, 'a') as f1:
|
|
1159
|
+
with rgd_meta(fn_h5_out, 'a') as f1:
|
|
1160
|
+
f1['data/production'][:,:,:,:] = production.T
|
|
1161
|
+
f1['data/dissipation'][:,:,:,:] = dissipation.T
|
|
1162
|
+
f1['data/transport'][:,:,:,:] = transport.T
|
|
1163
|
+
f1['data/diffusion'][:,:,:,:] = diffusion.T
|
|
1164
|
+
f1['data/p_diffusion'][:,:,:,:] = p_diffusion.T
|
|
1165
|
+
f1['data/p_dilatation'][:,:,:,:] = p_dilatation.T
|
|
1166
|
+
self.comm.Barrier()
|
|
1167
|
+
|
|
1168
|
+
## report file contents
|
|
1169
|
+
if (self.rank==0):
|
|
1170
|
+
with h5py.File(fn_h5_out,'r') as hfr:
|
|
1171
|
+
h5_print_contents(hfr)
|
|
1172
|
+
self.comm.Barrier()
|
|
1173
|
+
|
|
1174
|
+
if verbose: print(72*'-')
|
|
1175
|
+
if verbose: print('total time : rgd.calc_turb_budget() : %s'%format_time_string((timeit.default_timer() - t_start_func)))
|
|
1176
|
+
if verbose: print(72*'-')
|
|
1177
|
+
|
|
1178
|
+
## make .xdmf
|
|
1179
|
+
if self.rank==0:
|
|
1180
|
+
#with rgd(fn_h5_out, 'r') as f1:
|
|
1181
|
+
with rgd_meta(fn_h5_out, 'r') as f1:
|
|
1182
|
+
f1.make_xdmf()
|
|
1183
|
+
self.comm.Barrier()
|
|
1184
|
+
|
|
1185
|
+
## make .xdmf
|
|
1186
|
+
if save_unsteady:
|
|
1187
|
+
if self.rank==0:
|
|
1188
|
+
#with rgd(fn_h5_out_unsteady, 'r') as f1:
|
|
1189
|
+
with rgd_meta(fn_h5_out_unsteady, 'r') as f1:
|
|
1190
|
+
f1.make_xdmf()
|
|
1191
|
+
self.comm.Barrier()
|
|
1192
|
+
|
|
1193
|
+
return
|